1 /*******************************************************************************
2 * Copyright (c) 2014 IBM Corp.
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * and Eclipse Distribution License v1.0 which accompany this distribution.
7 *
8 * The Eclipse Public License is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 * and the Eclipse Distribution License is available at
11 * http://www.eclipse.org/org/documents/edl-v10.php.
12 *
13 * Contributors:
14 * Ian Craggs - initial API and implementation and/or initial documentation
15 * Sergio R. Caprile - port and nonblocking
16 *******************************************************************************/
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21
22 #include "MQTTPacket.h"
23 #include "transport.h"
24
25 #define KEEPALIVE_INTERVAL 20
26
27 /* This is to get a timebase in seconds to test the sample */
28 #include <time.h>
29 time_t old_t;
start_ping_timer(void)30 void start_ping_timer(void)
31 {
32 time(&old_t);
33 old_t += KEEPALIVE_INTERVAL/2 + 1;
34 }
35
time_to_ping(void)36 int time_to_ping(void)
37 {
38 time_t t;
39
40 time(&t);
41 if(t >= old_t)
42 return 1;
43 return 0;
44 }
45
46 /* This is in order to get an asynchronous signal to stop the sample,
47 as the code loops waiting for msgs on the subscribed topic.
48 Your actual code will depend on your hw and approach*/
49 #include <signal.h>
50
51 int toStop = 0;
52
cfinish(int sig)53 void cfinish(int sig)
54 {
55 signal(SIGINT, NULL);
56 toStop = 1;
57 }
58
stop_init(void)59 void stop_init(void)
60 {
61 signal(SIGINT, cfinish);
62 signal(SIGTERM, cfinish);
63 }
64 /* */
65
66 enum states { IDLE, GETPONG };
67
main(int argc,char * argv[])68 int main(int argc, char *argv[])
69 {
70 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
71 int rc = 0;
72 int mysock = 0;
73 unsigned char buf[200];
74 int buflen = sizeof(buf);
75 int len = 0;
76 char *host = MQTT_HOST;
77 int port = MQTT_PORT;
78 MQTTTransport mytransport;
79 int state;
80
81 stop_init();
82 if (argc > 1)
83 host = argv[1];
84
85 if (argc > 2)
86 port = atoi(argv[2]);
87
88 mysock = transport_open(host, port);
89 if(mysock < 0)
90 return mysock;
91
92 printf("Sending to hostname %s port %d\n", host, port);
93
94 mytransport.sck = &mysock;
95 mytransport.getfn = transport_getdatanb;
96 mytransport.state = 0;
97 data.clientID.cstring = "me";
98 data.keepAliveInterval = KEEPALIVE_INTERVAL;
99 data.cleansession = 1;
100 data.username.cstring = "testuser";
101 data.password.cstring = "testpassword";
102
103 len = MQTTSerialize_connect(buf, buflen, &data);
104 rc = transport_sendPacketBuffer(mysock, buf, len);
105
106 printf("Sent MQTT connect\n");
107 /* wait for connack */
108 do {
109 int frc;
110 if ((frc=MQTTPacket_readnb(buf, buflen, &mytransport)) == CONNACK){
111 unsigned char sessionPresent, connack_rc;
112 if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0){
113 printf("Unable to connect, return code %d\n", connack_rc);
114 goto exit;
115 }
116 break;
117 }
118 else if (frc == -1)
119 goto exit;
120 } while (1); /* handle timeouts here */
121
122 printf("MQTT connected\n");
123 start_ping_timer();
124
125 state = IDLE;
126 while (!toStop) {
127 switch(state){
128 case IDLE:
129 if(time_to_ping()){
130 len = MQTTSerialize_pingreq(buf, buflen);
131 transport_sendPacketBuffer(mysock, buf, len);
132 printf("Ping...");
133 state = GETPONG;
134 }
135 break;
136 case GETPONG:
137 if((rc=MQTTPacket_readnb(buf, buflen, &mytransport)) == PINGRESP){
138 printf("Pong\n");
139 start_ping_timer();
140 state = IDLE;
141 } else if(rc == -1){
142 printf("OOPS\n");
143 goto exit;
144 }
145 break;
146 }
147 }
148
149 printf("disconnecting\n");
150 len = MQTTSerialize_disconnect(buf, buflen);
151 rc = transport_sendPacketBuffer(mysock, buf, len);
152
153 exit:
154 transport_close(mysock);
155
156 return 0;
157 }
158