Avnet AT&T IoT Starter Kit demo for Pubnub

Dependencies:   FXOS8700CQ mbed

Committer:
sveljko
Date:
Wed Aug 31 18:04:30 2016 +0000
Revision:
36:382cb978bddc
Parent:
35:d0d86a2bcdb3
Fixed "gobbling" of the last character in received message (from the subscribe transaction);

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sveljko 35:d0d86a2bcdb3 1 #include "pubnub.h"
sveljko 35:d0d86a2bcdb3 2
sveljko 35:d0d86a2bcdb3 3 #include "mbed.h"
sveljko 35:d0d86a2bcdb3 4 #include <string>
sveljko 35:d0d86a2bcdb3 5 #include "wnc_control.h"
sveljko 35:d0d86a2bcdb3 6
sveljko 35:d0d86a2bcdb3 7 #include <stdio.h>
sveljko 35:d0d86a2bcdb3 8
sveljko 35:d0d86a2bcdb3 9
sveljko 35:d0d86a2bcdb3 10 pubnub_ctx::pubnub_ctx(char const* pub_key, char const *key_sub)
sveljko 35:d0d86a2bcdb3 11 : d_pub_key(pub_key)
sveljko 35:d0d86a2bcdb3 12 , d_key_sub(key_sub)
sveljko 35:d0d86a2bcdb3 13 , d_token("0")
sveljko 35:d0d86a2bcdb3 14 {
sveljko 35:d0d86a2bcdb3 15 }
sveljko 35:d0d86a2bcdb3 16
sveljko 35:d0d86a2bcdb3 17
sveljko 35:d0d86a2bcdb3 18 pubnub_ctx::~pubnub_ctx()
sveljko 35:d0d86a2bcdb3 19 {
sveljko 35:d0d86a2bcdb3 20 }
sveljko 35:d0d86a2bcdb3 21
sveljko 35:d0d86a2bcdb3 22
sveljko 35:d0d86a2bcdb3 23 static void append_epilogue(std::string &s, std::string const& uuid, std::string const& auth)
sveljko 35:d0d86a2bcdb3 24 {
sveljko 35:d0d86a2bcdb3 25 s += "?pnsdk=AvnetATTmbed";
sveljko 35:d0d86a2bcdb3 26 if (!uuid.empty()) {
sveljko 35:d0d86a2bcdb3 27 s += "&uuid=";
sveljko 35:d0d86a2bcdb3 28 s += uuid;
sveljko 35:d0d86a2bcdb3 29 }
sveljko 35:d0d86a2bcdb3 30 if (!auth.empty()) {
sveljko 35:d0d86a2bcdb3 31 s += "&auth=";
sveljko 35:d0d86a2bcdb3 32 s += auth;
sveljko 35:d0d86a2bcdb3 33 }
sveljko 35:d0d86a2bcdb3 34 s += " HTTP/1.1\r\nHost: pubsub.pubnub.com\r\n\r\n";
sveljko 35:d0d86a2bcdb3 35 }
sveljko 35:d0d86a2bcdb3 36
sveljko 35:d0d86a2bcdb3 37
sveljko 35:d0d86a2bcdb3 38 pubnub_ctx::result pubnub_ctx::publish(char const* channel, char const* message)
sveljko 35:d0d86a2bcdb3 39 {
sveljko 35:d0d86a2bcdb3 40 char const *pmessage = message;
sveljko 35:d0d86a2bcdb3 41 std::string s("GET /publish/");
sveljko 35:d0d86a2bcdb3 42 s += d_pub_key; s += "/";
sveljko 35:d0d86a2bcdb3 43 s += d_key_sub; s += "/0/";
sveljko 35:d0d86a2bcdb3 44 s += channel; s += "/0/";
sveljko 35:d0d86a2bcdb3 45
sveljko 35:d0d86a2bcdb3 46 while (pmessage[0]) {
sveljko 35:d0d86a2bcdb3 47 /* RFC 3986 Unreserved characters plus few
sveljko 35:d0d86a2bcdb3 48 * safe reserved ones. */
sveljko 35:d0d86a2bcdb3 49 size_t okspan = strspn(pmessage, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~" ",=:;@[]");
sveljko 35:d0d86a2bcdb3 50 if (okspan > 0) {
sveljko 35:d0d86a2bcdb3 51 s.append(pmessage, okspan);
sveljko 35:d0d86a2bcdb3 52 pmessage += okspan;
sveljko 35:d0d86a2bcdb3 53 }
sveljko 35:d0d86a2bcdb3 54 if (pmessage[0]) {
sveljko 35:d0d86a2bcdb3 55 /* %-encode a non-ok character. */
sveljko 35:d0d86a2bcdb3 56 s.append(1, '%');
sveljko 35:d0d86a2bcdb3 57 s.append(1, "0123456789ABCDEF"[pmessage[0] / 16]);
sveljko 35:d0d86a2bcdb3 58 s.append(1, "0123456789ABCDEF"[pmessage[0] % 16]);
sveljko 35:d0d86a2bcdb3 59 ++pmessage;
sveljko 35:d0d86a2bcdb3 60 }
sveljko 35:d0d86a2bcdb3 61 }
sveljko 35:d0d86a2bcdb3 62
sveljko 35:d0d86a2bcdb3 63 append_epilogue(s, d_uuid, d_auth);
sveljko 35:d0d86a2bcdb3 64
sveljko 35:d0d86a2bcdb3 65 sockwrite_mdm(s.c_str());
sveljko 35:d0d86a2bcdb3 66 string response;
sveljko 35:d0d86a2bcdb3 67 unsigned read = sockread_mdm(&response, 1024, 50);
sveljko 35:d0d86a2bcdb3 68
sveljko 35:d0d86a2bcdb3 69 if (read < 5) {
sveljko 35:d0d86a2bcdb3 70 extern Serial pc;
sveljko 35:d0d86a2bcdb3 71 pc.printf("read = %d\r\n", read);
sveljko 35:d0d86a2bcdb3 72 return response_too_short;
sveljko 35:d0d86a2bcdb3 73 }
sveljko 35:d0d86a2bcdb3 74 char const* start = strchr(response.data(), '[');
sveljko 35:d0d86a2bcdb3 75 if (NULL == start) {
sveljko 35:d0d86a2bcdb3 76 return missing_open_bracket;
sveljko 35:d0d86a2bcdb3 77 }
sveljko 35:d0d86a2bcdb3 78 if (NULL == strrchr(response.data() + response.size() - 1, ']')) {
sveljko 35:d0d86a2bcdb3 79 return missing_close_bracket;
sveljko 35:d0d86a2bcdb3 80 }
sveljko 35:d0d86a2bcdb3 81
sveljko 35:d0d86a2bcdb3 82 if (1 != strtol(start + 1, NULL, 10)) {
sveljko 35:d0d86a2bcdb3 83 return publish_failed;
sveljko 35:d0d86a2bcdb3 84 }
sveljko 35:d0d86a2bcdb3 85
sveljko 35:d0d86a2bcdb3 86 return ok;
sveljko 35:d0d86a2bcdb3 87 }
sveljko 35:d0d86a2bcdb3 88
sveljko 35:d0d86a2bcdb3 89 pubnub_ctx::result pubnub_ctx::subscribe(char const* channel, std::vector<std::string>& messages)
sveljko 35:d0d86a2bcdb3 90 {
sveljko 35:d0d86a2bcdb3 91 std::string s("GET /subscribe/");
sveljko 35:d0d86a2bcdb3 92 s += d_key_sub; s += "/";
sveljko 35:d0d86a2bcdb3 93 s += channel; s += "/0/";
sveljko 35:d0d86a2bcdb3 94 s += d_token;;
sveljko 35:d0d86a2bcdb3 95 append_epilogue(s, d_uuid, d_auth);
sveljko 35:d0d86a2bcdb3 96
sveljko 35:d0d86a2bcdb3 97 sockwrite_mdm(s.c_str());
sveljko 35:d0d86a2bcdb3 98 string response;
sveljko 35:d0d86a2bcdb3 99 unsigned read = sockread_mdm(&response, 1024, 50);
sveljko 35:d0d86a2bcdb3 100
sveljko 35:d0d86a2bcdb3 101 if (read < 10) {
sveljko 35:d0d86a2bcdb3 102 return response_too_short;
sveljko 35:d0d86a2bcdb3 103 }
sveljko 35:d0d86a2bcdb3 104 char const* start = strchr(response.c_str(), '[');
sveljko 35:d0d86a2bcdb3 105 if (NULL == start) {
sveljko 35:d0d86a2bcdb3 106 return missing_open_bracket;
sveljko 35:d0d86a2bcdb3 107 }
sveljko 35:d0d86a2bcdb3 108 if (start[1] != '[') {
sveljko 35:d0d86a2bcdb3 109 return missing_open_bracket;
sveljko 35:d0d86a2bcdb3 110 }
sveljko 35:d0d86a2bcdb3 111 enum {
sveljko 35:d0d86a2bcdb3 112 idle,
sveljko 35:d0d86a2bcdb3 113 in_string,
sveljko 35:d0d86a2bcdb3 114 escape,
sveljko 35:d0d86a2bcdb3 115 done
sveljko 35:d0d86a2bcdb3 116 } state = idle;
sveljko 35:d0d86a2bcdb3 117 start += 2;
sveljko 35:d0d86a2bcdb3 118 char const* end;
sveljko 35:d0d86a2bcdb3 119 int bracket_level = 1;
sveljko 35:d0d86a2bcdb3 120 for (end = start; (*end != '\0') && (state != done); ++end) {
sveljko 35:d0d86a2bcdb3 121 char c = *end;
sveljko 35:d0d86a2bcdb3 122 switch (state) {
sveljko 35:d0d86a2bcdb3 123 case idle:
sveljko 35:d0d86a2bcdb3 124 switch (c) {
sveljko 35:d0d86a2bcdb3 125 case '"':
sveljko 35:d0d86a2bcdb3 126 state = in_string;
sveljko 35:d0d86a2bcdb3 127 break;
sveljko 35:d0d86a2bcdb3 128 case ',':
sveljko 35:d0d86a2bcdb3 129 if (bracket_level == 1) {
sveljko 36:382cb978bddc 130 messages.push_back(std::string(start, end-start));
sveljko 35:d0d86a2bcdb3 131 start = end + 1;
sveljko 35:d0d86a2bcdb3 132 }
sveljko 35:d0d86a2bcdb3 133 break;
sveljko 35:d0d86a2bcdb3 134 case '{':
sveljko 35:d0d86a2bcdb3 135 case '[':
sveljko 35:d0d86a2bcdb3 136 ++bracket_level;
sveljko 35:d0d86a2bcdb3 137 break;
sveljko 35:d0d86a2bcdb3 138 case '}':
sveljko 35:d0d86a2bcdb3 139 --bracket_level;
sveljko 35:d0d86a2bcdb3 140 break;
sveljko 35:d0d86a2bcdb3 141 case ']':
sveljko 35:d0d86a2bcdb3 142 if (--bracket_level <= 0) {
sveljko 35:d0d86a2bcdb3 143 if (end-start-1 > 0) {
sveljko 36:382cb978bddc 144 messages.push_back(std::string(start, end-start));
sveljko 35:d0d86a2bcdb3 145 }
sveljko 35:d0d86a2bcdb3 146 state = done;
sveljko 35:d0d86a2bcdb3 147 }
sveljko 35:d0d86a2bcdb3 148 break;
sveljko 35:d0d86a2bcdb3 149 }
sveljko 35:d0d86a2bcdb3 150 break;
sveljko 35:d0d86a2bcdb3 151 case in_string:
sveljko 35:d0d86a2bcdb3 152 switch (c) {
sveljko 35:d0d86a2bcdb3 153 case '"':
sveljko 35:d0d86a2bcdb3 154 state = idle;
sveljko 35:d0d86a2bcdb3 155 break;
sveljko 35:d0d86a2bcdb3 156 case '\\':
sveljko 35:d0d86a2bcdb3 157 state = escape;
sveljko 35:d0d86a2bcdb3 158 break;
sveljko 35:d0d86a2bcdb3 159 }
sveljko 35:d0d86a2bcdb3 160 break;
sveljko 35:d0d86a2bcdb3 161 case escape:
sveljko 35:d0d86a2bcdb3 162 state = in_string;
sveljko 35:d0d86a2bcdb3 163 break;
sveljko 35:d0d86a2bcdb3 164 default:
sveljko 35:d0d86a2bcdb3 165 state = done;
sveljko 35:d0d86a2bcdb3 166 break;
sveljko 35:d0d86a2bcdb3 167 }
sveljko 35:d0d86a2bcdb3 168 }
sveljko 35:d0d86a2bcdb3 169 if (state != done) {
sveljko 35:d0d86a2bcdb3 170 return format_error;
sveljko 35:d0d86a2bcdb3 171 }
sveljko 35:d0d86a2bcdb3 172 if ((end[0] != ',') && (end[1] != '"')) {
sveljko 35:d0d86a2bcdb3 173 return missing_time_token;
sveljko 35:d0d86a2bcdb3 174 }
sveljko 35:d0d86a2bcdb3 175 start = end + 2;
sveljko 35:d0d86a2bcdb3 176 end = strchr(start, '"');
sveljko 35:d0d86a2bcdb3 177 if (NULL == end) {
sveljko 35:d0d86a2bcdb3 178 return bad_time_token;
sveljko 35:d0d86a2bcdb3 179 }
sveljko 35:d0d86a2bcdb3 180 d_token.assign(start, end-start);
sveljko 35:d0d86a2bcdb3 181
sveljko 35:d0d86a2bcdb3 182 return ok;
sveljko 35:d0d86a2bcdb3 183 }