Simple client to illustrate the functionality of cantcoap library. The client sits in a while loop sending CoAP PUTs to a remote server and prints each acknowledgement.

Dependencies:   VodafoneUSBModem cantcoap mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /// Simple example making use of cantcoap library, just keeps sending packets to a server and prints the response.
00002 
00003 #include "rtos.h"
00004 #include "mbed.h"
00005 #include "VodafoneUSBModem.h"
00006 #include "cantcoap.h"
00007 #include "bsd_socket.h"
00008 
00009 DigitalOut myled(LED1);
00010 
00011 void fail(int code) {
00012    while(1) {
00013       myled = !myled;
00014       Thread::wait(100);
00015    }
00016 }
00017 
00018 #define APN_GDSP
00019 //#define APN_CONTRACT
00020 
00021 #ifdef APN_GDSP
00022    #define APN "ppinternetd.gdsp" 
00023    #define APN_USERNAME ""
00024    #define APN_PASSWORD ""
00025 #endif
00026 
00027 #ifdef APN_CONTRACT
00028    #define APN "internet" 
00029    #define APN_USERNAME "web"
00030    #define APN_PASSWORD "web"
00031 #endif
00032 
00033 sockaddr_in bindAddr,serverAddress;
00034 bool connectToSocketUDP(char *ipAddress, int port, int *sockfd) {
00035   *sockfd = -1;
00036   // create the socket
00037   if((*sockfd=socket(AF_INET,SOCK_DGRAM,0))<0) {
00038      DBG("Error opening socket");
00039      return false;
00040   }
00041   socklen_t sockAddrInLen = sizeof(struct sockaddr_in);
00042    
00043   // bind socket to 11111
00044   memset(&bindAddr,  0x00, sockAddrInLen);
00045   bindAddr.sin_family = AF_INET; // IP family
00046   bindAddr.sin_port = htons(port);
00047   bindAddr.sin_addr.s_addr = IPADDR_ANY; // 32 bit IP representation
00048   // call bind
00049   if(bind(*sockfd,(const struct sockaddr *)&bindAddr,sockAddrInLen)!=0) {
00050      DBG("Error binding socket");
00051      perror(NULL);
00052   }
00053 
00054   INFO("UDP socket created and bound to: %s:%d",inet_ntoa(bindAddr.sin_addr),ntohs(bindAddr.sin_port));
00055          
00056   // create the socket address
00057   memset(&serverAddress, 0x00, sizeof(struct sockaddr_in));
00058   serverAddress.sin_addr.s_addr = inet_addr(ipAddress);
00059   serverAddress.sin_family = AF_INET;
00060   serverAddress.sin_port = htons(port);
00061 
00062   // do socket connect
00063   //LOG("Connecting socket to %s:%d", inet_ntoa(serverAddress.sin_addr), ntohs(serverAddress.sin_port));
00064   if(connect(*sockfd, (const struct sockaddr *)&serverAddress, sizeof(serverAddress))<0) {
00065      shutdown(*sockfd,SHUT_RDWR);
00066      close(*sockfd);
00067      DBG("Could not connect");
00068      return false;
00069   }
00070   return true;
00071 }
00072 
00073 int main() {
00074     DBG_INIT();
00075     DBG_SET_SPEED(115200);
00076     DBG_SET_NEWLINE("\r\n");
00077     
00078     // structure for getting address of incoming packets
00079     sockaddr_in fromAddr;
00080     socklen_t fromAddrLen = sizeof(struct sockaddr_in);
00081     memset(&fromAddr,0x00,fromAddrLen);
00082     
00083     // connect to cellular network
00084     VodafoneUSBModem modem;
00085     modem.connect(APN,APN_USERNAME,APN_PASSWORD);
00086 
00087     // setup socket to remote server
00088     int sockfd = NULL;
00089     if(!connectToSocketUDP("109.74.199.96", 5683, &sockfd)) {
00090        DBG("Error connecting to socket");
00091        fail(1);
00092     }
00093     DBG("\"Connected\" to UDP socket");
00094 
00095     // construct CoAP packet
00096     CoapPDU *pdu = new CoapPDU();
00097     pdu->setVersion(1);
00098     pdu->setType(CoapPDU::COAP_CONFIRMABLE);
00099     pdu->setCode(CoapPDU::COAP_PUT);
00100     pdu->setToken((uint8_t*)"\3\2\1\1",4);
00101     pdu->setURI((char*)"test",4);
00102     
00103     #define BUFLEN 128
00104     short messageID = 0;
00105     char buffer[BUFLEN];
00106     
00107     // reuse the below coap object
00108     CoapPDU *recvPDU = new CoapPDU((uint8_t*)buffer,BUFLEN,BUFLEN);
00109     
00110     // send packets to server
00111     while(1) {
00112         // set PDU parameters
00113         pdu->setMessageID(messageID++);
00114     
00115         // send packet 
00116         int ret = send(sockfd,pdu->getPDUPointer(),pdu->getPDULength(),0);
00117         if(ret!=pdu->getPDULength()) {
00118             INFO("Error sending packet.");
00119             perror(NULL);
00120             fail(2);
00121         }
00122         INFO("Packet sent");
00123 
00124         // receive response
00125         ret = recvfrom(sockfd,&buffer,BUFLEN,0,(struct sockaddr *)&fromAddr,&fromAddrLen);
00126         if(ret==-1) {
00127             INFO("Error receiving data");
00128             fail(3);
00129         }
00130         INFO("Received %d bytes from %s:%d",ret,inet_ntoa(fromAddr.sin_addr),ntohs(fromAddr.sin_port));
00131         
00132         if(ret>BUFLEN) {
00133             INFO("PDU too large to fit in pre-allocated buffer");
00134             continue;
00135         }
00136 
00137         // validate packet
00138         recvPDU->setPDULength(ret);
00139         if(recvPDU->validate()!=1) {
00140             INFO("Malformed CoAP packet");
00141             fail(4);
00142         }
00143         INFO("Valid CoAP PDU received");
00144         recvPDU->printHuman();
00145         
00146         Thread::wait(5000);
00147     }
00148 }