mirror of
https://github.com/obgm/libcoap.git
synced 2026-10-31 23:15:48 +03:00
125 lines
2.6 KiB
C
125 lines
2.6 KiB
C
/* coap -- simple implementation of the Constrained Application Protocol (CoAP)
|
|
* as defined in draft-ietf-core-coap-00
|
|
*
|
|
* (c) 2010 Olaf Bergmann <bergmann@tzi.org>
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <sys/select.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
|
|
#include "pdu.h"
|
|
#include "net.h"
|
|
|
|
coap_pdu_t *
|
|
coap_new_get( const char *uri ) {
|
|
coap_pdu_t *pdu;
|
|
|
|
if ( !uri || ! ( pdu = coap_new_pdu() ) )
|
|
return NULL;
|
|
|
|
pdu->hdr->type = COAP_MESSAGE_CON;
|
|
pdu->hdr->code = COAP_REQUEST_GET;
|
|
|
|
if ( *uri ) {
|
|
if ( *uri != '/' )
|
|
coap_add_option ( pdu, COAP_OPTION_URI_FULL, strlen( uri ), uri );
|
|
else {
|
|
++uri;
|
|
if ( *uri )
|
|
coap_add_option ( pdu, COAP_OPTION_URI_PATH, strlen( uri ), uri );
|
|
}
|
|
}
|
|
|
|
return pdu;
|
|
}
|
|
|
|
void
|
|
send_request( coap_context_t *ctx, coap_pdu_t *pdu ) {
|
|
struct addrinfo *res, *ainfo;
|
|
struct addrinfo hints;
|
|
int error;
|
|
struct sockaddr_in6 dst;
|
|
|
|
memset ((char *)&hints, 0, sizeof(hints));
|
|
hints.ai_socktype = SOCK_DGRAM;
|
|
hints.ai_family = AF_INET6;
|
|
|
|
error = getaddrinfo("ns.tzi.org", "", &hints, &res);
|
|
|
|
if (error != 0) {
|
|
perror("getaddrinfo");
|
|
exit(1);
|
|
}
|
|
|
|
|
|
for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) {
|
|
|
|
if ( ainfo->ai_family == AF_INET6 ) {
|
|
|
|
memset(&dst, 0, sizeof dst );
|
|
dst.sin6_family = AF_INET6;
|
|
dst.sin6_port = htons( COAP_DEFAULT_PORT );
|
|
memcpy( &dst.sin6_addr, &((struct sockaddr_in6 *)ainfo->ai_addr)->sin6_addr, ainfo->ai_addrlen );
|
|
|
|
coap_send_confirmed( ctx, &dst, pdu );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv) {
|
|
coap_context_t *ctx;
|
|
fd_set readfds;
|
|
time_t timeout;
|
|
struct timeval tv;
|
|
int result;
|
|
time_t now;
|
|
coap_sendqueue_t *nextpdu;
|
|
coap_pdu_t *pdu;
|
|
|
|
ctx = coap_new_context();
|
|
if ( !ctx )
|
|
return -1;
|
|
|
|
if (! (pdu = coap_new_get( COAP_DEFAULT_URI_WELLKNOWN ) ) )
|
|
return -1;
|
|
|
|
send_request( ctx, pdu );
|
|
|
|
while ( 1 ) {
|
|
FD_ZERO(&readfds);
|
|
FD_SET( ctx->sockfd, &readfds );
|
|
|
|
nextpdu = coap_peek_next( ctx );
|
|
|
|
time(&now);
|
|
while ( nextpdu && nextpdu->t <= now ) {
|
|
coap_retransmit( ctx, coap_pop_next( ctx ) );
|
|
nextpdu = coap_peek_next( ctx );
|
|
}
|
|
|
|
tv.tv_usec = 0;
|
|
tv.tv_sec = nextpdu ? nextpdu->t - now : 0;
|
|
|
|
result = select( ctx->sockfd + 1, &readfds, 0, 0, &tv );
|
|
|
|
if ( result < 0 ) { /* error */
|
|
perror("select");
|
|
} else if ( result > 0 ) { /* read from socket */
|
|
/* if FD_ISSET( ... ) coap_read( ctx );*/
|
|
}
|
|
}
|
|
|
|
coap_free_context( ctx );
|
|
|
|
return 0;
|
|
}
|