diff --git a/esp32/include/communication/webserver.h b/esp32/include/communication/webserver.h index 07d09c9..754c5e4 100644 --- a/esp32/include/communication/webserver.h +++ b/esp32/include/communication/webserver.h @@ -74,12 +74,25 @@ class WebServer { template static esp_err_t sendProto(httpd_req_t* req, int status, const T& msg, const pb_msgdesc_t* fields) { - uint8_t buffer[1024]; - pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + size_t size = 0; + if (!pb_get_encoded_size(&size, fields, &msg)) { + return sendError(req, 500, "Failed to calculate proto size"); + } + + uint8_t* buffer = (uint8_t*)malloc(size); + if (!buffer) { + return sendError(req, 500, "Failed to allocate memory for proto"); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, size); if (!pb_encode(&stream, fields, &msg)) { + free(buffer); return sendError(req, 500, "Failed to encode proto"); } - return sendProto(req, status, buffer, stream.bytes_written); + + esp_err_t result = sendProto(req, status, buffer, stream.bytes_written); + free(buffer); + return result; } template diff --git a/esp32/src/mdns_service.cpp b/esp32/src/mdns_service.cpp index e508679..118e2d0 100644 --- a/esp32/src/mdns_service.cpp +++ b/esp32/src/mdns_service.cpp @@ -92,7 +92,7 @@ esp_err_t MDNSService::getStatus(httpd_req_t *request) { status.global_txt_records[i] = state().global_txt_records[i]; } - return WebServer::sendProto(request, 200, api_Response_fields, &response, api_Response_size); + return WebServer::sendProto(request, 200, response, api_Response_fields); } esp_err_t MDNSService::queryServices(httpd_req_t *request, api_Request *protoReq) { @@ -120,5 +120,5 @@ esp_err_t MDNSService::queryServices(httpd_req_t *request, api_Request *protoReq queryResp.services[i].port = MDNS.port(i); } - return WebServer::sendProto(request, 200, api_Response_fields, &response, api_Response_size); + return WebServer::sendProto(request, 200, response, api_Response_fields); } diff --git a/esp32/src/wifi_service.cpp b/esp32/src/wifi_service.cpp index 4996543..9c40d49 100644 --- a/esp32/src/wifi_service.cpp +++ b/esp32/src/wifi_service.cpp @@ -60,23 +60,26 @@ esp_err_t WiFiService::getNetworks(httpd_req_t *request) { return handleScan(request); } - api_Response response = api_Response_init_zero; - response.which_payload = api_Response_wifi_network_list_tag; - api_WifiNetworkList &networkList = response.payload.wifi_network_list; - - // Limit to max_count from options file (20) + // Limit to 20 networks max size_t count = (numNetworks > 20) ? 20 : static_cast(numNetworks); - networkList.networks_count = count; + + // Allocate networks array on stack (pointer type in proto) + api_WifiNetworkScan networks[20] = {}; for (size_t i = 0; i < count; i++) { - networkList.networks[i].rssi = WiFi.RSSI(i); - strncpy(networkList.networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networkList.networks[i].ssid) - 1); - strncpy(networkList.networks[i].bssid, WiFi.BSSIDstr(i).c_str(), sizeof(networkList.networks[i].bssid) - 1); - networkList.networks[i].channel = WiFi.channel(i); - networkList.networks[i].encryption_type = static_cast(WiFi.encryptionType(i)); + networks[i].rssi = WiFi.RSSI(i); + strncpy(networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networks[i].ssid) - 1); + strncpy(networks[i].bssid, WiFi.BSSIDstr(i).c_str(), sizeof(networks[i].bssid) - 1); + networks[i].channel = WiFi.channel(i); + networks[i].encryption_type = static_cast(WiFi.encryptionType(i)); } - return WebServer::sendProto(request, 200, api_Response_fields, &response, api_Response_size); + api_Response response = api_Response_init_zero; + response.which_payload = api_Response_wifi_network_list_tag; + response.payload.wifi_network_list.networks = networks; + response.payload.wifi_network_list.networks_count = count; + + return WebServer::sendProto(request, 200, response, api_Response_fields); } void WiFiService::setupMDNS(const char *hostname) { @@ -115,7 +118,7 @@ esp_err_t WiFiService::getNetworkStatus(httpd_req_t *request) { } } - return WebServer::sendProto(request, 200, api_Response_fields, &response, api_Response_size); + return WebServer::sendProto(request, 200, response, api_Response_fields); } void WiFiService::manageSTA() { diff --git a/platform_shared/api.options b/platform_shared/api.options index 9da0aeb..4864f16 100644 --- a/platform_shared/api.options +++ b/platform_shared/api.options @@ -26,7 +26,7 @@ api.WifiSettings.wifi_networks max_count:5 api.WifiNetworkScan.ssid max_size:33 api.WifiNetworkScan.bssid max_size:18 -api.WifiNetworkList.networks max_count:20 +api.WifiNetworkList.networks type:FT_POINTER api.WifiStatus.mac_address max_size:18 api.WifiStatus.ssid max_size:33