2021-05-17 01:16:50 +02:00
|
|
|
/* Copyright (C) 2020-2021 JF, Adam Pigg, Avamander
|
2020-10-11 02:11:55 +02:00
|
|
|
|
|
|
|
This file is part of InfiniTime.
|
|
|
|
|
|
|
|
InfiniTime is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published
|
|
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
InfiniTime is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2020-07-13 13:40:39 +02:00
|
|
|
#include "MusicService.h"
|
2020-11-15 15:05:51 +01:00
|
|
|
#include "systemtask/SystemTask.h"
|
2020-07-13 13:40:39 +02:00
|
|
|
|
2021-05-17 01:08:12 +02:00
|
|
|
int MusicCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) {
|
|
|
|
return static_cast<Pinetime::Controllers::MusicService*>(arg)->OnCommand(conn_handle, attr_handle, ctxt);
|
2020-07-13 13:40:39 +02:00
|
|
|
}
|
|
|
|
|
2021-04-18 19:28:14 +02:00
|
|
|
Pinetime::Controllers::MusicService::MusicService(Pinetime::System::SystemTask& system) : m_system(system) {
|
2021-05-17 01:08:12 +02:00
|
|
|
characteristicDefinition[0] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msEventCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
2021-04-18 19:28:14 +02:00
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_NOTIFY,
|
|
|
|
.val_handle = &eventHandle};
|
2021-05-17 01:08:12 +02:00
|
|
|
characteristicDefinition[1] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msStatusCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
2021-04-18 19:28:14 +02:00
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
2021-05-17 01:08:12 +02:00
|
|
|
characteristicDefinition[2] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTrackCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
2021-04-18 19:28:14 +02:00
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
2021-05-17 01:08:12 +02:00
|
|
|
characteristicDefinition[3] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msArtistCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
2021-04-18 19:28:14 +02:00
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
2021-05-17 01:08:12 +02:00
|
|
|
characteristicDefinition[4] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msAlbumCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
2021-04-18 19:28:14 +02:00
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
2021-05-17 01:08:12 +02:00
|
|
|
characteristicDefinition[5] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msPositionCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
|
|
|
characteristicDefinition[6] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTotalLengthCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
|
|
|
characteristicDefinition[7] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTotalLengthCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
|
|
|
characteristicDefinition[8] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTrackNumberCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
|
|
|
characteristicDefinition[9] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTrackTotalCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
|
|
|
characteristicDefinition[10] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msPlaybackSpeedCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
|
|
|
characteristicDefinition[11] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msRepeatCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
|
|
|
characteristicDefinition[12] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msShuffleCharUuid),
|
|
|
|
.access_cb = MusicCallback,
|
2021-04-18 19:28:14 +02:00
|
|
|
.arg = this,
|
|
|
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
2020-10-11 02:11:55 +02:00
|
|
|
characteristicDefinition[13] = {0};
|
2021-04-18 19:28:14 +02:00
|
|
|
|
2021-05-17 01:08:12 +02:00
|
|
|
serviceDefinition[0] = {
|
|
|
|
.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = reinterpret_cast<ble_uuid_t*>(&msUuid), .characteristics = characteristicDefinition};
|
2020-10-11 02:11:55 +02:00
|
|
|
serviceDefinition[1] = {0};
|
2021-04-18 19:28:14 +02:00
|
|
|
|
2020-10-11 02:11:55 +02:00
|
|
|
artistName = "Waiting for";
|
|
|
|
albumName = "";
|
2021-04-04 17:19:41 +02:00
|
|
|
trackName = "track information..";
|
2020-10-11 02:11:55 +02:00
|
|
|
playing = false;
|
|
|
|
repeat = false;
|
|
|
|
shuffle = false;
|
|
|
|
playbackSpeed = 1.0f;
|
|
|
|
trackProgress = 0;
|
|
|
|
trackLength = 0;
|
2020-07-13 13:40:39 +02:00
|
|
|
}
|
|
|
|
|
2020-10-11 02:11:55 +02:00
|
|
|
void Pinetime::Controllers::MusicService::Init() {
|
2021-05-17 01:08:12 +02:00
|
|
|
uint8_t res = 0;
|
2020-07-13 13:40:39 +02:00
|
|
|
res = ble_gatts_count_cfg(serviceDefinition);
|
|
|
|
ASSERT(res == 0);
|
2021-04-18 19:28:14 +02:00
|
|
|
|
2020-07-13 13:40:39 +02:00
|
|
|
res = ble_gatts_add_svcs(serviceDefinition);
|
|
|
|
ASSERT(res == 0);
|
|
|
|
}
|
|
|
|
|
2021-04-18 19:28:14 +02:00
|
|
|
int Pinetime::Controllers::MusicService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) {
|
2020-07-13 13:40:39 +02:00
|
|
|
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
|
2020-10-11 02:11:55 +02:00
|
|
|
size_t notifSize = OS_MBUF_PKTLEN(ctxt->om);
|
2021-05-17 01:08:12 +02:00
|
|
|
char data[notifSize + 1];
|
2020-10-11 02:11:55 +02:00
|
|
|
data[notifSize] = '\0';
|
|
|
|
os_mbuf_copydata(ctxt->om, 0, notifSize, data);
|
2021-05-17 01:08:12 +02:00
|
|
|
char* s = &data[0];
|
|
|
|
if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msArtistCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
artistName = s;
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msTrackCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
trackName = s;
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msAlbumCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
albumName = s;
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msStatusCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
playing = s[0];
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msRepeatCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
repeat = s[0];
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msShuffleCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
shuffle = s[0];
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msPositionCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
trackProgress = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msTotalLengthCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
trackLength = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msTrackNumberCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
trackNumber = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msTrackTotalCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
tracksTotal = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
2021-05-17 01:08:12 +02:00
|
|
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msPlaybackSpeedCharUuid)) == 0) {
|
2020-10-11 02:11:55 +02:00
|
|
|
playbackSpeed = static_cast<float>(((s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3])) / 100.0f;
|
|
|
|
}
|
2020-07-13 13:40:39 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-05-17 01:08:12 +02:00
|
|
|
std::string Pinetime::Controllers::MusicService::getAlbum() const {
|
2020-10-11 02:11:55 +02:00
|
|
|
return albumName;
|
2020-07-13 13:40:39 +02:00
|
|
|
}
|
|
|
|
|
2021-05-17 01:08:12 +02:00
|
|
|
std::string Pinetime::Controllers::MusicService::getArtist() const {
|
2020-10-11 02:11:55 +02:00
|
|
|
return artistName;
|
2020-07-13 13:40:39 +02:00
|
|
|
}
|
|
|
|
|
2021-05-17 01:08:12 +02:00
|
|
|
std::string Pinetime::Controllers::MusicService::getTrack() const {
|
2020-10-11 02:11:55 +02:00
|
|
|
return trackName;
|
2020-07-13 13:40:39 +02:00
|
|
|
}
|
|
|
|
|
2021-05-17 01:08:12 +02:00
|
|
|
bool Pinetime::Controllers::MusicService::isPlaying() const {
|
2020-10-11 02:11:55 +02:00
|
|
|
return playing;
|
2020-07-20 22:28:21 +02:00
|
|
|
}
|
|
|
|
|
2021-05-17 01:08:12 +02:00
|
|
|
float Pinetime::Controllers::MusicService::getPlaybackSpeed() const {
|
2020-10-11 02:11:55 +02:00
|
|
|
return playbackSpeed;
|
|
|
|
}
|
2020-07-13 13:40:39 +02:00
|
|
|
|
2021-05-17 01:08:12 +02:00
|
|
|
int Pinetime::Controllers::MusicService::getProgress() const {
|
|
|
|
return trackProgress;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Pinetime::Controllers::MusicService::getTrackLength() const {
|
|
|
|
return trackLength;
|
|
|
|
}
|
|
|
|
|
2020-10-11 02:11:55 +02:00
|
|
|
void Pinetime::Controllers::MusicService::event(char event) {
|
2021-04-18 19:28:14 +02:00
|
|
|
auto* om = ble_hs_mbuf_from_flat(&event, 1);
|
|
|
|
|
2020-10-11 02:11:55 +02:00
|
|
|
uint16_t connectionHandle = m_system.nimble().connHandle();
|
2021-04-18 19:28:14 +02:00
|
|
|
|
2020-10-11 02:11:55 +02:00
|
|
|
if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) {
|
|
|
|
return;
|
|
|
|
}
|
2021-04-18 19:28:14 +02:00
|
|
|
|
2020-10-11 02:11:55 +02:00
|
|
|
ble_gattc_notify_custom(connectionHandle, eventHandle, om);
|
2021-05-17 01:08:12 +02:00
|
|
|
}
|