@brief OTA UDP server task - handles OTA invitations and protocol @param pvParameters Pointer to ESP32OTA instance
| 1210 | /// @brief OTA UDP server task - handles OTA invitations and protocol |
| 1211 | /// @param pvParameters Pointer to ESP32OTA instance |
| 1212 | static void otaServerTask(void* pvParameters) { |
| 1213 | ESP32OTA* self = static_cast<ESP32OTA*>(pvParameters); |
| 1214 | |
| 1215 | // Create UDP socket |
| 1216 | self->mOtaUdpSocket = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
| 1217 | if (self->mOtaUdpSocket < 0) { |
| 1218 | FL_WARN("OTA: Failed to create UDP socket"); |
| 1219 | self->mOtaRunning = false; |
| 1220 | vTaskDelete(nullptr); |
| 1221 | return; |
| 1222 | } |
| 1223 | |
| 1224 | // Bind to port 3232 |
| 1225 | struct sockaddr_in addr; |
| 1226 | fl::memset(&addr, 0, sizeof(addr)); |
| 1227 | addr.sin_family = AF_INET; |
| 1228 | addr.sin_port = lwip_htons(3232); |
| 1229 | addr.sin_addr.s_addr = lwip_htonl(INADDR_ANY); |
| 1230 | |
| 1231 | if (lwip_bind(self->mOtaUdpSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { |
| 1232 | FL_WARN("OTA: Failed to bind UDP socket to port 3232"); |
| 1233 | lwip_close(self->mOtaUdpSocket); |
| 1234 | self->mOtaUdpSocket = -1; |
| 1235 | self->mOtaRunning = false; |
| 1236 | vTaskDelete(nullptr); |
| 1237 | return; |
| 1238 | } |
| 1239 | |
| 1240 | FL_DBG("OTA: UDP server listening on port 3232"); |
| 1241 | |
| 1242 | // Set receive timeout for responsive shutdown |
| 1243 | struct timeval timeout; |
| 1244 | timeout.tv_sec = 1; |
| 1245 | timeout.tv_usec = 0; |
| 1246 | lwip_setsockopt(self->mOtaUdpSocket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); |
| 1247 | |
| 1248 | char buffer[512]; |
| 1249 | struct sockaddr_in client_addr; |
| 1250 | socklen_t client_len = sizeof(client_addr); |
| 1251 | |
| 1252 | while (self->mOtaRunning) { |
| 1253 | int len = lwip_recvfrom(self->mOtaUdpSocket, buffer, sizeof(buffer) - 1, 0, |
| 1254 | (struct sockaddr*)&client_addr, &client_len); |
| 1255 | |
| 1256 | if (len <= 0) { |
| 1257 | continue; // Timeout or error, check mOtaRunning flag |
| 1258 | } |
| 1259 | |
| 1260 | buffer[len] = '\0'; |
| 1261 | FL_DBG("OTA: Received UDP packet: " << buffer); |
| 1262 | |
| 1263 | // Parse command: "<cmd> <port> <size> <md5>\n" |
| 1264 | int cmd, port, size; |
| 1265 | char md5[33]; |
| 1266 | if (sscanf(buffer, "%d %d %d %32s", &cmd, &port, &size, md5) != 4) { |
| 1267 | FL_WARN("OTA: Invalid invitation format"); |
| 1268 | continue; |
| 1269 | } |