Skip to content

Commit

Permalink
Added sendto and recvfrom and fixed returned port byte order
Browse files Browse the repository at this point in the history
  • Loading branch information
gershnik committed Mar 23, 2024
1 parent 1ab04f0 commit 40499bf
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 8 deletions.
20 changes: 18 additions & 2 deletions src/WiFiSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ WiFiSocket WiFiSocket::accept(arduino::IPAddress & remoteIpAddress, uint16_t & r
return WiFiSocket(res);
}

bool WiFiSocket::connect(const arduino::IPAddress & remoteIpAddress, uint16_t remotePort) {
return SocketDrv::connect(m_handle, remoteIpAddress, remotePort);
bool WiFiSocket::connect(const arduino::IPAddress & ipAddress, uint16_t port) {
return SocketDrv::connect(m_handle, ipAddress, port);
}

int32_t WiFiSocket::send(const void * buf, uint16_t size) {
Expand All @@ -73,6 +73,22 @@ int32_t WiFiSocket::recv(void * buf, uint16_t size) {
return ret;
}

int32_t WiFiSocket::sendTo(const void * buf, uint16_t size,
const arduino::IPAddress & ipAddress, uint16_t port) {
auto ret = SocketDrv::sendTo(m_handle, buf, size, ipAddress, port);
if (ret == 0 && lastError() != 0)
ret = -1;
return ret;
}

int32_t WiFiSocket::recvFrom(void * buf, uint16_t size,
arduino::IPAddress & remoteIpAddress, uint16_t & remotePort) {
auto ret = SocketDrv::recvFrom(m_handle, buf, size, remoteIpAddress, remotePort);
if (ret == 0 && lastError() != 0)
ret = -1;
return ret;
}

bool WiFiSocket::setNonBlocking(bool val) {
uint32_t value = val;
auto size = SocketDrv::ioctl(m_handle, uint32_t(IOControl::NonBlockingIO),
Expand Down
24 changes: 21 additions & 3 deletions src/WiFiSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@ class WiFiSocket {
* Connects a socket to remote endpoint
*
* @returns success flag. Check lastError() for more information about failure
* @param remoteIpAddress host to connect to
* @param remotePort port to connect to
* @param ipAddress host to connect to
* @param port port to connect to
*/
bool connect(const arduino::IPAddress & remoteIpAddress, uint16_t remotePort);
bool connect(const arduino::IPAddress & ipAddress, uint16_t port);


/**
Expand All @@ -222,6 +222,24 @@ class WiFiSocket {
* to accommodate -1. When non-negative it will never be bigger than the size parameter.
*/
int32_t recv(void * buf, uint16_t size);

/**
* Sends data to remote endpoint
*
* @return the amount of data actually sent or -1 on failure. Check lastError()
* for more information about failure. The type of the return value is int32_t
* to accommodate -1. When non-negative it will never be bigger than the size parameter.
*/
int32_t sendTo(const void * buf, uint16_t size, const arduino::IPAddress & ipAddress, uint16_t port);

/**
* Receives data from remote endpoint
*
* @return the amount of data actually read or -1 on failure. Check lastError()
* for more information about failure. The type of the return value is int32_t
* to accommodate -1. When non-negative it will never be bigger than the size parameter.
*/
int32_t recvFrom(void * buf, uint16_t size, arduino::IPAddress & remoteIpAddress, uint16_t & remotePort);

/**
* Sets the socket into non-blocking or blocking mode
Expand Down
125 changes: 122 additions & 3 deletions src/utility/socket_drv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,11 @@ uint8_t SocketDrv::accept(uint8_t s, arduino::IPAddress & remoteIpAddress, uint1
// Wait for reply
uint8_t resultSocket;
uint8_t remoteIpBuf[4];
uint8_t remotePortBuf[2];
uint16_t remotePortTmp;
tParam params[PARAM_NUMS_3] = {
{0, (char*)&resultSocket},
{0, (char*)&remoteIpBuf},
{0, (char*)&remotePortBuf}
{0, (char*)&remotePortTmp}
};
if (!SpiDrv::waitResponseParams(cmd, PARAM_NUMS_3, params)) {
WARN("error waitResponse");
Expand All @@ -321,7 +321,7 @@ uint8_t SocketDrv::accept(uint8_t s, arduino::IPAddress & remoteIpAddress, uint1
if (resultSocket != 255) {
g_lastError = 0;
remoteIpAddress = IPAddress(arduino::IPv4, remoteIpBuf); //buf is in network order
remotePort = (uint16_t(remotePortBuf[0]) << 8) | uint16_t(remotePortBuf[1]);
remotePort = remotePortTmp; //port is host order
}
return resultSocket;
}
Expand Down Expand Up @@ -471,6 +471,125 @@ int32_t SocketDrv::recv(uint8_t s, void * buf, uint16_t size) {
}
}

int32_t SocketDrv::sendTo(uint8_t s, const void * buf, uint16_t size,
const arduino::IPAddress & ipAddress, uint16_t port) {

if (ipAddress.type() != arduino::IPv4) {
g_lastError = EINVAL;
return false;
}
auto ipv4Address = uint32_t(ipAddress);
uint8_t portNetOrder[2] = {uint8_t(port >> 8), uint8_t(port)};

g_lastError.reset();
if (!SpiDrv::initialized)
SpiDrv::begin();

//keep the size well below 4096 which seems to be SPI_MAX_DMA_LEN
if (size > 4000)
size = 4000;

uint8_t cmd = SOCKET_SENDTO_CMD;

{
SelectSlave sel;

// Send Command
int commandSize = 4;
SpiDrv::sendCmd(cmd, PARAM_NUMS_4);
SpiDrv::sendBuffer(&s, sizeof(s), NO_LAST_PARAM);
commandSize += (2 + sizeof(s));
SpiDrv::sendBuffer((uint8_t *)&ipv4Address, sizeof(ipv4Address), NO_LAST_PARAM);
commandSize += (2 + sizeof(ipv4Address));
SpiDrv::sendBuffer(portNetOrder, sizeof(portNetOrder), NO_LAST_PARAM);
commandSize += (2 + sizeof(portNetOrder));
SpiDrv::sendBuffer((uint8_t *)buf, size, LAST_PARAM);
commandSize += (2 + size);

// pad to multiple of 4
while (commandSize % 4) {
SpiDrv::readChar();
commandSize++;
}
}
{
//Wait the reply elaboration
SelectSlave sel;

// Wait for reply
uint8_t data[2] = {};
uint8_t dataLen = 0;
if (!SpiDrv::waitResponseCmd(cmd, PARAM_NUMS_1, data, &dataLen)) {
WARN("error waitResponse");
g_lastError = SocketDrv::Failure;
return -1;
}

uint16_t ret = (uint16_t(data[0]) << 8) | uint16_t(data[1]);
if (ret)
g_lastError = 0;
return ret;
}
}

int32_t SocketDrv::recvFrom(uint8_t s, void * buf, uint16_t size,
arduino::IPAddress & remoteIpAddress, uint16_t & remotePort) {
g_lastError.reset();
if (!SpiDrv::initialized)
SpiDrv::begin();

//keep the size well below 4096 which seems to be SPI_MAX_DMA_LEN
if (size > 4000)
size = 4000;

uint8_t cmd = SOCKET_RECVFROM_CMD;

{
SelectSlave sel;

// Send Command
int commandSize = 4;
SpiDrv::sendCmd(cmd, PARAM_NUMS_2);
SpiDrv::sendParam(&s, sizeof(s), NO_LAST_PARAM);
commandSize += (1 + sizeof(s));
SpiDrv::sendParam((uint8_t*)&size, sizeof(size), LAST_PARAM);
commandSize += (1 + sizeof(size));

// pad to multiple of 4
while (commandSize % 4) {
SpiDrv::readChar();
commandSize++;
}
}
{
//Wait the reply elaboration
SelectSlave sel;

// Wait for reply
uint8_t remoteIpBuf[4];
uint16_t remotePortTmp;
tDataParam params[PARAM_NUMS_3] = {
{0, (char*)&remoteIpBuf},
{0, (char*)&remotePortTmp},
{0, (char*)buf}
};
if (!SpiDrv::waitResponseParams(cmd, PARAM_NUMS_3, params)) {
WARN("error waitResponse");
g_lastError = SocketDrv::Failure;
return -1;
}

if (params[2].dataLen) {
g_lastError = 0;
remoteIpAddress = IPAddress(arduino::IPv4, remoteIpBuf); //buf is in network order
remotePort = remotePortTmp; //port is in host order
}

return params[2].dataLen;
}
}


uint8_t SocketDrv::ioctl(uint8_t s, uint32_t code, void * buf, uint8_t bufSize) {

g_lastError.reset();
Expand Down
2 changes: 2 additions & 0 deletions src/utility/socket_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ namespace SocketDrv {
bool connect(uint8_t s, const arduino::IPAddress & ipAddress, uint16_t port);
int32_t send(uint8_t s, const void * buf, uint16_t size);
int32_t recv(uint8_t s, void * buf, uint16_t size);
int32_t sendTo(uint8_t s, const void * buf, uint16_t size, const arduino::IPAddress & ipAddress, uint16_t port);
int32_t recvFrom(uint8_t s, void * buf, uint16_t size, arduino::IPAddress & remoteIpAddress, uint16_t & remotePort);
uint8_t ioctl(uint8_t s, uint32_t code, void * buf, uint8_t bufSize);
SocketState poll(uint8_t s);

Expand Down
39 changes: 39 additions & 0 deletions src/utility/spi_drv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,45 @@ int SpiDrv::waitResponseParams(uint8_t cmd, uint8_t numParam, tParam* params)
return 1;
}

int SpiDrv::waitResponseParams(uint8_t cmd, uint8_t numParam, tDataParam* params)
{
char _data = 0;
int i =0, ii = 0;


IF_CHECK_START_CMD(_data)
{
CHECK_DATA(cmd | REPLY_FLAG, _data){};

uint8_t _numParam = readChar();
if (_numParam != 0)
{
for (i=0; i<_numParam; ++i)
{
params[i].dataLen = readParamLen16();
for (ii=0; ii<params[i].dataLen; ++ii)
{
// Get Params data
params[i].data[ii] = spiTransfer(DUMMY_DATA);
}
}
} else
{
WARN("Error numParam == 0");
return 0;
}

if (numParam != _numParam)
{
WARN("Mismatch numParam");
return 0;
}

readAndCheckChar(END_CMD, &_data);
}
return 1;
}

/*
int SpiDrv::waitResponse(uint8_t cmd, tParam* params, uint8_t* numParamRead, uint8_t maxNumParams)
{
Expand Down
2 changes: 2 additions & 0 deletions src/utility/spi_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class SpiDrv
static char readChar();

static int waitResponseParams(uint8_t cmd, uint8_t numParam, tParam* params);

static int waitResponseParams(uint8_t cmd, uint8_t numParam, tDataParam* params);

static int waitResponseCmd(uint8_t cmd, uint8_t numParam, uint8_t* param, uint8_t* param_len);

Expand Down

0 comments on commit 40499bf

Please sign in to comment.