Building IoTivity for ARM on ARTIK Devices

There are several options to build IoTivity for ARM targets or any non x86 hardware, but first you have to decide which operating system you want to use. In this article, I won’t compare OS or devices; instead, I’ll give a couple of hints that apply to ARTIK 5, 7, and 10 devices (not the ARTIK 0 family, which run TizenRT). These steps can also be applied to other single board computers like the Raspberry PI.

Build for Tizen with GBS

The first and easiest way to build IoTivity is for Tizen, using GBS. This process was explained in a previous article.

For your knowledge, GBS was inspired by Debian’s git-build-package and uses an ARM toolchain that runs in a chrooted ARM environment using QEMU. Both ARTIK boards and the Raspberry Pi are used as Tizen reference platforms.

Build for Yocto with Bitbake

The second option is to crossbuild with the Yocto toolchain. Theoretically, it should be the fastest way, but in practice it might be the opposite because external packages will be rebuilt from scratch if the project doesn’t provide a Yocto SDK; this can be a long, resource consuming process.

Anyway, this is what is used in some OSS automotive projects (like AGL or GENIVI); the following slides provide a tutorial to get familiar with bitbake and OE layers (like meta-oic for IoTivity).

This can then be deployed to ARTIK 5 or 10 using meta-artik (ARTIK7 might need extra patches).

Cross Building Manually

Another option is to setup your toolchain with the scons environment, but I would not recommend it because you’ll probably lack tracking or control (output binaries will not be packaged) and risk consistency issues. If you choose this method, refer to IoTivity’s wiki page about crossbuilding.

Build on the Device

The last and most obvious option is to build on the device itself; this takes a bit longer, but is totally possible assuming your device has the resources (it worked for me on the RPI3 and ARTIK10). For this to work cleanly I suggest you build system package if your distro is supports it it (.rpm, .deb etc). This way you can track the different build configurations and avoid mistakes caused by manual operations.

Build on ARTIK10

ARTIK 10 supports building with Fedora 22, RPM packages can be built from Tizen’s spec file plus a handful of patches (I needed to use scons install and avoid duplication of packaging efforts). This work is still under review in the master branch, and will be backported to 1.3-rel branch once 1.3.1 is released. Meanwhile, you can clone my sandbox branch.

mkdir -p ${HOME}/rpmbuild/SOURCES/
git clone http://github.com/tizenteam/iotivity -b sandbox/pcoval/on/next/fedora
cd iotivity
git archive HEAD | gzip - > ${HOME}/rpmbuild/SOURCES/iotivity-1.3.1.tar.gz
rpmbuild -ba tools/tizen/iotivity.spec -D "_smp_mflags -j1" 

This is easy because the ARTIK10 has a lot of eMMC and RAM. The 8-core CPU is nice, but it won’t help because parallelizing too much will eat all of the device’s RAM. To be ensure reproductibility use -j1, but if you’re in a hurry you can try -j2 or more.

Build on ARTIK7

The next challenge is the ARITK710 which less powerful than ARTIK10 (RAM=1GB , eMMC=4GB) and uses Fedora 24. This is a slightly less favorable case because there are some extra steps due to the RAM and disk space being more limited. We’ll use extra storage to add a memory swap and mock: a nice Fedora tool to build RPM from git sources (it’s very similar to pbuilder for Debian). Extra storage can be connected to the board via SD or USB bus, but I prefer to use NFS; it’s not optimal, but it works.

Setup NFS

First, setup NFS on your development host and share a directory on the LAN; mine is Debian based:

sudo apt-get install nfs-kernel-server
mkdir -p /tmp/srv/nfs
ifconfig # Note interface IP to be used later

cat /etc/exports
# TODO: LAN's IP might be adjusted here:
/tmp/srv/nfs 192.0.0.0/255.0.0.0(rw,sync,no_root_squash,no_subtree_check)

Use NFS

Now, login to the target and install NFS and the other tools we’ll use:

dnf remove iotivity # Uninstall previous version if present
dnf install nfs-utils mock-scm mock rpm-build screen

Mount a directory for the device:

mnt=/tmp/mnt/nfs/host/$(hostname)/
host=192.168.0.2 # TODO adjust with IP of your host
mkdir -p $mnt ; mount $host:/tmp/srv/nfs $mnt

Attach a swap file:

file="$mnt/swap.tmp"
dd if=/dev/zero of=$file bs=1k count=2097152 # 2GB

losetup /dev/loop0 "$file"
mkswap /dev/loop0
swapon /dev/loop0

Because the eMMC is also limited, the build will be done in remote storage too. This won’t use an NFS shared folder directly because mock doesn’t support it, so let’s cheat it by mounting an ext4 partition file over NFS, the same way we did above:

file="$mnt/ext4.tmp"
dd if=/dev/zero of=$file bs=1k count=2097152 # 2GB

losetup /dev/loop1 "$file"
mkfs.ext4 /dev/loop1

src=/dev/loop1
dst=/var/lib/mock/
mount $src $dst

Build IoTivity

Create a user to run mock on remote filesystem:

user=abuild # TODO change if needed
adduser $user
home="/home/$user"
mnt=/tmp/mnt/nfs/host/$(hostname)/
mkdir -p "$home" "$mnt$home"
chown -Rv $user $s "$home" "$mnt$home"
mount --bind "$mnt$home" "$home"

su -l $user

Mock is pretty straightforward, but here is an example of the upcoming 1.3.1 release with the patches I mentioned above. If necessary, you can rebase your own private repo on it.

package=iotivity
url="https://github.com/TizenTeam/iotivity.git"
branch="sandbox/pcoval/on/next/fedora"
conf="fedora-24-armhfp"
spec=./tools/tizen/iotivity.spec
  
time mock -r "$conf" \
    --scm-enable \
    --scm-option method=git \
    --scm-option package="${package}" \
    --scm-option git_get=set \
    --scm-option write_tar=True \
    --scm-option branch="${branch}" \
    --scm-option git_get="git clone $url" \
    --scm-option spec="${spec}" \
    --resultdir=${HOME}/mock \
    --define "_smp_mflags -j1" \
    #eol

Now wait and check log trace:

You are attempting to run "mock" which requires administrative
privileges, but more information is needed in order to do so.
Authenticating as "root"
Password: 
INFO: mock.py version 1.3.4 starting (python version = 3.5.3)...
(...)
Start: run
(... time to clone and build iotivity repo ...)
Finish: rpmbuild iotivity-1.3.1-0.src.rpm
Finish: build phase for iotivity-1.3.1-0.src.rpm
INFO: Done(/home/abuild/mock/iotivity-1.3.1-0.src.rpm) Config(fedora-24-armhfp) 116 minutes 1 seconds
INFO: Results and/or logs in: /home/abuild/mock
INFO: Cleaning up build root ('cleanup_on_success=True')
Start: clean chroot
Finish: clean chroot
Finish: run

Depending on network bandwidth, RPMs will be produced in a reasonable time (less than a night for sure).

You can now validate reference examples:

su root -c "dnf remove -y iotivity"
su root -c "dnf install -y --allowerasing ${HOME}/mock/iotivity*.arm*.rpm"

rpm -ql iotivity-test

cd /usr/lib/iotivity/resource/examples ; ./simpleserver 2 
# 2 is needed to enable security node.

In other session:

cd /usr/lib/iotivity/resource/examples ; ./simpleclient
GET request was successful
Resource URI: /a/light
Server format in GET response:10000
Server version in GET response:2048

Bringing it all Together

There has been one major relevant change since 1.2.x, the default build configuration is using secured mode (Tizen had it enabled for longer). For developers, this means that if your application is not configured to support security ACL, it won’t work, and you might expect this OC_STACK_UNAUTHORIZED_REQ error:

onGET Response error: 46

The following presentation provides some insight on the IoTivity security features.

The fall back option is to rebuild IoTivity without SECURITY enabled (using –define SECURED 0), but this won’t be certified as OCF compliant. Finally, these build steps can be replicated for other projects using IoTivity.

Author: Phil Coval

Philippe is committed to free software and open hardware and is deeply involved in the Tizen and IoTivity communities.