This is my third article for the IOTA community, the second in form of a tutorial. It presents the possibilities of the meta-iota OpenEmbedded layer with a hands-on tutorial that acts as a proof-of-concept. In the first tutorial, I talked about how to run IOTA cIRI on a BeagleBone Black with Yocto Project and OpenEmbedded. It showed how the meta-iota layer can help with the cross-compilation of an embeddable IOTA node.

This time, I want to focus on the client side of things. The repository c-iota-workshop has practical examples of how to use the CClient library to write C applications and interact with the Tangle. Although both the enTangled and the c-iota-workshop repositories provide the possibility of building with Bazel, which in theory allows cross-compilation for a Raspberry Pi, I want to show how to do that with BitBake. This tutorial can be easily translated into several different boards, as long as there is an OpenEmbedded BSP layer supporting it.

There are other repositories similar to c-iota-workshop, but in different programming languages. You can read more about them on Dave de Fijter’s article Learning by example: IOTA Workshops. I’ll soon publish tutorials based on the Go and Python examples too.

Introduction

First, let’s take a look at the contents of c-iota-workshop. It contains 6 examples, namely:

These examples show how C code can be used to write Client applications to interact with the Tangle. There are, however, some restrictions. Many parameters (such as SEED, RECEIVER_ADDR, ADDR_HASH and TLS_CERTIFICATE_PEM) are hard-coded into the source code, and real production applications should handle them differently (especially the seed, which is the most critical piece information of a client and should never be revealed). Nevertheless, these are still extremely useful references to understand how the CClient API should be manipulated.

Now, let’s take a look at the BitBake repice (c-iota-workshop_git.bb) that cross-compiles these examples:

SUMMARY = "C IOTA workshop"

DESCRIPTION = "Some simple examples to get you started on developing with IOTA using C."

LICENSE = "MIT"

LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"



SRC_URI = " \

git://github.com/iota-community/c-iota-workshop.git \

"



SRCREV = "${AUTOREV}"



S = "${WORKDIR}/git"



DEPENDS = " libcclient uthash keccak logger"



do_compile(){

${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_hello_world examples/e01_hello_world.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread

${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_send_hello examples/e02_send_hello.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread -lm

${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_receive_hello examples/e03_receive_hello.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread

${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_generate_address examples/e04_generate_address.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread

${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_check_balance examples/e05_check_balance.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread

${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_send_tokens examples/e06_send_tokens.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread -lm

}



do_install(){

install -m 0755 -d ${D}${bindir}

install -m 0755 ${S}/iota_c_hello_world ${D}${bindir}

install -m 0755 ${S}/iota_c_send_hello ${D}${bindir}

install -m 0755 ${S}/iota_c_receive_hello ${D}${bindir}

install -m 0755 ${S}/iota_c_generate_address ${D}${bindir}

install -m 0755 ${S}/iota_c_check_balance ${D}${bindir}

install -m 0755 ${S}/iota_c_send_tokens ${D}${bindir}

}

Here, the variable DEPENDS is telling BitBake what are the other recipes that need to be compiled before it starts with this one. That is necessary so the recipe’s sysroot is correctly set up with the appropriate libs and headers. The dependency list should actually be much bigger, but luckily libcclient_1.0.0.bb already declares most of them, and because our recipe depends on it, we don’t need to declare them again.

Then, the do_compile() task is defined. We are not using Make, CMake, Bazel or any other tool to coordinate the compilation. Each one of the 6 examples is explicitly compiled with the invocation of ${CC} , which is the BitBake variable that represents the C Cross Compiler. All the libraries are explicitly listed for linking.