Skip to content

Commit

Permalink
Firmware support for Smart Reconnect
Browse files Browse the repository at this point in the history
App side work for Smart Reconnect
  • Loading branch information
XScorpion2 committed Nov 8, 2020
1 parent c053ea5 commit 52cb03d
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 63 deletions.
Expand Up @@ -297,6 +297,9 @@ private void Read(DateTime now)
case Command.VOLUME_NEXT_CHANGE:
ReadMessage<VolumeData>(now, command);
break;
case Command.MODE_STATES:
ReadMessage<ModeStates>(now, command);
break;
case Command.ERROR:
case Command.NONE:
case Command.DEBUG:
Expand Down Expand Up @@ -378,6 +381,7 @@ private void Write(DateTime now)
case Command.VOLUME_ALT_CHANGE:
case Command.VOLUME_PREV_CHANGE:
case Command.VOLUME_NEXT_CHANGE:
case Command.MODE_STATES:
case Command.DEBUG:
WriteMessage(now, pair.Key, pair.Value);
break;
Expand Down
Expand Up @@ -13,14 +13,7 @@ static class FirmwareVersions
#if DEBUG
"0.0.0",
#endif
"1.4.0",
"1.4.1",
"1.4.2",
"1.4.3",
"1.4.4",
"1.4.5",
"1.4.6",
"1.4.7"
"1.5.0"
};

public static bool IsCompatible(string version)
Expand Down
90 changes: 90 additions & 0 deletions Desktop/Application/MaxMix/Services/Communication/Messages.cs
Expand Up @@ -20,6 +20,7 @@ public enum Command
VOLUME_ALT_CHANGE,
VOLUME_PREV_CHANGE,
VOLUME_NEXT_CHANGE,
MODE_STATES,
DEBUG
}

Expand All @@ -42,6 +43,28 @@ public enum DisplayMode
MODE_MAX
};

public enum SplashState
{
STATE_LOGO,
STATE_INFO,
STATE_MAX
};

public enum SessionState
{
STATE_NAVIGATE,
STATE_EDIT,
STATE_MAX
};

public enum GameState
{
STATE_SELECT_A,
STATE_SELECT_B,
STATE_GAME_EDIT,
STATE_MAX
};

internal static class MessageUtils
{
public static unsafe bool UnsafeEquals<T>(this T data, T other, uint offset = 0, uint count = uint.MaxValue) where T : unmanaged, IMessage
Expand Down Expand Up @@ -407,4 +430,71 @@ public override string ToString()
return $"{sleepAfterSeconds}, {accelerationPercentage}, {continuousScroll}, {volumeMinColor}, {volumeMaxColor}, {mixChannelAColor}, {mixChannelBColor} > {this.ToByteString()}";
}
}

public unsafe struct ModeStates : IMessage, IEquatable<ModeStates>
{
fixed byte m_Data[5];

public SplashState splash
{
get => (SplashState)m_Data[0];
set => m_Data[0] = (byte)value;
}

public SessionState output
{
get => (SessionState)m_Data[1];
set => m_Data[1] = (byte)value;
}

public SessionState input
{
get => (SessionState)m_Data[2];
set => m_Data[2] = (byte)value;
}

public SessionState application
{
get => (SessionState)m_Data[3];
set => m_Data[3] = (byte)value;
}

public GameState game
{
get => (GameState)m_Data[4];
set => m_Data[4] = (byte)value;
}

public static ModeStates Default()
{
return new ModeStates
{
splash = SplashState.STATE_LOGO,
output = SessionState.STATE_EDIT,
input = SessionState.STATE_EDIT,
application = SessionState.STATE_NAVIGATE,
game = GameState.STATE_SELECT_A
};
}

public bool Equals(ModeStates other)
{
return this.UnsafeEquals(other);
}

public unsafe void GetBytes(MemoryStream stream)
{
this.UnsafeCopyTo(stream);
}

public void SetBytes(byte[] bytes)
{
this.UnsafeCopyFrom(bytes);
}

public override string ToString()
{
return $"{splash}, {output}, {input}, {application}, {game} > {this.ToByteString()}";
}
}
}
71 changes: 35 additions & 36 deletions Desktop/Application/MaxMix/ViewModels/MainViewModel.cs
Expand Up @@ -90,7 +90,9 @@ public ICommand RequestExitCommand
// Device State Tracking
SessionInfo m_SessionInfo = SessionInfo.Default();
SessionData[] m_Sessions = new SessionData[(int)SessionIndex.INDEX_MAX] { SessionData.Default(), SessionData.Default(), SessionData.Default(), SessionData.Default() };
ModeStates m_ModeStates = ModeStates.Default();
Dictionary<int, int> m_IndexToId = new Dictionary<int, int>();
bool m_HasPreviouslyConnected = false;

private IAudioSessionService _audioSessionService;
private CommunicationService _communicationService;
Expand Down Expand Up @@ -136,11 +138,16 @@ public override void Stop()
_settingsViewModel.Stop();
}

private void OnDefaultDeviceChanged(object sender, int id, DeviceFlow deviceFlow)
private void SendMessage(Command command, IMessage message)
{
if (!IsConnected)
return;

_communicationService.SendMessage(command, message);
}

private void OnDefaultDeviceChanged(object sender, int id, DeviceFlow deviceFlow)
{
for (int i = (int)SessionIndex.INDEX_PREVIOUS; i < (int)SessionIndex.INDEX_MAX; i++)
{
if (!m_IndexToId.TryGetValue(m_Sessions[i].data.id, out var sessionId))
Expand All @@ -149,29 +156,23 @@ private void OnDefaultDeviceChanged(object sender, int id, DeviceFlow deviceFlow
if (sessionId == id)
{
m_Sessions[i].data.isDefault = true;
_communicationService.SendMessage(Command.VOLUME_CURR_CHANGE + i, m_Sessions[i]);
SendMessage(Command.VOLUME_CURR_CHANGE + i, m_Sessions[i]);
}
else if (m_Sessions[i].data.isDefault)
{
m_Sessions[i].data.isDefault = false;
_communicationService.SendMessage(Command.VOLUME_CURR_CHANGE + i, m_Sessions[i]);
SendMessage(Command.VOLUME_CURR_CHANGE + i, m_Sessions[i]);
}
}
}

private void OnDeviceVolumeChanged(object sender, int id, int volume, bool isMuted, DeviceFlow deviceFlow)
{
if (!IsConnected)
return;

UpdateSessionState(id, false, volume, isMuted);
}

private void OnAudioSessionVolumeChanged(object sender, int id, int volume, bool isMuted)
{
if (!IsConnected)
return;

UpdateSessionState(id, false, volume, isMuted);
}

Expand All @@ -189,53 +190,41 @@ private void UpdateSessionState(int id, bool isDefault, int volume, bool isMuted
m_Sessions[i].data.isMuted = isMuted;
if (string.IsNullOrEmpty(name))
{
_communicationService.SendMessage(Command.VOLUME_CURR_CHANGE + i, m_Sessions[i].data);
SendMessage(Command.VOLUME_CURR_CHANGE + i, m_Sessions[i].data);
}
else
{
string prevName = m_Sessions[i].name;
m_Sessions[i].name = name;
if (m_Sessions[i].name != prevName)
_communicationService.SendMessage(Command.CURRENT_SESSION + i, m_Sessions[i]);
SendMessage(Command.CURRENT_SESSION + i, m_Sessions[i]);
else
_communicationService.SendMessage(Command.VOLUME_CURR_CHANGE + i, m_Sessions[i].data);
SendMessage(Command.VOLUME_CURR_CHANGE + i, m_Sessions[i].data);
}
}
}
}

private void OnDeviceCreated(object sender, int id, string displayName, int volume, bool isMuted, DeviceFlow deviceFlow)
{
if (!IsConnected)
return;

bool isCurrentMode = deviceFlow.ToDisplayMode() == m_SessionInfo.mode;
UpdateSessionData(id, isCurrentMode, true);
}

private void OnDeviceRemoved(object sender, int id, DeviceFlow deviceFlow)
{
if (!IsConnected)
return;

bool isCurrentMode = deviceFlow.ToDisplayMode() == m_SessionInfo.mode;
UpdateSessionData(id, isCurrentMode, false);
}

private void OnAudioSessionCreated(object sender, int id, string displayName, int volume, bool isMuted)
{
if (!IsConnected)
return;

bool isCurrentMode = m_SessionInfo.mode == DisplayMode.MODE_APPLICATION || m_SessionInfo.mode == DisplayMode.MODE_GAME;
UpdateSessionData(id, isCurrentMode, true);
}

private void OnAudioSessionRemoved(object sender, int id)
{
if (!IsConnected)
return;

bool isCurrentMode = m_SessionInfo.mode == DisplayMode.MODE_APPLICATION || m_SessionInfo.mode == DisplayMode.MODE_GAME;
UpdateSessionData(id, isCurrentMode, false);
}
Expand Down Expand Up @@ -272,23 +261,23 @@ private void UpdateSessionData(int id, bool IsCurrentMode, bool addition)
else if (m_SessionInfo.current > 0)
m_SessionInfo.current--;
}

if (addition && _settingsViewModel.DisplayNewSession && m_SessionInfo.mode != DisplayMode.MODE_GAME)
{
PopulateIndexToIdMap(sessions);
m_SessionInfo.current = FindSessionIndex(sessions, x => x.Id == id);
}

UpdateAndFlushSessionData(sessions, true);
}
_communicationService.SendMessage(Command.SESSION_INFO, m_SessionInfo);

SendMessage(Command.SESSION_INFO, m_SessionInfo);
}

private void OnSettingsChanged(object sender, PropertyChangedEventArgs e)
{
if (!IsConnected)
return;

DeviceSettings settings = _settingsViewModel.ToDeviceSettings();
_communicationService.SendMessage(Command.SETTINGS, settings);
SendMessage(Command.SETTINGS, settings);
}

/****************************************
Expand All @@ -310,20 +299,25 @@ private void OnDeviceConnected()
OnSettingsChanged(null, null);
// Send device initial screen data

m_SessionInfo.mode = DisplayMode.MODE_OUTPUT;
if (!m_HasPreviouslyConnected)
m_SessionInfo.mode = DisplayMode.MODE_OUTPUT;

// NOTE: we can now have a setting to determin the initial screen
ISession[] sessions = _audioSessionService.GetSessions(m_SessionInfo.mode);
_audioSessionService.GetSessionCounts(out var output, out var input, out int application);

m_SessionInfo.current = FindSessionIndex(sessions, x => x.IsDefault);
if (!m_HasPreviouslyConnected)
m_SessionInfo.current = FindSessionIndex(sessions, x => x.IsDefault);
m_SessionInfo.output = (byte)output;
m_SessionInfo.input = (byte)input;
m_SessionInfo.application = (byte)application;

UpdateAndFlushSessionData(sessions, true);

_communicationService.SendMessage(Command.SESSION_INFO, m_SessionInfo);
SendMessage(Command.MODE_STATES, m_ModeStates);
SendMessage(Command.SESSION_INFO, m_SessionInfo);

m_HasPreviouslyConnected = true;
}

private void OnMessageRecieved(Command command, IMessage message)
Expand Down Expand Up @@ -354,14 +348,19 @@ private void OnMessageRecieved(Command command, IMessage message)
m_SessionInfo.current = FindSessionIndex(sessions, x => x.IsDefault);
UpdateAndFlushSessionData(sessions, isNewMode);
if (isNewMode)
_communicationService.SendMessage(Command.SESSION_INFO, m_SessionInfo);
SendMessage(Command.SESSION_INFO, m_SessionInfo);
}
else if (command == Command.ALTERNATE_SESSION)
{
// This comes from game mode and tells us what it selected.
SessionData data = (SessionData)message;
m_Sessions[(int)SessionIndex.INDEX_ALTERNATE] = data;
}
else if (command == Command.MODE_STATES)
{
ModeStates data = (ModeStates)message;
m_ModeStates = data;
}
}

byte FindSessionIndex(ISession[] sessions, Predicate<ISession> match)
Expand All @@ -385,9 +384,9 @@ void UpdateAndFlushSessionData(ISession[] data, bool updateIndexMap = false)
m_Sessions[(int)SessionIndex.INDEX_CURRENT] = data.ToSessionData(index);
m_Sessions[(int)SessionIndex.INDEX_PREVIOUS] = data.ToSessionData(prevIndex);
m_Sessions[(int)SessionIndex.INDEX_NEXT] = data.ToSessionData(nextIndex);
_communicationService.SendMessage(Command.CURRENT_SESSION, m_Sessions[(int)SessionIndex.INDEX_CURRENT]);
_communicationService.SendMessage(Command.PREVIOUS_SESSION, m_Sessions[(int)SessionIndex.INDEX_PREVIOUS]);
_communicationService.SendMessage(Command.NEXT_SESSION, m_Sessions[(int)SessionIndex.INDEX_NEXT]);
SendMessage(Command.CURRENT_SESSION, m_Sessions[(int)SessionIndex.INDEX_CURRENT]);
SendMessage(Command.PREVIOUS_SESSION, m_Sessions[(int)SessionIndex.INDEX_PREVIOUS]);
SendMessage(Command.NEXT_SESSION, m_Sessions[(int)SessionIndex.INDEX_NEXT]);
}

void ComputeIndexes(int index, out int previous, out int next)
Expand Down
7 changes: 6 additions & 1 deletion Embedded/MaxMix/Communications.cpp
Expand Up @@ -4,6 +4,7 @@
extern DeviceSettings g_Settings;
extern SessionInfo g_SessionInfo;
extern SessionData g_Sessions[4];
extern ModeStates g_ModeStates;
extern uint32_t g_HeartbeatTimeout;
extern uint32_t g_Now;

Expand Down Expand Up @@ -39,6 +40,8 @@ namespace Communications
else if (command >= Command::VOLUME_CURR_CHANGE && command <= Command::VOLUME_NEXT_CHANGE)
// SessionIndex follows same ordering as Command.
Serial.readBytes((char *)&g_Sessions[command - Command::VOLUME_CURR_CHANGE].data, sizeof(VolumeData));
else if (command == Command::MODE_STATES)
Serial.readBytes((char *)&g_ModeStates, sizeof(ModeStates));
// Do nothing: DEBUG, NONE, ERROR?
#ifdef TEST_HARNESS
else if (command == Command::DEBUG)
Expand Down Expand Up @@ -77,8 +80,10 @@ namespace Communications
Serial.write((char *)&g_Sessions[command - Command::CURRENT_SESSION], sizeof(SessionData));
else if (command >= Command::VOLUME_CURR_CHANGE && command <= Command::VOLUME_NEXT_CHANGE)
Serial.write((char *)&g_Sessions[command - Command::VOLUME_CURR_CHANGE].data, sizeof(VolumeData));
else if (command == Command::MODE_STATES)
Serial.write((char *)&g_ModeStates, sizeof(ModeStates));
// command == Command::OK just replies with command
// Send buffered data
Serial.flush();
}
} // namespace Communications
} // namespace Communications
2 changes: 1 addition & 1 deletion Embedded/MaxMix/Config.h
Expand Up @@ -20,7 +20,7 @@
// *** DEFINES
//********************************************************
#ifndef VERSION
#define VERSION "1.4.7"
#define VERSION "1.5.0"
#endif

//********************************************************
Expand Down
1 change: 1 addition & 0 deletions Embedded/MaxMix/Enums.h
Expand Up @@ -16,6 +16,7 @@ enum Command : int8_t
VOLUME_ALT_CHANGE,
VOLUME_PREV_CHANGE,
VOLUME_NEXT_CHANGE,
MODE_STATES,
DEBUG
};

Expand Down

0 comments on commit 52cb03d

Please sign in to comment.