Skip to content

Instantly share code, notes, and snippets.

@maesoser
Created February 14, 2020 18:24
Show Gist options
  • Select an option

  • Save maesoser/3d8e735a0da216d9a44918d7033dc6d4 to your computer and use it in GitHub Desktop.

Select an option

Save maesoser/3d8e735a0da216d9a44918d7033dc6d4 to your computer and use it in GitHub Desktop.
CoAP Node that simulates a being a temperature sensor. Written used libcoap library
/* Sergio Maeso Jimenez
* semaesoj@it.uc3m.es
* 03.08.2016
*
* coap code which simulates a temperature sensor
* based on https://github.com/nikosft/libcoap/blob/master/piggybacked/server.c
*
*. gcc -Wall -I /usr/local/include/coap -L /usr/local/lib termo.c -o termo -lcoap-1 -DWITH_POSIX
*/
// DO NOT FORGET export LD_LIBRARY_PATH=/usr/local/lib
//#include "dtls.h"
#include "coap.h" // /usr/local/include/coap
#include "stdio.h"
#include <time.h>
#define DEFAULT_PORT 5683
unsigned char fan = 0;
/*
* get (simulate) mocked temperature readings
*
*/
int getTemp(){
srand(time(NULL));
int r = rand() % 20 ; // rnd numb between 0 and 20
return 20 + r; // rnd temp between 20 an 40
}
/*
* The resource handler
*/
static void gettemp_handler(coap_context_t *cntx, struct coap_resource_t *resource,
const coap_endpoint_t *local_interface, coap_address_t *peer,
coap_pdu_t *request, str *token, coap_pdu_t *response)
{
unsigned char buf[8];
char response_data[8];
int temp = getTemp();
printf("Sending Temp %d ºC\n",temp);
sprintf(response_data, "%d", temp);
response->hdr->code = COAP_RESPONSE_CODE(205);
coap_add_option(response, COAP_OPTION_CONTENT_TYPE, coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf);
coap_add_data (response, strlen(response_data), (const unsigned char *)response_data);
}
static void deltemp_handler(coap_context_t *cntx, struct coap_resource_t *resource,
const coap_endpoint_t *local_interface, coap_address_t *peer,
coap_pdu_t *request, str *token, coap_pdu_t *response)
{
(void)cntx;
(void)resource;
(void)peer;
(void)request;
(void)token;
(void)response;
}
static void gettime_handler(coap_context_t *cntx, struct coap_resource_t *resource, const coap_endpoint_t *local_interface, coap_address_t *peer, coap_pdu_t *request, str *token, coap_pdu_t *response)
{
char response_data[8];
time_t timer;
unsigned char buffer[26];
struct tm* tm_info;
time(&timer);
tm_info = localtime(&timer);
strftime((char *)buffer, 26, "%Y:%m:%d %H:%M:%S", tm_info);
printf("Sending Time %s\n",buffer);
sprintf(response_data, "%s", buffer);
response->hdr->code = COAP_RESPONSE_CODE(205);
coap_add_option(response, COAP_OPTION_CONTENT_TYPE, coap_encode_var_bytes(buffer, COAP_MEDIATYPE_TEXT_PLAIN), buffer);
coap_add_data (response, strlen(response_data), (const unsigned char *)response_data);
}
static void settime_handler(coap_context_t *cntx, struct coap_resource_t *resource, const coap_endpoint_t *local_interface, coap_address_t *peer, coap_pdu_t *request, str *token, coap_pdu_t *response)
{
}
static void deltime_handler(coap_context_t *cntx, struct coap_resource_t *resource,
const coap_endpoint_t *local_interface, coap_address_t *peer,
coap_pdu_t *request, str *token, coap_pdu_t *response)
{
(void)cntx;
(void)resource;
(void)peer;
(void)request;
(void)token;
(void)response;
}
void setfan_handler(coap_context_t *cntx, struct coap_resource_t *resource,
const coap_endpoint_t *local_interface, coap_address_t *peer,
coap_pdu_t *request, str *token, coap_pdu_t *response) {
size_t size;
unsigned char *data;
response->hdr->code = COAP_RESPONSE_CODE(204);
coap_get_data(request, &size, &data);
fan = atoi((char*)data);
printf("Received %s -> %d\n",data,fan);
if(fan>100)fan=100;
}
static void getfan_handler(coap_context_t *cntx, struct coap_resource_t *resource,
const coap_endpoint_t *local_interface, coap_address_t *peer,
coap_pdu_t *request, str *token, coap_pdu_t *response)
{
unsigned char buf[8];
char response_data[8];
printf("Sending Fan %d %%\n",fan);
sprintf(response_data, "%d", fan);
response->hdr->code = COAP_RESPONSE_CODE(205);
coap_add_option(response, COAP_OPTION_CONTENT_TYPE, coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf);
coap_add_data (response, strlen(response_data), (const unsigned char *)response_data);
}
int main(int argc, char* argv[])
{
coap_context_t* cntx;
coap_address_t serv_addr;
coap_resource_t* temp_resource;
coap_resource_t* time_resource;
coap_resource_t* fan_resource;
fd_set readfds;
/* Prepare the CoAP server socket */
coap_address_init(&serv_addr);
serv_addr.addr.sin.sin_family = AF_INET;
serv_addr.addr.sin.sin_addr.s_addr = INADDR_ANY;
serv_addr.addr.sin.sin_port = htons(DEFAULT_PORT); //default port
cntx = coap_new_context(&serv_addr);
if (!cntx) exit(EXIT_FAILURE);
/* Initialize the fan resource */
fan_resource = coap_resource_init((unsigned char *)"fan", 3, 0);
coap_register_handler(fan_resource, COAP_REQUEST_GET, getfan_handler);
coap_register_handler(fan_resource, COAP_REQUEST_PUT, setfan_handler);
coap_add_resource(cntx, fan_resource);
/* Initialize the temperature resource */
temp_resource = coap_resource_init((unsigned char *)"temperature", 11, 0);
coap_register_handler(temp_resource, COAP_REQUEST_GET, gettemp_handler);
coap_register_handler(temp_resource, COAP_REQUEST_DELETE, deltemp_handler);
temp_resource->observable = 1;
coap_add_attr(temp_resource, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0);
coap_add_attr(temp_resource, (unsigned char *)"title", 5, (unsigned char *)"\"CPU temperature\"", 16, 0);
coap_add_resource(cntx, temp_resource);
/* Initialize the temperature resource */
time_resource = coap_resource_init((unsigned char *)"time", 4, 0);
coap_register_handler(time_resource, COAP_REQUEST_GET, gettime_handler);
coap_register_handler(time_resource, COAP_REQUEST_PUT, settime_handler);
coap_register_handler(time_resource, COAP_REQUEST_DELETE, deltime_handler);
coap_add_attr(time_resource, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0);
coap_add_attr(time_resource, (unsigned char *)"title", 5, (unsigned char *)"\"Internal Clock\"", 16, 0);
coap_add_attr(time_resource, (unsigned char *)"rt", 2, (unsigned char *)"\"Ticks\"", 7, 0);
coap_add_attr(time_resource, (unsigned char *)"if", 2, (unsigned char *)"\"clock\"", 7, 0);
time_resource->observable = 1;
coap_add_resource(cntx, time_resource);
/*
The Content-Format code "ct" attribute provides a hint about the Content-Formats
this resource returns. Note that this is only a hint, and it does not
override the Content-Format Option of
a CoAP response obtained by actually requesting the representation of
the resource. The value is in the CoAP identifier code format as a
decimal ASCII integer and MUST be in the range of 0-65535 (16-bit
unsigned integer). For example, "application/xml" would be indicated
as "ct=41". If no Content-Format code attribute is present, then
nothing about the type can be assumed. The Content-Format code
attribute MAY include a space-separated sequence of Content-Format
codes, indicating that multiple content-formats are available.
*/
/*Listen for incoming connections*/
while (1) {
FD_ZERO(&readfds);
FD_SET( cntx->sockfd, &readfds );
int result = select( FD_SETSIZE, &readfds, 0, 0, NULL );
if (result<0) /* socket error */
{
exit(EXIT_FAILURE);
}
else if ( result > 0 && FD_ISSET( cntx->sockfd, &readfds )) /* socket read*/
{
coap_read(cntx);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment