Add UDP Broadcast for OpenMV Cam discovery.

* Now OpenMV Cam's can be discovered in the wild by OpenMV IDE without
hardcoding the OpenMV Cam WiFi IP address and port.
* The firmware reads settings from OpenMV IDE for STA and AP mode.
* Boradcast in both modes works and OpenMV IDE can find the cam.
* AP mode works (albeit the driver needs help).
* Station mode sometimes connects every now and then. There's a bug in
the WiFi module that prevents this from working right. The same code
executes on the cam and in the IDE for both modes but station mode has
issues...
This commit is contained in:
Kwabena W. Agyeman 2018-08-07 01:23:28 -04:00 committed by iabdalkader
parent abe97a73ba
commit 60f6d1ddc7
4 changed files with 137 additions and 45 deletions

View File

@ -300,14 +300,24 @@ int ini_handler_callback(void *user, const char *section, const char *name, cons
openmv_config->wifidbg = ini_is_true(value); openmv_config->wifidbg = ini_is_true(value);
} else if (MATCH("WiFiConfig", "Mode")) { } else if (MATCH("WiFiConfig", "Mode")) {
openmv_config->wifidbg_config.mode = ini_atoi(value); openmv_config->wifidbg_config.mode = ini_atoi(value);
} else if (MATCH("WiFiConfig", "SSID")) { } else if (MATCH("WiFiConfig", "ClientSSID")) {
strncpy(openmv_config->wifidbg_config.ssid, value, WINC_MAX_SSID_LEN); strncpy(openmv_config->wifidbg_config.client_ssid, value, WINC_MAX_SSID_LEN);
} else if (MATCH("WiFiConfig", "Key")) { } else if (MATCH("WiFiConfig", "ClientKey")) {
strncpy(openmv_config->wifidbg_config.key, value, WINC_MAX_PSK_LEN); strncpy(openmv_config->wifidbg_config.client_key, value, WINC_MAX_PSK_LEN);
} else if (MATCH("WiFiConfig", "Security")) { } else if (MATCH("WiFiConfig", "ClientSecurity")) {
openmv_config->wifidbg_config.security = ini_atoi(value); openmv_config->wifidbg_config.client_security = ini_atoi(value);
} else if (MATCH("WiFiConfig", "Channel")) { } else if (MATCH("WiFiConfig", "ClientChannel")) {
openmv_config->wifidbg_config.channel = ini_atoi(value); openmv_config->wifidbg_config.client_channel = ini_atoi(value);
} else if (MATCH("WiFiConfig", "AccessPointSSID")) {
strncpy(openmv_config->wifidbg_config.access_point_ssid, value, WINC_MAX_SSID_LEN);
} else if (MATCH("WiFiConfig", "AccessPointKey")) {
strncpy(openmv_config->wifidbg_config.access_point_key, value, WINC_MAX_PSK_LEN);
} else if (MATCH("WiFiConfig", "AccessPointSecurity")) {
openmv_config->wifidbg_config.access_point_security = ini_atoi(value);
} else if (MATCH("WiFiConfig", "AccessPointChannel")) {
openmv_config->wifidbg_config.access_point_channel = ini_atoi(value);
} else if (MATCH("WiFiConfig", "BoardName")) {
strncpy(openmv_config->wifidbg_config.board_name, value, WINC_MAX_BOARD_NAME_LEN);
} else { } else {
return 0; return 0;
} }

View File

@ -30,16 +30,23 @@
#define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif #endif
#define OPENMVCAM_BROADCAST_ADDR ((uint8_t [5]){255, 255, 255, 255})
#define OPENMVCAM_BROADCAST_PORT (0xABD1)
#define SERVER_ADDR ((uint8_t [5]){192, 168, 1, 1}) #define SERVER_ADDR ((uint8_t [5]){192, 168, 1, 1})
#define SERVER_PORT (9000) #define SERVER_PORT (9000)
#define BUFFER_SIZE (512) #define BUFFER_SIZE (512)
#define UDPCAST_STRING "%d.%d.%d.%d:%d:%s"
#define UDPCAST_STRING_SIZE 4+4+4+4+6+WINC_MAX_BOARD_NAME_LEN+1
#define close_all_sockets() \ #define close_all_sockets() \
do { \ do { \
winc_socket_close(client_fd); \ winc_socket_close(client_fd); \
winc_socket_close(server_fd); \ winc_socket_close(server_fd); \
winc_socket_close(udpbcast_fd); \
client_fd = -1; \ client_fd = -1; \
server_fd = -1; \ server_fd = -1; \
udpbcast_fd = -1; \
} while (0) } while (0)
#define close_server_socket() \ #define close_server_socket() \
@ -48,15 +55,51 @@
server_fd = -1; \ server_fd = -1; \
} while (0) } while (0)
#define close_udpbcast_socket() \
do { \
winc_socket_close(udpbcast_fd); \
udpbcast_fd = -1; \
} while (0)
#define TIMEDOUT(x) (x == -ETIMEDOUT || x == SOCK_ERR_TIMEOUT) #define TIMEDOUT(x) (x == -ETIMEDOUT || x == SOCK_ERR_TIMEOUT)
static int client_fd = -1; static int client_fd = -1;
static int server_fd = -1; static int server_fd = -1;
static int udpbcast_fd = -1;
static int udpbcast_time = 0;
static uint8_t ip_addr[WINC_IP_ADDR_LEN] = {};
static char udpbcast_string[UDPCAST_STRING_SIZE] = {};
int wifidbg_init(wifidbg_config_t *config) int wifidbg_init(wifidbg_config_t *config)
{ {
client_fd = -1; client_fd = -1;
server_fd = -1; server_fd = -1;
udpbcast_fd = -1;
if(!config->mode) { // STA Mode
// Initialize WiFi in STA mode.
if (winc_init(WINC_MODE_STA) != 0) {
return -1;
}
// Connect to network.
if (winc_connect(config->client_ssid,
config->client_security,
config->client_key,
config->client_channel) != 0) {
return -2;
}
winc_ifconfig_t ifconfig;
if (winc_ifconfig(&ifconfig) < 0) {
return -3;
}
memcpy(ip_addr, ifconfig.ip_addr, WINC_IP_ADDR_LEN);
} else { // AP Mode
// Initialize WiFi in AP mode. // Initialize WiFi in AP mode.
if (winc_init(WINC_MODE_AP) != 0) { if (winc_init(WINC_MODE_AP) != 0) {
@ -64,10 +107,20 @@ int wifidbg_init(wifidbg_config_t *config)
} }
// Start WiFi in AP mode. // Start WiFi in AP mode.
if (winc_start_ap(config->ssid, config->security, config->key, config->channel) != 0) { if (winc_start_ap(config->access_point_ssid,
config->access_point_security,
config->access_point_key,
config->access_point_channel) != 0) {
return -2; return -2;
} }
memcpy(ip_addr, SERVER_ADDR, WINC_IP_ADDR_LEN);
}
snprintf(udpbcast_string, UDPCAST_STRING_SIZE, UDPCAST_STRING,
ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
SERVER_PORT, config->board_name);
return 0; return 0;
} }
@ -77,9 +130,35 @@ void wifidbg_dispatch()
uint8_t buf[BUFFER_SIZE]; uint8_t buf[BUFFER_SIZE];
sockaddr client_sockaddr; sockaddr client_sockaddr;
if (udpbcast_fd < 0) {
// Create broadcast socket
MAKE_SOCKADDR(udpbcast_sockaddr, OPENMVCAM_BROADCAST_ADDR, OPENMVCAM_BROADCAST_PORT)
if ((udpbcast_fd = winc_socket_socket(SOCK_DGRAM)) < 0) {
return;
}
if ((ret = winc_socket_bind(udpbcast_fd, &udpbcast_sockaddr)) < 0) {
close_udpbcast_socket();
return;
}
}
if ((udpbcast_fd >= 0) && (!(udpbcast_time++ % 100))) {
// Create broadcast socket
MAKE_SOCKADDR(udpbcast_sockaddr, OPENMVCAM_BROADCAST_ADDR, OPENMVCAM_BROADCAST_PORT)
if ((ret = winc_socket_sendto(udpbcast_fd,
(uint8_t *) udpbcast_string, strlen(udpbcast_string) + 1,
&udpbcast_sockaddr, 500)) < 0) {
close_udpbcast_socket();
return;
}
}
if (server_fd < 0) { if (server_fd < 0) {
// Create server socket // Create server socket
MAKE_SOCKADDR(server_sockaddr, SERVER_ADDR, SERVER_PORT) MAKE_SOCKADDR(server_sockaddr, ip_addr, SERVER_PORT)
if ((server_fd = winc_socket_socket(SOCK_STREAM)) < 0) { if ((server_fd = winc_socket_socket(SOCK_STREAM)) < 0) {
return; return;
@ -107,7 +186,6 @@ void wifidbg_dispatch()
} }
return; return;
} }
} }
if ((ret = winc_socket_recv(client_fd, buf, 8, 10)) < 0) { if ((ret = winc_socket_recv(client_fd, buf, 8, 10)) < 0) {

View File

@ -8,12 +8,14 @@
typedef struct wifidbg_config { typedef struct wifidbg_config {
winc_mode_t mode; winc_mode_t mode;
winc_security_t security; winc_security_t client_security, access_point_security;
char key[WINC_MAX_PSK_LEN + 1]; char client_key[WINC_MAX_PSK_LEN + 1], access_point_key[WINC_MAX_PSK_LEN + 1];
char ssid[WINC_MAX_SSID_LEN + 1]; char client_ssid[WINC_MAX_SSID_LEN + 1], access_point_ssid[WINC_MAX_SSID_LEN + 1];
uint8_t channel; uint8_t client_channel, access_point_channel;
char board_name[WINC_MAX_BOARD_NAME_LEN + 1];
} wifidbg_config_t; } wifidbg_config_t;
void wifidbg_dispatch();
int wifidbg_init(wifidbg_config_t *config); int wifidbg_init(wifidbg_config_t *config);
void wifidbg_dispatch();
#endif /* __WIFIDBG_H__ */ #endif /* __WIFIDBG_H__ */

View File

@ -13,6 +13,7 @@
#define WINC_MAC_ADDR_LEN (6) #define WINC_MAC_ADDR_LEN (6)
#define WINC_MAX_SSID_LEN (33) #define WINC_MAX_SSID_LEN (33)
#define WINC_MAX_PSK_LEN (65) #define WINC_MAX_PSK_LEN (65)
#define WINC_MAX_BOARD_NAME_LEN (33)
#define MAKE_SOCKADDR(addr, ip, port) \ #define MAKE_SOCKADDR(addr, ip, port) \
struct sockaddr addr; \ struct sockaddr addr; \
@ -110,4 +111,5 @@ int winc_socket_recv(int fd, uint8_t *buf, uint32_t len, uint32_t timeout);
int winc_socket_sendto(int fd, const uint8_t *buf, uint32_t len, sockaddr *addr, uint32_t timeout); int winc_socket_sendto(int fd, const uint8_t *buf, uint32_t len, sockaddr *addr, uint32_t timeout);
int winc_socket_recvfrom(int fd, uint8_t *buf, uint32_t len, sockaddr *addr, uint32_t timeout); int winc_socket_recvfrom(int fd, uint8_t *buf, uint32_t len, sockaddr *addr, uint32_t timeout);
int winc_socket_setsockopt(int fd, uint32_t level, uint32_t opt, const void *optval, uint32_t optlen); int winc_socket_setsockopt(int fd, uint32_t level, uint32_t opt, const void *optval, uint32_t optlen);
#endif //__WINC_H__ #endif //__WINC_H__