UNPKG

5.05 kBtext/x-cView Raw
1/*
2Copyright (c) 2009, Roger Light <roger@atchoo.org>
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7
81. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
102. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
133. Neither the name of mosquitto nor the names of its
14 contributors may be used to endorse or promote products derived from
15 this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <errno.h>
31#include <fcntl.h>
32#include <stdbool.h>
33#include <stdint.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <sys/stat.h>
38#include <sys/types.h>
39#include <sys/select.h>
40#include <unistd.h>
41
42#include <mqtt3.h>
43
44typedef enum {
45 stStart,
46 stSocketOpened,
47 stConnSent,
48 stConnAckd,
49 stSubSent,
50 stSubAckd,
51 stPause
52} stateType;
53
54static stateType state = stStart;
55
56int handle_read(mqtt3_context *context)
57{
58 uint8_t buf;
59 int rc;
60
61 rc = read(context->sock, &buf, 1);
62 printf("rc: %d\n", rc);
63 if(rc == -1){
64 printf("Error: %s\n", strerror(errno));
65 return 1;
66 }else if(rc == 0){
67 return 2;
68 }
69
70 switch(buf&0xF0){
71 case CONNACK:
72 if(mqtt3_handle_connack(context)) return 3;
73 state = stConnAckd;
74 break;
75 case SUBACK:
76 if(mqtt3_handle_suback(context)) return 3;
77 state = stSubAckd;
78 break;
79 case PINGREQ:
80 if(mqtt3_handle_pingreq(context)) return 3;
81 break;
82 case PINGRESP:
83 if(mqtt3_handle_pingresp(context)) return 3;
84 break;
85 case PUBACK:
86 if(mqtt3_handle_puback(context)) return 3;
87 break;
88 case PUBCOMP:
89 if(mqtt3_handle_pubcomp(context)) return 3;
90 break;
91 case PUBLISH:
92 if(mqtt3_handle_publish(context)) return 0;
93 break;
94 case PUBREC:
95 if(mqtt3_handle_pubrec(context)) return 3;
96 break;
97 case UNSUBACK:
98 if(mqtt3_handle_unsuback(context)) return 3;
99 break;
100 default:
101 printf("Unknown command: %s (%d)\n", mqtt3_command_to_string(buf&0xF0), buf&0xF0);
102 break;
103 }
104 return 0;
105}
106
107void send_random(mqtt3_context *context, int length)
108{
109 int fd = open("/dev/urandom", O_RDONLY);
110 uint8_t buf[length];
111
112 if(fd >= 0){
113 if(read(fd, buf, length) == length){
114 mqtt3_write_bytes(context, buf, length);
115 }
116 close(fd);
117 }
118}
119
120/* pselect loop test */
121int main(int argc, char *argv[])
122{
123 struct timespec timeout;
124 fd_set readfds, writefds;
125 int fdcount;
126 int run = 1;
127 mqtt3_context context;
128 char id[30];
129
130 if(argc == 2){
131 sprintf(id, "test%s", argv[1]);
132 }else{
133 sprintf(id, "test");
134 }
135 context.sock = mqtt3_socket_connect("127.0.0.1", 1883);
136 if(context.sock == -1){
137 return 1;
138 }
139 state = stSocketOpened;
140
141 while(run){
142 FD_ZERO(&readfds);
143 FD_SET(context.sock, &readfds);
144 FD_ZERO(&writefds);
145 //FD_SET(0, &writefds);
146 timeout.tv_sec = 1;
147 timeout.tv_nsec = 0;
148
149 fdcount = pselect(context.sock+1, &readfds, &writefds, NULL, &timeout, NULL);
150 if(fdcount == -1){
151 fprintf(stderr, "Error in pselect: %s\n", strerror(errno));
152 run = 0;
153 }else if(fdcount == 0){
154 switch(state){
155 case stSocketOpened:
156 mqtt3_raw_connect(&context, id, true, 2, true, "will", "aargh", 60, true);
157 state = stConnSent;
158 break;
159 case stConnSent:
160 printf("Waiting for CONNACK\n");
161 break;
162 case stConnAckd:
163 // printf("CONNACK received\n");
164 // mqtt3_raw_subscribe(&context, false, "a/b/c", 0);
165 // state = stSubSent;
166 send_random(&context, 100);
167 break;
168 case stSubSent:
169 printf("Waiting for SUBACK\n");
170 break;
171 case stSubAckd:
172 printf("SUBACK received\n");
173 mqtt3_raw_publish(&context, 0, 0, 0, 1, "a/b/c", 5, (uint8_t *)"Roger");
174 state = stPause;
175 break;
176 case stPause:
177 //mqtt3_raw_disconnect(&context);
178 printf("Pause\n");
179 break;
180 default:
181 fprintf(stderr, "Error: Unknown state\n");
182 break;
183 }
184 }else{
185 printf("fdcount=%d\n", fdcount);
186
187 if(FD_ISSET(context.sock, &readfds)){
188 if(handle_read(&context)){
189 fprintf(stderr, "Socket closed on remote side\n");
190 mqtt3_socket_close(&context);
191 run = 0;
192 }
193 }
194 }
195 }
196 return 0;
197}
198