libcoap  4.1.1
 All Data Structures Files Functions Variables Typedefs Macros Groups Pages
tiny.c
Go to the documentation of this file.
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 
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 }
#define COAP_REQUEST_POST
Definition: pdu.h:51
unsigned short id
Definition: pdu.h:173
int coap_tid_t
Definition: pdu.h:155
#define COAP_MESSAGE_NON
Definition: pdu.h:44
void usage(const char *program)
Definition: tiny.c:51
coap_pdu_t * make_pdu(unsigned int value)
Definition: tiny.c:26
coap_hdr_t * hdr
Definition: pdu.h:209
coap_context_t * coap_new_context(const coap_address_t *listen_addr)
Creates a new coap_context_t object that will hold the CoAP stack status.
Definition: net.c:296
coap_context_t * get_context(const char *node, const char *port)
Definition: tiny.c:66
int main(int argc, char **argv)
Definition: tiny.c:100
unsigned int code
Definition: pdu.h:172
Header structure for CoAP PDUs.
Definition: pdu.h:206
static coap_tid_t id
Definition: tiny.c:23
int coap_add_data(coap_pdu_t *pdu, unsigned int len, const unsigned char *data)
Adds given data to the pdu that is passed as first parameter.
Definition: pdu.c:238
coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu)
Sends a non-confirmed CoAP message to given destination.
Definition: net.c:653
#define COAP_PSEUDOFP_DECODE_8_4(r)
Definition: encode.h:25
#define COAP_DEFAULT_PORT
Definition: pdu.h:24
void coap_delete_pdu(coap_pdu_t *pdu)
Definition: pdu.c:143
void coap_free_context(coap_context_t *context)
Definition: net.c:419
unsigned int type
Definition: pdu.h:170
coap_pdu_t * coap_new_pdu()
Creates a new CoAP PDU.
Definition: pdu.c:126
The CoAP stack's global state is stored in a coap_context_t object.
Definition: net.h:97
#define COAP_PSEUDOFP_ENCODE_8_4_DOWN(v, ls)
Definition: encode.h:35