Created
February 14, 2020 18:24
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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