From be4681134835a8925a4cbcc288d44cb09a07c182 Mon Sep 17 00:00:00 2001 From: Tom Isaacson Date: Sun, 26 May 2013 22:43:42 +1200 Subject: [PATCH] First drop of code --- GoFreeWebSocketTest/WebSocketTest.sln | 45 + GoFreeWebSocketTest/WebSocketTest/GoFree.cs | 969 ++++++++++++++++++ .../WebSocketTest/NavicoDiscovery.cs | 240 +++++ GoFreeWebSocketTest/WebSocketTest/Program.cs | 702 +++++++++++++ .../WebSocketTest/Properties/AssemblyInfo.cs | 36 + .../WebSocketTest/WebSocketTest.csproj | 116 +++ GoFreeWebSocketTest/WebSocketTest/app.config | 3 + 7 files changed, 2111 insertions(+) create mode 100644 GoFreeWebSocketTest/WebSocketTest.sln create mode 100644 GoFreeWebSocketTest/WebSocketTest/GoFree.cs create mode 100644 GoFreeWebSocketTest/WebSocketTest/NavicoDiscovery.cs create mode 100644 GoFreeWebSocketTest/WebSocketTest/Program.cs create mode 100644 GoFreeWebSocketTest/WebSocketTest/Properties/AssemblyInfo.cs create mode 100644 GoFreeWebSocketTest/WebSocketTest/WebSocketTest.csproj create mode 100644 GoFreeWebSocketTest/WebSocketTest/app.config diff --git a/GoFreeWebSocketTest/WebSocketTest.sln b/GoFreeWebSocketTest/WebSocketTest.sln new file mode 100644 index 0000000..929aac8 --- /dev/null +++ b/GoFreeWebSocketTest/WebSocketTest.sln @@ -0,0 +1,45 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebSocketTest", "WebSocketTest\WebSocketTest.csproj", "{3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}" + ProjectSection(ProjectDependencies) = postProject + {B357BAC7-529E-4D81-A0D2-71041B19C8DE} = {B357BAC7-529E-4D81-A0D2-71041B19C8DE} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "websocket-sharp", "..\websocket-sharp\websocket-sharp\websocket-sharp.csproj", "{B357BAC7-529E-4D81-A0D2-71041B19C8DE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Debug|Any CPU.ActiveCfg = Debug|x86 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Debug|x86.ActiveCfg = Debug|x86 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Debug|x86.Build.0 = Debug|x86 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Release|Any CPU.ActiveCfg = Release|x86 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Release|Mixed Platforms.Build.0 = Release|x86 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Release|x86.ActiveCfg = Release|x86 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF}.Release|x86.Build.0 = Release|x86 + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|x86.ActiveCfg = Debug|Any CPU + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release|Any CPU.Build.0 = Release|Any CPU + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release|x86.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/GoFreeWebSocketTest/WebSocketTest/GoFree.cs b/GoFreeWebSocketTest/WebSocketTest/GoFree.cs new file mode 100644 index 0000000..678355e --- /dev/null +++ b/GoFreeWebSocketTest/WebSocketTest/GoFree.cs @@ -0,0 +1,969 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using WebSocketSharp; +using WebSocketSharp.Frame; + +namespace Navico +{ + enum eDataGroup + { + GPS = 1, + Navigation = 2, + Vessel = 3, + Sonar = 4, + Weather = 5, + Trip = 6, + Time = 7, + Engine = 8, + Transmission = 9, + FuelTank = 10, + FreshWaterTank = 11, + GrayWaterTank = 12, + LiveWellTank = 13, + OilTank = 14, + BlackWaterTank = 15, + EngineRoom = 16, + Cabin = 17, + BaitWell = 18, + Refrigerator = 19, + HeatingSystem = 20, + Freezer = 21, + Battery = 22, + Rudder = 23, + TrimTab = 24, + ACInput = 25, + DigitalSwitching = 26, + Other = 27, + GPSStatus = 28, + RouteData = 29, + SpeedDepth = 30, + LogTimer = 31, + Environment = 32, + Wind = 33, + Pilot = 34, + Sailing = 35, + AcOutput = 36, + Charger = 37, + Inverter = 38, + + Count = 39, + AllData = 40, + Invalid = 255 + }; + + enum eDataType + { + Altitude = 1, + PositionError = 3, + Hdop = 4, + Vdop = 5, + Tdop = 6, + Pdop = 7, + GeoidalSeperation = 8, + Cog = 9, + PositionQuality = 10, + PositionIntegrity = 11, + SatsInView = 12, + WaasStatus = 13, + Bearing = 14, + Course = 15, + CourseToSteer = 17, + CrossTrack = 18, + VelocityMadeGood = 19, + Destination = 20, + DistanceToTurn = 21, + DistanceToDest = 22, + TimeToTurn = 23, + TimeToDest = 24, + EtaAtTurn = 25, + EtaAtDest = 26, + TotalDistance = 27, + SteerArrow = 28, + Odometer = 29, + TripDistance = 30, + TripTime = 31, + Date = 32, + Time = 33, + UtcDate = 34, + UtcTime = 35, + LocalTimeOffset = 36, + Heading = 37, + Voltage = 38, + CurrentSet = 39, + CurrentDrift = 40, + SpeedSog = 41, + SpeedWater = 42, + SpeedPitot = 43, + SpeedTripAvg = 44, + SpeedTripMax = 45, + SpeedWindApp = 46, + SpeedWindTrue = 47, + TempWater = 48, + TempOutside = 49, + TempInside = 50, + TempEngineRoom = 51, + TempMainCabin = 52, + TempLiveWell = 53, + TempBaitWell = 54, + TempRefrigeration = 55, + TempHeatingSystem = 56, + TempDewPoint = 57, + TempWindChillApp = 58, + TempWindChillTheoretic = 59, + TempHeatIndex = 60, + TempFreezer = 61, + EngineTemp = 62, + EngineAirTemp = 63, + EngineOilTemp = 64, + TempBattery = 65, + PressureAtmospheric = 66, + EngineBoostPres = 67, + EngineOilPres = 68, + EngineWaterPres = 69, + EngineFuelPres = 70, + EngineManifoldPres = 71, + PressureSteam = 72, + PressureComprAir = 73, + PressureHydraulic = 74, + Depth = 77, + WaterDistance = 78, + EngineRpm = 79, + EngineTrim = 80, + EngineAlternatorPotential = 81, + EngineFuelRate = 82, + EnginePercentLoad = 83, + EnginePercentTorque = 84, + SuzukiAlarmLevLo = 85, + SuzukiAlarmLevHigh = 86, + TankFuelLevel = 87, + FluidLevelFreshWater = 88, + FluidLevelGrayWater = 89, + FluidLevelLiveWell = 90, + FluidLevelOil = 91, + FluidLevelBlackWater = 92, + TankFuelRemaining = 93, + FluidVolumeFreshWater = 94, + FluidVolumeGrayWater = 95, + FluidVolumeLiveWell = 96, + FluidVolumeOil = 97, + FluidVolumeBlackWater = 98, + GenFluidVolume = 99, + GenTankCapacity = 105, + TankFuelCapacity = 106, + TankCapacityFreshWater = 107, + TankCapacityGrayWater = 108, + TankCapacityLiveWell = 109, + TankCapacityOil = 110, + TankCapacityBlackWater = 111, + TankFuelUsed = 112, + EngineFuelUsed = 113, + EngineFuelUsedTrip = 114, + EngineFuelUsedSeasonal = 115, + EngineFuelKValue = 116, + BatteryPotential = 117, + BatteryCurrent = 118, + TrimTab = 119, + RateOfTurn = 121, + AttitudeYaw = 122, + AttitudePitch = 123, + AttitudeRoll = 124, + MagneticVariation = 125, + Deviation = 126, + FuelEconomyWtr = 127, + FuelEconomyGps = 128, + FuelRangeWtr = 130, + FuelRangeGps = 131, + EngineHoursUsed = 132, + EngineType = 133, + VesselFuelRate = 134, + VesselFuelEconomyWtr = 135, + VesselFuelEconomyGps = 136, + VesselFuelRemaining = 137, + VesselFuelRangeWtr = 138, + VesselFuelRangeGps = 139, + WindAppDirection = 140, + WindTrueAngle = 141, + WindTrueDirection = 142, + HumidityInside = 143, + HumidityOutside = 144, + SetHumidity = 145, + RudderAngle = 146, + TransGear = 147, + TransOilPressure = 148, + TransOilTemp = 149, + CmdRudderAngle = 150, + RudderLimit = 151, + OffHeadingLim = 152, + RadiusOfTurnOrder = 153, + RateOfTurnOrder = 154, + OffTrackLim = 155, + LoggingTimeRemaining = 156, + PositionFixType = 157, + EngineDiscreteStatus = 158, + TransmissionDiscreteStatus = 159, + GpsBestOfFourSnr = 160, + GenFluidLevel = 161, + GenPressure = 162, + GenTemperature = 163, + InternalVoltage = 164, + StructureDepth = 166, + LoranPosition = 167, + VesselStatus = 168, + BatteryDcType = 169, + BatteryStateOfCharge = 170, + BatteryStateOfHealth = 171, + BatteryTimeRemaining = 172, + BatteryRippleVoltage = 173, + Ac1Acceptability = 174, + Ac2Acceptability = 175, + Ac3Acceptability = 176, + Ac1Voltage = 177, + Ac2Voltage = 178, + Ac3Voltage = 179, + Ac1Current = 180, + Ac2Current = 181, + Ac3Current = 182, + Ac1Frequency = 183, + Ac2Frequency = 184, + Ac3Frequency = 185, + Ac1BreakerSize = 186, + Ac2BreakerSize = 187, + Ac3BreakerSize = 188, + Ac1RealPower = 189, + Ac2RealPower = 190, + Ac3RealPower = 191, + Ac1ReactivePower = 192, + Ac2ReactivePower = 193, + Ac3ReactivePower = 194, + Ac1PowerFactor = 195, + Ac2PowerFactor = 196, + Ac3PowerFactor = 197, + SwitchState = 198, + SwitchCurrent = 199, + SwitchFault = 200, + SwitchDimLevel = 201, + PreviousCmdHeading = 202, + CmdWindAngle = 203, + CmdBearingOffset = 204, + CmdBearing = 205, + CmdDepthContour = 206, + CmdCourseChange = 207, + PilotDrift = 208, + PilotDistanceToTurn = 209, + PilotTimeToTurn = 210, + PilotReferencePosition = 211, + DcStatus = 212, + AcStatus = 213, + SwitchVoltage = 214, + BatteryCapacityRemaining = 215, + H3000Linear1 = 217, + H3000Linear2 = 218, + H3000Linear3 = 219, + BoomPosition = 220, + SailingCourse = 221, + DaggerboardPosition = 222, + H3000Linear4 = 223, + HeadingOnNextTack = 224, + KeelAngle = 225, + Leeway = 226, + MastAngle = 227, + TargetTrueWindAngle = 228, + KeelTrimTab = 229, + RaceTimer = 230, + CanardAngle = 231, + NextLegApparentWindAngle = 232, + NextLegApparentWindSpeed = 233, + TargetBoatSpeed = 234, + VmgToWind = 235, + TimeToLaylines = 236, + DistanceToLaylines = 237, + AftDepth = 238, + ForeStay = 239, + PolarSpeed = 240, + PolarPerformance = 241, + TackingPerformance = 242, + WindAngleToMast = 243, + CanBusVoltage = 244, + InternalTemperature = 245, + EngageCurrent = 246, + UrefVoltage = 247, + SupplyVoltage = 248, + DestinationPosition = 249, + EngineSyncState = 252, + EngineGeneralMaintenance = 253, + EnginePercentThrottle = 254, + EngineSteeringAngle = 255, + EngineBreakInReqd = 256, + EngineBreakInAccum = 258, + EngineTrimStatus = 259, + PilotPresent = 260, + Ac1OutWaveform = 261, + Ac2OutWaveform = 262, + Ac3OutWaveform = 263, + Ac1OutVoltage = 264, + Ac2OutVoltage = 265, + Ac3OutVoltage = 266, + Ac1OutCurrent = 267, + Ac2OutCurrent = 268, + Ac3OutCurrent = 269, + Ac1OutFrequency = 270, + Ac2OutFrequency = 271, + Ac3OutFrequency = 272, + Ac1OutBreakerSize = 273, + Ac2OutBreakerSize = 274, + Ac3OutBreakerSize = 275, + Ac1OutRealPower = 276, + Ac2OutRealPower = 277, + Ac3OutRealPower = 278, + Ac1OutReactivePower = 279, + Ac2OutReactivePower = 280, + Ac3OutReactivePower = 281, + Ac1OutPowerFactor = 282, + Ac2OutPowerFactor = 283, + Ac3OutPowerFactor = 284, + Ac2Status = 285, + Ac3Status = 286, + Ac1OutStatus = 287, + Ac2OutStatus = 288, + Ac3OutStatus = 289, + SwitchManualOverride = 290, + SwitchReversePolarity = 291, + SwitchAcsourceAvailable = 292, + SwitchAccontactorSystemsonstate = 293, + ChargerBatteryInstance = 294, + ChargerOperatingState = 295, + ChargerMode = 296, + ChargerEnabled = 297, + ChargerEqualizationPending = 298, + ChargerEqualizationTimeRemaining = 299, + InverterAcInstance = 300, + InverterDcInstance = 301, + InverterOperatingState = 302, + InverterEnabled = 303, + SailingTimeToWaypoint = 304, + SailingDistanceToWaypoint = 305, + SailingETA = 306, + Latitude = 309, + Longitude = 310, + }; + +/* + enum eInstanceLocation // TODO A: update this to match the enum in NOS + { + locPORT = 0, + locPORT_CENTER = 1, + locCENTER_PORT = 2, + locCENTER = 3, + locCENTER_STARBOARD = 4, + locSTARBOARD_CENTER = 5, + locSTARBOARD = 6, + locPRIMARY = 7, + locOTHER = 8, + + NUM_LOCATIONS + }; +*/ + + enum eSettingTypes + { + Enumeration = 1, + Boolean = 2, + Number = 3, + }; + + enum eSettingGroups + { + Display = 1, + Units = 2, + Alarms = 3, + TripLog = 4, + }; + + enum eSettingIDs + { + BacklightLevel = 1, + NightMode = 2, + TripLog1 = 3, + TripLog2 = 4, +// DistanceUnits = 5, + // TODO A: Populate the rest of this + }; + + enum eEvents + { + AlarmActivate = 1, + AlarmDeactivate = 2, + AlarmAcknowledge = 3, + AlarmSilence = 4, + MOB = 5, + WaypointCreate = 6, + TripLogReset = 7, + ZoomIn = 8, + ZoomOut = 9, + }; + + enum eVesselTypes + { + AIS = 1, + }; + + enum eVesselStatus + { + Dangerous = 1, + Safe = 2, + Acquiring = 3, + AcquiringFailed = 4, + OutOfRange = 5, + LostOutOfRange = 6, + }; + + public class Root + { +// public string key { get; set; } + } + + public class DataList + { + public int groupId { get; set; } + public List list { get; set; } + } + + public class RootDataList : Root + { + public DataList DataList { get; set; } + } + + public class InstanceInfo + { + public int inst { get; set; } + public int location { get; set; } + public string str { get; set; } + } + + public class DataInfo + { + public int id { get; set; } + public string sname { get; set; } + public string lname { get; set; } + public string unit { get; set; } + public double min { get; set; } + public double max { get; set; } + public int numInstances { get; set; } + public List instanceInfo { get; set; } + } + + public class RootDataInfo : Root + { + public List DataInfo { get; set; } + } + + public class Data + { + public int id { get; set; } + public double val { get; set; } + public string valStr { get; set; } + public double sysVal { get; set; } + public int inst { get; set; } + public bool valid { get; set; } + } + + public class RootData : Root + { + public List Data { get; set; } + } + + public class SettingList + { + public int groupId { get; set; } + public List list { get; set; } + } + + public class RootSettingList : Root + { + public SettingList SettingList { get; set; } + } + + public class Value + { + public int id { get; set; } + public string title { get; set; } + } + + public class SettingInfo + { + public int id { get; set; } + public string name { get; set; } + public int type { get; set; } + public List values { get; set; } + public double low { get; set; } + public double high { get; set; } + public double step { get; set; } + } + + public class RootSettingInfo : Root + { + public List SettingInfo { get; set; } + } + + public class Setting + { + public int id { get; set; } + public bool value { get; set; } + } + + public class RootSetting : Root + { + public List Setting { get; set; } + } + + public class TrafficReq + { + public bool subscribe { get; set; } + public int id { get; set; } + public int sourceType { get; set; } + } + + public class RootTrafficReq + { + public TrafficReq TrafficReq { get; set; } + } + + public class RootTrafficReg + { + public List TrafficReg { get; set; } + } + + public class RootTrafficUnreg + { + public List TrafficUnreg { get; set; } + } + + public class Dimensions + { + public double bow { get; set; } + public double stern { get; set; } + public double port { get; set; } + public double stbd { get; set; } + } + + public class Traffic + { + public string type { get; set; } + public int id { get; set; } + public string name { get; set; } + public bool lost { get; set; } + public double distance { get; set; } + public double lat { get; set; } + public double lon { get; set; } + public double trueBearing { get; set; } + public double cpa { get; set; } + public int tcpa { get; set; } + public double sog { get; set; } + public double cog { get; set; } + public double relativeSog { get; set; } + public double relativeCog { get; set; } + public string status { get; set; } + public string eta { get; set; } + public double draught { get; set; } + public string destination { get; set; } + public bool isAton { get; set; } + public int atonType { get; set; } + public Dimensions dimensions { get; set; } + public bool offPosition { get; set; } + + public bool accuratePosition { get; set; } + public int aisClass { get; set; } + public string callsign { get; set; } + public int imo { get; set; } + public int sourceType { get; set; } + public double trueHeading { get; set; } + } + + public class RootTraffic : Root + { + public List Traffic { get; set; } + } + + public class TrafficRemoved + { + public int sourceType { get; set; } + public int id { get; set; } + } + + public class RootTrafficRemoved + { + public List TrafficRemoved { get; set; } + } + +/* + public struct QueueMessage + { + public string Summary; + public var Class; + } +*/ + + public class DataListReq + { + public int group { get; set; } + } + + public class RootDataListReq + { + public DataListReq DataListReq { get; set; } + } + + public class RootDataInfoReq + { + public List DataInfoReq { get; set; } + } + + public class DataReq + { + public int id { get; set; } + public bool repeat { get; set; } + public int inst { get; set; } + } + + public class RootDataReq + { + public List DataReq { get; set; } + } + + public class UnsubscribeData + { + public int id { get; set; } + public int inst { get; set; } + } + + public class RootUnsubscribeData + { + public List UnsubscribeData { get; set; } + } + + public class SettingListReq + { + public int groupId { get; set; } + } + + public class RootSettingListReq + { + public List SettingListReq { get; set; } + } + + public class RootSettingInfoReq + { + public List SettingInfoReq { get; set; } + } + + public class SettingReq + { + public List ids { get; set; } + public bool register { get; set; } + } + + public class RootSettingReq + { + public SettingReq SettingReq { get; set; } + } + + public class RootUnsubscribeSetting + { + public List UnsubscribeSetting { get; set; } + } + + public class RootEventReg + { + public List EventReg { get; set; } + } + + public class RootEventUnreg + { + public List EventUnreg { get; set; } + } + + public class EventSet + { + public int id { get; set; } + public string name { get; set; } + public int severity { get; set; } + public double latitude { get; set; } + public double longitude { get; set; } + public int alarmId { get; set; } + public int alarmInstance { get; set; } + public string alarmText { get; set; } + public int inst { get; set; } + public bool active { get; set; } + public string wpName { get; set; } + public string wpId { get; set; } + } + + public class RootEventSet : Root + { + public List EventSet { get; set; } + } + +/* + public class TrafficReq + { + public bool subscribe { get; set; } + public int id { get; set; } + public int sourceType { get; set; } + } + + public class RootTrafficReq + { + public TrafficReq TrafficReq { get; set; } + } + + public class RootTrafficReg + { + public List TrafficReg { get; set; } + } + + public class RootTrafficUnreg + { + public List TrafficUnreg { get; set; } + } + + public class TrafficRemoved + { + public int sourceType { get; set; } + public int id { get; set; } + } + + public class RootTrafficRemoved + { + public List TrafficRemoved { get; set; } + } +*/ + + public class ThreadState + { + public bool Enabled { get; set; } + public AutoResetEvent Notification { get; private set; } + + public ThreadState() + { + Enabled = true; + Notification = new AutoResetEvent(false); + } + } + + public class TimeOfTick : EventArgs + { + private DateTime TimeNow; + public DateTime Time + { + set + { + TimeNow = value; + } + get + { + return this.TimeNow; + } + } + } + + public class GoFree : IDisposable + { + public delegate void TickHandler(string className, Root root); + public event TickHandler Tick; + +// private Queue _msgQ; + private WaitCallback _notifyMsg; + private ThreadState _notifyMsgState; + private TimerCallback _sendHeartbeat; + private Timer _heartbeatTimer; + private WebSocket _ws; + + public GoFree(string url) + { + _ws = new WebSocket(url); +// _msgQ = Queue.Synchronized(new Queue()); + + configure(); + } + + private void configure() + { + _ws.OnOpen += (sender, e) => + { + }; + + _ws.OnMessage += (sender, e) => + { + switch (e.Type) + { + case Opcode.TEXT: + /*var msg =*/ parseTextMessage(e.Data); +// _msgQ.Enqueue(msg); + break; + case Opcode.BINARY: + break; + default: + break; + } + }; + + _ws.OnError += (sender, e) => + { +// enNfMessage("[GoFree] error", "WS: Error: " + e.Message, "notification-message-im"); + }; + + _ws.OnClose += (sender, e) => + { +/* + enNfMessage + ( + "[GoFree] disconnect", + String.Format("WS: Close({0}:{1}): {2}", (ushort)e.Code, e.Code, e.Reason), + "notification-message-im" + ); +*/ + }; + + _notifyMsgState = new ThreadState(); + _notifyMsg = (state) => + { + while (_notifyMsgState.Enabled /*|| _msgQ.Count > 0*/) + { + Thread.Sleep(500); +/* + if (_msgQ.Count > 0) + { + QueueMessage msg = (QueueMessage)_msgQ.Dequeue(); + Console.WriteLine("{0}", msg.Summary); + } +*/ + } + + _notifyMsgState.Notification.Set(); + }; + + _sendHeartbeat = (state) => + { +// var msg = createTextMessage("heartbeat", String.Empty); +// _ws.Send(msg); + }; + } + + private void parseTextMessage(string data) + { + JObject msg = JObject.Parse(data); + string key = ""; + foreach (var x in msg) + { + key = x.Key; + } + + switch (key) + { + case "DataList": + { + RootDataList rootDataList = JsonConvert.DeserializeObject(data); + Tick(key, rootDataList); + } + break; + + case "DataInfo": + { + RootDataInfo rootDataInfo = JsonConvert.DeserializeObject(data); + Tick(key, rootDataInfo); + } + break; + + case "Data": + { + RootData rootData = JsonConvert.DeserializeObject(data); + Tick(key, rootData); + } + break; + + case "SettingList": + { + RootSettingList rootSettingList = JsonConvert.DeserializeObject(data); + Tick(key, rootSettingList); + } + break; + + case "SettingInfo": + { + RootSettingInfo rootSettingInfo = JsonConvert.DeserializeObject(data); + Tick(key, rootSettingInfo); + } + break; + + case "Setting": + { + RootSetting rootSetting = JsonConvert.DeserializeObject(data); + Tick(key, rootSetting); + } + break; + +// case "Vessel": + case "Traffic": + { + RootTraffic rootTraffic = JsonConvert.DeserializeObject(data); + Tick(key, rootTraffic); + } + break; + + case "EventSet": + { + RootEventSet rootEventSet = JsonConvert.DeserializeObject(data); + Tick(key, rootEventSet); + } + break; + + default: + { + System.Diagnostics.Debug.WriteLine("Eh? {0}", key); + } + break; + } + } + + public void Connect() + { + _ws.Connect(); + + ThreadPool.QueueUserWorkItem(_notifyMsg); + _heartbeatTimer = new Timer(_sendHeartbeat, null, 30 * 1000, 30 * 1000); + } + + public void Disconnect() + { + var wait = new AutoResetEvent(false); + _heartbeatTimer.Dispose(wait); + wait.WaitOne(); + + _ws.Close(); + + _notifyMsgState.Enabled = false; + _notifyMsgState.Notification.WaitOne(); + } + + public void Dispose() + { + Disconnect(); + } + + public void Write(string data) + { + _ws.Send(data); + } + + public void Write(FileInfo file) + { + throw new NotImplementedException(); + } + } +} diff --git a/GoFreeWebSocketTest/WebSocketTest/NavicoDiscovery.cs b/GoFreeWebSocketTest/WebSocketTest/NavicoDiscovery.cs new file mode 100644 index 0000000..a58ec0b --- /dev/null +++ b/GoFreeWebSocketTest/WebSocketTest/NavicoDiscovery.cs @@ -0,0 +1,240 @@ +using System; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using Newtonsoft.Json; +using System.Diagnostics; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Navico +{ + class NavicoDiscovery + { + public class MFDService + { + public MFDService(string service, uint version, uint port) + { + Service = service; + Version = version; + Port = port; + } + + public string Service; + public uint Version; + public uint Port; + } + + public class MFD + { + public string Name; + public string IP; + public string Model; + public MFDService[] Services; + } + + static readonly object _locker = new object(); + + public static void ReceiveOldMessage(List MFDList) + { +#if DEBUG_MGS + string output = string.Format("Enter ReceiveOldMessage"); + lock (_locker) + { + Console.WriteLine(output); + Debug.Print(output + string.Format("\r\n")); + } +#endif + + // Navico NSS 2.0: Multicast 239.2.1.1, port 2050 + UdpClient client = new UdpClient(); + client.Client.ReceiveTimeout = 2000; + + IPEndPoint localEp = new IPEndPoint(IPAddress.Any, 2050); + client.Client.Bind(localEp); + + IPAddress multicastaddress = IPAddress.Parse("239.2.1.1"); + client.JoinMulticastGroup(multicastaddress); + + DateTime timeLastNewFound = DateTime.Now; + while (timeLastNewFound.AddSeconds(2) > DateTime.Now) + { + Byte[] data = null; + try + { + data = client.Receive(ref localEp); + } + catch (Exception ex) + { + break; + } + if (data.Length > 0) + { + string strData = Encoding.ASCII.GetString(data); + char[] lineEnd = { '\r', '\n' }; + strData = strData.TrimEnd(lineEnd); + string[] strParams = strData.Split(','); + if (strParams.Count() >= 4) + { + bool foundMFD = false; + bool foundService = false; + foreach (MFD mfd in MFDList) + { + if (strParams[2] == mfd.IP) + { + foundMFD = true; + foreach (MFDService service in mfd.Services) + { + if (strParams[0] == service.Service) + { + foundService = true; + } + } + break; + } + } + + if (foundMFD) + { + if (!foundService) + { + timeLastNewFound = DateTime.Now; + foreach (MFD mfd in MFDList) + { + if (strParams[2] == mfd.IP) + { + lock (_locker) + { + MFDService[] newList = new MFDService[mfd.Services.Count() + 1]; + for (int service = 0; service < mfd.Services.Count(); service++) + { + newList[service] = mfd.Services[service]; + } + newList[mfd.Services.Count()].Service = strParams[0]; + newList[mfd.Services.Count()].Port = Convert.ToUInt32(strParams[3]); + mfd.Services = newList; + } + } + } + } + } + else + { + timeLastNewFound = DateTime.Now; + MFD mfd = new MFD(); + mfd.IP = strParams[2]; + mfd.Services = new MFDService[1]; + mfd.Services[0] = new MFDService(strParams[0], 0, Convert.ToUInt32(strParams[3])); +#if DEBUG_MGS + output = string.Format("Service: {0}\tVersion: {1}\tIP: {2}\tPort: {3}", strParams[0], strParams[1], strParams[2], strParams[3]); +#endif + lock (_locker) + { + MFDList.Add(mfd); + +#if DEBUG_MGS + Console.WriteLine(output); + Debug.Print(output + string.Format("\r\n")); +#endif + } + } + } + } + } + +#if DEBUG_MGS + output = string.Format("Exit ReceiveOldMessage"); + lock (_locker) + { + Console.WriteLine(output); + Debug.Print(output + string.Format("\r\n")); + } +#endif + } + + public static void ReceiveNewMessage(List MFDList) + { +#if DEBUG_MGS + string output = string.Format("Enter ReceiveNewMessage"); + lock (_locker) + { + Console.WriteLine(output); + Debug.Print(output + string.Format("\r\n")); + } +#endif + + // Navico NSS 2.5: Multicast 239.2.1.1, port 2052 + UdpClient client = new UdpClient(); + client.Client.ReceiveTimeout = 2000; + + IPEndPoint localEp = new IPEndPoint(IPAddress.Any, 2052); + client.Client.Bind(localEp); + + IPAddress multicastaddress = IPAddress.Parse("239.2.1.1"); + client.JoinMulticastGroup(multicastaddress); + + DateTime timeLastNewFound = DateTime.Now; + while (timeLastNewFound.AddSeconds(2) > DateTime.Now) + { + Byte[] data = null; + try + { + data = client.Receive(ref localEp); + } + catch (Exception ex) + { + break; + } + if (data.Length > 0) + { + string strData = Encoding.ASCII.GetString(data); + MFD deserializedMFD = JsonConvert.DeserializeObject(strData); + + bool found = false; + foreach (MFD mfd in MFDList) + { + if (deserializedMFD.IP == mfd.IP) + { + found = true; + break; + } + } + + if (!found) + { + timeLastNewFound = DateTime.Now; +#if DEBUG_MGS + output = string.Format("MFD: {0}\tModel: {1}\tIP: {2}", deserializedMFD.Name, deserializedMFD.Model, deserializedMFD.IP); +#endif + lock (_locker) + { + MFDList.Add(deserializedMFD); + +#if DEBUG_MGS + Console.WriteLine(output); + Debug.Print(output); + for (uint service = 0; service < deserializedMFD.Services.Count(); service++) + { + output = string.Format("\tService {0}: {1}\tVersion: {2}\tPort: {3}", service, deserializedMFD.Services[service].Service, deserializedMFD.Services[service].Version, deserializedMFD.Services[service].Port); + Console.WriteLine(output); + Debug.Print(output); + } +#endif + } + } + } + } + +#if DEBUG_MGS + output = string.Format("Exit ReceiveNewMessage"); + lock (_locker) + { + Console.WriteLine(output); + Debug.Print(output + string.Format("\r\n")); + } +#endif + } + } +} diff --git a/GoFreeWebSocketTest/WebSocketTest/Program.cs b/GoFreeWebSocketTest/WebSocketTest/Program.cs new file mode 100644 index 0000000..8fbf55a --- /dev/null +++ b/GoFreeWebSocketTest/WebSocketTest/Program.cs @@ -0,0 +1,702 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using CommandLine; +using CommandLine.Text; +using System.ComponentModel; + +using WebSocketSharp; +using WebSocketSharp.Frame; +using System.Threading; +using Newtonsoft.Json; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +using Navico; + +namespace WebSocketTest +{ + class Program + { + static public void DbgOutput(string message, + [CallerFilePath] string sourceFilePath = "", + [CallerLineNumber] int sourceLineNumber = 0) + { + Debug.Print(sourceFilePath + "(" + sourceLineNumber + "): " + message); + Console.WriteLine(message); + } + + private sealed class Options + { + [Option('v', null, HelpText = "Print details during execution.")] + public bool Verbose { get; set; } + + [Option('m', "model", HelpText = "Specify model to search for.")] + public string Model { get; set; } + + [Option('i', "ip", HelpText = "Specify ip address to search for.")] + public string IP { get; set; } + + [Option('p', "port", HelpText = "Specify port address to search for.")] + public string Port { get; set; } + + [Option("RequestingAListOfDataIDs", DefaultValue = true, HelpText = "Requesting A List Of Data IDs.")] + public bool RequestingAListOfDataIDs { get; set; } + + [Option("RequestFullInformationAboutADataValue", DefaultValue = true, HelpText = "Request Full Information About A Data Value.")] + public bool RequestFullInformationAboutADataValue { get; set; } + + [Option("RequestingAValue", DefaultValue = true, HelpText = "Requesting A Value.")] + public bool RequestingAValue { get; set; } + + [Option("RequestASettingsGroup", DefaultValue = true, HelpText = "Request A Settings Group.")] + public bool RequestASettingsGroup { get; set; } + + [Option("RequestSettingInformation", DefaultValue = true, HelpText = "Request Setting Information.")] + public bool RequestSettingInformation { get; set; } + + [Option("RequestAListOfSettings", DefaultValue = true, HelpText = "Request A List Of Settings.")] + public bool RequestAListOfSettings { get; set; } + + [Option("RegisterToReceiveAnEvent", DefaultValue = true, HelpText = "Register To Receive An Event.")] + public bool RegisterToReceiveAnEvent { get; set; } + + [Option("MOBEvent", DefaultValue = true, HelpText = "MOB Event.")] + public bool MOBEvent { get; set; } + + [Option("CreateAWaypoint", DefaultValue = true, HelpText = "Create A Waypoint.")] + public bool CreateAWaypoint { get; set; } + + [Option("ActivateSilenceAcknowledgeDeactivateAnAlarm", DefaultValue = true, HelpText = "Activate Silence Acknowledge Deactivate An Alarm.")] + public bool ActivateSilenceAcknowledgeDeactivateAnAlarm { get; set; } + + [Option("ResetATripLog", DefaultValue = true, HelpText = "Reset A Trip Log.")] + public bool ResetATripLog { get; set; } + + [Option("RegisterForVesselsId", DefaultValue = true, HelpText = "Register For Vessels Id.")] + public bool RegisterForVesselsId { get; set; } + + [Option("RegisterForVesselsType", DefaultValue = true, HelpText = "Register For Vessels Type.")] + public bool RegisterForVesselsType { get; set; } + +/* + #region Specialized Option Attribute + [ValueList(typeof(List))] + [DefaultValue(null)] + public IList DefinitionFiles { get; set; } + + [OptionList("o", "operators", Separator = ';', HelpText = "Operators included in processing (+;-;...)." + + " Separate each operator with a semicolon." + " Do not include spaces between operators and separator.")] + [DefaultValue(null)] + public IList AllowedOperators { get; set; } + #endregion +*/ + + #region Help Screen + + [HelpOption] + public string GetUsage() + { + return HelpText.AutoBuild(this, (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current)); + } + +/* + [HelpOption] + public string GetUsage() + { + return HelpText.AutoBuild(this, delegate(HelpText current) { + if (this.LastPostParsingState.Errors.Count > 0) + { + var errors = current.RenderParsingErrorsText(this, 2); // indent with two spaces + if (!string.IsNullOrEmpty(errors)) + { + current.AddPreOptionsLine(string.Concat(Environment.NewLine, "ERROR(S):")); + current.AddPreOptionsLine(errors); + } + } + }); + } +*/ +/* + [HelpOption] + public string GetUsage() + { + var help = new HelpText { Heading = Program._headingInfo, + Copyright = new CopyrightInfo("Giacomo Stelluti Scala", 2005, 2012), + AdditionalNewLineAfterOption = true, + AddDashesToOption = true + }; + this.HandleParsingErrorsInHelp(help); + help.AddPreOptionsLine("This is free software. You may redistribute copies of it under the terms of"); + help.AddPreOptionsLine("the MIT License ."); + help.AddPreOptionsLine("Usage: SampleApp -rMyData.in -wMyData.out --calculate"); + help.AddPreOptionsLine(string.Format(" SampleApp -rMyData.in -i -j{0} file0.def file1.def", 9.7)); + help.AddPreOptionsLine(" SampleApp -rMath.xml -wReport.bin -o *;/;+;-"); + help.AddOptions(this); + + return help; + } + + private void HandleParsingErrorsInHelp(HelpText help) + { + if (this.LastPostParsingState.Errors.Count > 0) + { + var errors = help.RenderParsingErrorsText(this, 2); // indent with two spaces + if (!string.IsNullOrEmpty(errors)) + { + help.AddPreOptionsLine(string.Concat(Environment.NewLine, "ERROR(S):")); + help.AddPreOptionsLine(errors); + } + } + } +*/ + #endregion + } + + public class Listener + { + private GoFree _goFree; + + public Listener(GoFree goFree) + { + _goFree = goFree; + } + + public void Subscribe(GoFree goFree) + { + goFree.Tick += new GoFree.TickHandler(HeardIt); + } + + private void HeardIt(string className, Root root) + { +// System.Console.WriteLine("HEARD IT"); + + switch (className) + { + case "DataList": + { + RootDataList rootDataList = root as RootDataList; + +// RootDataInfoReq rootDataInfoReq = new RootDataInfoReq(); +// rootDataInfoReq.DataInfoReq = new List(); + + string output = string.Format("\tDataList:"); + DbgOutput(output); + output = ""; + foreach (int n in rootDataList.DataList.list) + { + output += string.Format("{0} ", n); +// rootDataInfoReq.DataInfoReq.Add(n); + } + DbgOutput(output); + +// string data; +// data = JsonConvert.SerializeObject(rootDataInfoReq); +// _goFree.Write(data); + } + break; + + case "DataInfo": + { + RootDataInfo rootDataInfo = root as RootDataInfo; + + DbgOutput("\tDataInfo:"); + foreach (DataInfo dataInfo in rootDataInfo.DataInfo) + { + DbgOutput(string.Format("\t\tid: {0}, sname: {1}, lname: {2}, unit: {3}, min: {4}, max: {5}, numInstance: {6}", dataInfo.id, dataInfo.sname, dataInfo.lname, dataInfo.unit, dataInfo.min, dataInfo.max, dataInfo.numInstances)); + if (dataInfo.instanceInfo != null) + { + foreach (InstanceInfo instanceInfo in dataInfo.instanceInfo) + { + DbgOutput(string.Format("\t\tinst: {0}, location: {1}, str: {2}", instanceInfo.inst, instanceInfo.location, instanceInfo.str)); + } + } + } + } + break; + + case "Data": + { + RootData rootData = root as RootData; + + DbgOutput("\tData:"); + foreach (Data data in rootData.Data) + { + DbgOutput(string.Format("\t\tid: {0}, val: {1}, valStr: {2}, sysVal: {3}, inst: {4}, valid: {5}", data.id, data.val, data.valStr, data.sysVal, data.inst, data.valid)); + } + } + break; + + case "SettingList": + { + RootSettingList rootSettingList = root as RootSettingList; + + DbgOutput(string.Format("\tSettingList:\r\n\tgroupId: {0}", rootSettingList.SettingList.groupId)); + foreach (int setting in rootSettingList.SettingList.list) + { + DbgOutput(string.Format("\t\tsetting: {0}", setting)); + } + } + break; + + case "SettingInfo": + { + RootSettingInfo rootSettingInfo = root as RootSettingInfo; + + DbgOutput("\tSettingInfo:"); + foreach (SettingInfo settingInfo in rootSettingInfo.SettingInfo) + { + DbgOutput(string.Format("\t\tid: {0}, name: {1}, type: {2}, low: {3}, high: {4}, step: {5}", settingInfo.id, settingInfo.name, settingInfo.type, settingInfo.low, settingInfo.high, settingInfo.step)); + if (settingInfo.values != null) + { + foreach (Value value in settingInfo.values) + { + DbgOutput(string.Format("\t\t\tid: {0}, title: {1}", value.id, value.title)); + } + } + } + } + break; + + case "Setting": + { + RootSetting rootSetting = root as RootSetting; + + DbgOutput("\tSetting:"); + foreach (Setting setting in rootSetting.Setting) + { + DbgOutput(string.Format("\t\tid: {0}, value: {1}", setting.id, setting.value)); + } + } + break; + + case "Traffic": + { + RootTraffic rootTraffic = root as RootTraffic; + + DbgOutput("\tTraffic:"); + foreach (Traffic traffic in rootTraffic.Traffic) + { + DbgOutput(string.Format("\t\ttype: {0}, id: {1}, name: {2}, lost: {3}, distance: {4}, lat: {5}, lon: {6}, trueBearing: {7}, cpa: {8}, tcpa: {9}, sog: {10}, cog: {11}, relativesog: {12}, relativecog: {13}, status: {14}", + traffic.type, traffic.id, traffic.name, traffic.lost, traffic.distance, traffic.lat, traffic.lon, traffic.trueBearing, traffic.cpa, traffic.tcpa, traffic.sog, traffic.cog, traffic.relativeSog, traffic.relativeCog, traffic.status)); + } + } + break; + + case "EventSet": + { + RootEventSet rootEventSet = root as RootEventSet; + + DbgOutput("\tEventSet:"); + foreach (EventSet eventSet in rootEventSet.EventSet) + { + DbgOutput(string.Format("\t\tid: {0}, name: {1}, severity: {2}, latitude: {3}, longitude: {4}, alarmId: {5}, alarmInstance: {6}, alarmText: {7}, inst: {8}, active: {9}, wpName: {10}, wpId: {11}", + eventSet.id, eventSet.name, eventSet.severity, eventSet.latitude, eventSet.longitude, eventSet.alarmId, eventSet, eventSet.alarmInstance, eventSet.alarmText, eventSet.inst, eventSet.active, eventSet.wpName, eventSet.wpId)); + } + } + break; + + default: + { + DbgOutput(string.Format("Eh? {0}", className)); + } + break; + } + } + } + + static void Main(string[] args) + { + var options = new Options(); + CommandLine.ParserSettings parserSettings = new ParserSettings(); + parserSettings.HelpWriter = Console.Error; + CommandLine.Parser parser = new Parser(parserSettings); + if (parser.ParseArguments(args, options)) + { + if (options.Verbose) + { + Console.WriteLine(options.Model); + Console.WriteLine(options.IP); + Console.WriteLine(options.Port); + } + } + else + { + Environment.Exit(1); + } + + string output; +/* + string test1 = "{\"SettingInfo\":[{\"id\":40, \"name\":\"Boat Type\", \"type\":1, \"values\":[{\"id\":0, \"title\":\"Sailing\"}, {\"id\":1,\"title\":\"Fishing\"}, {\"id\":2, \"title\":\"Planing\" }]}]}"; + RootSettingInfo rootSettingInfo1 = JsonConvert.DeserializeObject(test1); + + string test2 = "{\"SettingInfo\":[{\"id\":1,\"name\":\"Backlight Level\",\"type\":2,\"low\":0,\"high\":10}]}"; + RootSettingInfo rootSettingInfo2 = JsonConvert.DeserializeObject(test2); + + string test3 = "{\"SettingInfo\":[{\"id\":2,\"name\":\"Night Mode\",\"type\":3}]}"; + RootSettingInfo rootSettingInfo3 = JsonConvert.DeserializeObject(test3); +*/ + + Navico.NavicoDiscovery.MFD websocketMFD = null; + + if ((options.IP == null) && (options.Port == null)) + { + List MFDList = new List(); + + Thread newThread; + newThread = new Thread(() => Navico.NavicoDiscovery.ReceiveNewMessage(MFDList)); + newThread.IsBackground = true; + newThread.Start(); + + newThread.Join(); + + foreach (Navico.NavicoDiscovery.MFD mfd in MFDList) + { + if (options.Model != null) + { +// if (string.Compare(mfd.Model, options.Model, true) != 0) + if (mfd.Model.IndexOf(options.Model) != 0) + { + continue; + } + } + if (options.IP != null) + { +// if (string.Compare(mfd.IP, options.IP, true) != 0) + if (mfd.IP.IndexOf(options.IP) != 0) + { + continue; + } + } + + DbgOutput(string.Format("MFD: {0}\tModel: {1}\tIP: {2}", mfd.Name, mfd.Model, mfd.IP)); + foreach (Navico.NavicoDiscovery.MFDService service in mfd.Services) + { + DbgOutput(string.Format("\tService: {0}\tVersion: {1}\tPort: {2}", service.Service, service.Version, service.Port)); + + if ((service.Service == "navico-nav-ws") /*|| (service.Service == "navico-navdata-websocket")*/) + { + if (websocketMFD == null) + { + websocketMFD = mfd; + websocketMFD.Services = null; + websocketMFD.Services = new NavicoDiscovery.MFDService[1]; + websocketMFD.Services[0] = service; + } + } + } + } + + if (websocketMFD == null) + { + return; + } + } + else + { + websocketMFD = new NavicoDiscovery.MFD(); + websocketMFD.IP = options.IP; + websocketMFD.Services = new NavicoDiscovery.MFDService[1]; + websocketMFD.Services[0] = new NavicoDiscovery.MFDService("", 0, Convert.ToUInt32(options.Port)); + } + + DbgOutput(string.Format("Connect to {0}:{1}", websocketMFD.IP, websocketMFD.Services[0].Port)); + + string wsURL; + wsURL = string.Format("ws://{0}:{1}", websocketMFD.IP, websocketMFD.Services[0].Port); + //wsURL = string.Format("ws://172.28.29.224:2053"); + using (GoFree streamer = new GoFree(wsURL)) + { + Listener l = new Listener(streamer); + l.Subscribe(streamer); + streamer.Connect(); + + Thread.Sleep(500); + Console.WriteLine("\nType \"exit\" to exit.\n"); + + string data; + + if (options.RequestingAListOfDataIDs) + { + DbgOutput("Requesting a list of data IDs"); + +// data = "{\"DataListReq\":{\"group\":1}}"; +// streamer.Write(data); + + RootDataListReq rootDataListReq = new RootDataListReq(); + rootDataListReq.DataListReq = new DataListReq(); + + foreach (eDataGroup dataGroup in System.Enum.GetValues(typeof(eDataGroup))) + { + rootDataListReq.DataListReq.group = (int)dataGroup; + data = JsonConvert.SerializeObject(rootDataListReq); + streamer.Write(data); + } + + Thread.Sleep(1000); + } + + if (options.RequestFullInformationAboutADataValue) + { + DbgOutput("Request full information about a data value"); + +// data = "{\"DataInfoReq\":[40]}"; +// streamer.Write(data); + + foreach (eDataType dataType in System.Enum.GetValues(typeof(eDataType))) + { + RootDataInfoReq rootDataInfoReq = new RootDataInfoReq(); + rootDataInfoReq.DataInfoReq = new List(); + rootDataInfoReq.DataInfoReq.Add((int)dataType); + data = JsonConvert.SerializeObject(rootDataInfoReq); + streamer.Write(data); + } + + Thread.Sleep(1000); + } + + if (options.RequestingAValue) + { + DbgOutput("Requesting a value"); + +// data = "{\"DataReq\":[{\"id\":1,\"repeat\":false,\"inst\":0}]}"; +// streamer.Write(data); + + foreach (eDataType dataType in System.Enum.GetValues(typeof(eDataType))) + { + RootDataReq rootDataReq = new RootDataReq(); + rootDataReq.DataReq = new List(); + DataReq dataReq = new DataReq(); + dataReq.id = (int)dataType; + rootDataReq.DataReq.Add(dataReq); + data = JsonConvert.SerializeObject(rootDataReq); + streamer.Write(data); + } + + Thread.Sleep(1000); + } + + if (options.RequestASettingsGroup) + { + DbgOutput("Request a settings group"); + +// data = "{\"SettingListReq\":[{\"group\":1}]}"; +// streamer.Write(data); + + foreach (eDataGroup dataGroup in System.Enum.GetValues(typeof(eDataGroup))) + { + RootSettingListReq rootSettingListReq = new RootSettingListReq(); + rootSettingListReq.SettingListReq = new List(); + SettingListReq settingListReq = new SettingListReq(); + settingListReq.groupId = (int)dataGroup; + rootSettingListReq.SettingListReq.Add(settingListReq); + data = JsonConvert.SerializeObject(rootSettingListReq); + streamer.Write(data); + } + + Thread.Sleep(1000); + } + + if (options.RequestSettingInformation) + { + DbgOutput("Request setting information"); + +// data = "{\"SettingInfoReq\":[1]}"; +// streamer.Write(data); + + foreach (eSettingIDs setting in System.Enum.GetValues(typeof(eSettingIDs))) + { + RootSettingInfoReq rootSettingInfoReq = new RootSettingInfoReq(); + rootSettingInfoReq.SettingInfoReq = new List(); + rootSettingInfoReq.SettingInfoReq.Add((int)setting); + data = JsonConvert.SerializeObject(rootSettingInfoReq); + streamer.Write(data); + } + + Thread.Sleep(1000); + } + + if (options.RequestAListOfSettings) + { + DbgOutput("Request a list of settings"); + +// data = "{\"SettingReq\":{\"ids\":[1,2,3],\"register\":false}}"; +// streamer.Write(data); + + foreach (eSettingIDs setting in System.Enum.GetValues(typeof(eSettingIDs))) + { + RootSettingReq rootSettingReq = new RootSettingReq(); + rootSettingReq.SettingReq = new SettingReq(); + rootSettingReq.SettingReq.ids = new List(); + rootSettingReq.SettingReq.ids.Add((int)setting); + data = JsonConvert.SerializeObject(rootSettingReq); + streamer.Write(data); + } + + Thread.Sleep(1000); + } + + if (options.RegisterToReceiveAnEvent) + { + DbgOutput("Register to receive an event"); + +// data = "{\"EventReg\":[1,2]}"; +// streamer.Write(data); + + foreach (eEvents eventValue in System.Enum.GetValues(typeof(eEvents))) + { + RootEventReg rootEventReg = new RootEventReg(); + rootEventReg.EventReg = new List(); + rootEventReg.EventReg.Add((int)eventValue); + data = JsonConvert.SerializeObject(rootEventReg); + streamer.Write(data); + } + + Thread.Sleep(1000); + } + +/* + if (true) + { + DbgOutput("Set event"); + + foreach (eEvents eventValue in System.Enum.GetValues(typeof(eEvents))) + { + RootEventSet rootEventSet = new RootEventSet(); + rootEventSet.EventSet = new List(); + EventSet eventSet = new EventSet(); + eventSet.id = (int)eventValue; + eventSet. + rootEventSet.EventSet.Add(eventSet); + data = JsonConvert.SerializeObject(rootEventSet); + streamer.Write(data); + } + + Thread.Sleep(1000); + } +*/ + + if (options.MOBEvent) + { + DbgOutput("MOB event"); + + RootEventSet rootEventSet = new RootEventSet(); + rootEventSet.EventSet = new List(); + EventSet eventSet = new EventSet(); + eventSet.id = (int)eEvents.MOB; + eventSet.name = "MOB"; + eventSet.active = true; + rootEventSet.EventSet.Add(eventSet); + data = JsonConvert.SerializeObject(rootEventSet); + streamer.Write(data); + + Thread.Sleep(1000); + } + + if (options.CreateAWaypoint) + { + DbgOutput("Create a waypoint"); + + RootEventSet rootEventSet = new RootEventSet(); + rootEventSet.EventSet = new List(); + EventSet eventSet = new EventSet(); + eventSet.id = (int)eEvents.WaypointCreate; + eventSet.latitude = 50.9892; + eventSet.longitude = -1.4975; + eventSet.name = "Waypoint1"; + rootEventSet.EventSet.Add(eventSet); + data = JsonConvert.SerializeObject(rootEventSet); + streamer.Write(data); + + Thread.Sleep(1000); + } + + if (options.ActivateSilenceAcknowledgeDeactivateAnAlarm) + { + DbgOutput("Activate/Silence/Acknowledge/Deactivate an alarm"); + + RootEventSet rootEventSet = new RootEventSet(); + rootEventSet.EventSet = new List(); + EventSet eventSet = new EventSet(); +// eventSet.id = (int)eEvents.AlarmActivate; + eventSet.id = (int)eEvents.AlarmSilence; +// eventSet.id = (int)eEvents.AlarmAcknowledge; +// eventSet.id = (int)eEvents.AlarmDeactivate; + eventSet.alarmId = 5; + eventSet.alarmText = "Low Speed"; + eventSet.severity = 1; + rootEventSet.EventSet.Add(eventSet); + data = JsonConvert.SerializeObject(rootEventSet); + streamer.Write(data); + + Thread.Sleep(1000); + } + + if (options.ResetATripLog) + { + DbgOutput("Reset a trip log"); + + RootEventSet rootEventSet = new RootEventSet(); + rootEventSet.EventSet = new List(); + EventSet eventSet = new EventSet(); + eventSet.id = (int)eEvents.TripLogReset; + eventSet.inst = 0; + rootEventSet.EventSet.Add(eventSet); + data = JsonConvert.SerializeObject(rootEventSet); + streamer.Write(data); + + Thread.Sleep(1000); + } + + if (options.RegisterForVesselsId) + { + DbgOutput("Register for vessels (id)"); + +// data = "{\"TrafficReq\":{\"subscribe\":true,\"id\":12345,\"sourceType\":0}}"; +// streamer.Write(data); + + RootTrafficReq rootTrafficReq = new RootTrafficReq(); + rootTrafficReq.TrafficReq = new TrafficReq(); + rootTrafficReq.TrafficReq.subscribe = true; + rootTrafficReq.TrafficReq.id = 12345; + rootTrafficReq.TrafficReq.sourceType = 0; + data = JsonConvert.SerializeObject(rootTrafficReq); + streamer.Write(data); + + Thread.Sleep(1000); + } + + if (options.RegisterForVesselsType) + { + DbgOutput("Register for vessels (type)"); + +// data = "{\"TrafficReg\":[0,2]}"; +// streamer.Write(data); + + RootTrafficReg rootTrafficReg = new RootTrafficReg(); + rootTrafficReg.TrafficReg = new List(); + rootTrafficReg.TrafficReg.Add(0); + rootTrafficReg.TrafficReg.Add(2); + data = JsonConvert.SerializeObject(rootTrafficReg); + streamer.Write(data); + } + + while (true) + { + Thread.Sleep(500); + + Console.Write("> "); + data = Console.ReadLine(); + if (data == "exit") + { + break; + } + + streamer.Write(data); + } + } + } + } +} diff --git a/GoFreeWebSocketTest/WebSocketTest/Properties/AssemblyInfo.cs b/GoFreeWebSocketTest/WebSocketTest/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3816ee3 --- /dev/null +++ b/GoFreeWebSocketTest/WebSocketTest/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ClientWebSocket")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ClientWebSocket")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3dad4a6a-0565-4d68-be08-307321e85fcb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/GoFreeWebSocketTest/WebSocketTest/WebSocketTest.csproj b/GoFreeWebSocketTest/WebSocketTest/WebSocketTest.csproj new file mode 100644 index 0000000..63da07b --- /dev/null +++ b/GoFreeWebSocketTest/WebSocketTest/WebSocketTest.csproj @@ -0,0 +1,116 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {3FB9520D-E4D5-4503-B862-EBB7F36C2EAF} + Exe + Properties + WebSocketTest + WebSocketTest + v4.5 + + + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + False + .\CommandLine.dll + + + False + .\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + {B357BAC7-529E-4D81-A0D2-71041B19C8DE} + websocket-sharp + + + + + False + Microsoft .NET Framework 4 Client Profile %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + + + + + + + \ No newline at end of file diff --git a/GoFreeWebSocketTest/WebSocketTest/app.config b/GoFreeWebSocketTest/WebSocketTest/app.config new file mode 100644 index 0000000..c5e1dae --- /dev/null +++ b/GoFreeWebSocketTest/WebSocketTest/app.config @@ -0,0 +1,3 @@ + + +