Lobaro CoAP – Lobaro.com (original) (raw)

Lobaro CoAP

This page is an introduction to our free CoAP Software-Stack named “Lobaro-CoAP”, which enables you to create CoAP applications in C and other programing languages.

The target audiance are experienced programmers with rich knowledge of the “C” programming language.

Project Page at Github
Example ESP8266 Project

We also offer integration in other languages that are based on the same C code:

Lobaro CoAP Go at Github

Quick Facts

Key Terms

Simple “CoAP GET” example

This resource returns the current ip configuration as payload and is accessed via “GET coap://…/wifi/ipconfig”.
[code lang=”c”]
#include “../lobaro-coap/coap.h”

CoAP_Res_t* pWifi_ip_Res = NULL;

static CoAP_HandlerResult_t ICACHE_FLASH_ATTR RequestHandler(CoAP_Message_t* pReq, CoAP_Message_t* pResp) {
struct ip_info ipconfig;
char payloadTemp[100];

if(wifi_get_ip_info(STATION_IF, &ipconfig)) {
coap_sprintf(payloadTemp, “Station: %d.%d.%d.%drn”,IP2STR(&ipconfig.ip));
CoAP_SetPayload(pReq, pResp, (uint8_t*)payloadTemp, coap_strlen(payloadTemp), true);
} else {
pResp->Code=RESP_INTERNAL_SERVER_ERROR_5_00;
}

return HANDLER_OK;
}

CoAP_Res_t* Create_Wifi_IPs_Resource() {
CoAP_ResOpts_t Options = {.Cf = COAP_CF_TEXT_PLAIN, .Flags = RES_OPT_GET };
return (pWifi_ip_Res=CoAP_CreateResource(“wifi/ipconfig”, “ESP8266 IP configuration”,Options, RequestHandler, NULL));
}
[/code]

Observable resource example

This observable resource returns the current system time and is accessed via “GET coap://…/rtc”.
[code lang=”c”]
#include “../lobaro-coap/coap.h”
#include “rtc_res.h”

CoAP_Res_t* pRTC_Res = NULL;

static CoAP_HandlerResult_t RequestHandler(CoAP_Message_t* pReq, CoAP_Message_t* pResp) {
char myString[20];
coap_sprintf(myString,”%d [s]”, hal_rtc_1Hz_Cnt());
CoAP_SetPayload(pReq, pResp, myString, coap_strlen(myString), true);

return HANDLER_OK;
}

static CoAP_HandlerResult_t NotifyHandler(CoAP_Observer_t* pObserver, CoAP_Message_t* pResp) {
char myString[20];
coap_sprintf(myString,”%d [s]”, hal_rtc_1Hz_Cnt());
CoAP_SetPayload(NULL, pResp, myString, coap_strlen(myString), true);

return HANDLER_OK;
}

//Update Observers every second
#define DELAY_LOOP 1000 // milliseconds
LOCAL os_timer_t Notify_timer;

LOCAL void notify_cb(void *arg) {
CoAP_NotifyResourceObservers(pRTC_Res);
}

CoAP_Res_t* Create_RTC_Resource() {
CoAP_ResOpts_t Options = {.Cf = COAP_CF_TEXT_PLAIN, .Flags = RES_OPT_GET};

//Start Update timer
os_timer_disarm(&Notify_timer);
os_timer_setfn(&Notify_timer, (os_timer_func_t *)notify_cb, (void *)0);
os_timer_arm(&Notify_timer, DELAY_LOOP, 1);

return (pRTC_Res=CoAP_CreateResource(“/rtc”, “esp8266 RTC”, Options, RequestHandler, NotifyHandler));
}
[/code]

resource control via uri-query

This resource can change the state of a led via “POST coap://…/esp8266/led_gpio12″.
[code lang=”c” highlight=”12-17″]
static void SetLedstatePayload(CoAP_Message_t* pReq, CoAP_Message_t* pResp){
if(LedState) CoAP_SetPayload(pReq, pResp, “Led is on!”, coap_strlen(“Led is on!”), true);
else CoAP_SetPayload(pReq, pResp, “Led is off!”, coap_strlen(“Led is off!”), true);
}

static CoAP_HandlerResult_t Res_ReqHandler(CoAP_Message_t* pReq, CoAP_Message_t* pResp) {
if(pReq->Code == REQ_POST) {
CoAP_option_t* pOpt;
bool Found = false;

for(pOpt =pReq->pOptionsList ; pOpt != NULL; pOpt = pOpt->next) {
switch(CoAP_FindUriQueryVal(pOpt,””,3, “on”,”off”, “tgl”)) { // no prefix used
case 0: break; //not found
case 1: led(true); Found=true; break; //found “on”
case 2: led(false); Found=true; break; //found “off”
case 3: led(!LedState); Found=true; break; //found “tgl”
}
if(Found) {
SetLedstatePayload(pReq, pResp);
break;
}
}

if(!Found){
char info[] = {“usage: coap://…/led_gpio12?on (or “off”, “tgl”)”};
CoAP_SetPayload(pReq, pResp, info, coap_strlen(info), true);
pResp->Code=RESP_ERROR_BAD_REQUEST_4_00;
}

}else if(pReq->Code == REQ_GET){
SetLedstatePayload(pReq, pResp);
}

return HANDLER_OK;
}

static CoAP_HandlerResult_t Res_NotifyHandler(CoAP_Observer_t* pObserver, CoAP_Message_t* pResp) {
SetLedstatePayload(NULL, pResp);
return HANDLER_OK;
}

CoAP_Res_t* Create_Led_Resource() {
CoAP_ResOpts_t Options = {.Cf = COAP_CF_TEXT_PLAIN, .Flags = RES_OPT_POST | RES_OPT_GET};
return (pLed_Res=CoAP_CreateResource(“esp8266/led_gpio12”, “LED at GPIO12”,Options, Res_ReqHandler, Res_NotifyHandler));
}
[/code]

big blockwise resource

This resource gets transmitted over multiple GET requests using the blockwise protocol (draft-ietf-core-block-18)
[code lang=”c”]
static const char CoapInfoStringInFlash[] = {”
The Constrained Application Protocol (CoAP) is a specialized web
transfer protocol for use with constrained nodes and constrained
(e.g., low-power, lossy) networks. The nodes often have 8-bit
microcontrollers with small amounts of ROM and RAM, while constrained
networks such as IPv6 over Low-Power Wireless Personal Area Networks
(6LoWPANs) often have high packet error rates and a typical
throughput of 10s of kbit/s. The protocol is designed for machine-
to-machine (M2M) applications such as smart energy and building
automation.rnrn

CoAP provides a request/response interaction model between
application endpoints, supports built-in discovery of services and
resources, and includes key concepts of the Web such as URIs and
Internet media types. CoAP is designed to easily interface with HTTP
for integration with the Web while meeting specialized requirements
such as multicast support, very low overhead, and simplicity for
constrained environments.
“};

CoAP_Res_t* pAbout_Res = NULL;

static CoAP_HandlerResult_t RequestHandler(CoAP_Message_t* pReq, CoAP_Message_t* pResp) {
static uint16_t payloadSize = sizeof(CoapInfoStringInFlash)-1;

CoAP_SetPayload(pReq, pResp, (uint8_t*)&(CoapInfoStringInFlash[0]), payloadSize, false);

return HANDLER_OK;
}

CoAP_Res_t* Create_About_Resource() {
CoAP_ResOpts_t Options = {.Cf = COAP_CF_TEXT_PLAIN, .Flags = RES_OPT_GET};
return (pAbout_Res=CoAP_CreateResource(“about/coap”, “CoAP Description”,Options, RequestHandler, NULL));
}
[/code]

Set RTC Clock by URI query

This ressource sets a DS3231 RTC via CoAP request to date 21.2.2016 14:00h

coap://[IP]:5683/ds3231?y=2016&mn=2&d=21&h=14&m=0&s=0

[code lang=”c”]
static CoAP_HandlerResult_t Handler(CoAP_Message_t* pReq, CoAP_Message_t* pResp)
{
static char myString[100];
static datetime_t datetime;

uint8_t valLen = 0;
uint8_t* pVal = NULL;

drv_DS3231_GetDateTime(&datetime);
if(pReq->Code == REQ_PUT) {
if((pVal=CoAP_GetUriQueryValFromMsg(pReq, “d=”, &valLen)) && valLen) datetime.w_day = (uint8_t) CoAP_atoi(pVal, valLen);
if((pVal=CoAP_GetUriQueryValFromMsg(pReq, “h=”, &valLen)) && valLen) datetime.hour = (uint8_t) CoAP_atoi(pVal, valLen);
if((pVal=CoAP_GetUriQueryValFromMsg(pReq, “m=”, &valLen)) && valLen) datetime.min = (uint8_t) CoAP_atoi(pVal, valLen);
if((pVal=CoAP_GetUriQueryValFromMsg(pReq, “s=”, &valLen)) && valLen) datetime.sec = (uint8_t) CoAP_atoi(pVal, valLen);
if((pVal=CoAP_GetUriQueryValFromMsg(pReq, “mm=”, &valLen)) && valLen) datetime.w_month = (uint8_t) CoAP_atoi(pVal, valLen);
if((pVal=CoAP_GetUriQueryValFromMsg(pReq, “y=”, &valLen)) && valLen) datetime.w_year = (uint8_t) CoAP_atoi(pVal, valLen);
drv_DS3231_SetDateTime(&datetime);
}

sprintf(myString,”%02d.%02d.20%02d %02d:%02d:%02drn”, datetime.w_day, datetime.w_month, datetime.w_year, datetime.hour, datetime.min, datetime.sec);
CoAP_SetPayload(pReq, pResp, myString, strlen(myString), false);

return HANDLER_OK;
}
[/code]