Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@technobly
Last active October 12, 2017 17:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save technobly/8670143 to your computer and use it in GitHub Desktop.
Save technobly/8670143 to your computer and use it in GitHub Desktop.
TCP CLIENT JSON PARSE EXAMPLE
/**
******************************************************************************
* @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;
}
/**
******************************************************************************
* @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
#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