1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
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 |
|
44 | typedef enum {
|
45 | stStart,
|
46 | stSocketOpened,
|
47 | stConnSent,
|
48 | stConnAckd,
|
49 | stSubSent,
|
50 | stSubAckd,
|
51 | stPause
|
52 | } stateType;
|
53 |
|
54 | static stateType state = stStart;
|
55 |
|
56 | int 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 |
|
107 | void 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 |
|
121 | int 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 |
|
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 |
|
164 |
|
165 |
|
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 |
|
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 |
|