BIG TCP Overhaul and passcode start

- Switch to Serilog for console logging
- TCPSender is now persistent (let's hope) so can be used with passcode protected workspaces
- UDP connection works with passcodes just can't timeout
- Passcode prompt is automatic for workspaces that are password protected
This commit is contained in:
2020-06-05 23:53:16 -05:00
parent 4eb84939ca
commit 9899a6d33e
25 changed files with 245 additions and 191 deletions
+5 -2
View File
@@ -5,7 +5,7 @@ using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Net;
using Serilog;
namespace qController.Droid
{
[Activity(Label = "qController", Icon = "@drawable/icon", Theme = "@style/MyTheme", ScreenOrientation = ScreenOrientation.Portrait, MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
@@ -21,7 +21,10 @@ namespace qController.Droid
global::Xamarin.Forms.Forms.Init(this, bundle);
Log.Logger = new LoggerConfiguration().WriteTo.AndroidLog().CreateLogger();
LoadApplication(new App());
Acr.UserDialogs.UserDialogs.Init(this);
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
@@ -34,7 +37,7 @@ namespace qController.Droid
NetworkInfo networkInfo = connMgr.GetNetworkInfo(network);
if (networkInfo.Type == ConnectivityType.Wifi && networkInfo.IsAvailable && networkInfo.IsConnected)
{
Console.WriteLine("ANDROID MAIN ACTIVITY - First Wi-Fi found......binding");
Log.Debug("ANDROID MAIN ACTIVITY - First Wi-Fi found......binding");
connMgr.BindProcessToNetwork(network);
}
}
+1 -2
View File
@@ -2,7 +2,6 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -15,7 +14,7 @@ namespace qController.Droid
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
public partial class Resource
{
+2
View File
@@ -9,6 +9,8 @@
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="monoandroid71" />
<package id="NETStandard.Library" version="2.0.3" targetFramework="monoandroid81" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="monoandroid81" />
<package id="Serilog" version="2.9.0" targetFramework="monoandroid81" />
<package id="Serilog.Sinks.Xamarin" version="0.2.0.64" targetFramework="monoandroid81" />
<package id="Splat" version="8.1.1" targetFramework="monoandroid81" />
<package id="System.AppContext" version="4.3.0" targetFramework="monoandroid71" />
<package id="System.Collections" version="4.3.0" targetFramework="monoandroid71" />
+6
View File
@@ -181,6 +181,12 @@
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors" />
<Reference Include="Serilog">
<HintPath>..\packages\Serilog.2.9.0\lib\netstandard2.0\Serilog.dll</HintPath>
</Reference>
<Reference Include="Serilog.Sinks.Xamarin">
<HintPath>..\packages\Serilog.Sinks.Xamarin.0.2.0.64\lib\MonoAndroid403\Serilog.Sinks.Xamarin.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="MainActivity.cs" />
+4 -5
View File
@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using Foundation;
using UIKit;
using Serilog;
namespace qController.iOS
{
@@ -14,6 +11,8 @@ namespace qController.iOS
{
global::Xamarin.Forms.Forms.Init();
Log.Logger = new LoggerConfiguration().WriteTo.NSLog().MinimumLevel.Debug().CreateLogger();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
+1 -6
View File
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using UIKit;
using UIKit;
namespace qController.iOS
{
+2
View File
@@ -8,6 +8,8 @@
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="xamarinios10" />
<package id="NETStandard.Library" version="2.0.3" targetFramework="xamarinios10" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="xamarinios10" />
<package id="Serilog" version="2.9.0" targetFramework="xamarinios10" />
<package id="Serilog.Sinks.Xamarin" version="0.2.0.64" targetFramework="xamarinios10" />
<package id="System.AppContext" version="4.3.0" targetFramework="xamarinios10" />
<package id="System.Collections" version="4.3.0" targetFramework="xamarinios10" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="xamarinios10" />
+6
View File
@@ -137,6 +137,12 @@
<Reference Include="Xamarin.Essentials">
<HintPath>..\packages\Xamarin.Essentials.1.2.0\lib\xamarinios10\Xamarin.Essentials.dll</HintPath>
</Reference>
<Reference Include="Serilog">
<HintPath>..\packages\Serilog.2.9.0\lib\netstandard2.0\Serilog.dll</HintPath>
</Reference>
<Reference Include="Serilog.Sinks.Xamarin">
<HintPath>..\packages\Serilog.Sinks.Xamarin.0.2.0.64\lib\Xamarin.iOS10\Serilog.Sinks.Xamarin.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json">
@@ -130,7 +130,7 @@ namespace qController
{
string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id;
string command = workspace_prefix + ((QButton)sender).qCommand.osc;
qController.qClient.sendStringUDP(command);
qController.qClient.sendUDP(command);
}
}
}
@@ -1,5 +1,6 @@
using System;
using Xamarin.Forms;
using Serilog;
namespace qController
{
@@ -102,7 +103,7 @@ namespace qController
void Delete(object sender, EventArgs e)
{
Console.WriteLine("QINSTANCECELL - Delete " + nameLabel.Text + "," + addressLabel.Text + " Pressed");
Log.Debug("QINSTANCECELL - Delete " + nameLabel.Text + "," + addressLabel.Text + " Pressed");
QStorage.RemoveInstance(nameLabel.Text,addressLabel.Text);
}
@@ -110,7 +111,7 @@ namespace qController
void Connect(object sender, EventArgs e)
{
App.NavigationPage.Navigation.PushAsync(new ControlPage(nameLabel.Text,addressLabel.Text));
Console.WriteLine("QINSTANCECELL - Connect To " + nameLabel.Text + " Pressed");
Log.Debug("QINSTANCECELL - Connect To " + nameLabel.Text + " Pressed");
}
}
}
@@ -1,8 +1,9 @@
//Class used to facilitate communication with a QInstance
//Listens for incoming messages via qReceiver (UDP) and tcpSender (TCP)
//WEIRD MESSAGE PARSING RULES NEED FIXED
//TODO: WEIRD MESSAGE PARSING RULES NEED FIXED
using System;
using SharpOSC;
using Serilog;
namespace qController
{
@@ -22,7 +23,8 @@ namespace qController
qParser = new QParser();
qReceiver = new QReceiver(Port + 1);
tcpSender = new TCPSender(Address, Port);
//udpSender = new UDPSender(Address, Port);
tcpSender.Connect();
udpSender = new UDPSender(Address, Port);
tcpSender.MessageReceived += OnMessageReceived;
qReceiver.UpdateMessageReceived += OnMessageReceived;
@@ -32,8 +34,10 @@ namespace qController
//one method for messages received whether from TCP or UDP (SAME MSG FORMAT)
private void OnMessageReceived(object source, MessageEventArgs args)
{
Console.WriteLine("QCLIENT - Message Received: " + args.Message.Address);
//try to find a better filtering process
Log.Debug("QCLIENT - Message Received: " + args.Message.Address);
//TODO: find a better filtering process
if (!args.Message.Address.Contains("update"))
qParser.ParseMessage(args.Message);
else if (args.Message.Address.Contains("playbackPosition") || args.Message.Address.Contains("cueList") || args.Message.Address.Contains("dashboard"))
@@ -55,61 +59,54 @@ namespace qController
}
catch (Exception ex)
{
Console.WriteLine("QCLIENT - Send Exception: " + ex.Message);
Log.Debug("QCLIENT - Send Exception: " + ex.Message);
}
}
public void sendArgs(string address, object args)
public void sendUDP(string address)
{
Log.Debug($"QCLIENT - UDP Sent with address: {address}");
udpSender = new UDPSender(Address,Port);
udpSender.Send(new OscMessage(address));
udpSender.Close();
}
public void sendUDP(string address, params object[] args)
{
Log.Debug($"QCLIENT - UDP Sent with address: {address}");
udpSender = new UDPSender(Address, Port);
udpSender.Send(new OscMessage(address, args));
udpSender.Close();
}
public void sendTCP(string address)
{
Log.Debug($"QCLIENT - TCP Sent with address: {address}");
try
{
tcpSender.Send(new OscMessage(address));
}
catch (Exception ex)
{
Log.Debug("QCLIENT - Send and Receive Exception: " + ex.Message);
}
}
public void sendTCP(string address, params object[] args)
{
Log.Debug($"QCLIENT - TCP Sent with address: {address}");
try
{
tcpSender.Send(new OscMessage(address, args));
}
catch (Exception ex)
{
Console.WriteLine("QCLIENT - Send w/Args Exception: " + ex.Message);
}
}
public void sendStringUDP(string address)
{
udpSender = new UDPSender(Address,Port);
udpSender.Send(new OscMessage(address));
udpSender.Close();
}
public void sendArgsUDP(string address, params object[] args)
{
udpSender = new UDPSender(Address, Port);
udpSender.Send(new OscMessage(address, args));
udpSender.Close();
}
public void sendAndReceiveString(string address)
{
try
{
tcpSender.SendAndReceive(new OscMessage(address));
}
catch (Exception ex)
{
Console.WriteLine("QCLIENT - Send and Receive Exception: " + ex.Message);
}
}
public void sendAndReceiveStringArgs(string address, params object[] args)
{
try
{
tcpSender.SendAndReceive(new OscMessage(address, args));
}
catch (Exception ex)
{
Console.WriteLine("QCLIENT - Send and Receive w/Args Exception: " + ex.Message);
Log.Debug("QCLIENT - Send and Receive w/Args Exception: " + ex.Message);
}
}
public void ProcessUpdate(OscMessage msg)
{
Console.WriteLine("QCLIENT - Process Update: " + msg.Address);
Log.Debug("QCLIENT - Process Update: " + msg.Address);
if (msg.Address.Contains("workspace"))
{
UpdateWorkspace("not yet implemented");
@@ -120,19 +117,19 @@ namespace qController
{
string valuesForKeys = "[\"number\",\"uniqueID\",\"flagged\",\"listName\",\"type\",\"colorName\",\"name\",\"armed\",\"displayName\",\"isBroken\",\"isLoaded\",\"isPaused\",\"isRunning\",\"preWait\",\"duration\",\"postWait\",\"translationX\",\"translationY\",\"opacity\",\"scaleX\",\"scaleY\",\"notes\",\"levels\"]";
string address = "/workspace/" + workspace_id + "/cue_id/" + cue_id + "/valuesForKeys";
sendAndReceiveStringArgs(address, valuesForKeys);
sendTCP(address, valuesForKeys);
}
public void UpdateSelectedCue(string workspace_id)
{
string valuesForKeys = "[\"number\",\"uniqueID\",\"flagged\",\"listName\",\"type\",\"colorName\",\"name\",\"armed\",\"displayName\",\"isBroken\",\"isLoaded\",\"isPaused\",\"isRunning\",\"preWait\",\"duration\",\"postWait\",\"translationX\",\"translationY\",\"opacity\",\"scaleX\",\"scaleY\",\"notes\",\"levels\"]";
string address = "/workspace/" + workspace_id + "/cue/selected/valuesForKeys";
sendAndReceiveStringArgs(address, valuesForKeys);
sendTCP(address, valuesForKeys);
}
public void UpdateWorkspace(string ws_id)
{
Console.WriteLine("QCLIENT - Workspace needs to be updated: " + ws_id);
Log.Debug("QCLIENT - Workspace needs to be updated: " + ws_id);
}
public void Close()
@@ -1,9 +1,9 @@
//Class used for overall Workspace control (ONLY REPRESENTS ONE WORKSPACE)
//Contains all necessary items to facilitate communication (sending, receiving) to a QLab workspace
//Also contains the local QWorkspace object which stores all the information that is used in displaying
//STILL NEED TO WORK ON PASSWORD PROTECTED WORKSPACES
//TODO: STILL NEED TO WORK ON PASSWORD PROTECTED WORKSPACES
using System;
using System.Diagnostics;
using Serilog;
namespace qController
{
@@ -29,27 +29,28 @@ namespace qController
public void Connect(string workspace_id)
{
Console.WriteLine("QCONTROLLER - Connect Called: " + workspace_id);
Log.Debug($"QCONTROLLER - Connect Called: {workspace_id}");
qWorkspace = new QWorkspace(workspace_id);
qUpdater.Start();
qClient.sendArgsUDP("/workspace/"+workspace_id+"/connect");
qClient.sendArgsUDP("/workspace/"+workspace_id+"/updates", 1);
qClient.sendAndReceiveString("/workspace/"+workspace_id+"/cueLists");
qClient.sendUDP("/workspace/"+workspace_id+"/connect");
}
public void Connect(string workspace_id, string passcode)
{
Log.Debug($"QCONTROLLER - Connect with Passcode Called: {workspace_id}:{passcode}");
qWorkspace = new QWorkspace(workspace_id);
qClient.sendUDP("/workspace/" + workspace_id + "/connect", passcode);
qClient.sendTCP("/workspace/" + workspace_id + "/connect", passcode);
}
public void KickOff()
{
qClient.sendArgsUDP("/workspaces");
qClient.sendUDP("/workspaces");
}
public void Disconnect()
{
qClient.sendStringUDP("/workspace/"+qWorkspace.workspace_id+"/disconnect");
}
public void ConnectWithPass(string pass)
{
qClient.sendArgsUDP("/workspace/" + qWorkspace.workspace_id + "/connect", pass);
qClient.sendUDP("/workspace/"+qWorkspace.workspace_id+"/disconnect");
}
public void Resume()
@@ -58,7 +59,7 @@ namespace qController
//qUpdater = new QUpdater(this);
if(qWorkspace != null)
{
Console.WriteLine("QCONTROLLER - Resuming: " + qWorkspace.workspace_id);
Log.Debug($"QCONTROLLER - Resuming: {qWorkspace.workspace_id}");
}
}
@@ -1,6 +1,6 @@
//Currently unused would like to reimplement eventually
//Currently being done in qConnectionPage.xaml.cs Scan() method
using System;
using Serilog;
using System.Collections.Generic;
using Zeroconf;
@@ -14,9 +14,9 @@ namespace qController
public async void SearchForWorkspaces()
{
Console.WriteLine("QFINDER - Scanning Started");
Log.Debug("QFINDER - Scanning Started");
IReadOnlyList<IZeroconfHost> results = await ZeroconfResolver.ResolveAsync("_qlab._udp.local.");
Console.WriteLine("QFINDER - Scanning Done");
Log.Debug("QFINDER - Scanning Done");
}
}
}
@@ -3,6 +3,8 @@ using SharpOSC;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Collections.Generic;
using Serilog;
namespace qController
{
public class CueEventArgs : EventArgs
@@ -39,6 +41,12 @@ namespace qController
get;
set;
}
public string WorkspaceId
{
get;
set;
}
}
public class WorkspaceInfoArgs : EventArgs
@@ -102,7 +110,7 @@ namespace qController
else if (msg.Address.Contains("playbackPosition"))
ParsePositionUpdateInfo(msg);
else if (msg.Address.Contains("thump"))
Console.WriteLine("QPARSER - Heartbeat Received");
Log.Debug("QPARSER - Heartbeat Received");
else if (msg.Address.Contains("disconnect"))
OnWorkspaceDisconnect();
else if (msg.Address.Contains("connect"))
@@ -113,10 +121,10 @@ namespace qController
ParseQInfo(msg);
else
{
Console.WriteLine("QPARSER - Unkown message type: " + msg.Address);
Log.Debug("QPARSER - Unkown message type: " + msg.Address);
foreach (var item in msg.Arguments)
{
Console.WriteLine(item);
Log.Debug(item.ToString());
}
}
}
@@ -127,7 +135,8 @@ namespace qController
if (msg.Arguments.Count > 0)
{
JToken connectStatus = OSC2JSON(msg);
OnConnectionStatusChanged(connectStatus.ToString());
;
OnConnectionStatusChanged(connectStatus.ToString(), msg.Address.Split('/')[3]);
}
}
@@ -223,10 +232,10 @@ namespace qController
if (PlaybackPositionUpdated != null)
PlaybackPositionUpdated(this, new PlaybackPositionArgs() { PlaybackPosition = id });
}
protected virtual void OnConnectionStatusChanged(string status)
protected virtual void OnConnectionStatusChanged(string status, string workspace_id)
{
if (ConnectionStatusChanged != null)
ConnectionStatusChanged(this, new ConnectEventArgs() { Status = status });
ConnectionStatusChanged(this, new ConnectEventArgs() { Status = status, WorkspaceId = workspace_id });
}
protected virtual void OnChildrenUpdated(string id, List<QCue> cues)
{
@@ -1,6 +1,7 @@
//Class used for receiving workspace update messages (UDP)
using SharpOSC;
using System.Threading;
using Serilog;
namespace qController
{
@@ -31,7 +32,7 @@ namespace qController
if (messageReceived != null)
OnUpdateMessageReceived(messageReceived);
else
Console.WriteLine("Message came back null");
Log.Debug("Message came back null");
};
udpListener = new UDPListener(Port, callback);
@@ -1,7 +1,9 @@
//Class used for updating local "copy" of workspace info, cue-lists, cues, etc.
using System;
using System.Threading;
using Serilog;
using Xamarin.Forms;
using Serilog;
namespace qController
{
@@ -10,7 +12,8 @@ namespace qController
private bool active = true;
private QController qController;
private Thread updateThread;
private Thread updateThread;
public QUpdater(QController controller)
{
qController = controller;
@@ -19,19 +22,31 @@ namespace qController
qController.qClient.qParser.WorkspaceUpdated += OnWorkspaceUpdated;
qController.qClient.qParser.PlaybackPositionUpdated += OnPlaybackPositionUpdated;
qController.qClient.qParser.WorkspaceLoadError += OnWorkspaceLoadError;
qController.qClient.qParser.ConnectionStatusChanged += OnConnectionStatusChanged;
}
private void OnConnectionStatusChanged(object source, ConnectEventArgs args)
{
Log.Debug("QUPDATER - Connection Status Changed: " + args.Status);
if (args.Status == "ok")
{
qController.qClient.sendTCP("/workspace/" + qController.qWorkspace.workspace_id + "/updates", 1);
qController.qClient.sendTCP("/workspace/" + qController.qWorkspace.workspace_id + "/cueLists");
}
}
private void OnWorkspaceLoadError(object source, WorkspaceEventArgs args)
{
Console.WriteLine("QUPDATER - Loading cuelists has failed for some reason retrying");
qController.qClient.sendArgsUDP("/workspace/" + args.UpdatedWorkspace.workspace_id + "/connect");
qController.qClient.sendArgsUDP("/workspace/" + args.UpdatedWorkspace.workspace_id + "/updates", 1);
qController.qClient.sendAndReceiveString("/workspace/" + args.UpdatedWorkspace.workspace_id + "/cueLists");
Log.Debug("QUPDATER - Loading cuelists has failed for some reason retrying");
//qController.qClient.sendArgsUDP("/workspace/" + args.UpdatedWorkspace.workspace_id + "/connect");
//qController.qClient.sendArgsUDP("/workspace/" + args.UpdatedWorkspace.workspace_id + "/updates", 1);
//qController.qClient.sendTCP("/workspace/" + args.UpdatedWorkspace.workspace_id + "/cueLists");
}
public void Start(){
Log.Debug("QUPDATER - Start() method called");
updateThread.Start();
}
@@ -51,8 +66,8 @@ namespace qController
if (args.Cue.type == "Group")
{
//Console.WriteLine("QUpdater/Updated cue was group cue, sending children request");
qController.qClient.sendStringUDP("/workspace/"+qController.qWorkspace.workspace_id+"/cue_id/" + args.Cue.uniqueID + "/children");
//Log.Debug("QUpdater/Updated cue was group cue, sending children request");
qController.qClient.sendUDP("/workspace/"+qController.qWorkspace.workspace_id+"/cue_id/" + args.Cue.uniqueID + "/children");
}
}
@@ -63,7 +78,7 @@ namespace qController
qController.qWorkspace.CheckPopulated();
if (qController.qWorkspace.IsPopulated)
{
Console.WriteLine("QUPDATER - Workspace group cues are already populated");
Log.Debug("QUPDATER - Workspace group cues are already populated");
App.showToast("Workspace cues have been loaded....");
//get selected cue
qController.qClient.UpdateSelectedCue(qController.qWorkspace.workspace_id);
@@ -74,14 +89,14 @@ namespace qController
public void OnPlaybackPositionUpdated(object source, PlaybackPositionArgs args)
{
qController.playbackPosition = args.PlaybackPosition;
Console.WriteLine("QUPDATER - Update Specific Cue Called because of Playback Position Updated");
Log.Debug("QUPDATER - Update Specific Cue Called because of Playback Position Updated");
qController.qClient.UpdateSpecificCue(qController.qWorkspace.workspace_id,args.PlaybackPosition);
}
public void SendThump()
{
qController.qClient.sendStringUDP("/workspace/" + qController.qWorkspace.workspace_id + "/thump");
qController.qClient.sendUDP("/workspace/" + qController.qWorkspace.workspace_id + "/thump");
}
public void Kill(){
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Serilog;
namespace SharpOSC
{
@@ -27,8 +27,8 @@ namespace SharpOSC
private static OscMessage parseMessage(byte[] msg)
{
int index = 0;
//Console.WriteLine("Raw ASCII DATA: " + System.Text.Encoding.ASCII.GetString(msg));
//Console.WriteLine("Raw UTF-8 DATA: " + System.Text.Encoding.UTF8.GetString(msg));
//Log.Debug("Raw ASCII DATA: " + System.Text.Encoding.ASCII.GetString(msg));
//Log.Debug("Raw UTF-8 DATA: " + System.Text.Encoding.UTF8.GetString(msg));
string address = null;
char[] types = new char[0];
List<object> arguments = new List<object>();
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using Serilog;
namespace SharpOSC
{
@@ -46,20 +47,40 @@ namespace SharpOSC
_address = address;
}
public void Send(byte[] message)
public void Connect()
{
client = new TcpClient(Address, Port);
Log.Debug($"TCPSender - connect called for <{Address}:{Port}>");
Thread receivingThread = new Thread(ReceiveLoop);
receivingThread.Start();
}
public void Send(byte[] message)
{
byte[] slipData = SlipEncode(message);
NetworkStream netStream = client.GetStream();
netStream.Write(slipData.ToArray(), 0, slipData.ToArray().Length);
}
public async void Receive()
public void Send(OscPacket packet)
{
byte[] data = packet.GetBytes();
Send(data);
}
public void ReceiveLoop()
{
while (client.Connected)
{
Receive();
}
Log.Debug("TCPSender - Receive Loop has exited for some reason");
}
public void Receive()
{
Random random = new Random();
int num = random.Next(1000);
OscMessage response = new OscMessage("/null");
NetworkStream netStream = client.GetStream();
try
{
@@ -67,49 +88,25 @@ namespace SharpOSC
List<byte> responseData = new List<byte>();
if (netStream.CanRead)
{
byte[] buffer = new byte[1024];
byte[] buffer = new byte[256];
int bytesRead = 0;
do
{
bytesRead = await netStream.ReadAsync(buffer, 0, buffer.Length);
bytesRead = netStream.Read(buffer, 0, buffer.Length);
responseData.AddRange(buffer);
Thread.Sleep(1);
//Console.WriteLine( "Thread " + num + ": Bytes read: " + bytesRead + " - " + Encoding.UTF8.GetString(buffer));
Thread.Sleep(30);
//Log.Debug("Thread " + num + ": Bytes read: " + bytesRead + " - " + Encoding.UTF8.GetString(buffer));
} while (netStream.DataAvailable);
//Console.WriteLine("Raw TCP In: " + System.Text.Encoding.UTF8.GetString(responseData.ToArray()));
response = (OscMessage)OscPacket.GetPacket(responseData.Skip(1).ToArray());
//Log.Debug("Raw TCP In: " + System.Text.Encoding.UTF8.GetString(responseData.ToArray()));
OscMessage response = (OscMessage)OscPacket.GetPacket(responseData.Skip(1).ToArray());
OnMessageReceived(response);
}
} catch(Exception e)
{
Console.WriteLine("TCPSENDER - Receive Exception: " + e.ToString());
//Log.Debug("TCPSENDER - Receive Exception: " + e.ToString());
}
OnMessageReceived(response);
}
public void SendAndReceive(byte[] message)
{
client = new TcpClient(Address, Port);
byte[] slipData = SlipEncode(message);
NetworkStream netStream = client.GetStream();
netStream.Write(slipData.ToArray(), 0, slipData.ToArray().Length);
Receive();
}
public void SendAndReceive(OscPacket packet)
{
OscMessage msg = (OscMessage)packet;
//Console.WriteLine("TCPSENDER - TCP Message Sent: " + msg.Address);
byte[] data = packet.GetBytes();
SendAndReceive(data);
}
public void Send(OscPacket packet)
{
byte[] data = packet.GetBytes();
Send(data);
}
public byte[] SlipEncode(byte[] data)
@@ -4,6 +4,7 @@ using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using Serilog;
namespace SharpOSC
{
@@ -96,10 +97,10 @@ namespace SharpOSC
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Log.Debug(e.ToString());
// If there is an error reading the packet, null is sent to the callback
}
//Console.WriteLine("Raw UDP In: " + System.Text.Encoding.ASCII.GetString(bytes));
//Log.Debug("Raw UDP In: " + System.Text.Encoding.ASCII.GetString(bytes));
OscPacketCallback(packet);
}
else
@@ -150,7 +151,7 @@ namespace SharpOSC
{
byte[] bytes = queue.Dequeue();
var packet = OscPacket.GetPacket(bytes);
//Console.WriteLine("Raw UDP In: " + System.Text.Encoding.ASCII.GetString(bytes));
//Log.Debug("Raw UDP In: " + System.Text.Encoding.ASCII.GetString(bytes));
return packet;
}
else
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using Serilog;
namespace qController
{
@@ -54,7 +55,7 @@ namespace qController
{
if(data[i].cues[j].uniqueID == cue.uniqueID)
{
//Console.WriteLine("Cue found and updated in workspace: " + cue.uniqueID);
//Log.Debug("Cue found and updated in workspace: " + cue.uniqueID);
data[i].cues[j] = cue;
return;
}
@@ -101,7 +102,7 @@ namespace qController
{
foreach (var cueList in data)
{
Console.WriteLine(cueList.listName + "("+ cueList.cues.Count + " cues)");
Log.Debug(cueList.listName + "("+ cueList.cues.Count + " cues)");
}
}
}
@@ -1,4 +1,4 @@
using System;
using Serilog;
using System.Collections.ObjectModel;
using Acr.Settings;
@@ -13,7 +13,7 @@ namespace qController
if (qInstances == null)
{
Console.WriteLine("QSTORAGE - No qInstance exists creating one");
Log.Debug("QSTORAGE - No qInstance exists creating one");
qInstances = new ObservableCollection<QInstance>();
updateStorage();
}
@@ -54,7 +54,7 @@ namespace qController
public static bool Contains(string name, string address){
foreach (var item in qInstances)
{
//Console.WriteLine("Item name: " + item.name + " Found Name: " + name);
//Log.Debug("Item name: " + item.name + " Found Name: " + name);
if (item.address == address)
{
return true;
-2
View File
@@ -1,7 +1,6 @@
using Acr.UserDialogs;
using Xamarin.Forms;
using Xamarin.Essentials;
using System;
namespace qController
{
public partial class App : Application
@@ -31,7 +30,6 @@ namespace qController
public App()
{
InitializeComponent();
/*MainPage = new NavigationPage(new QConnectionPage());
iNav = MainPage.Navigation;*/
+60 -41
View File
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using System.Collections;
using Serilog;
using Acr.UserDialogs;
namespace qController
{
@@ -13,6 +13,7 @@ namespace qController
QCueListCell qCueListCell;
ShadowButton showLevelsButton;
QControlsBlock qControlsBlock;
public ControlPage(string name, string address)
{
InitializeComponent();
@@ -22,6 +23,7 @@ namespace qController
qController.qClient.qParser.WorkspaceUpdated += WorkspaceUpdated;
qController.qClient.qParser.WorkspaceDisconnect += WorkspaceDisconnected;
qController.qClient.qParser.PlaybackPositionUpdated += PlaybackPositionUpdated;
qController.qClient.qParser.ConnectionStatusChanged += OnConnectionStatusChanged;
qController.qClient.qParser.CueInfoUpdated += OnCueUpdateReceived;
qController.qClient.qParser.ChildrenUpdated += OnChildrenUpdated;
@@ -34,37 +36,43 @@ namespace qController
qController.KickOff();
}
private void OnConnectionStatusChanged(object source, ConnectEventArgs args)
{
Log.Debug($"CONTROLPAGE - Connection Status Changed: {args.WorkspaceId} : {args.Status}");
if (args.Status.Equals("ok"))
{
qController.qUpdater.Start();
Device.BeginInvokeOnMainThread(() => {
FinishUI();
});
}
else if (args.Status.Equals("badpass"))
{
promptWorkspacePasscode(args.WorkspaceId);
}
}
private void WorkspaceInfoReceived(object source, WorkspaceInfoArgs args)
{
if(args.WorkspaceInfo.Count > 1)
{
Console.WriteLine("CONTROLPAGE - MULTIPLE WORKSPACES ON SELECTED COMPUTER");
Log.Debug("CONTROLPAGE - MULTIPLE WORKSPACES ON SELECTED COMPUTER");
PromptForWorkspace(args.WorkspaceInfo);
}
else if (args.WorkspaceInfo.Count == 1)
{
Console.WriteLine("CONTROLPAGE - ONLY ONE WORKSPACE ON SELECTED COMPUTER");
Log.Debug("CONTROLPAGE - ONLY ONE WORKSPACE ON SELECTED COMPUTER");
if (!args.WorkspaceInfo[0].hasPasscode)
{
qController.Connect(args.WorkspaceInfo[0].uniqueID);
Device.BeginInvokeOnMainThread(() => {
FinishUI();
});
}
else
{
UserDialogs.Instance.Confirm(new ConfirmConfig
{
Message = "Woops....I haven't implemented password protected workspaces yet...",
OkText = "Disconnect",
OnAction = (resp) =>
{
if (resp)
Back();
}
});
promptWorkspacePasscode(args.WorkspaceInfo[0].uniqueID);
}
}
else
{
@@ -89,27 +97,14 @@ namespace qController
{
QWorkspaceInfo workspace = workspaces[i];
config.Add(workspace.displayName, new Action(() => {
Console.WriteLine("CONTROLPAGE - Workspace Selected " + workspace.displayName);
Log.Debug("CONTROLPAGE - Workspace Selected " + workspace.displayName);
if (!workspace.hasPasscode)
{
qController.Connect(workspace.uniqueID);
Device.BeginInvokeOnMainThread(() =>
{
FinishUI();
});
}
else
{
UserDialogs.Instance.Confirm(new ConfirmConfig
{
Message = "Woops....I haven't implemented password protected workspaces yet...",
OkText = "Disconnect",
OnAction = (resp) =>
{
if (resp)
Back();
}
});
promptWorkspacePasscode(workspace.uniqueID);
}
}));
@@ -158,7 +153,7 @@ namespace qController
private void OnSelectedCueEdited(object source, CueEditArgs args)
{
string address = "/workspace/" + qController.qWorkspace.workspace_id + "/cue_id/" + args.CueID + "/" + args.Property;
qController.qClient.sendArgsUDP(address, args.NewValue);
qController.qClient.sendUDP(address, args.NewValue);
}
void FinishUI()
@@ -169,15 +164,15 @@ namespace qController
qLevelsCell.mainSlider.ValueChanged += (sender, args) =>
{
qController.qClient.sendArgs(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/0", (float)args.NewValue);
qController.qClient.sendUDP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/0", (float)args.NewValue);
};
qLevelsCell.leftSlider.ValueChanged += (sender, args) =>
{
qController.qClient.sendArgs(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/1", (float)args.NewValue);
qController.qClient.sendUDP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/1", (float)args.NewValue);
};
qLevelsCell.rightSlider.ValueChanged += (sender, args) =>
{
qController.qClient.sendArgs(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/2", (float)args.NewValue);
qController.qClient.sendUDP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/2", (float)args.NewValue);
};
Button showLevelsInnerButton = new Button
@@ -269,10 +264,10 @@ namespace qController
noSelect.number = "!";
qCell.UpdateSelectedCue(noSelect);
});
Console.WriteLine("CONTROLPAGE - Update Selected Cue Called because of Inital Workspace Load");
Log.Debug("CONTROLPAGE - Update Selected Cue Called because of Inital Workspace Load");
qController.qClient.UpdateSelectedCue(qController.qWorkspace.workspace_id);
}
Console.WriteLine("CONTROLPAGE - Workspace Updated " + qController.qWorkspace.workspace_id);
Log.Debug("CONTROLPAGE - Workspace Updated " + qController.qWorkspace.workspace_id);
}
}
}
@@ -280,7 +275,7 @@ namespace qController
public void PlaybackPositionUpdated(object sender, PlaybackPositionArgs e)
{
qController.playbackPosition = e.PlaybackPosition;
Console.WriteLine("CONTROLPAGE - Playback Position Updated " + qController.playbackPosition);
Log.Debug("CONTROLPAGE - Playback Position Updated " + qController.playbackPosition);
QCue cue = qController.qWorkspace.GetCue(qController.playbackPosition);
if(cue != null)
{
@@ -313,7 +308,7 @@ namespace qController
{
Device.BeginInvokeOnMainThread(() =>
{
Console.WriteLine("CONTROLPAGE - Refreshing Currently Displayed Cue");
Log.Debug("CONTROLPAGE - Refreshing Currently Displayed Cue");
if (args.Cue.levels != null)
showLevelsButton.IsVisible = true;
else
@@ -352,7 +347,7 @@ namespace qController
{
if (args.Command.Contains("/"))
{
qController.qClient.sendStringUDP(args.Command);
qController.qClient.sendUDP(args.Command);
}
else if (args.Command == "disconnect")
{
@@ -375,6 +370,30 @@ namespace qController
}
}
private void promptWorkspacePasscode(string workspace_id)
{
UserDialogs.Instance.Prompt(new PromptConfig
{
InputType = InputType.Number,
MaxLength = 4,
Title = "Enter Workspace Passcode",
OkText = "Connect",
IsCancellable = true,
OnAction = (resp) =>
{
if (resp.Ok)
{
qController.Connect(workspace_id, resp.Value);
}
else
{
Back();
}
}
});
}
private void CloseCueList(object sender, EventArgs e)
{
CloseCueList();
@@ -392,7 +411,7 @@ namespace qController
{
OSCListItem cue = (OSCListItem)e.SelectedItem;
string selectCueOSC = "/workspace/" + qController.qWorkspace.workspace_id + cue.Command;
qController.qClient.sendStringUDP(selectCueOSC);
qController.qClient.sendUDP(selectCueOSC);
CloseCueList();
}
@@ -3,6 +3,7 @@ using System;
using Acr.UserDialogs;
using Zeroconf;
using System.Collections.Generic;
using Serilog;
namespace qController
{
@@ -122,7 +123,7 @@ namespace qController
async void Scan(){
bool workspacesFound = false;
App.showToast("Scanning for Instances...");
Console.WriteLine("QCONNECTIONPAGE - Begin Scanning");
Log.Debug("QCONNECTIONPAGE - Begin Scanning");
IReadOnlyList<IZeroconfHost> results = await ZeroconfResolver.ResolveAsync("_qlab._udp.local.",TimeSpan.FromSeconds(3));
if(results != null){
@@ -132,7 +133,7 @@ namespace qController
{
QInstance instance = new QInstance(result.DisplayName, result.IPAddress);
if(QStorage.AddInstance(instance)){
Console.WriteLine($"QCONNECTIONPAGE - {result.DisplayName} @ {result.IPAddress} added");
Log.Debug($"QCONNECTIONPAGE - {result.DisplayName} @ {result.IPAddress} added");
workspacesFound = true;
}
}
+1
View File
@@ -59,6 +59,7 @@
<PackageReference Include="Acr.Settings" Version="9.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Xamarin.Essentials" Version="1.2.0" />
<PackageReference Include="Serilog" Version="2.9.0" />
</ItemGroup>
<ItemGroup>
<None Remove="App.xaml" />