Ambient Library
Fork of AmbientLib by
Ambient library. It provides "set" function to set data to a packet and "send" function to send the packet to the Ambient server. It also provides "bulk_send" function to send multiple data. (Japanese: IoT用のクラウドサービス「Ambient」のデーター送信ライブラリーです。Ambientはマイコンから送られたセンサーデーターを受信し、蓄積し、可視化(グラフ化)します。http://ambidata.io)
Ambient.cpp@0:d2972e5edb22, 2016-05-07 (annotated)
- Committer:
- TakehikoShimojima
- Date:
- Sat May 07 01:11:27 2016 +0000
- Revision:
- 0:d2972e5edb22
initial
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
TakehikoShimojima | 0:d2972e5edb22 | 1 | #include "Ambient.h" |
TakehikoShimojima | 0:d2972e5edb22 | 2 | |
TakehikoShimojima | 0:d2972e5edb22 | 3 | #define _DEBUG 0 |
TakehikoShimojima | 0:d2972e5edb22 | 4 | |
TakehikoShimojima | 0:d2972e5edb22 | 5 | #if _DEBUG |
TakehikoShimojima | 0:d2972e5edb22 | 6 | #define DBG(...) { printf(__VA_ARGS__); } |
TakehikoShimojima | 0:d2972e5edb22 | 7 | #define ERR(...) { printf(__VA_ARGS__); } |
TakehikoShimojima | 0:d2972e5edb22 | 8 | #else |
TakehikoShimojima | 0:d2972e5edb22 | 9 | #define DBG(...) |
TakehikoShimojima | 0:d2972e5edb22 | 10 | #define ERR(...) |
TakehikoShimojima | 0:d2972e5edb22 | 11 | #endif /* _DBG */ |
TakehikoShimojima | 0:d2972e5edb22 | 12 | |
TakehikoShimojima | 0:d2972e5edb22 | 13 | const char* AMBIENT_HOST = "54.65.206.59"; |
TakehikoShimojima | 0:d2972e5edb22 | 14 | const int AMBIENT_PORT = 80; |
TakehikoShimojima | 0:d2972e5edb22 | 15 | const char* AMBIENT_HOST_DEV = "192.168.0.8"; |
TakehikoShimojima | 0:d2972e5edb22 | 16 | const int AMBIENT_PORT_DEV = 4567; |
TakehikoShimojima | 0:d2972e5edb22 | 17 | |
TakehikoShimojima | 0:d2972e5edb22 | 18 | const char * ambient_keys[] = {"\"d1\":\"", "\"d2\":\"", "\"d3\":\"", "\"d4\":\"", "\"d5\":\"", "\"d6\":\"", "\"d7\":\"", "\"d8\":\"", "\"lat\":\"", "\"lng\":\"", "\"created\":\""}; |
TakehikoShimojima | 0:d2972e5edb22 | 19 | |
TakehikoShimojima | 0:d2972e5edb22 | 20 | AMBIENT::AMBIENT() { |
TakehikoShimojima | 0:d2972e5edb22 | 21 | } |
TakehikoShimojima | 0:d2972e5edb22 | 22 | |
TakehikoShimojima | 0:d2972e5edb22 | 23 | bool |
TakehikoShimojima | 0:d2972e5edb22 | 24 | AMBIENT::init(unsigned int channelId, const char * writeKey, TCPSocketConnection * s, int dev) { |
TakehikoShimojima | 0:d2972e5edb22 | 25 | this->channelId = channelId; |
TakehikoShimojima | 0:d2972e5edb22 | 26 | |
TakehikoShimojima | 0:d2972e5edb22 | 27 | if (sizeof(writeKey) > AMBIENT_WRITEKEY_SIZE) { |
TakehikoShimojima | 0:d2972e5edb22 | 28 | ERR("writeKey length > AMBIENT_WRITEKEY_SIZE"); |
TakehikoShimojima | 0:d2972e5edb22 | 29 | return false; |
TakehikoShimojima | 0:d2972e5edb22 | 30 | } |
TakehikoShimojima | 0:d2972e5edb22 | 31 | strcpy(this->writeKey, writeKey); |
TakehikoShimojima | 0:d2972e5edb22 | 32 | |
TakehikoShimojima | 0:d2972e5edb22 | 33 | if(NULL == s) { |
TakehikoShimojima | 0:d2972e5edb22 | 34 | ERR("Socket Pointer is NULL, open a socket."); |
TakehikoShimojima | 0:d2972e5edb22 | 35 | return false; |
TakehikoShimojima | 0:d2972e5edb22 | 36 | } |
TakehikoShimojima | 0:d2972e5edb22 | 37 | this->s = s; |
TakehikoShimojima | 0:d2972e5edb22 | 38 | this->dev = dev; |
TakehikoShimojima | 0:d2972e5edb22 | 39 | if (dev) { |
TakehikoShimojima | 0:d2972e5edb22 | 40 | strcpy(this->host, AMBIENT_HOST_DEV); |
TakehikoShimojima | 0:d2972e5edb22 | 41 | this->port = AMBIENT_PORT_DEV; |
TakehikoShimojima | 0:d2972e5edb22 | 42 | } else { |
TakehikoShimojima | 0:d2972e5edb22 | 43 | strcpy(this->host, AMBIENT_HOST); |
TakehikoShimojima | 0:d2972e5edb22 | 44 | this->port = AMBIENT_PORT; |
TakehikoShimojima | 0:d2972e5edb22 | 45 | } |
TakehikoShimojima | 0:d2972e5edb22 | 46 | for (int i = 0; i < AMBIENT_NUM_PARAMS; i++) { |
TakehikoShimojima | 0:d2972e5edb22 | 47 | this->data[i].set = false; |
TakehikoShimojima | 0:d2972e5edb22 | 48 | } |
TakehikoShimojima | 0:d2972e5edb22 | 49 | return true; |
TakehikoShimojima | 0:d2972e5edb22 | 50 | } |
TakehikoShimojima | 0:d2972e5edb22 | 51 | |
TakehikoShimojima | 0:d2972e5edb22 | 52 | bool |
TakehikoShimojima | 0:d2972e5edb22 | 53 | AMBIENT::set(int field, char * data) { |
TakehikoShimojima | 0:d2972e5edb22 | 54 | --field; |
TakehikoShimojima | 0:d2972e5edb22 | 55 | if (field < 0 || field >= AMBIENT_NUM_PARAMS) { |
TakehikoShimojima | 0:d2972e5edb22 | 56 | return false; |
TakehikoShimojima | 0:d2972e5edb22 | 57 | } |
TakehikoShimojima | 0:d2972e5edb22 | 58 | if (strlen(data) > AMBIENT_DATA_SIZE) { |
TakehikoShimojima | 0:d2972e5edb22 | 59 | return false; |
TakehikoShimojima | 0:d2972e5edb22 | 60 | } |
TakehikoShimojima | 0:d2972e5edb22 | 61 | this->data[field].set = true; |
TakehikoShimojima | 0:d2972e5edb22 | 62 | strcpy(this->data[field].item, data); |
TakehikoShimojima | 0:d2972e5edb22 | 63 | |
TakehikoShimojima | 0:d2972e5edb22 | 64 | return true; |
TakehikoShimojima | 0:d2972e5edb22 | 65 | } |
TakehikoShimojima | 0:d2972e5edb22 | 66 | |
TakehikoShimojima | 0:d2972e5edb22 | 67 | bool |
TakehikoShimojima | 0:d2972e5edb22 | 68 | AMBIENT::clear(int field) { |
TakehikoShimojima | 0:d2972e5edb22 | 69 | --field; |
TakehikoShimojima | 0:d2972e5edb22 | 70 | if (field < 0 || field >= AMBIENT_NUM_PARAMS) { |
TakehikoShimojima | 0:d2972e5edb22 | 71 | return false; |
TakehikoShimojima | 0:d2972e5edb22 | 72 | } |
TakehikoShimojima | 0:d2972e5edb22 | 73 | this->data[field].set = false; |
TakehikoShimojima | 0:d2972e5edb22 | 74 | |
TakehikoShimojima | 0:d2972e5edb22 | 75 | return true; |
TakehikoShimojima | 0:d2972e5edb22 | 76 | } |
TakehikoShimojima | 0:d2972e5edb22 | 77 | |
TakehikoShimojima | 0:d2972e5edb22 | 78 | bool |
TakehikoShimojima | 0:d2972e5edb22 | 79 | AMBIENT::send() { |
TakehikoShimojima | 0:d2972e5edb22 | 80 | |
TakehikoShimojima | 0:d2972e5edb22 | 81 | int retry; |
TakehikoShimojima | 0:d2972e5edb22 | 82 | for (retry = 0; retry < AMBIENT_MAX_RETRY; retry++) { |
TakehikoShimojima | 0:d2972e5edb22 | 83 | int ret; |
TakehikoShimojima | 0:d2972e5edb22 | 84 | ret = this->s->connect(this->host, this->port); |
TakehikoShimojima | 0:d2972e5edb22 | 85 | if (ret == 0) { |
TakehikoShimojima | 0:d2972e5edb22 | 86 | break ; |
TakehikoShimojima | 0:d2972e5edb22 | 87 | } |
TakehikoShimojima | 0:d2972e5edb22 | 88 | } |
TakehikoShimojima | 0:d2972e5edb22 | 89 | if(retry == AMBIENT_MAX_RETRY) { |
TakehikoShimojima | 0:d2972e5edb22 | 90 | ERR("Could not connect socket to host\r\n"); |
TakehikoShimojima | 0:d2972e5edb22 | 91 | return false; |
TakehikoShimojima | 0:d2972e5edb22 | 92 | } |
TakehikoShimojima | 0:d2972e5edb22 | 93 | |
TakehikoShimojima | 0:d2972e5edb22 | 94 | char str[360] = {0}; |
TakehikoShimojima | 0:d2972e5edb22 | 95 | char header[54] = {0}; |
TakehikoShimojima | 0:d2972e5edb22 | 96 | char host[32] = {0}; |
TakehikoShimojima | 0:d2972e5edb22 | 97 | char contentLen[28] = {0}; |
TakehikoShimojima | 0:d2972e5edb22 | 98 | const char *contentType = "Content-Type: application/json\r\n\r\n"; |
TakehikoShimojima | 0:d2972e5edb22 | 99 | char body[192] = {0}; |
TakehikoShimojima | 0:d2972e5edb22 | 100 | |
TakehikoShimojima | 0:d2972e5edb22 | 101 | strcat(body, "{\"writeKey\":\""); |
TakehikoShimojima | 0:d2972e5edb22 | 102 | strcat(body, this->writeKey); |
TakehikoShimojima | 0:d2972e5edb22 | 103 | strcat(body, "\","); |
TakehikoShimojima | 0:d2972e5edb22 | 104 | |
TakehikoShimojima | 0:d2972e5edb22 | 105 | for (int i = 0; i < AMBIENT_NUM_PARAMS; i++) { |
TakehikoShimojima | 0:d2972e5edb22 | 106 | if (this->data[i].set) { |
TakehikoShimojima | 0:d2972e5edb22 | 107 | strcat(body, ambient_keys[i]); |
TakehikoShimojima | 0:d2972e5edb22 | 108 | strcat(body, this->data[i].item); |
TakehikoShimojima | 0:d2972e5edb22 | 109 | strcat(body, "\","); |
TakehikoShimojima | 0:d2972e5edb22 | 110 | } |
TakehikoShimojima | 0:d2972e5edb22 | 111 | } |
TakehikoShimojima | 0:d2972e5edb22 | 112 | body[strlen(body) - 1] = '\0'; |
TakehikoShimojima | 0:d2972e5edb22 | 113 | |
TakehikoShimojima | 0:d2972e5edb22 | 114 | strcat(body, "}\r\n"); |
TakehikoShimojima | 0:d2972e5edb22 | 115 | |
TakehikoShimojima | 0:d2972e5edb22 | 116 | sprintf(header, "POST /api/v2/channels/%d/data HTTP/1.1\r\n", this->channelId); |
TakehikoShimojima | 0:d2972e5edb22 | 117 | if (this->port == 80) { |
TakehikoShimojima | 0:d2972e5edb22 | 118 | sprintf(host, "Host: %s\r\n", this->host); |
TakehikoShimojima | 0:d2972e5edb22 | 119 | } else { |
TakehikoShimojima | 0:d2972e5edb22 | 120 | sprintf(host, "Host: %s:%d\r\n", this->host, this->port); |
TakehikoShimojima | 0:d2972e5edb22 | 121 | } |
TakehikoShimojima | 0:d2972e5edb22 | 122 | sprintf(contentLen, "Content-Length: %d\r\n", strlen(body)); |
TakehikoShimojima | 0:d2972e5edb22 | 123 | sprintf(str, "%s%s%s%s%s", header, host, contentLen, contentType, body); |
TakehikoShimojima | 0:d2972e5edb22 | 124 | |
TakehikoShimojima | 0:d2972e5edb22 | 125 | DBG("sending: %d bytes\r\n%s", strlen(str), str); |
TakehikoShimojima | 0:d2972e5edb22 | 126 | |
TakehikoShimojima | 0:d2972e5edb22 | 127 | int ret; |
TakehikoShimojima | 0:d2972e5edb22 | 128 | ret = this->s->send_all(str, strlen(str)); |
TakehikoShimojima | 0:d2972e5edb22 | 129 | wait_ms(30); |
TakehikoShimojima | 0:d2972e5edb22 | 130 | DBG("%d bytes sent\r\n", ret); |
TakehikoShimojima | 0:d2972e5edb22 | 131 | if (ret < 0) { |
TakehikoShimojima | 0:d2972e5edb22 | 132 | ERR("send failed\r\n"); |
TakehikoShimojima | 0:d2972e5edb22 | 133 | return false; |
TakehikoShimojima | 0:d2972e5edb22 | 134 | } |
TakehikoShimojima | 0:d2972e5edb22 | 135 | |
TakehikoShimojima | 0:d2972e5edb22 | 136 | ret = this->s->receive(str,sizeof(str)); |
TakehikoShimojima | 0:d2972e5edb22 | 137 | str[ret]=0; |
TakehikoShimojima | 0:d2972e5edb22 | 138 | DBG("Received String : (%d)\r\n%s\r\n",ret, str); |
TakehikoShimojima | 0:d2972e5edb22 | 139 | |
TakehikoShimojima | 0:d2972e5edb22 | 140 | this->s->close(); |
TakehikoShimojima | 0:d2972e5edb22 | 141 | |
TakehikoShimojima | 0:d2972e5edb22 | 142 | for (int i = 0; i < AMBIENT_NUM_PARAMS; i++) { |
TakehikoShimojima | 0:d2972e5edb22 | 143 | this->data[i].set = false; |
TakehikoShimojima | 0:d2972e5edb22 | 144 | } |
TakehikoShimojima | 0:d2972e5edb22 | 145 | |
TakehikoShimojima | 0:d2972e5edb22 | 146 | return true; |
TakehikoShimojima | 0:d2972e5edb22 | 147 | } |