Added function deleteLocations to delete the location history.
Dependents: WNCInterface_M2Xdemo ATT_WNCInterface_Info WNCInterface_HTTP_example Public_IoT_M2X_Cellular_Demo
Fork of M2XStreamClient by
Diff: m2x-mbed.h
- Revision:
- 22:4d895e732765
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m2x-mbed.h Wed Jun 15 12:36:55 2016 +0000 @@ -0,0 +1,264 @@ +#include "mbed.h" +#define USER_AGENT "User-Agent: M2X Mbed Client/" M2X_VERSION + +#ifdef DEBUG +#define DBG(fmt_, data_) printf((fmt_), (data_)) +#define DBGLN(fmt_, data_) printf((fmt_), (data_)); printf("\n") +#define DBGLNEND printf("\n") +#endif /* DEBUG */ + +class M2XTimer { +public: + void start() { _timer.start(); } + + unsigned long read_ms() { + // In case of a timestamp overflow, we reset the server timestamp recorded. + // Notice that unlike Arduino, mbed would overflow every 30 minutes, + // so if 2 calls to this API are more than 30 minutes apart, we are + // likely to run into troubles. This is a limitation of the current + // mbed platform. However, we argue that it might be a rare case that + // 2 calls to this are 30 minutes apart. In most cases, we would call + // this API every few seconds or minutes, this won't be a huge problem. + // However, if you have a use case that would require 2 intervening + // calls to this be 30 minutes apart, you might want to leverage a RTC + // clock instead of the simple ticker here, or call TimeService::reset() + // before making an API call to sync current time. + return _timer.read_ms(); + } +private: + Timer _timer; +}; + +#include "TCPSocketConnection.h" + +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void delay(int ms) +{ + wait_ms(ms); +} + +char* strdup(const char* s) +{ + char* ret = (char*) malloc(strlen(s) + 1); + if (ret == NULL) { return ret;} + return strcpy(ret, s); +} + +#ifdef __cplusplus +} +#endif + +class Print { +public: + size_t print(const char* s); + size_t print(char c); + size_t print(int n); + size_t print(long n); + size_t print(double n, int digits = 2); + + size_t println(const char* s); + size_t println(char c); + size_t println(int n); + size_t println(long n); + size_t println(double n, int digits = 2); + size_t println(); + + virtual size_t write(uint8_t c) = 0; + virtual size_t write(const uint8_t* buf, size_t size); +}; + +size_t Print::write(const uint8_t* buf, size_t size) { + size_t ret = 0; + while (size--) { + ret += write(*buf++); + } + return ret; +} + +size_t Print::print(const char* s) { + return write((const uint8_t*)s, strlen(s)); +} + +size_t Print::print(char c) { + return write(c); +} + +size_t Print::print(int n) { + return print((long) n); +} + +size_t Print::print(long n) { + char buf[8 * sizeof(long) + 1]; + snprintf(buf, sizeof(buf), "%ld", n); + return print(buf); +} + +// Digits are ignored for now +size_t Print::print(double n, int digits) { + char buf[65]; + snprintf(buf, sizeof(buf), "%g", n); + return print(buf); +} + +size_t Print::println(const char* s) { + return print(s) + println(); +} + +size_t Print::println(char c) { + return print(c) + println(); +} + +size_t Print::println(int n) { + return print(n) + println(); +} + +size_t Print::println(long n) { + return print(n) + println(); +} + +size_t Print::println(double n, int digits) { + return print(n, digits) + println(); +} + +size_t Print::println() { + return print('\r') + print('\n'); +} + +/* + * TCP Client + */ +class Client : public Print { +public: + Client(); + ~Client(); + + virtual int connect(const char *host, uint16_t port); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + virtual int available(); + virtual int read(); + virtual void flush(); + virtual void stop(); + virtual uint8_t connected(); +private: + virtual int read(uint8_t *buf, size_t size); + void _fillin(void); + uint8_t _inbuf[128]; + uint8_t _incnt; + void _flushout(void); + uint8_t _outbuf[128]; + uint8_t _outcnt; + TCPSocketConnection _sock; +}; + +Client::Client() : _incnt(0), _outcnt(0), _sock() { + _sock.set_blocking(false, 1500); +} + +Client::~Client() { +} + +int Client::connect(const char *host, uint16_t port) { + return _sock.connect(host, port) == 0; +} + +size_t Client::write(uint8_t b) { + return write(&b, 1); +} + +size_t Client::write(const uint8_t *buf, size_t size) { + size_t cnt = 0; + while (size) { + int tmp = sizeof(_outbuf) - _outcnt; + if (tmp > size) tmp = size; + memcpy(_outbuf + _outcnt, buf, tmp); + _outcnt += tmp; + buf += tmp; + size -= tmp; + cnt += tmp; + // if no space flush it + if (_outcnt == sizeof(_outbuf)) + _flushout(); + } + return cnt; +} + +void Client::_flushout(void) +{ + if (_outcnt > 0) { + // NOTE: we know it's dangerous to cast from (const uint8_t *) to (char *), + // but we are trying to maintain a stable interface between the Arduino + // one and the mbed one. What's more, while TCPSocketConnection has no + // intention of modifying the data here, it requires us to send a (char *) + // typed data. So we belive it's safe to do the cast here. + _sock.send_all(const_cast<char*>((const char*) _outbuf), _outcnt); + _outcnt = 0; + } +} + +void Client::_fillin(void) +{ + int tmp = sizeof(_inbuf) - _incnt; + if (tmp) { + tmp = _sock.receive_all((char*)_inbuf + _incnt, tmp); + if (tmp > 0) + _incnt += tmp; + } +} + +void Client::flush() { + _flushout(); +} + +int Client::available() { + if (_incnt == 0) { + _flushout(); + _fillin(); + } + return (_incnt > 0) ? 1 : 0; +} + +int Client::read() { + uint8_t ch; + return (read(&ch, 1) == 1) ? ch : -1; +} + +int Client::read(uint8_t *buf, size_t size) { + int cnt = 0; + while (size) { + // need more + if (size > _incnt) { + _flushout(); + _fillin(); + } + if (_incnt > 0) { + int tmp = _incnt; + if (tmp > size) tmp = size; + memcpy(buf, _inbuf, tmp); + if (tmp != _incnt) + memmove(_inbuf, _inbuf + tmp, _incnt - tmp); + _incnt -= tmp; + size -= tmp; + buf += tmp; + cnt += tmp; + } else // no data + break; + } + return cnt; +} + +void Client::stop() { + _sock.close(); +} + +uint8_t Client::connected() { + return _sock.is_connected() ? 1 : 0; +}