Skip to content

Commit

Permalink
Add high level wifi driver
Browse files Browse the repository at this point in the history
  • Loading branch information
nedseb committed Feb 21, 2022
1 parent 674c8e1 commit 0b513a7
Show file tree
Hide file tree
Showing 3 changed files with 494 additions and 14 deletions.
280 changes: 280 additions & 0 deletions inc/drivers/WIFI/Wifi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
#include <memory>

#include "CodalComponent.h"
#include "Ism43362Driver.h"
#include "ManagedString.h"

#define WIFI_ISM43362_DEVICE_ID 2510

#define WIFI_ISM43362_DEFAULT_BUFFER_SIZE ES_WIFI_DATA_SIZE

#define WIFI_ISM43362_EVT_DATA_RECEIVED 1
#define WIFI_ISM43362_EVT_RX_FULL 2

#define WIFI_ISM43362_STATUS_RX_IN_USE 0x01
#define WIFI_ISM43362_STATUS_TX_IN_USE 0x02
#define WIFI_ISM43362_STATUS_RX_BUFF_INIT 0x04
#define WIFI_ISM43362_STATUS_TX_BUFF_INIT 0x08
#define WIFI_ISM43362_STATUS_RXD 0x10

namespace codal {

class WiFiClient;

class WiFi : public CodalComponent {
private:
Ism43362Driver ism43362;
uint8_t wifi_status;

public:
/**
* @brief Contructor
*
*/
WiFi(codal::STM32SPI* spi, codal::STM32Pin* cs, codal::STM32Pin* commandDataReady, codal::STM32Pin* reset,
codal::STM32Pin* wakeup)
: CodalComponent(WIFI_ISM43362_DEVICE_ID, 0),
ism43362(spi, cs, commandDataReady, reset, wakeup),
wifi_status(WL_NO_SHIELD)
{
}

/**
* @brief Contructor
*
*/
WiFi(Ism43362Driver& ism43362)
: CodalComponent(WIFI_ISM43362_DEVICE_ID, 0), ism43362(ism43362), wifi_status(WL_NO_SHIELD)
{
}

virtual int init() override final
{
if (wifi_status == WL_NO_SHIELD) {
if (ism43362.ES_WIFI_Init() != ES_WIFI_STATUS_OK) {
wifi_status = WL_NO_SHIELD;
return DEVICE_INVALID_STATE;
}
else {
wifi_status = WL_IDLE_STATUS;
}
}

return DEVICE_OK;
}

/**
* @brief Destructor
*
*/
virtual ~WiFi()
{
if (isAttached()) {
detach();
}
}

/**
* @brief Get the number of networks visible.
* @param None
* @retval Number of discovered networks. The device can see 10 AP max.
*/
int networksVisible();

/**
* @brief Connect to the wifi network.
* @param ssid name of the network
* @param passphrase Passphrase. Valid characters in a passphrase
* must be between 32-126 chars.
* @retval none
*/
void attach(const ManagedString& ssid, const ManagedString& passphrase);

/**
* @brief Check if we are connected to the wifi network.
* @param None
* @retval true if the device is connected to an AP
*/
bool isAttached();

/**
* @brief Disconnect from the wifi network.
* @param None
* @retval none
*/
void detach();

/**
* @brief Start a Client connection to a remote host
* @param hostname : name of the host to which to connect
* @param port : port to which to connect
* @retval A pointer to the client object connected to the remote host
*/
std::unique_ptr<WiFiClient> connect(const ManagedString& host, uint16_t port);

/**
* @brief
*
*/
virtual void idleCallback() final override
{
if (this->status & WIFI_ISM43362_STATUS_RXD) {
Event(this->id, WIFI_ISM43362_EVT_DATA_RECEIVED);
this->status &= ~WIFI_ISM43362_STATUS_RXD;
}
}

friend WiFiClient;
};

class WiFiClient {
private:
WiFi* wifi;
uint8_t sock;
bool connected;
uint16_t status;

uint8_t* rxBuff;
uint8_t rxBuffSize;
volatile uint16_t rxBuffHead;
uint16_t rxBuffTail;

public:
/**
* @brief Destroy the WiFiClient object
*
*/
~WiFiClient()
{
if ((this->status & WIFI_ISM43362_STATUS_RX_BUFF_INIT) != 0) {
free(this->rxBuff);
}
}

/**
* @brief Check if the connection is active with the remote host
* @param None
* @retval true if the client is connected to the remote host
*/
bool isConnected();

/**
* @brief Get connection state
* @param None
* @retval Socket state, FREE or BUSY
*/
uint8_t connectionState();

/**
* @brief Close the to the remote host connection
* @param None
* @retval None
*/
void disconnect();

/**
* Determines whether there is any data waiting in our reception buffer.
*
* @return 1 if we have space, 0 if we do not.
*
*/
int isReadable();

/**
* Determines if the socket is currently in use by another fiber for reception.
*
* @return The state of our mutex lock for reception.
*
*/
int rxInUse();

/**
* Locks the mutex so that others can't use this serial instance for reception
*/
void lockRx();

/**
* Unlocks the mutex so that others can use this serial instance for reception
*/
void unlockRx();

/**
* @brief Read up to size bytes from the current packet and place them into buffer
* @param buffer : Where to place read data
* @param size : length of data to read
* @retval Returns the number of bytes read, or 0 if none are available
*/
int read(char* buf, size_t size);

/**
* @brief Read a single byte from the current packet
* @param None
* @retval the read byte
*/
char read();

/**
* @brief Write size bytes from buffer into the packet
* @param buf : data to write
* @param size : size of data to write
* @retval size of write data
*/
size_t write(const char* buf, size_t size);

friend WiFi;

private:
/**
* @brief Construct a WiFiClient object
*
*/
WiFiClient(WiFi* wifi) : wifi(wifi), sock(SOCK_NOT_AVAIL), connected(false), status(0) {}

/**
* @brief Get the first socket number free.
* @param None
* @retval socket number or -1 if no available.
*/
uint8_t getFirstSocket();

/**
* @brief Start a TCP connection to the remote host
* @param ip : IP to which to send packets
* @param port : port to which to send packets
* @retval true if successful, false if there was a problem with the supplied IP address or port
*/
bool connect(IPAddress ip, uint16_t port);

/**
* @brief Start a TCP connection to the remote host
* @param host : host to which to send the packet
* @param port : port to which to send the packet
* @retval true if successful, false if there was a problem with the supplied IP address or port
*/
bool connect(const ManagedString& host, uint16_t port);

/**
* We do not want to always have our buffers initialised, especially if users to not
* use them. We only bring them up on demand.
*/
int initialiseReceptionBuffer()
{
if ((this->status & WIFI_ISM43362_STATUS_RX_BUFF_INIT) != 0) {
free(this->rxBuff);
}

this->status &= ~WIFI_ISM43362_STATUS_RX_BUFF_INIT;

if ((this->rxBuff = (uint8_t*)malloc(rxBuffSize)) == NULL) {
return DEVICE_NO_RESOURCES;
}

this->rxBuffHead = 0;
this->rxBuffTail = 0;

this->status |= WIFI_ISM43362_STATUS_RX_BUFF_INIT;

return DEVICE_OK;
}
};
} // namespace codal
45 changes: 31 additions & 14 deletions samples/WIFI/HttpClient/WIFI_Http_Client_Sample.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "WIFI_Http_Client_Sample.h"
#include <memory>

#include "Ism43362Driver.h"
#include "WIFI_Buffer_Sample.h"
#include "Wifi.h"
#include "ssd1306.h"

codal::STM32Pin miso3(ID_PIN_WIFI_ISM43362_MISO, PinNumber::PC_11, codal::PIN_CAPABILITY_DIGITAL);
Expand All @@ -16,11 +18,14 @@ codal::STM32Pin commandDataReadyPin(ID_PIN_WIFI_ISM43362_COMMAND_DATA_READY, Pin
codal::PIN_CAPABILITY_DIGITAL);

Ism43362Driver DrvWiFi(&spi3, &csPin, &commandDataReadyPin, &resetPin, &wakeUpPin);
codal::WiFi wifi(DrvWiFi);

const char* ssid = "SSID";
const char* passphrase = "PASSWORD";
const char* ssid = "NEDJAR";
const char* passphrase = "Camevenere1!";
const char* host = "google.com";
const char* methodName = "GET";

void Wifi_Http_Client_Sample_main(codal::STM32DISCO_L475VG_IOT& discoL475VgIot)
void Wifi_Buffer_Sample_main(codal::STM32DISCO_L475VG_IOT& discoL475VgIot)
{
discoL475VgIot.serial.init(115200);

Expand All @@ -29,23 +34,35 @@ void Wifi_Http_Client_Sample_main(codal::STM32DISCO_L475VG_IOT& discoL475VgIot)
printf("* Demonstration du wifi *\r\n");
printf("*******************************************\r\n");

if (DrvWiFi.ES_WIFI_Init() != ES_WIFI_STATUS_OK) {
if (wifi.init() != DEVICE_OK) {
printf("Init not Ok\r\n");
return;
}
else
printf("Init Ok\r\n");

printf("Init Ok\r\n");
printf("Number of network : %d \r\n", wifi.networksVisible());

printf("Begin scan network\r\n");
DrvWiFi.ES_WIFI_ListAccessPoints();
printf("End scan network\r\n");
printf("Connection to %s \r\n", ssid);

printf("Number of network : %d\r\n", DrvWiFi.ES_WIFI_GetApNbr());
wifi.attach(ssid, passphrase);

if (DrvWiFi.ES_WIFI_Connect(ssid, passphrase, ES_WIFI_SEC_WPA2) != ES_WIFI_STATUS_OK) {
printf("Connection to %s not Ok\r\n", ssid);
DrvWiFi.ES_WIFI_Disconnect();
if (!wifi.isAttached()) {
printf("Not connected to %s \r\n", ssid);
wifi.detach();
return;
}
printf("Connected to %s\r\n", ssid);

printf("Connected to %s \r\n", ssid);

auto client = wifi.connect(host, 80);

if (client->isConnected()) {
auto req = "GET / HTTP/1.1\r\nHost: google.com\r\nConnection: Close\r\n\r\n";
client->write(req, strlen(req));
char buffer[2000];
memset(buffer, 0, 2000);
client->read(buffer, 2000);
printf("Received : %s\r\n", buffer);
}
}
Loading

0 comments on commit 0b513a7

Please sign in to comment.