Пример #1
0
        public DiscoveryControllerResponse Discovery(AlexaDiscoveryControllerRequest request)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            AlexaDiscoveryController controller = new AlexaDiscoveryController(request);

            if (controller.ValidateDirective())
            {
                controller.ProcessControllerDirective();
            }
            stopwatch.Stop();
            PremiseServer.WriteToWindowsApplicationEventLog(EventLogEntryType.Information, $"Discovery processing time {stopwatch.ElapsedMilliseconds}ms", 51);
            return(controller.Response);
        }
Пример #2
0
        public SystemResponse System(SystemRequest alexaRequest)
        {
            var response = new SystemResponse
            {
                header = new Header
                {
                    @namespace = "System"
                },
                payload = new SystemResponsePayload()
            };

            if (PremiseServer.HomeObject == null)
            {
                response.header.@namespace = Faults.Namespace;
                response.header.name       = Faults.DependentServiceUnavailableError;
                response.payload.exception = new ExceptionResponsePayload
                {
                    dependentServiceName = "Premise Server"
                };
                return(response);
            }

            switch (alexaRequest.header.name)
            {
            case "HealthCheckRequest":
                PremiseServer.InformLastContactAsync("System:HealthCheckRequest").GetAwaiter().GetResult();
                response.header.name = "HealthCheckResponse";
                response.payload     = GetHealthCheckResponseV3();
                break;

            default:
                response.header.@namespace = Faults.Namespace;
                response.header.name       = Faults.UnsupportedOperationError;
                response.payload.exception = new ExceptionResponsePayload();
                break;
            }
            return(response);
        }
Пример #3
0
        public AuthorizationResponse Authorization(AuthorizationRequest request)
        {
            AuthorizationDirective directive = request.directive;

            var response = new AuthorizationResponse(directive);

            #region Validate request

            if (directive.header.payloadVersion != "3")
            {
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INVALID_DIRECTIVE, "Invalid payload version.");
                return(response);
            }

            #endregion Validate request

            #region Verify Access

            if ((directive.payload.grantee == null) || (directive.payload.grantee.type != "BearerToken"))
            {
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INVALID_DIRECTIVE, "Invalid bearer token.");
                return(response);
            }

            try
            {
                if (!PremiseServer.CheckAccessTokenAsync(directive.payload.grantee.localAccessToken).GetAwaiter().GetResult())
                {
                    [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INVALID_AUTHORIZATION_CREDENTIAL, "Not authorized on local premise server.");
                    return(response);
                }
            }
            catch (Exception ex)
            {
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INTERNAL_ERROR, ex.Message);
                return(response);
            }

            #endregion Verify Access

            try
            {
                if (PremiseServer.HomeObject == null)
                {
                    [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.ENDPOINT_UNREACHABLE, "Premise Server.");
                    return(response);
                }

                using (PremiseServer.AsyncObjectsLock.Lock())
                {
                    PremiseServer.HomeObject.SetValueAsync("AlexaAsyncAuthorizationCode", directive.payload.grant.access_token).GetAwaiter().GetResult();
                    PremiseServer.HomeObject.SetValueAsync("AlexaAsyncAuthorizationRefreshToken", directive.payload.grant.refresh_token).GetAwaiter().GetResult();
                    PremiseServer.HomeObject.SetValueAsync("AlexaAsyncAuthorizationClientId", directive.payload.grant.client_id).GetAwaiter().GetResult();
                    PremiseServer.HomeObject.SetValueAsync("AlexaAsyncAuthorizationSecret", directive.payload.grant.client_secret).GetAwaiter().GetResult();

                    DateTime expiry = DateTime.UtcNow.AddSeconds(directive.payload.grant.expires_in);
                    PremiseServer.HomeObject.SetValueAsync("AlexaAsyncAuthorizationCodeExpiry", expiry.ToString(CultureInfo.InvariantCulture)).GetAwaiter().GetResult();
                }

                const string message = "Skill is now enabled and authorized to send async updates to Alexa. A task has been started to subscribe to property change events.";
                PremiseServer.InformLastContactAsync(message).GetAwaiter().GetResult();
                PremiseServer.WriteToWindowsApplicationEventLog(EventLogEntryType.Information, message, 60);

                Task.Run(async() =>
                {
                    // Generate Discovery Json
                    await PremiseServer.HomeObject.SetValueAsync("GenerateDiscoveryJson", "True").ConfigureAwait(false);
                    // Signal sending async property change events - this will also subscribe to all properties
                    await PremiseServer.HomeObject.SetValueAsync("SendAsyncEventsToAlexa", "True").ConfigureAwait(false);
                });
            }
            catch (Exception ex)
            {
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INTERNAL_ERROR, ex.Message);
                return(response);
            }

            return(response);
        }
Пример #4
0
        public ReportStateResponse ReportState(ReportStateRequest request)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            AlexaDirective directive = request.directive;

            var response = new ReportStateResponse(directive);

            #region Validate request

            if (directive.header.payloadVersion != "3")
            {
                response.context        = null;
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INVALID_DIRECTIVE, "Invalid payload version.");
                return(response);
            }

            #endregion Validate request

            #region Connect To Premise Server

            try
            {
                if (PremiseServer.HomeObject == null)
                {
                    response.context        = null;
                    [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.ENDPOINT_UNREACHABLE, "Premise Server.");
                    return(response);
                }
            }
            catch (Exception)
            {
                response.context        = null;
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.ENDPOINT_UNREACHABLE, "Premise Server.");
                return(response);
            }

            #endregion Connect To Premise Server

            #region Verify Access

            try
            {
                if ((directive.endpoint.scope == null) || (directive.endpoint.scope.type != "BearerToken"))
                {
                    response.context        = null;
                    [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INVALID_DIRECTIVE, "Invalid bearer token.");
                    return(response);
                }

                if (!PremiseServer.CheckAccessTokenAsync(directive.endpoint.scope.localAccessToken).GetAwaiter().GetResult())
                {
                    response.context        = null;
                    [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INVALID_AUTHORIZATION_CREDENTIAL, "Not authorized on local premise server.");
                    return(response);
                }
            }
            catch
            {
                response.context        = null;
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INTERNAL_ERROR, "Cannot find Alexa home object on local Premise server.");
                return(response);
            }

            #endregion Verify Access

            #region Get Premise Object

            IPremiseObject endpoint;
            try
            {
                Guid premiseId = new Guid(directive.endpoint.endpointId);
                endpoint = PremiseServer.HomeObject.GetObjectAsync(premiseId.ToString("B")).GetAwaiter().GetResult();
                if (!endpoint.IsValidObject())
                {
                    response.context        = null;
                    [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.NO_SUCH_ENDPOINT,
                                                                            $"Cannot find device {directive.endpoint.endpointId} on server.");
                    return(response);
                }
            }
            catch
            {
                response.context        = null;
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.NO_SUCH_ENDPOINT,
                                                                        $"Cannot find device {directive.endpoint.endpointId} on server.");
                return(response);
            }

            if (directive.header.name != "ReportState")
            {
                response.context        = null;
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INVALID_DIRECTIVE, "Invalid Directive");
                return(response);
            }

            #endregion Get Premise Object

            DiscoveryEndpoint discoveryEndpoint = PremiseServer.GetDiscoveryEndpointAsync(endpoint).GetAwaiter().GetResult();
            if (discoveryEndpoint == null)
            {
                response.context        = null;
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INTERNAL_ERROR,
                                                                        $"Cannot find or invalid discoveryJson for {directive.endpoint.endpointId} on server.");
                return(response);
            }
            [email protected] = discoveryEndpoint.cookie;
            try
            {
                // use reflection to instantiate all device type controllers
                var interfaceType = typeof(IAlexaDeviceType);
                var all           = AppDomain.CurrentDomain.GetAssemblies()
                                    .SelectMany(x => x.GetTypes())
                                    .Where(x => interfaceType.IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract)
                                    .Select(Activator.CreateInstance);

                foreach (IAlexaDeviceType deviceType in all)
                {
                    var related = deviceType.FindRelatedProperties(endpoint, "");
                    foreach (AlexaProperty property in related)
                    {
                        if (!response.context.propertiesInternal.ContainsKey(property.@namespace + "." + property.name))
                        {
                            response.context.propertiesInternal.Add(property.@namespace + "." + property.name, property);
                        }
                    }
                }

                foreach (Capability capability in discoveryEndpoint.capabilities)
                {
                    switch (capability.@interface)  // scenes are special cased
                    {
                    case "Alexa.SceneController":
                    {
                        AlexaSetSceneController controller = new AlexaSetSceneController(endpoint);
                        AlexaProperty           prop       = controller.GetPropertyStates()[0];
                        [email protected]   = (string)prop.value;
                        [email protected] = new ChangeReportCause
                        {
                            type = "VOICE_INTERACTION"
                        };
                        [email protected] = prop.timeOfSample;
                    }
                    break;
                    }
                }
            }
            catch (Exception ex)
            {
                response.context        = null;
                [email protected] = new AlexaErrorResponsePayload(AlexaErrorTypes.INTERNAL_ERROR, ex.Message);
                return(response);
            }

            [email protected] = "StateReport";
            PremiseServer.InformLastContactAsync($"StateReport: {response.@event?.endpoint?.cookie?.path}").GetAwaiter().GetResult();
            stopwatch.Stop();
            if ([email protected] != null)
            {
                [email protected] = stopwatch.ElapsedMilliseconds;
            }
            return(response);
        }
Пример #5
0
 public void Preload(string[] parameters)
 {
     Task.Run(() => PremiseServer.WarmUpCache());
 }