@@ -186,15 +186,24 @@ int DuckNet::setupWebServer(bool createCaptivePortal, std::string html) {
186186 }
187187 });
188188
189- webServer.on (" /atakHistory" , HTTP_GET, [&](AsyncWebServerRequest* request){
190- const uint8_t * atakBytes = DuckNet::serializeAtakHistoryToBytes (&atakBuffer);
191- size_t atakSize = 229 * CDPCFG_CDP_CHATBUF_SIZE + 4 ;
192- const char * atakType = " application/octet-stream" ;
193- AsyncWebServerResponse *response = request->beginResponse_P (200 , atakType, atakBytes, atakSize);
194- request->send (response);
195- delete[] atakBytes; // this needs to be fixed bc async
196-
197- });
189+ webServer.on (" /atakHistory" , HTTP_GET, [&](AsyncWebServerRequest* request) {
190+ uint8_t * atakBytes = DuckNet::serializeAtakHistoryToBytes (&atakBuffer);
191+ size_t atakSize = sizeof (atakBytes);
192+ // Use shared_ptr for safe cleanup
193+ std::shared_ptr<uint8_t > atakData (atakBytes, [](uint8_t * p) { delete[] p; });
194+
195+ AsyncWebServerResponse* response = request->beginResponse (" application/octet-stream" , atakSize,
196+ [atakData, atakSize](uint8_t * buffer, size_t maxLen, size_t alreadySent) -> size_t {
197+ size_t remaining = atakSize - alreadySent;
198+ size_t toSend = remaining < maxLen ? remaining : maxLen;
199+ memcpy (buffer, atakData.get () + alreadySent, toSend);
200+ return toSend;
201+ });
202+
203+ response->addHeader (" Content-Disposition" , " attachment; filename=\" atakHistory.bin\" " );
204+ request->send (response);
205+ });
206+
198207 webServer.on (" /atakChatHistory" , HTTP_GET, [&](AsyncWebServerRequest* request){
199208 std::string response = DuckNet::serializeAtakHistoryToJSON (&atakBuffer);
200209 const char * res = response.c_str ();
@@ -386,21 +395,29 @@ std::string DuckNet::serializeAtakHistoryToJSON(CircularBuffer* buffer) {
386395 return json;
387396
388397}
389- uint8_t * DuckNet::serializeAtakHistoryToBytes (CircularBuffer* buffer){
398+
399+ uint8_t * DuckNet::serializeAtakHistoryToBytes (CircularBuffer* buffer) {
400+ int atakBytes = buffer->getCount ();
401+ size_t dataSize = atakBytes * sizeof (CdpPacket);
402+ // outSize = dataSize + sizeof(uint32_t);
403+
404+ uint8_t * result = new uint8_t [dataSize];
405+
406+ // // First 4 bytes = count (little endian)
407+ // result[0] = atakBytes & 0xFF;
408+ // result[1] = (atakBytes >> 8) & 0xFF;
409+ // result[2] = (atakBytes >> 16) & 0xFF;
410+ // result[3] = (atakBytes >> 24) & 0xFF;
411+
412+ // Serialize packets
390413 int tail = buffer->getTail ();
391- uint8_t * atakBytes = new uint8_t [229 * CDPCFG_CDP_CHATBUF_SIZE + 4 ];
392- int offset = 0 ;
393- while (tail != buffer->getHead ()){
394- CdpPacket packet = buffer->getMessage (tail);
395- std::memcpy (atakBytes + offset, packet.data .data (), packet.data .size ()); // Copy the packet data into atakBytes
396- offset += packet.data .size (); // Move the offset forward by the size of the current packet
397- tail++;
398- if (tail == buffer->getBufferEnd ()){
399- tail = 0 ;
400- }
401- atakBytes[offset++] = ' duck' ;
414+ for (int i = 0 ; i < atakBytes; i++) {
415+ CdpPacket packet = buffer->getMessage (tail);
416+ memcpy (result + 4 + i * sizeof (CdpPacket), &packet, sizeof (CdpPacket));
417+ tail = (tail + 1 ) % buffer->getBufferEnd ();
402418 }
403- return atakBytes;
419+
420+ return result;
404421}
405422
406423void DuckNet::saveChannel (int val){
0 commit comments