libraries / Bridge / src / BridgeClient.cppon commit Added final version of code (649c546)
   1/*
   2  Copyright (c) 2013 Arduino LLC. All right reserved.
   3
   4  This library is free software; you can redistribute it and/or
   5  modify it under the terms of the GNU Lesser General Public
   6  License as published by the Free Software Foundation; either
   7  version 2.1 of the License, or (at your option) any later version.
   8
   9  This library is distributed in the hope that it will be useful,
  10  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12  Lesser General Public License for more details.
  13
  14  You should have received a copy of the GNU Lesser General Public
  15  License along with this library; if not, write to the Free Software
  16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17*/
  18
  19#include <BridgeClient.h>
  20
  21BridgeClient::BridgeClient(uint8_t _h, BridgeClass &_b) :
  22  bridge(_b), handle(_h), opened(true), buffered(0) {
  23}
  24
  25BridgeClient::BridgeClient(BridgeClass &_b) :
  26  bridge(_b), handle(0), opened(false), buffered(0) {
  27}
  28
  29BridgeClient::~BridgeClient() {
  30}
  31
  32BridgeClient& BridgeClient::operator=(const BridgeClient &_x) {
  33  opened = _x.opened;
  34  handle = _x.handle;
  35  return *this;
  36}
  37
  38void BridgeClient::stop() {
  39  if (opened) {
  40    uint8_t cmd[] = {'j', handle};
  41    bridge.transfer(cmd, 2);
  42  }
  43  opened = false;
  44  buffered = 0;
  45  readPos = 0;
  46}
  47
  48void BridgeClient::doBuffer() {
  49  // If there are already char in buffer exit
  50  if (buffered > 0)
  51    return;
  52
  53  // Try to buffer up to 32 characters
  54  readPos = 0;
  55  uint8_t cmd[] = {'K', handle, sizeof(buffer)};
  56  buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
  57}
  58
  59int BridgeClient::available() {
  60  // Look if there is new data available
  61  doBuffer();
  62  return buffered;
  63}
  64
  65int BridgeClient::read() {
  66  doBuffer();
  67  if (buffered == 0)
  68    return -1; // no chars available
  69  else {
  70    buffered--;
  71    return buffer[readPos++];
  72  }
  73}
  74
  75int BridgeClient::read(uint8_t *buff, size_t size) {
  76  size_t readed = 0;
  77  do {
  78    if (buffered == 0) {
  79      doBuffer();
  80      if (buffered == 0)
  81        return readed;
  82    }
  83    buff[readed++] = buffer[readPos++];
  84    buffered--;
  85  } while (readed < size);
  86  return readed;
  87}
  88
  89int BridgeClient::peek() {
  90  doBuffer();
  91  if (buffered == 0)
  92    return -1; // no chars available
  93  else
  94    return buffer[readPos];
  95}
  96
  97size_t BridgeClient::write(uint8_t c) {
  98  if (!opened)
  99    return 0;
 100  uint8_t cmd[] = {'l', handle, c};
 101  bridge.transfer(cmd, 3);
 102  return 1;
 103}
 104
 105size_t BridgeClient::write(const uint8_t *buf, size_t size) {
 106  if (!opened)
 107    return 0;
 108  uint8_t cmd[] = {'l', handle};
 109  bridge.transfer(cmd, 2, buf, size, NULL, 0);
 110  return size;
 111}
 112
 113void BridgeClient::flush() {
 114}
 115
 116uint8_t BridgeClient::connected() {
 117  if (!opened)
 118    return false;
 119  // Client is "connected" if it has unread bytes
 120  if (available())
 121    return true;
 122
 123  uint8_t cmd[] = {'L', handle};
 124  uint8_t res[1];
 125  bridge.transfer(cmd, 2, res, 1);
 126  return (res[0] == 1);
 127}
 128
 129int BridgeClient::connect(IPAddress ip, uint16_t port) {
 130  String address;
 131  address.reserve(18);
 132  address += ip[0];
 133  address += '.';
 134  address += ip[1];
 135  address += '.';
 136  address += ip[2];
 137  address += '.';
 138  address += ip[3];
 139  return connect(address.c_str(), port);
 140}
 141
 142int BridgeClient::connect(const char *host, uint16_t port) {
 143  uint8_t tmp[] = {
 144    'C',
 145    static_cast<uint8_t>(port >> 8),
 146    static_cast<uint8_t>(port)
 147  };
 148  uint8_t res[1];
 149  int l = bridge.transfer(tmp, 3, (const uint8_t *)host, strlen(host), res, 1);
 150  if (l == 0)
 151    return 0;
 152  handle = res[0];
 153
 154  // wait for connection
 155  uint8_t tmp2[] = { 'c', handle };
 156  uint8_t res2[1];
 157  while (true) {
 158    bridge.transfer(tmp2, 2, res2, 1);
 159    if (res2[0] == 0)
 160      break;
 161    delay(1);
 162  }
 163  opened = true;
 164
 165  // check for successful connection
 166  if (connected())
 167    return 1;
 168
 169  stop();
 170  handle = 0;
 171  return 0;
 172}
 173
 174int BridgeClient::connectSSL(const char *host, uint16_t port) {
 175  if (bridge.getBridgeVersion() < 161)
 176    return -1;
 177
 178  uint8_t tmp[] = {
 179    'Z',
 180    static_cast<uint8_t>(port >> 8),
 181    static_cast<uint8_t>(port)
 182  };
 183  uint8_t res[1];
 184  int l = bridge.transfer(tmp, 3, (const uint8_t *)host, strlen(host), res, 1);
 185  if (l == 0)
 186    return 0;
 187  handle = res[0];
 188
 189  // wait for connection
 190  uint8_t tmp2[] = { 'c', handle };
 191  uint8_t res2[1];
 192  while (true) {
 193    bridge.transfer(tmp2, 2, res2, 1);
 194    if (res2[0] == 0)
 195      break;
 196    delay(1);
 197  }
 198  opened = true;
 199
 200  // check for successful connection
 201  if (connected())
 202    return 1;
 203
 204  stop();
 205  handle = 0;
 206  return 0;
 207}