Files
localiserd/lib/localiser/web/controllers/firmware_controller.ex
T

83 lines
2.6 KiB
Elixir

defmodule Localiser.Web.Controllers.FirmwareController do
use Phoenix.Controller, formats: [:json]
alias Localiser.Domain.{Firmware, Sensors}
# Admin: upload a new firmware version.
# Expects multipart/form-data with fields: version (string), firmware (file).
def upload(conn, %{"version" => version, "firmware" => %Plug.Upload{} = upload}) do
case Firmware.store(version, upload) do
{:ok, _version} ->
json(conn, %{status: "ok", version: version})
{:error, reason} ->
conn
|> put_status(:internal_server_error)
|> json(%{error: "Upload failed: #{inspect(reason)}"})
end
end
def upload(conn, _params) do
conn
|> put_status(:bad_request)
|> json(%{error: "version and firmware file are required"})
end
# Admin: list available firmware versions.
def index(conn, _params) do
json(conn, Firmware.list())
end
# Public: serve firmware binary.
def download(conn, %{"version" => version}) do
case Firmware.get(version) do
{:ok, path} ->
conn
|> put_resp_content_type("application/octet-stream")
|> put_resp_header("content-disposition", ~s(attachment; filename="#{version}.bin"))
|> send_file(200, path)
:not_found ->
conn
|> put_status(:not_found)
|> json(%{error: "Firmware version not found"})
end
end
# Admin: broadcast OTA update to the entire fleet.
# POST /api/firmware/:version/ota
def ota_fleet(conn, %{"version" => version}) do
case Firmware.get(version) do
{:ok, _path} ->
url = firmware_url(conn, version)
Sensors.send_ota_broadcast(url, version)
json(conn, %{status: "ok", url: url, version: version})
:not_found ->
conn
|> put_status(:not_found)
|> json(%{error: "Firmware version not found"})
end
end
# Admin: upload a new firmware version and push OTA update to fleet immediately.
# Expects multipart/form-data with fields: version (string), firmware (file).
def ota_fleet_instant(conn, %{"version" => version, "firmware" => %Plug.Upload{} = upload}) do
case Firmware.store(version, upload) do
{:ok, _version} ->
url = firmware_url(conn, version)
Sensors.send_ota_broadcast(url, version)
json(conn, %{status: "ok", version: version})
{:error, reason} ->
conn
|> put_status(:internal_server_error)
|> json(%{error: "Upload failed: #{inspect(reason)}"})
end
end
defp firmware_url(conn, version) do
"#{conn.scheme}://#{conn.host}:#{conn.port}/api/firmware/#{version}"
end
end