adafruit / Adafruit_WICED_Arduino

Adafruit WICED Feather Arduino BSP
https://www.adafruit.com/products/3056
27 stars 19 forks source link

Feather Wiced UDP #43

Closed Krenuds closed 8 years ago

Krenuds commented 8 years ago

Hi there! I've got a function that calls adafruit::write(); more than once. Upon calling endPacket, a number of packets equal the number of write() calls are fired across the network instead of one. In other words, each call to write is creating it's own packet, instead of endPacket()

Is this SDEP related or working as intended? and if so, what is the procedure for adding more information to your packet buffer before sending it over?

Thanks!

hathach commented 8 years ago

Could you please post your sketch here. Just to make sure we are working on the exact code. It will help us to troubleshoot it quicker as well. Thanks

Krenuds commented 8 years ago

Anything like this or udp.write();

  udp.beginPacket(server_ip, port);
   udp.println(input); // send with newline
   udp.println(input); // send with newline
  udp.endPacket();

From Example:

#include <adafruit_feather.h>

#define WLAN_SSID             "WNSOM"
#define WLAN_PASS             "1westnewburyschoolofmusic"

// Your local PC's IP to test the throughput
// Run this command to create a server on your PC
// > nc -lu 8888
IPAddress server_ip(192, 168, 1, 9);
const uint16_t port = 5005;

AdafruitUDP udp;
const uint16_t local_port = 5005;

/**************************************************************************/
/*!
    @brief  The setup function runs once when reset the board
*/
/**************************************************************************/
void setup()
{
  Serial.begin(115200);

  // wait for serial port to connect. Needed for native USB port only
  while (!Serial) delay(1);

  Serial.println("UDP Client Example\r\n");

  // Print all software versions
  Feather.printVersions();

  while ( !connectAP() )
  {
    delay(500); // delay between each attempt
  }

  // Connected: Print network info
  Feather.printNetwork();

  udp.begin(local_port);

  Serial.println("Please run the following command on your PC");
  Serial.printf("> nc -lu %d", port);
  Serial.println();
  Serial.println();
}

/**************************************************************************/
/*!
    @brief  The loop function runs over and over again forever
*/
/**************************************************************************/
void loop()
{
  char* input;

  // Prompt and get input from user
  Serial.print("Enter character(s) to send: ");
  input = getUserInput();
  Serial.println();

  // Send to server
  Serial.printf("Sending '%s' to ", input);
  Serial.print(server_ip);
  Serial.print(" ... ");

  udp.beginPacket(server_ip, port);
   udp.println(input); // send with newline
   udp.println(input); // send with newline
  udp.endPacket();

  Serial.println("OK");
}

/**************************************************************************/
/*!
    @brief  Connect to defined Access Point
*/
/**************************************************************************/
bool connectAP(void)
{
  // Attempt to connect to an AP
  Serial.print("Please wait while connecting to: '" WLAN_SSID "' ... ");

  if ( Feather.connect(WLAN_SSID, WLAN_PASS) )
  {
    Serial.println("Connected!");
  }
  else
  {
    Serial.printf("Failed! %s (%d)", Feather.errstr(), Feather.errno());
    Serial.println();
  }
  Serial.println();

  return Feather.connected();
}

/**************************************************************************/
/*!
    @brief  Get user input from Serial
*/
/**************************************************************************/
char* getUserInput(void)
{
  static char inputs[64+1];
  memset(inputs, 0, sizeof(inputs));

  // wait until data is available
  while( Serial.available() == 0 ) { delay(1); }

  uint8_t count=0;
  do
  {
    count += Serial.readBytes(inputs+count, 64);
  } while( (count < 64) && Serial.available() );

  return inputs;
}
hathach commented 8 years ago

Update: Since UDP is currently not implemented as a buffered stream like TCP, so each write will send out an packet. We are looking at it to find where is the appropriate place to update the code.

Krenuds commented 8 years ago

This is currently working for me, just filling up a member buffer on the write() call:

size_t AdafruitUDP::write(const uint8_t* buffer, size_t size)
{
  if (_udp_handle == 0 || _sndIP == 0 || _sndPort == 0) {
    Serial.println("Handle, IP, port == 0 returning");
    return 0;
  }

  //Serial.printf("Inserting into Index: %d\n", _packetSize );
  memcpy(&_packetBuffer[_packetSize], buffer, size);
  _packetSize += size;
  //Serial.printf("Packet Size: %d\n", _packetSize );
  //Serial.printf("Packet Buffer: %d\n", buffer ); 
  return size;
}

And then actually I write the thing upon endPacket(); seems logical enough anyway:

int AdafruitUDP::endPacket()
{
    sdep_cmd_para_t para_arr[] =
  {
      { .len = 4   , .p_value = &_udp_handle },
      { .len = 4   , .p_value = &_sndIP      },
      { .len = 2   , .p_value = &_sndPort    },
      { .len = (uint16_t) _packetSize, .p_value = (void const*)_packetBuffer}
  };
  uint8_t para_count = sizeof(para_arr)/sizeof(sdep_cmd_para_t);

  VERIFY_RETURN(sdep_n(SDEP_CMD_UDP_WRITE, para_count, para_arr, NULL, NULL), 0);
  _sndIP   = 0;
  _sndPort = 0;
  _packetSize = 0;

   return 1;
}
hathach commented 8 years ago

Hi, sorry for patching it late. We need to make sure it does not affect other scenario/examples including UDP server. You will need to switch to development branch and perform featherlib (Release) upgrade. Then UDP should be an buffered stream now (like TCP).

Let us know if this fixes your issues.

Krenuds commented 8 years ago

Sir, you are a legend.

hathach commented 8 years ago

Noope, we should have got it right at the first time. Thanks for reporting the issue.