Ambient Library

Fork of AmbientLib by Takehiko Shimojima

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)

Committer:
TakehikoShimojima
Date:
Sat May 07 01:11:27 2016 +0000
Revision:
0:d2972e5edb22
initial

Who changed what in which revision?

UserRevisionLine numberNew 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 }