Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / resource / csdk / connectivity / lib / 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 {
28     coap_pdu_t *pdu;
29     unsigned char enc;
30     static unsigned char buf[20];
31     int len, ls;
32
33     if (!(pdu = coap_new_pdu()))
34         return NULL;
35
36     pdu->hdr->type = COAP_MESSAGE_NON;
37     pdu->hdr->code = COAP_REQUEST_POST;
38     pdu->hdr->id = htons(id++);
39
40     enc = COAP_PSEUDOFP_ENCODE_8_4_DOWN(value,ls);
41     coap_add_data(pdu, 1, &enc);
42
43     len = snprintf((char *) buf, sizeof(buf), "%u", COAP_PSEUDOFP_DECODE_8_4(enc));
44     if (len > 0)
45     {
46         coap_add_data(pdu, len, buf);
47     }
48
49     return pdu;
50 }
51
52 void usage(const char *program)
53 {
54     const char *p;
55
56     p = strrchr(program, '/');
57     if (p)
58         program = ++p;
59
60     fprintf(stderr, "%s -- tiny fake sensor\n"
61             "(c) 2010 Olaf Bergmann <bergmann@tzi.org>\n\n"
62             "usage: %s [group address]\n"
63             "\n\nSends some fake sensor values to specified multicast group\n", program, program);
64 }
65
66 coap_context_t *
67 get_context(const char *node, const char *port)
68 {
69     coap_context_t *ctx = NULL;
70     int s;
71     struct addrinfo hints;
72     struct addrinfo *result, *rp;
73
74     memset(&hints, 0, sizeof(struct addrinfo));
75     hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
76     hints.ai_socktype = SOCK_DGRAM; /* Coap uses UDP */
77     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV | AI_ALL;
78
79     s = getaddrinfo(node, port, &hints, &result);
80     if (s != 0)
81     {
82         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
83         return NULL;
84     }
85
86     /* iterate through results until success */
87     for (rp = result; rp != NULL; rp = rp->ai_next)
88     {
89         ctx = coap_new_context(rp->ai_addr, rp->ai_addrlen);
90         if (ctx)
91         {
92             /* TODO: output address:port for successful binding */
93             goto finish;
94         }
95     }
96
97     fprintf(stderr, "no context available for interface '%s'\n", node);
98
99     finish: freeaddrinfo(result);
100     return ctx;
101 }
102
103 int main(int argc, char **argv)
104 {
105     coap_context_t *ctx;
106     struct timeval tv;
107     coap_pdu_t *pdu;
108     struct sockaddr_in6 dst;
109     int hops = 16;
110
111     if (argc > 1 && strncmp(argv[1], "-h", 2) == 0)
112     {
113         usage(argv[0]);
114         exit(1);
115     }
116
117     ctx = get_context("::", NULL);
118     if (!ctx)
119         return -1;
120
121     id = rand() & INT_MAX;
122
123     memset(&dst, 0, sizeof(struct sockaddr_in6));
124     dst.sin6_family = AF_INET6;
125     inet_pton(AF_INET6, argc > 1 ? argv[1] : "::1", &dst.sin6_addr);
126     dst.sin6_port = htons(COAP_DEFAULT_PORT);
127
128     if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr))
129     {
130         /* set socket options for multicast */
131
132         if (setsockopt(ctx->sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &hops, sizeof(hops))
133                 < 0)
134             perror("setsockopt: IPV6_MULTICAST_HOPS");
135
136     }
137
138     while (1)
139     {
140
141         if (!(pdu = make_pdu(rand() & 0xfff)))
142             return -1;
143
144         coap_send(ctx, (struct sockaddr *) &dst, sizeof(dst), pdu);
145         coap_delete_pdu(pdu);
146
147         tv.tv_sec = 5;
148         tv.tv_usec = 0;
149
150         select(0, 0, 0, 0, &tv);
151
152     }
153
154     coap_free_context(ctx);
155
156     return 0;
157 }