Patrick Barrett / libexositecoap
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers client.c Source File

client.c

00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <errno.h>
00005 #include <string.h>
00006 #include <sys/types.h>
00007 #include <sys/socket.h>
00008 #include <netinet/in.h>
00009 #include <arpa/inet.h>
00010 #include <netdb.h>
00011 #include <time.h>
00012 
00013 #include "../../src/coap.h"
00014  
00015 void hex_dump(uint8_t* bytes, size_t len);
00016 void coap_pretty_print(coap_pdu*);
00017 
00018 int main(void)
00019 {
00020   char alias[] = "temp";
00021   char cik[] = "a32c85ba9dda45823be416246cf8b433baa068d7";
00022 
00023   char host[] = "coap.exosite.com";
00024   char port[] = "5683";
00025 
00026   srand(time(NULL));
00027 
00028   // CoAP Message Setup
00029   #define MSG_BUF_LEN 64
00030   uint8_t msg_send_buf[MSG_BUF_LEN];
00031   coap_pdu msg_send = {msg_send_buf, 0, 64};
00032   uint8_t msg_recv_buf[MSG_BUF_LEN];
00033   coap_pdu msg_recv = {msg_recv_buf, 0, 64};
00034 
00035   uint16_t message_id_counter = rand();
00036 
00037   // Socket to Exosite
00038   int remotesock;
00039   size_t bytes_sent;
00040   ssize_t bytes_recv;
00041   int rv;
00042 
00043   struct addrinfo exohints, *servinfo, *q;
00044 
00045   memset(&exohints, 0, sizeof exohints);
00046   exohints.ai_family = AF_UNSPEC;
00047   exohints.ai_socktype = SOCK_DGRAM;
00048   exohints.ai_flags = AI_PASSIVE;
00049 
00050   if ((rv = getaddrinfo(host, port, &exohints, &servinfo)) != 0) {
00051     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
00052     return 1;
00053   }
00054 
00055 
00056   // loop through all the results and make a socket
00057   for(q = servinfo; q != NULL; q = q->ai_next) {
00058     if ((remotesock = socket(q->ai_family, q->ai_socktype, q->ai_protocol)) == -1) {
00059       perror("bad socket");
00060       continue;
00061     }
00062 
00063     break;
00064   }
00065 
00066   if (q == NULL) {
00067       fprintf(stderr, "Failed to Bind Socket\n");
00068       return 2;
00069   }
00070  
00071   for (;;) 
00072   {
00073     printf("--------------------------------------------------------------------------------\n");
00074 
00075     // Build Message
00076     coap_init_pdu(&msg_send);
00077     //memset(msg_send, 0, msg_send_len);
00078     coap_set_version(&msg_send, COAP_V1);
00079     coap_set_type(&msg_send, CT_CON);
00080     coap_set_code(&msg_send, CC_GET); // or POST to write
00081     coap_set_mid(&msg_send, message_id_counter++);
00082     coap_set_token(&msg_send, rand(), 2);
00083     coap_add_option(&msg_send, CON_URI_PATH, (uint8_t*)"1a", 2);
00084     coap_add_option(&msg_send, CON_URI_PATH, (uint8_t*)alias, strlen(alias));
00085     coap_add_option(&msg_send, CON_URI_QUERY, (uint8_t*)cik, strlen(cik));
00086     // to write, set payload:
00087     //coap_set_payload(msg_send, &msg_send_len, MSG_BUF_LEN, (uint8_t*)"99", 2);
00088 
00089     // Send Message
00090     if ((bytes_sent = sendto(remotesock, msg_send.buf, msg_send.len, 0, q->ai_addr, q->ai_addrlen)) == -1){
00091       fprintf(stderr, "Failed to Send Message\n");
00092       return 2;
00093     }
00094 
00095     printf("Sent.\n");
00096     coap_pretty_print(&msg_send);
00097 
00098     // Wait for Response
00099     bytes_recv = recvfrom(remotesock, (void *)msg_recv.buf, msg_recv.max, 0, q->ai_addr, &q->ai_addrlen);
00100     if (bytes_recv < 0) {
00101       fprintf(stderr, "%s\n", strerror(errno));
00102       exit(EXIT_FAILURE);
00103     }
00104 
00105     msg_recv.len = bytes_recv;
00106 
00107     if(coap_validate_pkt(&msg_recv) == CE_NONE)
00108     {
00109       printf("Got Valid CoAP Packet\n");
00110       if(coap_get_mid(&msg_recv) == coap_get_mid(&msg_send) &&
00111          coap_get_token(&msg_recv) == coap_get_token(&msg_send))
00112       {
00113         printf("Is Response to Last Message\n");
00114         coap_pretty_print(&msg_recv);
00115       }
00116     }else{
00117       printf("Received %zi Bytes, Not Valid CoAP\n", msg_recv.len);
00118       hex_dump(msg_recv.buf, msg_recv.len);
00119     }
00120 
00121     sleep(1); // One Second
00122   }
00123 }
00124 
00125 void hex_dump(uint8_t* bytes, size_t len)
00126 {
00127   size_t i, j;
00128   for (i = 0; i < len; i+=16){
00129     printf("  0x%.3zx    ", i);
00130     for (j = 0; j < 16; j++){
00131       if (i+j < len)
00132         printf("%02hhx ", bytes[i+j]);
00133       else
00134         printf("%s ", "--");
00135     }
00136     printf("   %.*s\n", (int)(16 > len-i ? len-i : 16), bytes+i);
00137   }
00138 }
00139 
00140 void coap_pretty_print(coap_pdu *pdu)
00141 {
00142   coap_option opt;
00143 
00144   opt.num = 0;
00145 
00146   if (coap_validate_pkt(pdu) == CE_NONE){
00147       printf(" ------ Valid CoAP Packet (%zi) ------ \n", pdu->len);
00148       printf("Type:  %i\n",coap_get_type(pdu));
00149       printf("Code:  %i.%02i\n", coap_get_code_class(pdu), coap_get_code_detail(pdu));
00150       printf("MID:   0x%X\n", coap_get_mid(pdu));
00151       printf("Token: 0x%llX\n", coap_get_token(pdu));
00152 
00153       while ((opt = coap_get_option(pdu, &opt)).num != 0){
00154         if (opt.num == 0)
00155           break;
00156 
00157         printf("Option: %i\n", opt.num);
00158         if (opt.val != NULL && opt.len != 0)
00159           printf(" Value: %.*s (%zi)\n", (int)opt.len, opt.val, opt.len);
00160       }
00161       // Note: get_option returns payload pointer when it finds the payload marker
00162       if (opt.val != NULL && opt.len != 0)
00163         printf("Payload: %.*s (%zi)\n", (int)opt.len, opt.val, opt.len);
00164     } else {
00165       printf(" ------ Non-CoAP Message (%zi) ------ \n", pdu->len);
00166       hex_dump(pdu->buf, pdu->len);
00167     }
00168 }