private bool IsValidInput(Module source, string s) { Command cmd; Response rsp; if ((Response.IsResponse(s) && Response.TryParse(s, source, out rsp)) || Command.IsCommand(s) && Command.TryParse(s, source, out cmd)) { return(true); } return(false); }
private void Inject() { Module source; Command cmd; Response rsp; string[] inputs; HistoryToken token; if ((source = (Module)cbModules.SelectedItem) == null) { return; } inputs = BulkMode ? txtMessage.Text.Split(separators, StringSplitOptions.RemoveEmptyEntries) : new string[] { txtMessage.Text.Trim() }; foreach (string input in inputs) { //blackboard.Inject(source.Name + " " + input); token = null; if (Response.IsResponse(input) && Response.TryParse(input, source, out rsp)) { token = new HistoryToken(rsp); } else if (Command.IsCommand(input) && Command.TryParse(input, source, out cmd)) { token = new HistoryToken(cmd); } if (token == null) { blackboard.Inject(source.Name + " " + input); continue; } blackboard.Inject(token.StringToInject); AddHystoryToken(token); } txtMessage.Clear(); }
/// <summary> /// Generates a Prototypes Response which includes all the prototypes for this module /// </summary> /// <param name="baseCommand">A Command object used to generate the response</param> /// <param name="preAppendModuleName">indicates if the name of the module will be pre-appended</param> /// <returns>A Response which includes all the prototypes for this module</returns> protected Response GetPrototypesResponse(Command baseCommand, bool preAppendModuleName) { return GetPrototypesResponse(baseCommand, this.name, preAppendModuleName); }
/// <summary> /// Converts the string representation of a command to a Command object. /// A return value indicates whether the conversion succeded or not. /// </summary> /// <param name="s">A string containing the command to convert</param> /// <param name="source">The module which sent the command</param> /// <param name="destination">The destination module for the command</param> /// <param name="cmd">When this method returns, contains the Command equivalent to the command /// contained in s, if the conversion succeeded, or null if the conversion failed. /// The conversion fails if the s parameter is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <param name="ex">When this method returns, contains the Exception generated during the parse operation, /// if the conversion failed, or null if the conversion succeeded. The conversion fails if the s parameter /// is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <returns>true if conversion was successfull, false otherwise</returns> protected static bool TryParse(string s, Module source, Module destination, out Command cmd, out Exception ex) { Regex rx; Match m; Prototype proto; string sCommand; string sParams; string sId; int id; cmd = null; ex = null; // Module Validation if (source.Parent != destination.Parent) { ex = new Exception("Source and destination modules does not belong to the same blackboard"); return false; } // Regular Expresion Generation rx = rxCommandFromSrcDest; m = rx.Match(s); // Check if input string matchs Regular Expression if (!m.Success) { ex = new ArgumentException("Invalid String", "s"); return false; } // Extract Data sCommand = m.Result("${cmd}").ToLower(); sParams = m.Result("${params}"); sId = m.Result("${id}"); if ((sId == null) || (sId.Length < 1)) id = -1; else id = Int32.Parse(sId); // Browse for an adequate prototype proto = null; for (int i = 0; i < destination.Prototypes.Count; ++i) { if (destination.Prototypes[i].Command == sCommand) { proto = destination.Prototypes[i]; break; } } // Check if command matchs a prototype. If no prototype found, asume redirection if ((proto != null) && proto.ParamsRequired && ((sParams == null) || (sParams.Length < 1))) { ex = new Exception("Invalid string. The Command requires parameters"); return false; } // Create the Command cmd = new Command(source, destination, sCommand, sParams, id); cmd.prototype = proto; cmd.sentTime = DateTime.Now; return true; }
/// <summary> /// Converts the string representation of a command to a Command object. /// A return value indicates whether the conversion succeded or not. /// </summary> /// <param name="s">A string containing the command to convert</param> /// <param name="localEndpoint">The remote endpoint source of the string</param> /// <param name="destination">The module which received the command</param> /// <param name="cmd">When this method returns, contains the Command equivalent to the command /// contained in s, if the conversion succeeded, or null if the conversion failed. /// The conversion fails if the s parameter is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <param name="ex">When this method returns, contains the Exception generated during the parse operation, /// if the conversion failed, or null if the conversion succeeded. The conversion fails if the s parameter /// is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <returns>A command object that represents the command contained in s</returns> protected static bool TryParse(string s, System.Net.IPEndPoint localEndpoint, ModuleServer destination, out Command cmd, out Exception ex) { Regex rx; Match m; Prototype proto; //Module source; //Module destination; IModule src; IModule dest; string sCommand; string sParams; string sSrc; string sDest; string sId; int id; cmd = null; ex = null; // Regular Expresion Generation rx = rxCommandFromEndpoint; m = rx.Match(s); // Check if input string matchs Regular Expression if (!m.Success) { ex = new ArgumentException("Invalid String", "s"); return false; } // Extract Data sCommand = m.Result("${cmd}").ToLower(); if (!destination.SupportCommand(sCommand)) { ex = new Exception("Unsupported command provided"); return false; } sParams = m.Result("${params}"); sId = m.Result("${id}"); sSrc = m.Result("${src}"); sDest = m.Result("${dest}"); if ((sId == null) || (sId.Length < 1)) id = -1; else id = Int32.Parse(sId); // When at least one module is specified... if ((sSrc != null) && (sSrc.Length > 0)) { // If only one module is specified, there is two options: // the specified module is this (and we dont know the source module) or // the specified module is the source module if ((sDest == null) || (sDest.Length < 1)) { if (sSrc == destination.Name) dest = destination; else src = new Module(sSrc, localEndpoint.Address, localEndpoint.Port); } // If both, source and destination module are specified, since there is no // way of get the source module, a new one is created. // However its necesary to check if this is the apropiate destination module else { if (sDest != destination.Name) throw new Exception("Invalid destination module"); dest = destination; src = new Module(sSrc, localEndpoint.Address, localEndpoint.Port); } } // If no module is specified, then its set to null src = null; // Browse for an adequate prototype proto = destination.Prototypes[sCommand]; // Check if command matchs a prototype if ((proto != null) && proto.ParamsRequired && ((sParams == null) || (sParams.Length < 1))) { ex = new Exception("Invalid string. The Command requires parameters"); return false; } // Create the Command cmd = new Command(src, destination, sCommand, sParams, id); cmd.prototype = proto; cmd.sentTime = DateTime.Now; return true; }
/// <summary> /// Converts the string representation of a command to a Command object. /// A return value indicates whether the conversion succeded or not. /// </summary> /// <param name="s">A string containing the command to convert</param> /// <param name="blackboard">A blackboard which contains all information about modules</param> /// <param name="command">When this method returns, contains the Command equivalent to the command /// contained in s, if the conversion succeeded, or null if the conversion failed. /// The conversion fails if the s parameter is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <returns>true if conversion was successfull, false otherwise</returns> public static bool TryParse(string s, Blackboard blackboard, out Command command) { Exception ex; return TryParse(s, blackboard, out command, out ex); }
/// <summary> /// Converts the string representation of a command to a Command object. /// A return value indicates whether the conversion succeded or not. /// </summary> /// <param name="s">A string containing the command to convert</param> /// <param name="source">The module which sent the command</param> /// <param name="destination">The destination module for the command</param> /// <param name="cmd">When this method returns, contains the Command equivalent to the command /// contained in s, if the conversion succeeded, or null if the conversion failed. /// The conversion fails if the s parameter is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <param name="ex">When this method returns, contains the Exception generated during the parse operation, /// if the conversion failed, or null if the conversion succeeded. The conversion fails if the s parameter /// is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <returns>true if conversion was successfull, false otherwise</returns> protected static bool TryParse(string s, ModuleClient source, ModuleClient destination, out Command cmd, out Exception ex) { IPrototype proto; string sCommand; string sParams; int result; int id; cmd = null; ex = null; // Module Validation if (source.Parent != destination.Parent) { ex = new Exception("Source and destination modules does not belong to the same blackboard"); return false; } // Extract Data CommandBase.XtractCommandElements(s, out sCommand, out sParams, out result, out id); if ((sCommand == null) || (result != -1)) { ex = new ArgumentException("Invalid String", "s"); return false; } // Browse for an adequate prototype proto = null; if (destination.Prototypes.Contains(sCommand)) proto = destination.Prototypes[sCommand]; // Check if command matchs a prototype. If no prototype found, asume redirection if ((proto != null) && proto.ParamsRequired && ((sParams == null) || (sParams.Length < 1))) { ex = new Exception("Invalid string. The Command requires parameters"); return false; } // Create the Command cmd = new Command(source, destination, sCommand, sParams, id); cmd.prototype = proto; cmd.sentTime = DateTime.Now; return true; }
/// <summary> /// Finds the first suitable response in a response array. If not found returns null /// </summary> /// <param name="responses">A Response array to search in</param> /// <param name="command">The command for which response to search</param> /// <param name="heuristic">Indicates if use a heuristic to find the most adequate response. Set value to false to find only perfect matches</param> /// <returns>Returns the first suitable Response if found. If not, returns null</returns> public Response FindResponse(Command command, Response[] responses, bool heuristic) { if (responses.Length == 0) return null; // Candidates to be a response for provided command List<ResponseCandidate> candidates; Response r; int affinity = 0; candidates = new List<ResponseCandidate>(responses.Length); // Search for all suitable candidates for (int i = 0; i < responses.Length; ++i) { // Check if suitable... if ((responses[i].Source == command.Destination) && (responses[i].Command == command.Command)) { // If is the most suitable, then return it if (command.IsMatch(responses[i])) return responses[i]; if (heuristic && Command.IsMatch(command, responses[i], out affinity)) candidates.Add(new ResponseCandidate(command, responses[i], affinity)); } } // Heuristic: Sort by affinity if (!heuristic || (candidates.Count == 0)) return null; candidates.Sort(); //r = candidates[0].Response; r = candidates[0].Response; // The selected one is modified. The condition is always true, but its added by security if (r.Destination == null) r.Destination = command.Source; try { command.Response = r; } catch (Exception ex) { Log.WriteLine(6, "Error while searching for adequate response"); Log.WriteLine(6, "\tCommand: " + command.ToString()); Log.WriteLine(6, "\tResponse: " + r.ToString()); Log.WriteLine(6, "Error: " + ex.ToString()); } if (r.Source is ModuleClient) ((ModuleClient)r.Source).Unlock(r); return r; }
/// <summary> /// Creates a response from a command data /// </summary> /// <param name="command">The command to use as base for the response</param> /// <param name="failReason">the reason for which command has failed</param> /// <returns>A generic response for the command with same parameters</returns> public static Response CreateFromCommand(Command command, ResponseFailReason failReason) { Response response = new Response(); response.commandResponded = command; response.source = command.Destination; response.destination = command.Source; response.command = command.Command; response.parameters = command.Parameters; response.id = command.Id; response.failReason = failReason; response.success = (failReason == ResponseFailReason.None); response.prototype = command.Prototype; if (command.SentTime >= DateTime.Now) response.arrivalTime = command.SentTime.AddMilliseconds(5); response.arrivalTime = DateTime.Now; return response; }
/// <summary> /// Executes a read_var command. /// Requests the blackboard to send the content of a stored a variable /// </summary> /// <param name="command">Command to execute</param> protected virtual void ReadVarCommand(Command command) { string varName; string varType; SharedVariable variable; SharedVariableCollection sharedVariables = this.Parent.VirtualModule.SharedVariables; Match match = SharedVariable.RxReadSharedVariableValidator.Match(command.Parameters); if (!match.Success) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to read variable failed. Command is not well formed"); return; } varName = match.Result("${name}"); varType = match.Result("${type}"); if (!sharedVariables.Contains(varName)) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to read variable " + varName + " failed (variable does not exist)"); return; } variable = sharedVariables[varName]; if ((variable.Type != "var") && !String.IsNullOrEmpty(varType) && (varType != variable.Type)) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to read variable " + varName + " failed (type mismatch)"); } else { command.Parameters = variable.StringToSend; SendResponse(command, true); if (this.Parent.Log.VerbosityTreshold < 3) this.Parent.Log.WriteLine(2, this.Name + ": readed variable " + varName); else this.Parent.Log.WriteLine(3, this.Name + ": readed variable " + varName + " with " + Clamper.Clamp(command.StringToSend, 256)); } }
/// <summary> /// Executes a Prototypes command. /// Requests the blackboard to update the protype list of this module or requests the prototype list of another /// </summary> /// <param name="command">Command to execute</param> protected void PrototypesCommand(Command command) { if (!command.HasParams) return; Response rsp; if (this.parent.Modules.Contains(command.Parameters)) rsp = GetPrototypesResponse(command, command.Parameters, true); else { ParsePrototypeList(command.Parameters); rsp = GetPrototypesResponse(command, false); } if (rsp != null) Send(rsp); }
/// <summary> /// Parses a received command /// </summary> /// <param name="command">Command to parse</param> protected virtual void ParseCommand(Command command) { switch (command.Command) { case "create_var": CreateVarCommand(command); break; case "list_vars": ListVarsCommand(command); break; case "prototypes": PrototypesCommand(command); break; case "read_var": ReadVarCommand(command); break; case "read_vars": ReadVarsCommand(command); break; case "stat_var": StatVarCommand(command); break; //case "suscribe_var": //case "subscribe_var": // SubscribeVarCommand(command); // break; case "write_var": WriteVarCommand(command); break; default: OnCommandReceived(command); break; } }
/// <summary> /// Rises the CommandReceived event /// </summary> /// <param name="c">Command received</param> protected void OnCommandReceived(Command c) { try { if (this.CommandReceived != null) this.CommandReceived(this, c); } catch { } }
/// <summary> /// Executes a list_vars command. /// Requests the blackboard to send the list of shared variables /// </summary> /// <param name="command">Command to execute</param> protected virtual void ListVarsCommand(Command command) { command.Parameters = this.Parent.VirtualModule.SharedVariables.NameList; SendResponse(command, true); }
/// <summary> /// Generates a Prototypes Response which includes all the prototypes for this module /// </summary> /// <param name="baseCommand">A Command object used to generate the response</param> /// <param name="moduleName">The name of the module from which prototypes will be fetched</param> /// <param name="preAppendModuleName">indicates if the name of the module will be pre-appended</param> /// <returns>A Response which includes all the prototypes for this module</returns> protected Response GetPrototypesResponse(Command baseCommand, string moduleName, bool preAppendModuleName) { if ((baseCommand == null) || !this.parent.Modules.Contains(moduleName)) return null; ushort flags = 0; Response rsp= Response.CreateFromCommand(baseCommand, true); System.Text.StringBuilder sb = new System.Text.StringBuilder(); IModuleClient module = this.parent.Modules[moduleName]; IPrototype[] aProto; if (module.Prototypes is PrototypeCollection) aProto = ((PrototypeCollection)(module.Prototypes)).ToArray(false); else aProto = module.Prototypes.ToArray(); if (preAppendModuleName) { sb.Append(moduleName); sb.Append(' '); } foreach (IPrototype proto in aProto) { sb.Append(proto.Command); sb.Append(' '); flags = (ushort)(proto.Priority & 0xFF); if (proto.ResponseRequired) flags |= 0x0100; if (proto.ParamsRequired) flags |= 0x0200; sb.Append(flags); sb.Append(' '); sb.Append(proto.Timeout); sb.Append(' '); } if (sb.Length > 0) --sb.Length; rsp.Parameters = sb.ToString(); return rsp; }
/// <summary> /// Executes a read_var command. /// Requests the blackboard to send the content of a stored a variable /// </summary> /// <param name="command">Command to execute</param> protected virtual void ReadVarsCommand(Command command) { int count; System.Text.StringBuilder sb; char[] separator ={ ' ', '\t', ',' }; string[] varNames; SharedVariableCollection sharedVariables = this.Parent.VirtualModule.SharedVariables; Match match = SharedVariable.RxReadMultipleSharedVariableValidator.Match(command.Parameters); if (!match.Success) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to read multiple variables failed. Command is not well formed"); return; } count = 0; sb = new System.Text.StringBuilder(4096); varNames = match.Result("${names}").Split(separator, StringSplitOptions.RemoveEmptyEntries); foreach (string varName in varNames) { if (!sharedVariables.Contains(varName)) { this.Parent.Log.WriteLine(7, this.Name + ": attempt to read variable " + varName + " failed (the specified variable does not exist)"); continue; } ++count; sb.Append(sharedVariables[varName].StringToSend); } if(count ==0) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to read multiple variables failed (none of the specified variables exist)"); } else { command.Parameters = sb.ToString(); SendResponse(command, true); if (this.Parent.Log.VerbosityTreshold < 3) this.Parent.Log.WriteLine(2, this.Name + ": read of multiple variables succeeded"); else this.Parent.Log.WriteLine(3, this.Name + ": readed multiple variables with " + Clamper.Clamp(command.StringToSend, 256)); } }
/// <summary> /// Send a response using a command as base /// </summary> /// <param name="command">Base command</param> /// <param name="success">true if command succeded, false otherwise</param> protected virtual void SendResponse(Command command, bool success) { if (ResponseReceived == null) return; Response response = Response.CreateFromCommand(command, success); response.FailReason = ResponseFailReason.None; Send(response); }
/// <summary> /// Finds the perfect match response in a response array. If not found returns null /// </summary> /// <param name="responses">A Response array to search in</param> /// <param name="command">The command for which response to search</param> /// <returns>Returns the perfect match Response if found. If not, returns null</returns> public Response FindResponse(Command command, Response[] responses) { return FindResponse(command, responses, false); }
/// <summary> /// Gets all the information related to a shared variable /// </summary> /// <param name="command">Command to execute</param> protected virtual void StatVarCommand(Command command) { Robotics.API.SharedVariableInfo svInfo; string serialized; string varName = command.Parameters; if (!parent.VirtualModule.SharedVariables.Contains(varName)) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to get status of variable " + varName + " failed (variable does not exist)"); return; } svInfo = parent.VirtualModule.SharedVariables[varName].GetInfo(); if (!Robotics.API.SharedVariableInfo.Serialize(svInfo, out serialized)) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to get status of variable " + varName + " failed (serialization error)"); return; } command.Parameters = serialized; SendResponse(command, true); this.Parent.Log.WriteLine(7, this.Name + ": status of variable " + varName + " obtained successfully"); }
/// <summary> /// Raises the ResponseRedirected event /// </summary> /// <param name="command">Command tried to be executed</param> /// <param name="response">Response to command redirected</param> /// <param name="sendResponseSuccess">Indicates if the response was sent successfully</param> protected virtual void OnResponseRedirected(Command command, Response response, bool sendResponseSuccess) { if ((ResponseRedirected != null) && (command != null) && (command.Source != VirtualModule) && (command.Destination != VirtualModule)) ResponseRedirected(command, response, sendResponseSuccess); }
/// <summary> /// Executes a write_var command. /// Requests the blackboard to write to a stored a variable the content provided /// </summary> /// <param name="command">Command to execute</param> protected virtual void WriteVarCommand(Command command) { SharedVariableCollection sharedVariables = this.Parent.VirtualModule.SharedVariables; Match match; string varType; string varName; string varData; string sArraySize; int arraySize; bool result; bool isArray = false; string parameters; parameters = command.Parameters; if ((parameters[0] == '{') && (parameters[parameters.Length - 1] == '}')) parameters = parameters.Substring(1, parameters.Length - 2); match = SharedVariable.RxWriteSharedVariableValidator.Match(parameters); if (!match.Success) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to write variable failed"); return; } varName = match.Result("${name}"); varType = match.Result("${type}"); varData = match.Result("${data}"); arraySize = -1; if (String.IsNullOrEmpty(varType)) varType = "var"; if (!String.IsNullOrEmpty(match.Result("${array}"))) { isArray = true; sArraySize = match.Result("${size}"); if (!String.IsNullOrEmpty(sArraySize)) arraySize = Int32.Parse(sArraySize); } if(isArray) parameters = "{ " + varType + "[" + (arraySize != -1 ? arraySize.ToString() : String.Empty) + "]" + " " + varName + " }"; else parameters = "{ " + varType + " " + varName + " }"; command.Parameters = parameters; if (!sharedVariables.Contains(varName)) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to write variable " + varName + " failed (variable does not exist)"); return; } result = sharedVariables[varName].WriteStringData(command.Source, varType, arraySize, varData); SendResponse(command, result); if (this.Parent.Log.VerbosityTreshold < 3) this.Parent.Log.WriteLine(2, this.Name + ": written variable " + varName); else this.Parent.Log.WriteLine(3, this.Name + ": written variable " + varName + " with " + Clamper.Clamp(command.StringToSend, 256)); }
/// <summary> /// Gets a value indicating if provided Response is a response for provided command and calculates the afinity between them /// </summary> /// <param name="command">Command to check with</param> /// <param name="response">Response to check</param> /// <param name="afinity">An integer that represents how much compatible are the command and response provided. /// A Zero value indicates the most high afinity between them. This parameter is passed uninitialized.</param> /// <returns>true if provided Response is a response for command, false otherwise</returns> public static bool IsMatch(Command command, Response response, out int afinity) { // This one is if the response destination is known afinity = 0; bool result = false; if (response.Destination != null) { result = (command.Source == response.Destination) && (command.Destination == response.Source) && (command.Command == response.Command) && (command.SentTime <= response.ArrivalTime); //if((command.Id != -1) && (response.Id != -1) && (command.Id != response.Id)) ++afinity; if (command.Id != response.Id) ++afinity; if (command.parameters != response.Parameters) ++afinity; } else { ++afinity; result = (command.Destination == response.Source) && (command.Command == response.Command) && (command.SentTime <= response.ArrivalTime); //if((command.Id != -1) && (response.Id != -1) && (command.Id != response.Id)) ++afinity; if (command.Id != response.Id) ++afinity; if (command.parameters != response.Parameters) ++afinity; } // This one is for search for an adequate command-response match return result; }
/// <summary> /// Marks the module as Busy and adds the command to list of blocking commands /// </summary> /// <param name="command"></param> private void Lock(Command command) { lockList.Add(command); Busy = true; }
/// <summary> /// Converts the string representation of a command to a Command object. /// A return value indicates whether the conversion succeded or not. /// </summary> /// <param name="s">A string containing the command to convert</param> /// <param name="source">The module which sent the command</param> /// <param name="destination">The destination module for the command</param> /// <param name="command">When this method returns, contains the Command equivalent to the command /// contained in s, if the conversion succeeded, or null if the conversion failed. /// The conversion fails if the s parameter is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <returns>true if conversion was successfull, false otherwise</returns> public static bool TryParse(string s, ModuleClient source, ModuleClient destination, out Command command) { Exception ex; return TryParse(s, source, destination, out command, out ex); }
/// <summary> /// Check if given Command object matches a control command/response /// </summary> /// <param name="cmd">Command object to check</param> /// <returns>true if given CommandBase object is control command/, false otherwise</returns> public static bool IsControlCommand(Command cmd) { //return Regex.IsMatch(cmd.StringToSend, @"^(" + RxControlCommandNames + @")(\s+@\d+)?$") && !cmd.HasParams; return rxControlCommandParser.IsMatch(cmd.StringToSend) && !cmd.HasParams; }
/// <summary> /// Converts the string representation of a command to a Command object. /// A return value indicates whether the conversion succeded or not. /// </summary> /// <param name="s">A string containing the command to convert</param> /// <param name="source">The module which sent the command</param> /// <param name="cmd">When this method returns, contains the Command equivalent to the command /// contained in s, if the conversion succeeded, or null if the conversion failed. /// The conversion fails if the s parameter is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <param name="ex">When this method returns, contains the Exception generated during the parse operation, /// if the conversion failed, or null if the conversion succeeded. The conversion fails if the s parameter /// is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <returns>true if conversion was successfull, false otherwise</returns> protected static bool TryParse(string s, Module source, out Command cmd, out Exception ex) { Regex rx; Match m; Prototype proto; //Module destination; IModule destination; string sCommand; string sParams; string sDest; string sId; int id; cmd = null; ex = null; // Regular Expresion Generation //rx = new Regex(@"((?<src>[\w\-]+)(\s+(?<dest>[\w\-]+))?\s+)?(?<cmd>[A-Za-z_]+)\s+(""(?<params>[^""]*)"")?\s+(@(?<id>\d+))?"); rx = rxCommandFromSource; m = rx.Match(s); // Check if input string matchs Regular Expression if (!m.Success) { ex = new ArgumentException("Invalid String", "s"); return false; } // Extract Data sCommand = m.Result("${cmd}").ToLower(); sParams = m.Result("${params}"); sId = m.Result("${id}"); sDest = m.Result("${dest}"); if ((sId == null) || (sId.Length < 1)) id = -1; else id = Int32.Parse(sId); // Browse for destination module and prototype if (!source.Parent.FindDestinationModule(sCommand, out destination, out proto)) { // No destination module found. Must check if destination is availiable if ((sDest == null) || (sDest.Length < 1) || !source.Parent.Modules.Contains(sDest)) { ex = new Exception("No destination module found for command provided"); return false; } destination = source.Parent.Modules[sDest]; proto = null; } // Check if command matchs a prototype if ((proto != null) && proto.ParamsRequired && ((sParams == null) || (sParams.Length < 1))) { ex = new Exception("Invalid string. The Command requires parameters"); return false; } // Create the Command cmd = new Command(source, destination, sCommand, sParams, id); cmd.prototype = proto; cmd.sentTime = DateTime.Now; return true; }
/// <summary> /// Sends a command to the module /// </summary> /// <param name="command">Response to send</param> /// <returns>true if the command has been sent, false otherwise</returns> public virtual bool Send(Command command) { // Check if this module is the destination module for the command if (this != command.Destination) throw new Exception("Command marked to be sent through other module"); if (!this.enabled) return false; ++command.SendAttempts; // Simulation mode #region Simulation Mode if (simOptions.SimulationEnabled) { Response r = Response.CreateFromCommand(command, rnd.NextDouble() <= simOptions.SuccessRatio); command.SentStatus = SentStatus.SentSuccessfull; this.ParseResponse(r); return true; } #endregion // Check if module is not busy and command is not a priority command if (Busy && !command.Prototype.HasPriority && !IsControlCommand(command)) { command.SentStatus = SentStatus.SentFailed; return false; } // Send the command if (Send(command.StringToSend + "")) { command.SentStatus = SentStatus.SentSuccessfull; if (command.Prototype.ResponseRequired) Lock(command); } else { command.SentStatus = SentStatus.SentFailed; return false; } return true; }
/// <summary> /// Converts the string representation of a command to a Command object. /// A return value indicates whether the conversion succeded or not. /// </summary> /// <param name="s">A string containing the command to convert</param> /// <param name="source">The module which sent the command</param> /// <param name="cmd">When this method returns, contains the Command equivalent to the command /// contained in s, if the conversion succeeded, or null if the conversion failed. /// The conversion fails if the s parameter is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <param name="ex">When this method returns, contains the Exception generated during the parse operation, /// if the conversion failed, or null if the conversion succeeded. The conversion fails if the s parameter /// is a null reference (Nothing in Visual Basic) or is not of the correct format. /// This parameter is passed uninitialized</param> /// <returns>true if conversion was successfull, false otherwise</returns> protected static bool TryParse(string s, ModuleClient source, out Command cmd, out Exception ex) { IPrototype proto; //Module destination; IModuleClient destination; string sCommand; string sParams; string sDest; int result; int id; cmd = null; ex = null; // Extract Data CommandBase.XtractCommandElements(s, out sDest, out sCommand, out sParams, out result, out id); if ((sCommand == null) || (result != -1)) { ex = new ArgumentException("Invalid String", "s"); return false; } // Browse for destination module and prototype if (source.SupportCommand(sCommand, out proto)) destination = source; else if(!source.Parent.FindDestinationModule(sCommand, out destination, out proto)) { // No destination module found. Must check if destination is availiable if ((sDest == null) || (sDest.Length < 1) || !source.Parent.Modules.Contains(sDest)) { ex = new Exception("No destination module found for command provided"); return false; } destination = source.Parent.Modules[sDest]; proto = null; } // Check if command matchs a prototype if (proto == null) { ex = new Exception("No prototype for provided command was found"); return false; } if ((proto != null) && proto.ParamsRequired && ((sParams == null) || (sParams.Length < 1))) { ex = new Exception("Invalid string. The Command requires parameters"); return false; } // Create the Command cmd = new Command(source, destination, sCommand, sParams, id); cmd.prototype = proto; cmd.sentTime = DateTime.Now; return true; }
/// <summary> /// Executes a create_var command. /// Requests the blackboard to create a variable with the specified name and size /// </summary> /// <param name="command">Command to execute</param> protected virtual void CreateVarCommand(Command command) { SharedVariable variable; bool result; SharedVariableCollection sharedVariables = this.Parent.VirtualModule.SharedVariables; Match match = SharedVariable.RxCreateSharedVariableValidator.Match(command.Parameters); if (!match.Success) { SendResponse(command, false); this.Parent.Log.WriteLine(7, this.Name + ": attempt to create variable failed"); return; } string varName = match.Result("${name}"); string varType = match.Result("${type}"); bool isArray = false; string sArraySize; int arraySize = -1; if (String.IsNullOrEmpty(varType)) varType = "var"; if (!String.IsNullOrEmpty(match.Result("${array}"))) { isArray = true; sArraySize = match.Result("${size}"); if (!String.IsNullOrEmpty(sArraySize)) arraySize = Int32.Parse(sArraySize); } if (sharedVariables.Contains(varName)) { variable = sharedVariables[varName]; result = variable.Type == varType; result &= variable.IsArray == isArray; result &= arraySize == variable.Size; SendResponse(command, result); this.Parent.Log.WriteLine(7, this.Name + ": attempt to create variable failed (already exists)"); return; } SharedVariable sv = new SharedVariable(this, varType, varName, isArray, arraySize); sv.AllowedWriters.Add("*"); sharedVariables.Add(sv); SendResponse(command, true); if (this.Parent.Log.VerbosityTreshold < 3) this.Parent.Log.WriteLine(2, this.Name + ": created variable " + varName); else this.Parent.Log.WriteLine(3, this.Name + ": created variable " + varName + " with " + Clamper.Clamp(command.StringToSend, 256)); }