libraries / Bridge / src / BridgeUdp.cppon commit Added link to project report (97a3ba0)
   1/*
   2  Copyright (c) 2015 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 "BridgeUdp.h"
  20
  21BridgeUDP::BridgeUDP(BridgeClass &_b) :
  22  bridge(_b), opened(false), avail(0), buffered(0), readPos(0) {
  23}
  24
  25/* Start BridgeUDP socket, listening at local port PORT */
  26uint8_t BridgeUDP::begin(uint16_t port) {
  27  if (opened)
  28    return 0;
  29  uint8_t cmd[] = {'e', (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
  30  uint8_t res[2];
  31  bridge.transfer(cmd, 3, res, 2);
  32  if (res[1] == 1) // Error...
  33    return 0;
  34  handle = res[0];
  35  opened = true;
  36  return 1;
  37}
  38
  39/* Release any resources being used by this BridgeUDP instance */
  40void BridgeUDP::stop()
  41{
  42  if (!opened)
  43    return;
  44  uint8_t cmd[] = {'q', handle};
  45  bridge.transfer(cmd, 2);
  46  opened = false;
  47}
  48
  49int BridgeUDP::beginPacket(const char *host, uint16_t port)
  50{
  51  if (!opened)
  52    return 0;
  53  uint8_t cmd[] = {'E', handle, (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
  54  uint8_t res[1];
  55  bridge.transfer(cmd, 4, (const uint8_t *)host, strlen(host), res, 1);
  56  return res[0]; // 1=Success, 0=Error
  57}
  58
  59int BridgeUDP::beginBroadcastPacket(uint16_t port)
  60{
  61  if (!opened)
  62    return 0;
  63  uint8_t cmd[] = {'v', handle, (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF)};
  64  uint8_t res[1];
  65  bridge.transfer(cmd, 4, res, 1);
  66  return res[0]; // 1=Success, 0=Error
  67}
  68
  69int BridgeUDP::beginPacket(IPAddress ip, uint16_t port)
  70{
  71  if (!opened)
  72    return 0;
  73  String address;
  74  address.reserve(18);
  75  address += ip[0];
  76  address += '.';
  77  address += ip[1];
  78  address += '.';
  79  address += ip[2];
  80  address += '.';
  81  address += ip[3];
  82  return beginPacket(address.c_str(), port);
  83}
  84
  85int BridgeUDP::endPacket()
  86{
  87  if (!opened)
  88    return 0;
  89  uint8_t cmd[] = {'H', handle};
  90  uint8_t res[1];
  91  bridge.transfer(cmd, 2, res, 1);
  92  return res[0]; // 1=Success, 0=Error
  93}
  94
  95size_t BridgeUDP::write(const uint8_t *buffer, size_t size)
  96{
  97  if (!opened)
  98    return 0;
  99  uint8_t cmd[] = {'h', handle};
 100  uint8_t res[1];
 101  bridge.transfer(cmd, 2, buffer, size, res, 1);
 102  return res[0]; // 1=Success, 0=Error
 103}
 104
 105int BridgeUDP::parsePacket()
 106{
 107  if (!opened)
 108    return 0;
 109  buffered = 0;
 110  readPos = 0;
 111  uint8_t cmd[] = {'Q', handle};
 112  uint8_t res[3];
 113  bridge.transfer(cmd, 2, res, 3);
 114  if (res[0] == 0) {
 115    // There aren't any packets available
 116    return 0;
 117  }
 118  avail = (res[1] << 8) + res[2];
 119  return 1;
 120}
 121
 122void BridgeUDP::doBuffer() {
 123  // If there are already char in buffer exit
 124  if (buffered > 0)
 125    return;
 126  if (avail == 0)
 127    return;
 128
 129  // Try to buffer up to 32 characters
 130  readPos = 0;
 131  uint8_t cmd[] = {'u', handle, sizeof(buffer)};
 132  buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer));
 133}
 134
 135int BridgeUDP::read()
 136{
 137  if (!opened)
 138    return -1;
 139  doBuffer();
 140  if (buffered == 0) {
 141    return -1; // no chars available
 142  }
 143  buffered--;
 144  avail--;
 145  return buffer[readPos++];
 146}
 147
 148int BridgeUDP::read(unsigned char* buff, size_t size)
 149{
 150  if (!opened)
 151    return -1;
 152  size_t readed = 0;
 153  do {
 154    if (buffered == 0) {
 155      doBuffer();
 156      if (buffered == 0)
 157        return readed;
 158    }
 159    buff[readed++] = buffer[readPos++];
 160    buffered--;
 161    avail--;
 162  } while (readed < size);
 163  return readed;
 164}
 165
 166int BridgeUDP::peek()
 167{
 168  if (!opened)
 169    return -1;
 170  doBuffer();
 171  if (buffered == 0)
 172    return -1; // no chars available
 173  return buffer[readPos];
 174}
 175
 176IPAddress BridgeUDP::remoteIP()
 177{
 178  if (!opened)
 179    return -1;
 180  uint8_t cmd[] = {'T', handle};
 181  uint8_t res[7];
 182  bridge.transfer(cmd, 2, res, 7);
 183  if (res[0] == 0)
 184    return IPAddress(0,0,0,0);
 185  return IPAddress(res[1], res[2], res[3], res[4]);
 186}
 187
 188uint16_t BridgeUDP::remotePort()
 189{
 190  if (!opened)
 191    return -1;
 192  uint8_t cmd[] = {'T', handle};
 193  uint8_t res[7];
 194  bridge.transfer(cmd, 2, res, 7);
 195  if (res[0] == 0)
 196    return 0;
 197  return (res[5] << 8) + res[6];
 198}