Skip to content

OpenOCF/iochibity

Repository files navigation

OpenOCF

OpenOCF a minimal implementation of the OCF protocol, derived from Iotivity.

Differences:

  • Minimal, 100% C11 - only the C code from Iotivity, none of the C++ stuff

  • The build system is Bazel instead of Scons.

  • The code has been converted (reorganized) to a c-without-include-headers style, using makeheaders from D.Richard Hipp of Sqlite fame.

  • Refactoring and renaming.

    • API is the same, but source layout and some filenames have been changed.

    • Easy cross-compilation (current targets: Raspberry Pi 3B, WindRiver Linux on Intel IoT Gateway, ARM, Android NDK)

  • Arduino code is removed.

  • Java/Android support has been migrated to a separate repo, iochibity-java

    • No Android-specific code in OpenOCF (Work In Progress). Android support in Iotivity involves having the stack call into Android to create objects etc. This has been removed.

The source is in src/ and third_party/.

Warning
The source tree has been reorganized substantially:
  • csdk → //src

  • security → //src/sec

  • security/provisioning → //src/provisioning

  • src and include subdirs have been removed - source and header files go in same director (bazel treats header files as source; this makes good sense imho)

  • most header files are generated at build time, using makeheaders. The exceptions are .h files whose names have a leading underscore, e.g. src/ocf/_device.h; such files are processed by makeheaders, but are not #included anywhere.

Note

Using makeheaders to support a header-free style of programming may be unorthodox, but so far it has been a very positive experience. Each source file includes exactly one header, generated by makeheaders, of the same name. For example, foo.c will #include foo.h. That’s it. This means never having to worry about headers. You can refactor and reorganize your code at will, and makeheaders will always figure you what needs to go in the header of each source file.

See the original documentation for a description of the rationale and working of makeheaders. There are a few tricky bits to be aware of. For example, if a function signature uses a datatype declared elsewhere (e.g. uint32_t, from stdint.h), then that header must be #included before the (generated) prototype in the generated headers that need it. To enable this, enclose the #include within "#if INTERFACE …​ #endif". It is also possible to trip up makeheaders by going overboard with macros.

Important
Status: OpenOCF is based on Iotivity 1.3.0 and will be upgraded to new versions as they are released. On the Mac, network monitoring is not yet implemented. It runs, but will not detect network changes.

Building

First configure, then build.

OpenOCF uses GNU autotools (autoconf, etc.) for configuration. You will also need to configure the third-party libs. (Just coap so far). The instructions are at the top of third_party/coap/BUILD.

OpenOCF uses the Bazel build system.

OpenOCF is written in the c-without-include-headers style made possible by makeheaders. This requires a preprocessing step as part of the build.

Prerequisites: Bazel, GNU autotools. On Windows: msys2, mingw-64.

Warning
See notes below if you are building on Windows.

configuration

OpenOCF uses GNU autotools for configuration, as do some of the third-party libs like libcoap.

libcoap: automated. see src/coap/libcoap/BUILD.

OpenOCF: see the shell files in ./bin. To configure for the local machine: .bin/local_config.sh.

For cross-compiling,

building

Prep: first we construct the list of files to be processed by makeheaders; this list varies by platform, so we use a Bazel target:

$ bazel build :mkhdrs
Note
for cross-compiling (e.g. targeting android) you must supply the appropriate --config value, e.g.:
$ bazel build :mkhdrs --config=rpi-arm8

This creates ./bazel-bin/mkhdrs.dat. We process this to create our headers. First build the makeheaders program:

$ bazel build tools/makeheaders

The result will be ./bazel-bin/tools/makeheaders/makeheaders. Since makeheaders is extremely unlikely to change, you can copy it to a directory on your path, e.g.

$ cp ./bazel-bin/tools/makeheaders/makeheaders $HOME/bin

Now use it to produces the internal library headers, then the public API exposed to application developers:

$ makeheaders -f bazel-bin/mkhdrs.dat
$ makeheaders -f bazel-bin/mkhdrs.dat -H > include/openocf_h.h

See e.g. ./bin/rpi3b_arm8_mkhdrs.sh

Targets are defined by BUILD files; cross-compilation by flags. Before building, see tools/bazel.rc and make sure you’ve got the right ones. You can build any target. Examples:

  • $ bazel build src/provisioning

  • $ bazel build src/comm

  • etc

The main target for building OpenOCF for use by an application is //:openocf. You can build it like so: $ bazel build :openocf.

Warning
third-party libraries are built using Bazel’s support for external repos using the new_http_archive facility, as specified in the WORKSPACE file. You cannot build them using the above syntax; you have to use @ syntax. For example, instead of bazel build src/sec/mbedtls, do bazel build @mbedtls//:mbedtls.

Now build test apps:

$ bazel build examples/discovery:server
$ bazel build examples/discovery:client

Output executables will be in `./bazel-bin/examples/discovery

This example has been built and tested on Ubuntu (16.04.3 LTS), macOS Sierra (10.12.6), Windows 7, Raspberry Pi 3b, and Wind River Linux.

Important
As you develop code, you will need to rerun makeheaders whenever you make a change affecting the visibility of your code (fortunately makeheaders is lightning-fast). For example, if you change a function prototype or add code that refers to something in another file. If you add or remove source files, you will also need to rerun $ bazel build :mkhdrs before rerunning makeheaders. In the future I hope to automate all this so a single bazel command will do the all the right things.

windows

Prerequisites: mingw shell and GNU tools (autoheader, autoconf, etc.). Recommend using msys2. Use pacman to install needed packages.

Important
Currently only the MSVC compiler is supported. That’s the default for Bazel builds. Support for the Mingw GCC compiler is almost complete but there are still a few unresolved bugs. Patches welcome.

Libcoap (in third_party/coap) does not work with mingw64 out of the box; it requires some patches that have not been submitted yet. Search third_party/coap/src/coap_io.c for "GAR" to see what’s needed.

Windows needs some special therapy. Since we’re using mingw-based tools for feature test configuration but compiling with MSVC tools, we get some false positives: headers that exist in the mingw environment but not the MSVC environment. Specifically, the generated src/_openocf_config.h file will #define the following:

HAVE_LIBPTHREAD HAVE_PTHREAD_H HAVE_STRINGS_H HAVE_SYS_SOCKET_H HAVE_SYS_TIME_H TIME_WITH_SYS_TIME HAVE_UNISTD_H HAVE_SYS_UNISTD_H

These must be #undefined if compiling with the MSVC toolchain. As a convenience we provide src/_openocf_config_win.h which you can copy to src/_openocf_config.h instead of running ./configure.

cross-compiling

Cross-platform builds require source-code configuration and a toolchain for cross-compiling. See CROSSCOMPILE for details.

android

Support for Android builds is provided natively by Bazel; see the Tutorial. By default, Bazel will target the armeabi-v7a architectures; to target one of the other architectures supported by Android you must pass the appropriate --fat_apk_cpu and --android_cpu options; these options are used in the BUILD files to configure the build. As a convenience, several Android configurations are defined in tools/bazel.rc.

Warning
Bazel will only use the Android NDK toolchain for android_binary targets.

Assuming myapp is an android_binary target, you would build it for arm64-v8a as follows:

$ ./bin/android_config.sh v8a
$ bazel build myapp --config=android-arm8

This configuration is defined in tools/bazel.rc. The config shell script will run ./configure and build the :mkhdrs target with appropriate parameters to configure the source code.

Cross-platform builds using crosstool-NG toolchains to target the Raspberry Pi 3B and generic Linux are also supported.

Note
crosstool-NG on MacOS requires special treatment; see CROSSCOMPILE for details.

raspberry pi 3b

crosstool-NG toolchain: armv8-rpi3-linux-gnueabihf

Configure the source:

$ ./bin/rpi3b_config.sh

This will run ./configure with appropriate parameters, and then run bazel build :mkhdrs to generate the headers.

To build:

$ bazel build tools/browser/server --config=rpi3b-arm8

Configurations are defined in tools/bazel.rc; they drive the config_settings used to configure the build. The config_settings are defined in config/BUILD. The --config option is documented at A User’s Guide to Bazel.

generic linux

crosstool-NG toolchain: x86_64-unknown-linux-gnu

About

Iotivity alternative implementation

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 42