private void HandleReceivedADMMessage(ADMMessage message) { try { //do some general checking //TODO: check BoardID matches to SenderID lock (MessageStatsLock) { LastMessageReceived = message; LastMessageReceivedOn = DateTime.Now; MessageReceivedSuccess = message.Tag == LastMessageSent.Tag; MessagesReceived++; } //Console.WriteLine("<--------- {0}: Received message {1} tag {2} target {3} from sender {4}", PortAndNodeID, message.Type, message.Tag, message.TargetID, message.SenderID); switch (message.Type) { case Messaging.MessageType.INITIALISE_RESPONSE: message.AddValue("LittleEndian", message.ArgumentAsBool(0)); LittleEndian = message.GetBool("LittleEndian"); message.AddValue("FreeMemory", message.ArgumentAsInt(1)); BoardID = message.SenderID; message.AddValue("MaxDevices", message.ArgumentAsInt(2)); MaxDevices = message.GetInt("MaxDevices"); message.AddValue("LEDBI", message.ArgumentAsInt(3)); LEDBIPin = message.GetInt("LEDBI"); break; case Messaging.MessageType.STATUS_RESPONSE: try { if (message.TargetID == 0) { message.AddValue("FreeMemory", message.ArgumentAsInt(0)); message.AddValue("BoardType", message.ArgumentAsString(1)); message.AddValue("Initialised", message.ArgumentAsBool(2)); message.AddValue("DeviceCount", message.ArgumentAsInt(3)); } if (State == ADMState.CONNECTED) { State = ADMState.DEVICE_READY; } } catch (Exception e) { Tracing?.TraceEvent(TraceEventType.Error, 4000, "STATUS_RESPONSE error: {0}, {1}", e.GetType(), e.Message); throw new ArduinoException(PortAndNodeID, e.Message, e); } //record this LastStatusResponseMessage = message; LastStatusResponseOn = DateTime.Now; break; case Messaging.MessageType.PING_RESPONSE: //record this LastPingResponseMessage = message; LastPingResponseOn = DateTime.Now; break; case Messaging.MessageType.CONFIGURE_RESPONSE: break; case Messaging.MessageType.ERROR: //record last error message if (message.Arguments.Count > 0) { message.AddValue("ErrorCode", (ErrorCode)message.ArgumentAsByte(0)); } else { message.AddValue("ErrorCode", ErrorCode.ERROR_HOST_GENERATED); } LastErrorMessage = message; LastErrorOn = DateTime.Now; break; } if (State == ADMState.DEVICE_READY || State == ADMState.DEVICE_CONNECTED) { //direct messages to devices var dev = GetTargetedDevice(message); if (dev != null) { #if DEBUG Debug.Print(String.Format("Handling message {0} for device {1} ... connected: {2}, memory: {3}", message.Type, dev.ID, dev.IsConnected, message.HasValue("FM") ? message.GetValue("FM") : "N/A")); #endif try { dev.HandleMessage(message); } catch (Exception e) { Tracing?.TraceEvent(TraceEventType.Error, 4000, "Handling message for device {0} produced exception {1}: {2}", dev.ID, e.GetType(), e.Message); throw new ArduinoException(dev.ID, e.Message, e); } } //we do this test after handling message because the message maybe a CONFIGURE_RESPONSE message which will then set the 'connected' status of the device if (message.Type == Messaging.MessageType.CONFIGURE_RESPONSE && DevicesConnected) { State = ADMState.DEVICE_CONNECTED; } } } catch (Exception e) { byte tag = message != null ? message.Tag : (byte)0; message = new ADMMessage(); message.Type = Messaging.MessageType.ERROR; message.Value = e.Message; message.AddValue("ErrorCode", ErrorCode.ERROR_HOST_GENERATED); if (e is ArduinoException) { ArduinoException ae = (ArduinoException)e; message.AddValue("ErrorSource", ae.Source); } message.Tag = tag; } Broadcast(message); }
virtual protected void HandleADMMessage(ADMMessage message, ArduinoDeviceManager adm) { switch (message.Type) { case MessageType.ERROR: ErrorCode errCode = message.HasValue("ErrorCode") ? message.GetEnum <ErrorCode>("ErrorCode") : ErrorCode.ERROR_UNKNOWN; Tracing?.TraceEvent(TraceEventType.Error, 100, "ADM {0} produced error: {1}", adm.BoardID, errCode); switch (errCode) { case ErrorCode.ERROR_ADM_NOT_INITIALISED: ReconnectADM(adm); break; default: //currently do nothing break; } break; case MessageType.WARNING: Tracing?.TraceEvent(TraceEventType.Warning, 100, "ADM {0} produced warning: {1}", adm.BoardID, message.Value); break; case MessageType.STATUS_RESPONSE: if (!PortSharing && !IsRequiredBoard(adm.BoardID)) { Tracing?.TraceEvent(TraceEventType.Warning, 100, "ADM {0} is not one of the required boards ({1}). Disconnecting from port {2}...", adm.BoardID, RequiredBoards, adm.Port); DisconnectADM(adm.Port); break; } if (adm.State == ADMState.DEVICE_READY) { Tracing?.TraceEvent(TraceEventType.Verbose, 100, "ADM: Ready to add devices to {0} on port {1} ...", adm.BoardID, adm.PortAndNodeID); AddADMDevices(adm, message); Tracing?.TraceEvent(TraceEventType.Verbose, 100, "ADM: {0} devices added to {1} on port {2}. Now configure board", adm.DeviceCount, adm.BoardID, adm.PortAndNodeID); adm.Configure(); } else if (adm.State == ADMState.DEVICE_CONNECTED) { if (message.HasValue("Initialised") && !message.GetBool("Initialised")) { //Console.WriteLine("Whoa ... {0} has reset without us knowing", adm.PortAndNodeID); } } break; case MessageType.CONFIGURE_RESPONSE: String key = adm.PortAndNodeID; if (adm.State == ADMState.DEVICE_CONNECTED && !_devicesConnected[key]) { Tracing?.TraceEvent(TraceEventType.Verbose, 100, "ADM: All {0} devices now configured and connected to board {1} on port {2}", adm.DeviceCount, adm.BoardID, adm.PortAndNodeID); OnADMDevicesConnected(adm, message); } break; case MessageType.PING_RESPONSE: break; } if (message.Tag > 0) { ADMRequest req = GetADMRequest(adm, message.Tag); if (req != null) { if (req.HasExpired()) { Tracing?.TraceEvent(TraceEventType.Warning, 0, "ADM request for tag {0} and target {1} has expired so not returning message of type {2}", message.Tag, req.Target, message.Type); return; } else { message.Target = req.Target; } } } var schema = new ADMService.MessageSchema(message); schema.PrepareForBroadcast(adm); //notify other clients listening to this client Broadcast(ADMEvent.MESSAGE, message); }