Skip to content

Commit

Permalink
Merge pull request #661 from kaluma-project/develop/ap_mode_server
Browse files Browse the repository at this point in the history
Develop/ap mode server
  • Loading branch information
communix authored Jan 6, 2025
2 parents 7c69aee + 58d246b commit 846c9e7
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 57 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ if(NOT "${TARGET}" STREQUAL "rp2")
endif()

if(NOT VER)
set(VER "1.2.0-beta.1")
set(VER "1.2.0-beta.2")
endif()

include(${CMAKE_SOURCE_DIR}/targets/${TARGET}/target.cmake)
Expand Down
6 changes: 3 additions & 3 deletions lib/dhcpserver/dhcpserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,9 @@ static void dhcp_server_process(void *arg, struct udp_pcb *upcb, struct pbuf *p,
d->lease[yi].expiry = (cyw43_hal_ticks_ms() + DEFAULT_LEASE_TIME_S * 1000) >> 16;
dhcp_msg.yiaddr[3] = DHCPS_BASE_IP + yi;
opt_write_u8(&opt, DHCP_OPT_MSG_TYPE, DHCPACK);
printf("DHCPS: client connected: MAC=%02x:%02x:%02x:%02x:%02x:%02x IP=%u.%u.%u.%u\n",
dhcp_msg.chaddr[0], dhcp_msg.chaddr[1], dhcp_msg.chaddr[2], dhcp_msg.chaddr[3], dhcp_msg.chaddr[4], dhcp_msg.chaddr[5],
dhcp_msg.yiaddr[0], dhcp_msg.yiaddr[1], dhcp_msg.yiaddr[2], dhcp_msg.yiaddr[3]);
// printf("DHCPS: client connected: MAC=%02x:%02x:%02x:%02x:%02x:%02x IP=%u.%u.%u.%u\n",
// dhcp_msg.chaddr[0], dhcp_msg.chaddr[1], dhcp_msg.chaddr[2], dhcp_msg.chaddr[3], dhcp_msg.chaddr[4], dhcp_msg.chaddr[5],
// dhcp_msg.yiaddr[0], dhcp_msg.yiaddr[1], dhcp_msg.yiaddr[2], dhcp_msg.yiaddr[3]);
break;
}

Expand Down
119 changes: 67 additions & 52 deletions src/modules/pico_cyw43/module_pico_cyw43.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#define MAX_GPIO_NUM 2
#define SCAN_TIMEOUT 2000 /* 2 sec */
#define CONNECT_TIMEOUT 30000 /* 30 sec */
#define MAC_STR_LENGTH 19

#define NET_SOCKET_STREAM 0 /* TCP SOCKET */
#define NET_SOCKET_DGRAM 1 /* UDP SOCKET */
Expand All @@ -49,14 +50,15 @@

#define KM_MAX_SOCKET_NO 16

#define KM_CYW43_STATUS_DISABLED 0
#define KM_CYW43_STATUS_INIT 1 /* BIT 0 */
#define KM_CYW43_STATUS_DNS_DONE 2 /* BIT 1 */
#define KM_CYW43_STATUS_DISABLED 0
#define KM_CYW43_STATUS_INIT 1 /* BIT 0 */
#define KM_CYW43_STATUS_DNS_DONE 2 /* BIT 1 */
#define KM_CYW43_STATUS_AP_MODE 4 /* BIT 2 */

#define CYW43_WIFI_AUTH_OPEN 0
#define CYW43_WIFI_AUTH_WEP_PSK 1 /* BIT 0 */
#define CYW43_WIFI_AUTH_WPA 2 /* BIT 1 */
#define CYW43_WIFI_AUTH_WPA2 4 /* BIT 2 */
#define CYW43_WIFI_AUTH_OPEN 0
#define CYW43_WIFI_AUTH_WEP_PSK 1 /* BIT 0 */
#define CYW43_WIFI_AUTH_WPA 2 /* BIT 1 */
#define CYW43_WIFI_AUTH_WPA2 4 /* BIT 2 */

typedef struct {
int8_t fd;
Expand Down Expand Up @@ -95,6 +97,7 @@ typedef struct {
volatile uint8_t status_flag;
char current_ssid[33];
char current_bssid[18];
char ap_gateway_ip4[16];
} __cyw43_t;

__cyw43_t __cyw43_drv;
Expand Down Expand Up @@ -605,8 +608,7 @@ JERRYXX_FUN(pico_cyw43_network_socket) {
(const jerry_char_t *)"PICO-W CYW43 WiFi is not initialized.");
}
int wifi_status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA);
int wifi_ap_status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP);
if (wifi_status != CYW43_LINK_UP && wifi_ap_status != CYW43_LINK_UP) {
if ((wifi_status != CYW43_LINK_UP) && ((__cyw43_drv.status_flag & KM_CYW43_STATUS_AP_MODE) == 0)) {
return jerry_create_error(JERRY_ERROR_COMMON,
(const jerry_char_t *)"WiFi is not connected.");
}
Expand Down Expand Up @@ -646,10 +648,14 @@ JERRYXX_FUN(pico_cyw43_network_socket) {
jerryxx_set_property_number(__socket_info.socket[fd].obj,
MSTR_PICO_CYW43_SOCKET_STATE,
__socket_info.socket[fd].state);
struct netif *p_netif = &(cyw43_state.netif[CYW43_ITF_STA]);
const ip_addr_t *laddr = netif_ip_addr4(p_netif);
__socket_info.laddr = *laddr;
strncpy(p_str_buff, ipaddr_ntoa(laddr), sizeof(p_str_buff) - 1);
if (__cyw43_drv.status_flag & KM_CYW43_STATUS_AP_MODE) {
sprintf(p_str_buff, "%s", __cyw43_drv.ap_gateway_ip4);
} else {
struct netif *p_netif = &(cyw43_state.netif[CYW43_ITF_STA]);
const ip_addr_t *laddr = netif_ip_addr4(p_netif);
__socket_info.laddr = *laddr;
strncpy(p_str_buff, ipaddr_ntoa(laddr), sizeof(p_str_buff) - 1);
}
jerryxx_set_property_string(__socket_info.socket[fd].obj,
MSTR_PICO_CYW43_SOCKET_LADDR, p_str_buff);
jerryxx_set_property_string(JERRYXX_GET_THIS, MSTR_PICO_CYW43_NETWORK_IP,
Expand Down Expand Up @@ -1322,7 +1328,6 @@ JERRYXX_FUN(pico_cyw43_wifi_ap_mode) {
jerry_value_t ap_info = JERRYXX_GET_ARG(0);
jerry_size_t len;
uint8_t *pw_str = NULL;
uint8_t *str_buffer = NULL;
ip4_addr_t gw, mask;

// validate SSID
Expand Down Expand Up @@ -1356,50 +1361,49 @@ JERRYXX_FUN(pico_cyw43_wifi_ap_mode) {
jerry_release_value(password);

// validate Gateway
uint8_t *str_buffer = (uint8_t *)malloc(16);
jerry_value_t gateway = jerryxx_get_property(ap_info, MSTR_PICO_CYW43_WIFI_APMODE_GATEWAY);
if (jerry_value_is_string(gateway)) {
len = jerryxx_get_ascii_string_size(gateway);
str_buffer = (uint8_t *)malloc(len + 1);
jerryxx_string_to_ascii_char_buffer(gateway, str_buffer, len);
str_buffer[len] = '\0';
if (ipaddr_aton((const char *)str_buffer, &(gw)) == false) {
free(pw_str);
free(str_buffer);
jerry_release_value(gateway);
return jerry_create_error(JERRY_ERROR_COMMON,
(const jerry_char_t *)"Can't decode Gateway IP Address");
}
jerryxx_set_property_string(JERRYXX_GET_THIS, MSTR_PICO_CYW43_WIFI_APMODE_GATEWAY,
(char *)str_buffer);
} else {
IP4_ADDR(&gw, 192, 168, 4, 1);
jerryxx_set_property_string(JERRYXX_GET_THIS, MSTR_PICO_CYW43_WIFI_APMODE_GATEWAY,
"192.168.4.1");
const char *gate_ip4 = "192.168.4.1";
len = 11;
sprintf((char*)str_buffer, "%s", gate_ip4);
}
free(str_buffer);
str_buffer[len] = '\0';
if (ipaddr_aton((const char *)str_buffer, &(gw)) == false) {
free(pw_str);
free(str_buffer);
jerry_release_value(gateway);
return jerry_create_error(JERRY_ERROR_COMMON,
(const jerry_char_t *)"Can't decode Gateway IP Address");
}
jerryxx_set_property_string(JERRYXX_GET_THIS, MSTR_PICO_CYW43_WIFI_APMODE_GATEWAY,
(char *)str_buffer);
sprintf(__cyw43_drv.ap_gateway_ip4, "%s", str_buffer);
jerry_release_value(gateway);

// validate subnet mask
jerry_value_t subnet_mask = jerryxx_get_property(ap_info, MSTR_PICO_CYW43_WIFI_APMODE_SUBNET_MASK);
if (jerry_value_is_string(subnet_mask)) {
len = jerryxx_get_ascii_string_size(subnet_mask);
str_buffer = (uint8_t *)malloc(len + 1);
jerryxx_string_to_ascii_char_buffer(subnet_mask, str_buffer, len);
str_buffer[len] = '\0';
if (ipaddr_aton((const char *)str_buffer, &(mask)) == false) {
free(pw_str);
free(str_buffer);
jerry_release_value(subnet_mask);
return jerry_create_error(JERRY_ERROR_COMMON,
(const jerry_char_t *)"Can't decode Subnet Mask");
}
jerryxx_set_property_string(JERRYXX_GET_THIS, MSTR_PICO_CYW43_WIFI_APMODE_SUBNET_MASK,
(char *)str_buffer);
} else {
IP4_ADDR(&mask, 255, 255, 255, 0);
jerryxx_set_property_string(JERRYXX_GET_THIS, MSTR_PICO_CYW43_WIFI_APMODE_SUBNET_MASK,
"255.255.255.0");
const char *subnet_ip4 = "255.255.255.0";
len = 13;
sprintf((char *)str_buffer, "%s", subnet_ip4);
}
str_buffer[len] = '\0';
if (ipaddr_aton((const char *)str_buffer, &(mask)) == false) {
free(pw_str);
free(str_buffer);
jerry_release_value(subnet_mask);
return jerry_create_error(JERRY_ERROR_COMMON,
(const jerry_char_t *)"Can't decode Subnet Mask");
}
jerryxx_set_property_string(JERRYXX_GET_THIS, MSTR_PICO_CYW43_WIFI_APMODE_SUBNET_MASK,
(char *)str_buffer);
free(str_buffer);
jerry_release_value(subnet_mask);

Expand All @@ -1412,6 +1416,7 @@ JERRYXX_FUN(pico_cyw43_wifi_ap_mode) {
free(pw_str);
// start DHCP server
dhcp_server_init(&dhcp_server, &gw, &mask);
__cyw43_drv.status_flag |= KM_CYW43_STATUS_AP_MODE;

// call callback
if (JERRYXX_HAS_ARG(1)) {
Expand All @@ -1432,12 +1437,11 @@ JERRYXX_FUN(pico_cyw43_wifi_ap_mode) {

JERRYXX_FUN(pico_cyw43_wifi_disable_ap_mode) {
// verify if AP_mode is enabled
int wifi_ap_status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP);
if (wifi_ap_status != CYW43_LINK_UP) {
if ((__cyw43_drv.status_flag & KM_CYW43_STATUS_AP_MODE) == 0) {
return jerry_create_error(JERRY_ERROR_COMMON,
(const jerry_char_t *)"WiFi AP_mode is not enabled.");
}

__cyw43_drv.status_flag &= ~KM_CYW43_STATUS_AP_MODE;
// deinit DHCP server
dhcp_server_deinit(&dhcp_server);
km_cyw43_deinit();
Expand All @@ -1451,30 +1455,32 @@ JERRYXX_FUN(pico_cyw43_wifi_disable_ap_mode) {
// Function to get the MAC address of connected clients
JERRYXX_FUN(pico_cyw43_wifi_ap_get_stas) {
// verify if AP_mode is enabled
int wifi_ap_status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP);
if (wifi_ap_status != CYW43_LINK_UP) {
if ((__cyw43_drv.status_flag & KM_CYW43_STATUS_AP_MODE) == 0) {
return jerry_create_error(JERRY_ERROR_COMMON,
(const jerry_char_t *)"WiFi AP_mode is not enabled.");
}

int num_stas, max_stas, MAC_len = 18;
int num_stas;
int max_stas;
// get max stas
cyw43_wifi_ap_get_max_stas(&cyw43_state, &max_stas);
// declare
uint8_t *macs = (uint8_t*)malloc(num_stas * 6);
jerry_value_t MAC_array = jerry_create_array (num_stas);
uint8_t *macs = (uint8_t*)malloc(max_stas * 6);
//uint8_t macs[32 * 6];
cyw43_wifi_ap_get_stas(&cyw43_state, &num_stas, macs);
jerry_value_t MAC_array = jerry_create_array (num_stas);
char **mac_strs = (char **)malloc(num_stas * sizeof(char *));
for (int i = 0; i < num_stas; i++) {
mac_strs[i] = (char *)malloc(MAC_len * sizeof(char));
mac_strs[i] = (char *)malloc(MAC_STR_LENGTH * sizeof(char));
sprintf(mac_strs[i], "%02x:%02x:%02x:%02x:%02x:%02x", macs[i*6], macs[i*6+1], macs[i*6+2], macs[i*6+3], macs[i*6+4], macs[i*6+5]);
// add to the array
jerry_value_t prop = jerry_create_string((const jerry_char_t *)mac_strs[i]);
jerry_release_value(jerry_set_property_by_index(MAC_array, i, prop));
jerry_release_value(prop);
free(mac_strs[i]);
}
// deallocate memory
free(mac_strs);
free(macs);
// return the list of macs
return MAC_array;
Expand Down Expand Up @@ -1516,6 +1522,15 @@ jerry_value_t module_pico_cyw43_init() {
jerryxx_set_property_function(wifi_prototype,
MSTR_PICO_CYW43_WIFI_APMODE_DISABLE_FN,
pico_cyw43_wifi_disable_ap_mode);
jerryxx_set_property_function(wifi_prototype,
MSTR_PICO_CYW43_WIFI_APMODE_DRV_FN,
pico_cyw43_wifi_ap_mode);
jerryxx_set_property_function(wifi_prototype,
MSTR_PICO_CYW43_WIFI_APMODE_GET_STAS_DRV_FN,
pico_cyw43_wifi_ap_get_stas);
jerryxx_set_property_function(wifi_prototype,
MSTR_PICO_CYW43_WIFI_APMODE_DISABLE_DRV_FN,
pico_cyw43_wifi_disable_ap_mode);
jerry_release_value(wifi_prototype);

jerry_value_t pico_cyw43_network_ctor =
Expand Down
5 changes: 4 additions & 1 deletion src/modules/pico_cyw43/pico_cyw43_magic_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,17 @@
#define MSTR_PICO_CYW43_SOCKET_SHUTDOWN_CB "shutdown_cb"

/* AP_mode strings */
#define MSTR_PICO_CYW43_WIFI_APMODE_DRV_FN "ap_mode"
#define MSTR_PICO_CYW43_WIFI_APMODE_DISABLE_DRV_FN "disable_ap_mode"
#define MSTR_PICO_CYW43_WIFI_APMODE_GET_STAS_DRV_FN "get_ap_client"
#define MSTR_PICO_CYW43_WIFI_APMODE_FN "wifiApMode"
#define MSTR_PICO_CYW43_WIFI_APMODE_DISABLE_FN "disableWifiApMode"
#define MSTR_PICO_CYW43_WIFI_APMODE_GET_STAS_FN "getWifiApClients"

#define MSTR_PICO_CYW43_WIFI_APMODE_SSID "ssid"
#define MSTR_PICO_CYW43_WIFI_APMODE_PASSWORD "password"
#define MSTR_PICO_CYW43_WIFI_APMODE_GATEWAY "gateway"
#define MSTR_PICO_CYW43_WIFI_APMODE_SUBNET_MASK "subnetMask"
#define MSTR_PICO_CYW43_WIFI_APMODE_GET_STAS_FN "getWifiApClients"

#define MSTR_PICO_CYW43_PASSWORD "password"
#endif /* __PICO_CYW43_MAGIC_STRINGS_H */
65 changes: 65 additions & 0 deletions src/modules/wifi/wifi.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,71 @@ class WiFi extends EventEmitter {
if (cb) cb(new SystemError(6)); // ENXIO
}
}

/**
* Wifi AP mode (Optional driver function)
* @param {object} apmodeInfo
* .ssid {string}
* .password {string}
* @param {function} cb
*/
wifiApMode(apmodeInfo, cb) {
console.log(typeof this._dev.ap_mode)
if ((this._dev) && (typeof this._dev.ap_mode === 'function')) {
if (typeof apmodeInfo === 'function') {
cb = apmodeInfo
apmodeInfo = null
}
if (!apmodeInfo) {
apmodeInfo = {ssid: "Kaluma_AP",
password: "kalumaAp",
gateway: "192.168.4.1",
subnet_mask: "255.255.255.0"}
}
if (!apmodeInfo.ssid) {
apmodeInfo.ssid = storage ? storage.getItem('WIFI_AP_SSID') : "Kaluma_AP"
}
if (!apmodeInfo.password) {
apmodeInfo.password = storage ? storage.getItem('WIFI_AP_PASSWORD') : "kalumaAp"
}
if (!apmodeInfo.gateway) {
apmodeInfo.gateway = storage ? storage.getItem('WIFI_AP_GATEWAY') : "192.168.4.1"
}
if (!apmodeInfo.subnet_mask) {
apmodeInfo.subnet_mask = storage ? storage.getItem('WIFI_AP_SUBNET_MASK') : "255.255.255.0"
}
this._dev.ap_mode(apmodeInfo, err => {
if (err) {
if (cb) cb(new SystemError(this._dev.errno));
} else {
if (cb) cb(null, apmodeInfo);
}
});
} else {
if (cb) cb(new SystemError(6)); // ENXIO
}
}

/**
* Disable Wifi AP mode (Optional driver function)
*/
disableWifiApMode() {
if ((this._dev) && (typeof this._dev.disable_ap_mode === 'function')) {
return this._dev.disable_ap_mode();
} else {
if (cb) cb(new SystemError(6)); // ENXIO
}
}
/**
* Return Wifi AP clients (Optional driver function)
*/
getWifiApClients() {
if ((this._dev) && (typeof this._dev.get_ap_client === 'function')) {
return this._dev.get_ap_client();
} else {
if (cb) cb(new SystemError(6)); // ENXIO
}
}
}

// var wifi = new WiFi();
Expand Down

0 comments on commit 846c9e7

Please sign in to comment.