Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion firmware/main/audio/FreeDVMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ enum FreeDVMessageTypes
class FreeDVSyncStateMessage : public DVTaskMessageBase<SYNC_STATE, FreeDVSyncStateMessage>
{
public:
FreeDVSyncStateMessage(bool syncStateProvided = false)
FreeDVSyncStateMessage(bool syncStateProvided = false, int freqOffsetProvided = 0)
: DVTaskMessageBase<SYNC_STATE, FreeDVSyncStateMessage>(FREEDV_MESSAGE)
, syncState(syncStateProvided)
, freqOffset(freqOffsetProvided)
{}
virtual ~FreeDVSyncStateMessage() = default;

bool syncState;
int freqOffset;
};

enum FreeDVMode
Expand Down
6 changes: 5 additions & 1 deletion firmware/main/audio/FreeDVTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ void FreeDVTask::onTaskTick_()
if (!isActive_) return;

bool syncLed = false;
int freqOffset = 0;

//ESP_LOGI(CURRENT_LOG_TAG, "timer tick");

Expand Down Expand Up @@ -201,11 +202,14 @@ void FreeDVTask::onTaskTick_()
}

syncLed = freedv_get_sync(dv_) > 0;

freedv_get_modem_extended_stats(dv_, stats_);
freqOffset = stats_->foff;
}
}

// Broadcast current sync state
FreeDVSyncStateMessage* message = new FreeDVSyncStateMessage(syncLed);
FreeDVSyncStateMessage* message = new FreeDVSyncStateMessage(syncLed, freqOffset);
publish(message);
delete message;
}
Expand Down
14 changes: 14 additions & 0 deletions firmware/main/http_server_files/index.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
<li class="nav-item">
<button id="updateTab" class="nav-link" data-bs-toggle="tab" data-bs-target="#updateTabForm" aria-current="page-update">Firmware Update</button>
</li>
<li class="nav-item">
<button id="statusTab" class="nav-link" data-bs-toggle="tab" data-bs-target="#statusTabForm" aria-current="page-status">System Status</button>
</li>
</ul>
</div>
</div>
Expand Down Expand Up @@ -253,6 +256,17 @@
<div class="col-8">&nbsp;</div>
</div>
</form>
<form class="tab-pane fade show" id="statusTabForm">
<div class="table-responsive">
<table class="table">
<tbody>
<tr><th colspan="2">FreeDV Signal</th></tr>
<tr><td>Synced</td><td id="syncState">No</td></tr>
<tr><td>Frequency offset</td><td id="freqOffset">0</td></tr>
</tbody>
</table>
</div>
</form>
<form class="tab-pane fade" id="wifiTabForm">
<div class="row mb-3" id="wifiSuccessAlertRow">
<div class="col-xs-12 col-md-6">
Expand Down
13 changes: 13 additions & 0 deletions firmware/main/http_server_files/localscript.js
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,19 @@ function wsConnect()
$("#startVoiceKeyer").removeClass("btn-danger");
}
}
else if (json.type == "freedvStatus")
{
if (json.sync)
{
$("#syncState").text("Yes");
}
else
{
$("#syncState").text("No");
}

$("#freqOffset").text(json.freqOffset);
}
};

ws.onclose = function(e)
Expand Down
48 changes: 48 additions & 0 deletions firmware/main/network/HttpServerTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ extern "C"
#define JSON_WIFI_SAVED_TYPE "wifiSaved"
#define JSON_RADIO_STATUS_TYPE "radioInfo"
#define JSON_RADIO_SAVED_TYPE "radioSaved"
#define JSON_FREEDV_STATUS_TYPE "freedvStatus"

#define JSON_VOICE_KEYER_STATUS_TYPE "voiceKeyerInfo"
#define JSON_VOICE_KEYER_SAVED_TYPE "voiceKeyerSaved"
Expand Down Expand Up @@ -86,6 +87,8 @@ HttpServerTask::HttpServerTask()
: ezdv::task::DVTask("HttpServerTask", 4, 4096, tskNO_AFFINITY, 256)
, firmwareUploadInProgress_(false)
, isRunning_(false)
, currFreqOffset_(0)
, freqOffsetCount_(0)
{
registerMessageHandler(this, &HttpServerTask::onBatteryStateMessage_);

Expand Down Expand Up @@ -121,6 +124,8 @@ HttpServerTask::HttpServerTask()
registerMessageHandler(this, &HttpServerTask::onWifiNetworkListMessage_);

registerMessageHandler(this, &HttpServerTask::onHttpServeStaticFileMessage_);

registerMessageHandler(this, &HttpServerTask::onFreeDVSyncStateMessage_);
}

HttpServerTask::~HttpServerTask()
Expand Down Expand Up @@ -888,6 +893,49 @@ void HttpServerTask::onHttpWebsocketDisconnectedMessage_(DVTask* origin, HttpWeb
}
}

void HttpServerTask::onFreeDVSyncStateMessage_(DVTask* origin, audio::FreeDVSyncStateMessage* message)
{
const int NUM_OFFSETS_TO_AVERAGE = 25;

// Calculate average offset (enough samples so we report ~4x/sec, ensuring we don't
// overwhelm any web clients.
freqOffsets_.push_back(message->freqOffset);
if (freqOffsets_.size() > NUM_OFFSETS_TO_AVERAGE)
{
freqOffsets_.pop_front();
}

int sum = 0;
for (auto& val : freqOffsets_)
{
sum += val;
}
currFreqOffset_ = sum / freqOffsets_.size();

freqOffsetCount_++;
if (freqOffsetCount_ >= NUM_OFFSETS_TO_AVERAGE)
{
freqOffsetCount_ = 0;

// Report running average of the offset and sync state to web interace
cJSON *root = cJSON_CreateObject();
if (root != nullptr)
{
cJSON_AddStringToObject(root, "type", JSON_FREEDV_STATUS_TYPE);
cJSON_AddNumberToObject(root, "freqOffset", currFreqOffset_);
cJSON_AddBoolToObject(root, "sync", message->syncState);

// Note: below is responsible for cleanup.
sendJSONMessage_(root, activeWebSockets_);
}
else
{
// HTTP isn't 100% critical but we really should see what's leaking memory.
ESP_LOGE(CURRENT_LOG_TAG, "Could not create JSON object for codec status!");
}
}
}

void HttpServerTask::onBatteryStateMessage_(DVTask* origin, driver::BatteryStateMessage* message)
{
cJSON *root = cJSON_CreateObject();
Expand Down
8 changes: 8 additions & 0 deletions firmware/main/network/HttpServerTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define HTTP_SERVER_TASK_H

#include <vector>
#include <deque>

#include "esp_event.h"
#include "esp_http_server.h"
Expand Down Expand Up @@ -140,6 +141,10 @@ class HttpServerTask : public DVTask
WebSocketList activeWebSockets_;
bool isRunning_;

std::deque<int> freqOffsets_;
int currFreqOffset_;
int freqOffsetCount_;

void onHttpWebsocketConnectedMessage_(DVTask* origin, HttpWebsocketConnectedMessage* message);
void onHttpWebsocketDisconnectedMessage_(DVTask* origin, HttpWebsocketDisconnectedMessage* message);

Expand Down Expand Up @@ -169,6 +174,9 @@ class HttpServerTask : public DVTask
void onStartWifiScanMessage_(DVTask* origin, HttpServerTask::StartWifiScanMessage* message);
void onStopWifiScanMessage_(DVTask* origin, HttpServerTask::StopWifiScanMessage* message);
void onWifiNetworkListMessage_(DVTask* origin, WifiNetworkListMessage* message);

// FreeDV sync state reporting
void onFreeDVSyncStateMessage_(DVTask* origin, audio::FreeDVSyncStateMessage* message);

// Helper to asynchronously serve static files.
void onHttpServeStaticFileMessage_(DVTask* origin, HttpServeStaticFileMessage* message);
Expand Down