Last active
October 12, 2017 17:13
-
-
Save technobly/8670143 to your computer and use it in GitHub Desktop.
TCP CLIENT JSON PARSE EXAMPLE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
****************************************************************************** | |
* @file spark_wiring_tcpclient.cpp | |
* @author Satish Nair | |
* @version V1.0.0 | |
* @date 10-Nov-2013 | |
* @brief | |
****************************************************************************** | |
Copyright (c) 2013 Spark Labs, Inc. All rights reserved. | |
This library is free software; you can redistribute it and/or | |
modify it under the terms of the GNU Lesser General Public | |
License as published by the Free Software Foundation, either | |
version 3 of the License, or (at your option) any later version. | |
This library is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
Lesser General Public License for more details. | |
You should have received a copy of the GNU Lesser General Public | |
License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
****************************************************************************** | |
*/ | |
#include "spark_wiring_tcpclient.h" | |
uint16_t TCPClient::_srcport = 1024; | |
TCPClient::TCPClient() : _sock(MAX_SOCK_NUM) | |
{ | |
} | |
TCPClient::TCPClient(uint8_t sock) : _sock(sock) | |
{ | |
} | |
int TCPClient::connect(const char* host, uint16_t port) | |
{ | |
uint32_t ip_addr = 0; | |
if(gethostbyname((char*)host, strlen(host), &ip_addr) > 0) | |
{ | |
IPAddress remote_addr(BYTE_N(ip_addr, 3), BYTE_N(ip_addr, 2), BYTE_N(ip_addr, 1), BYTE_N(ip_addr, 0)); | |
return connect(remote_addr, port); | |
} | |
return 0; | |
} | |
int TCPClient::connect(IPAddress ip, uint16_t port) | |
{ | |
if(WLAN_DHCP != 1) | |
{ | |
return 0; | |
} | |
sockaddr tSocketAddr; | |
_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | |
if (_sock < 0) | |
{ | |
return 0; | |
} | |
_offset = 0; | |
_remaining = 0; | |
tSocketAddr.sa_family = AF_INET; | |
tSocketAddr.sa_data[0] = (port & 0xFF00) >> 8; | |
tSocketAddr.sa_data[1] = (port & 0x00FF); | |
tSocketAddr.sa_data[2] = ip._address[0]; | |
tSocketAddr.sa_data[3] = ip._address[1]; | |
tSocketAddr.sa_data[4] = ip._address[2]; | |
tSocketAddr.sa_data[5] = ip._address[3]; | |
if(socket_connect(_sock, &tSocketAddr, sizeof(tSocketAddr)) < 0) | |
{ | |
_sock = MAX_SOCK_NUM; | |
return 0; | |
} | |
return 1; | |
} | |
size_t TCPClient::write(uint8_t b) | |
{ | |
return write(&b, 1); | |
} | |
size_t TCPClient::write(const uint8_t *buffer, size_t size) | |
{ | |
if((WLAN_DHCP != 1) || (_sock == MAX_SOCK_NUM)) | |
{ | |
return -1; | |
} | |
return send(_sock, buffer, size, 0); | |
} | |
int TCPClient::available() | |
{ | |
if((WLAN_DHCP != 1) || (_sock == MAX_SOCK_NUM)) | |
{ | |
return 0; | |
} | |
if ((_remaining > 0) && (_offset < _buffered)) | |
{ | |
return (_buffered - _offset); | |
} | |
_types_fd_set_cc3000 readSet; | |
timeval timeout; | |
FD_ZERO(&readSet); | |
FD_SET(_sock, &readSet); | |
timeout.tv_sec = 0; | |
timeout.tv_usec = 5000; | |
if (select(_sock + 1, &readSet, NULL, NULL, &timeout) > 0) | |
{ | |
if (FD_ISSET(_sock, &readSet)) | |
{ | |
int ret = recv(_sock, _buffer, TCPCLIENT_BUF_MAX_SIZE, 0); | |
if (ret > 0) | |
{ | |
_offset = 0; | |
_remaining = ret; | |
_buffered = ret; | |
} | |
return ret; | |
} | |
} | |
return 0; | |
} | |
int TCPClient::read() | |
{ | |
if((WLAN_DHCP != 1) || (_sock == MAX_SOCK_NUM)) | |
{ | |
return -1; | |
} | |
uint8_t byte; | |
if ((_remaining > 0) && (_offset < TCPCLIENT_BUF_MAX_SIZE)) | |
{ | |
byte = _buffer[_offset++]; | |
_remaining--; | |
return byte; | |
} | |
return -1; | |
} | |
int TCPClient::read(uint8_t *buffer, size_t size) | |
{ | |
if((WLAN_DHCP != 1) || (_sock == MAX_SOCK_NUM)) | |
{ | |
return -1; | |
} | |
if ((_remaining > 0) && (_offset < TCPCLIENT_BUF_MAX_SIZE)) | |
{ | |
if (_remaining <= size) | |
{ | |
memcpy(buffer, _buffer, _remaining); | |
_offset = _remaining; | |
} | |
else | |
{ | |
memcpy(buffer, _buffer, size); | |
_offset = size; | |
} | |
if (_offset > 0) | |
{ | |
_remaining -= _offset; | |
return _offset; | |
} | |
} | |
return -1; | |
} | |
int TCPClient::peek() | |
{ | |
if (!available()) | |
{ | |
return -1; | |
} | |
return read(); | |
} | |
void TCPClient::flush() | |
{ | |
while (available()) | |
{ | |
read(); | |
} | |
} | |
void TCPClient::stop() | |
{ | |
if (closesocket(_sock) == 0) | |
{ | |
_sock = MAX_SOCK_NUM; | |
} | |
} | |
uint8_t TCPClient::connected() | |
{ | |
if (_sock == MAX_SOCK_NUM) | |
{ | |
return 0; | |
} | |
//To Do | |
return 1; | |
} | |
uint8_t TCPClient::status() | |
{ | |
if (_sock == MAX_SOCK_NUM) | |
{ | |
return 0; | |
} | |
//To Do | |
return 1; | |
} | |
TCPClient::operator bool() | |
{ | |
return _sock != MAX_SOCK_NUM; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
****************************************************************************** | |
* @file spark_wiring_tcpclient.h | |
* @author Satish Nair | |
* @version V1.0.0 | |
* @date 13-March-2013 | |
* @brief Header for spark_wiring_tcpclient.cpp module | |
****************************************************************************** | |
Copyright (c) 2013 Spark Labs, Inc. All rights reserved. | |
This library is free software; you can redistribute it and/or | |
modify it under the terms of the GNU Lesser General Public | |
License as published by the Free Software Foundation, either | |
version 3 of the License, or (at your option) any later version. | |
This library is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
Lesser General Public License for more details. | |
You should have received a copy of the GNU Lesser General Public | |
License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
****************************************************************************** | |
*/ | |
#ifndef __SPARK_WIRING_TCPCLIENT_H | |
#define __SPARK_WIRING_TCPCLIENT_H | |
#include "spark_wiring.h" | |
#define TCPCLIENT_BUF_MAX_SIZE 16 | |
class TCPClient : public Stream { | |
public: | |
TCPClient(); | |
TCPClient(uint8_t sock); | |
uint8_t status(); | |
virtual int connect(IPAddress ip, uint16_t port); | |
virtual int connect(const char *host, uint16_t port); | |
virtual size_t write(uint8_t); | |
virtual size_t write(const uint8_t *buffer, size_t size); | |
virtual int available(); | |
virtual int read(); | |
virtual int read(uint8_t *buffer, size_t size); | |
virtual int peek(); | |
virtual void flush(); | |
virtual void stop(); | |
virtual uint8_t connected(); | |
virtual operator bool(); | |
friend class TCPServer; | |
using Print::write; | |
private: | |
static uint16_t _srcport; | |
long _sock; | |
uint8_t _buffer[TCPCLIENT_BUF_MAX_SIZE]; | |
uint16_t _offset; | |
uint16_t _remaining; | |
uint16_t _buffered; | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "application.h" | |
/* ================ HTTP ================ */ | |
TCPClient client; | |
char buffer[1024]; | |
char * http_get(char const * hostname, String path) { | |
if (client.connect(hostname, 80)) { | |
client.print("GET "); | |
client.print(path); | |
client.print(" HTTP/1.1\r\n"); | |
client.print("HOST: "); | |
client.println(hostname); | |
client.print("\r\n\r\n\r\n"); | |
} else { | |
Serial.println("\r\n\r\nConnection Failed!"); | |
client.stop(); | |
return NULL; | |
} | |
int i,j,k = 0; | |
Serial.println("\r\n\r\n\r\nReading Facebook Data......"); | |
uint32_t lastRead = millis(); | |
while ((millis() - lastRead) < 1000) { | |
while (client.available()) { | |
char c = client.read(); | |
Serial.print(c); | |
if(i++ > 100) { | |
delay(100); | |
i = 0; | |
} | |
if (c == -1) break; | |
if(j++ >= 512) { // skip buffering the first 512 bytes | |
buffer[k++] = c; | |
if(k == 1023) { | |
client.flush(); | |
client.stop(); | |
} | |
} | |
lastRead = millis(); | |
} | |
} | |
client.flush(); | |
client.stop(); | |
//String response(buffer); | |
return buffer; | |
} | |
/* ================ APPLICATION.cpp ================ */ | |
char *ptrStr; | |
char result[21]; | |
uint32_t likes_val = 0; | |
char *ptrEnd; | |
void setup() { | |
pinMode(D7, OUTPUT); | |
digitalWrite(D7, HIGH); | |
Serial.begin(115200); | |
while (!Serial.available()); // After Core D7 LED turns on, open serial monitor and press enter! | |
} | |
uint32_t nextTime = millis(); // next time to contact the server | |
int count = 19; | |
bool state = 1; | |
void loop() { | |
if (millis() > nextTime) { | |
nextTime = millis() + 500UL; | |
if (++count == 20) { | |
count = 0; | |
char * response = http_get("graph.facebook.com", "/sparkdevices"); | |
Serial.println(response); | |
ptrStr = strstr(response, "\"likes\":"); // search for string ["likes": ] in response | |
if (ptrStr != NULL) // if succesfull then ptrStr now points at ["likes": ] | |
{ | |
ptrStr += 8; //advance pointer to likes number. | |
int x = 0; | |
while(x<20 && *ptrStr != ',') { | |
result[x++] = *ptrStr++; | |
} | |
result[x] = '\0'; | |
likes_val = strtol(result,&ptrEnd,10); // convert string to long int if you need a working number | |
Serial.print("Found likes: "); | |
Serial.println(likes_val); | |
} | |
else | |
{ | |
Serial.println("Likes not found!\n"); // `strstr` returns NULL if search string not found | |
} | |
} else { // toggle the led while we wait for 10 second mark | |
state = !state; | |
digitalWrite(D7, state); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment