Пример #1
0
        /// <summary>
        /// Remote call a function by its name with arguments and get the returned value
        /// </summary>
        /// <typeparam name="ReturnType">The .NET type expected. Should be the same as the Arduino function return type</typeparam>
        /// <param name="functionName">Name of the function to call</param>
        /// <param name="timeout">Maximum expected duration of the function execution on Arduino</param>
        /// <param name="arguments">Optional list of argument values.</param>
        /// <returns>Status of the function call with its returned value</returns>
        public SharerFunctionReturn <ReturnType> Call <ReturnType>(string functionName, TimeSpan timeout, params object[] arguments)
        {
            AssertConnected();

            if (functionName == null)
            {
                throw new ArgumentNullException("functionName");
            }

            Int16          functionId = -1;
            SharerFunction function   = null;

            for (int i = 0; i < Functions.Count; i++)
            {
                if (Functions[i].Name == functionName)
                {
                    function   = Functions[i];
                    functionId = (Int16)i;
                    break;
                }
            }

            if (function == null || functionId < 0)
            {
                throw new Exception(functionName + " not found in function list. Try to update the function List or check if this function has been shared.");
            }

            if (arguments == null || arguments.Length == 0)
            {
                if (function.Arguments.Count != 0)
                {
                    throw new Exception("Attempt to call the function " + function.Name + " with no arguments, but the function has " + function.Arguments.Count + " arguments");
                }
            }
            else if (function.Arguments.Count != arguments.Length)
            {
                throw new Exception("Attempt to call the function " + function.Name + " with " + arguments.Length + " argument(s), but the function has " + function.Arguments.Count + " argument(s)");
            }

            byte[] buffer;

            using (MemoryStream memory = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(memory))
                {
                    writer.Write(functionId);

                    if (arguments != null)
                    {
                        for (int i = 0; i < arguments.Length; i++)
                        {
                            if (arguments[i] == null)
                            {
                                throw new ArgumentNullException("arguments[" + i + "]");
                            }

                            try
                            {
                                SharerTypeHelper.Encode(function.Arguments[i].Type, writer, arguments[i]);
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Error in argument " + function.Arguments[i].Name + " of function " + function.Name, ex);
                            }
                        }
                    }


                    buffer = memory.ToArray();
                }
            }

            var cmd = new SharerCallFunctionCommand <ReturnType>(buffer, function.ReturnType);

            sendCommand(cmd);

            bool success = cmd.WaitAnswer(timeout);

            if (!success)
            {
                throw new Exception("Error while calling function " + functionName, cmd.Exception);
            }

            return(cmd.Return);
        }
        internal override bool DecodeArgument(byte b)
        {
            switch (_receivedStep)
            {
            case Steps.FunctionCountHigh:     // get number of functions
                Functions.Clear();
                _nbFunctions  = b;
                _receivedStep = Steps.FunctionCountLow;
                break;

            case Steps.FunctionCountLow:
                _nbFunctions = _nbFunctions + 256 * b;
                if (_nbFunctions == 0)
                {
                    _receivedStep = Steps.End;     // if no function, stop parsing
                }
                else
                {
                    _receivedStep = Steps.ArgumentCount;
                }
                break;

            case Steps.ArgumentCount:     // get number of functions
                _currentFunction = new SharerFunction();
                _nbArguments     = b;
                _receivedStep    = Steps.FunctionReturnType;
                break;

            case Steps.FunctionReturnType:     // get return type
                _currentFunction.ReturnType = (SharerType)b;
                _nameByte.Clear();
                _receivedStep = Steps.FunctionName;
                break;

            case Steps.FunctionName:     // get function name
                // if end of name
                if (b == 0)
                {
                    _currentFunction.Name = System.Text.Encoding.UTF8.GetString(_nameByte.ToArray(), 0, _nameByte.Count);
                    if (_nbArguments > 0)     // if this function has arguments
                    {
                        _receivedStep = Steps.ArgumentType;
                    }
                    else
                    {
                        Functions.Add(_currentFunction);

                        if (Functions.Count >= _nbFunctions)     // if enought function
                        {
                            _receivedStep = Steps.End;
                        }
                        else     // else, go to next function
                        {
                            _receivedStep = Steps.ArgumentCount;
                        }
                    }
                }
                else     // else, store value
                {
                    _nameByte.Add(b);
                }
                break;

            case Steps.ArgumentType:     // Get argument type
                _currentArgument      = new SharerFunctionArgument();
                _currentArgument.Type = (SharerType)b;
                _nameByte.Clear();
                _receivedStep = Steps.ArgumentName;
                break;

            case Steps.ArgumentName:     // Get argument name
                // if end of name
                if (b == 0)
                {
                    _currentArgument.Name = System.Text.Encoding.Default.GetString(_nameByte.ToArray(), 0, _nameByte.Count);
                    _currentFunction.Arguments.Add(_currentArgument);


                    if (_currentFunction.Arguments.Count >= _nbArguments)    // if all arguments for this function has been read
                    {
                        Functions.Add(_currentFunction);

                        if (Functions.Count >= _nbFunctions)     // if enought functions
                        {
                            _receivedStep = Steps.End;
                        }
                        else     // else, go to next function
                        {
                            _receivedStep = Steps.ArgumentCount;
                        }
                    }
                    else     // else, go to next argument
                    {
                        _receivedStep = Steps.ArgumentType;
                    }
                }
                else     // else, store value
                {
                    _nameByte.Add(b);
                }
                break;

            default:
                break;
            }


            return(_receivedStep == Steps.End);
        }