Initial merge-commit of the OIC code. Should successfully do discovery for single...
[platform/upstream/iotivity.git] / csdk / libcoap-4.1.1 / examples / tiny.c
1 /* tiny -- tiny sender
2  *
3  * Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
4  *
5  * This file is part of the CoAP library libcoap. Please see
6  * README for terms of use. 
7  */
8
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <ctype.h>
13 #include <limits.h>
14 #include <sys/select.h>
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <netdb.h>
20
21 #include "../coap.h"
22
23 static coap_tid_t id;
24
25 coap_pdu_t *
26 make_pdu( unsigned int value ) {
27   coap_pdu_t *pdu;
28   unsigned char enc;
29   static unsigned char buf[20];
30   int len, ls;
31
32   if ( ! ( pdu = coap_new_pdu() ) )
33     return NULL;
34
35   pdu->hdr->type = COAP_MESSAGE_NON;
36   pdu->hdr->code = COAP_REQUEST_POST;
37   pdu->hdr->id = htons(id++);
38
39   enc = COAP_PSEUDOFP_ENCODE_8_4_DOWN(value,ls);
40   coap_add_data( pdu, 1, &enc);
41
42   len = sprintf((char *)buf, "%u", COAP_PSEUDOFP_DECODE_8_4(enc));
43   if ( len > 0 ) {
44     coap_add_data( pdu, len, buf );
45   }
46
47   return pdu;
48 }
49
50 void
51 usage( const char *program ) {
52   const char *p;
53
54   p = strrchr( program, '/' );
55   if ( p )
56     program = ++p;
57
58   fprintf( stderr, "%s -- tiny fake sensor\n"
59            "(c) 2010 Olaf Bergmann <bergmann@tzi.org>\n\n"
60            "usage: %s [group address]\n"
61            "\n\nSends some fake sensor values to specified multicast group\n",
62            program, program );
63 }
64
65 coap_context_t *
66 get_context(const char *node, const char *port) {
67   coap_context_t *ctx = NULL;  
68   int s;
69   struct addrinfo hints;
70   struct addrinfo *result, *rp;
71
72   memset(&hints, 0, sizeof(struct addrinfo));
73   hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
74   hints.ai_socktype = SOCK_DGRAM; /* Coap uses UDP */
75   hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV | AI_ALL;
76   
77   s = getaddrinfo(node, port, &hints, &result);
78   if ( s != 0 ) {
79     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
80     return NULL;
81   } 
82
83   /* iterate through results until success */
84   for (rp = result; rp != NULL; rp = rp->ai_next) {
85     ctx = coap_new_context(rp->ai_addr, rp->ai_addrlen);
86     if (ctx) {
87       /* TODO: output address:port for successful binding */
88       goto finish;
89     }
90   }
91   
92   fprintf(stderr, "no context available for interface '%s'\n", node);
93
94  finish:
95   freeaddrinfo(result);
96   return ctx;
97 }
98
99 int
100 main(int argc, char **argv) {
101   coap_context_t  *ctx;
102   struct timeval tv;
103   coap_pdu_t  *pdu;
104   struct sockaddr_in6 dst;
105   int hops = 16;
106
107   if ( argc > 1 && strncmp(argv[1], "-h", 2) == 0 ) {
108     usage( argv[0] );
109     exit( 1 );
110   }
111
112   ctx = get_context("::", NULL);
113   if ( !ctx )
114     return -1;
115
116   id = rand() & INT_MAX;
117
118   memset(&dst, 0, sizeof(struct sockaddr_in6 ));
119   dst.sin6_family = AF_INET6;
120   inet_pton( AF_INET6, argc > 1 ? argv[1] : "::1", &dst.sin6_addr );
121   dst.sin6_port = htons( COAP_DEFAULT_PORT );
122
123   if ( IN6_IS_ADDR_MULTICAST(&dst.sin6_addr) ) {
124     /* set socket options for multicast */
125
126     if ( setsockopt( ctx->sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
127                      (char *)&hops, sizeof(hops) ) < 0 )
128       perror("setsockopt: IPV6_MULTICAST_HOPS");
129
130   }
131
132   while ( 1 ) {
133
134     if (! (pdu = make_pdu( rand() & 0xfff ) ) )
135       return -1;
136
137     coap_send( ctx, (struct sockaddr *)&dst, sizeof(dst), pdu );
138     coap_delete_pdu(pdu);
139
140     tv.tv_sec = 5; tv.tv_usec = 0;
141
142     select( 0, 0, 0, 0, &tv );
143
144   }
145
146   coap_free_context( ctx );
147
148   return 0;
149 }