Exemplo n.º 1
0
        public void OnDataAvailable(SensorDataPacket packet)
        {
            HandleTimeout();
            if (IsCancelled)
            {
                return;
            }
            if (packet.DataType != SensorDataType.Video)
            {
                // only video data supported
                return;
            }
            var frame = packet.GenericData as VideoFrame;

            if (frame == null)
            {
                // unsupported content
                return;
            }
            // generate a base64 string from the video frame
            string imageString = string.Empty;

            if (includeImage)
            {
                imageString = CompressImage(frame);
            }
            // craete a message that contains the compressed image
            // and send it through the consumer to the client
            var message = new JsonString(messageTemplate);

            var subject = JsonString.CreateDict();

            {
                subject.AddTerminal("type", JsonString.StringifyString("post"));
                subject.AddTerminal("topic", JsonString.StringifyString("sensorCapture"));
                subject.AddTerminal("position", JsonString.Stringify(sensorIndex));
                var dataArray = JsonString.CreateArray();
                {
                    var dataEntry = JsonString.CreateDict();
                    {
                        if (includeImage && imageString.Length > 2)
                        {
                            dataEntry.AddTerminal("image", imageString);
                        }
                        dataEntry.AddTerminal("frameWidth", JsonString.Stringify(frame.Width));
                        dataEntry.AddTerminal("frameHeight", JsonString.Stringify(frame.Height));
                        var metadata = frame.Metadata;
                        dataEntry.AddTerminal("frameRate", JsonString.Stringify(metadata.FrameRate));
                        dataEntry.AddTerminal("frameTime", JsonString.Stringify(metadata.FrameTime));
                        dataEntry.AddTerminal("frameTimeDeviation", JsonString.Stringify(metadata.FrameTimeDeviation));
                    }
                    dataArray.AddJsonString(string.Empty, dataEntry);
                }
                subject.AddJsonString("data", dataArray);
            }
            message.AddJsonString("subject", subject);
            string str = message.ToJsonString();

            consumer.EnqueueMessage(message);
        }
Exemplo n.º 2
0
        public override HttpStatusCode Respond(JsonString subject, JsonString response)
        {
            if (subject == null)
            {
                throw new ArgumentNullException("subject");
            }
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }


            bool   isGetRequest;
            string type = JsonString.ParseString(subject.GetTerminal("type", "error"), "error");

            if (type.Equals("get"))
            {
                isGetRequest = true;
            }
            else if (type.Equals("post"))
            {
                isGetRequest = false;
            }
            else
            {
                return(HttpStatusCode.BadRequest);
            }
            int[] positions = ReadPosition(subject);
            if (positions == null)
            {
                return(HttpStatusCode.BadRequest);
            }
            var responseSubject = JsonString.CreateDict();

            {
                responseSubject.AddTerminal("type", JsonString.StringifyString("post"));
                responseSubject.AddTerminal("topic", JsonString.StringifyString("tracker"));
            }
            response.AddJsonString("subject", responseSubject);

            if (isGetRequest)
            {
                return(RespondGet(subject, responseSubject, positions));
            }
            else
            {
                HttpStatusCode status = RespondPost(subject, responseSubject, positions);
                // not only send the result to one recipient but create an update for all clients
                if (status == HttpStatusCode.OK)
                {
                    var update = new JsonString(response);
                    update.RemoveTerminal("requestId");
                    update.AddTerminal("target", "\"all\"");
                    server.PostUpdate(update);
                }
                return(status);
            }
        }
Exemplo n.º 3
0
 private void CreateErrorResponse(JsonString request, JsonString response, HttpStatusCode status)
 {
     // add status code information
     if (response.Type == JsonStringType.Array)
     {
         // unexpected -> give minimal response
         var error = JsonString.CreateDict();
         error.AddTerminal("status", JsonString.Stringify((int)status));
         response.AddJsonString(string.Empty, error);
         return;
     }
     response.AddTerminal("status", JsonString.Stringify((int)status));
     // add the original message to failed updates
     // that way it is easier to recognize the failed operation
     if (response.GetTerminal("requestId", string.Empty).Length == 0)
     {
         response.AddJsonString("request", new JsonString(request));
     }
 }
Exemplo n.º 4
0
        private HttpStatusCode RespondGet(JsonString requestSubject, JsonString responseSubject, int sensorStart, int sensorEnd)
        {
            object     dataSync = new object();
            JsonString data;

            lock (dataSync) {             // TODO lock required?
                data = JsonString.CreateArray();
            }
            var readySignal = new ManualResetEvent(false);

            CaptureSystem.Instance.Invoke((object sender, EventArgs args) => {
                var system = (CaptureSystem)sender;
                for (int i = sensorStart; i <= sensorEnd; i++)
                {
                    var entry          = JsonString.CreateDict();
                    ISensorBase sensor = system.GetSensor(i);
                    if (sensor == null)
                    {
                        entry.AddTerminal("inuse", "false");
                    }
                    else if (sensor.SensorType == SensorType.Webcam)
                    {
                        var capture = (WebcamCapture)sensor;
                        EquipmentSettings settings = capture.GetSettings();
                        entry.AddTerminal("inuse", "true");
                        entry.AddJsonString("settings", EquipmentSettings.ToJson(settings));
                    }
                    else
                    {
                        entry.AddTerminal("inuse", "false");
                    }
                    data.AddJsonString(string.Empty, entry);
                }
                readySignal.Set();
            });
            readySignal.WaitOne();
            lock (dataSync) {
                responseSubject.AddJsonString("data", data);
            }
            return(HttpStatusCode.OK);
        }
Exemplo n.º 5
0
        public HttpStatusCode Respond(JsonString subject, JsonString response)
        {
            if (subject == null)
            {
                throw new ArgumentNullException("subject");
            }
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }
            // send the client and server origin ids as subject
            // while the type must be 'get' which is answered with 'post'
            HttpStatusCode status = HttpStatusCode.OK;

            do
            {
                string type = JsonString.ParseString(subject.GetTerminal("type", "error"), "error");
                if (!type.Equals("get"))
                {
                    status = HttpStatusCode.Forbidden;
                    break;
                }
                response.AddTerminal("origin", JsonString.Stringify(serverOrigin));
                var rSubject = JsonString.CreateDict();
                {
                    rSubject.AddTerminal("type", JsonString.StringifyString("post"));
                    rSubject.AddTerminal("topic", JsonString.StringifyString("origin"));
                    var data = JsonString.CreateDict();
                    {
                        data.AddTerminal("serverOrigin", JsonString.Stringify(serverOrigin));
                        data.AddTerminal("clientOrigin", JsonString.Stringify(clientOrigin));
                    }
                    rSubject.AddJsonString("data", data);
                }
                response.AddJsonString("subject", rSubject);
            } while (false);
            return(status);
        }
Exemplo n.º 6
0
        private HttpStatusCode RespondGet(JsonString requestSubject, JsonString responseSubject, int[] positions)
        {
            object     dataSync = new object();
            JsonString data;

            lock (dataSync) {             // TODO lock required?
                data = JsonString.CreateDict();
            }
            var readySignal = new ManualResetEvent(false);

            TrackingSystem.Instance.Invoke((object sender, EventArgs args) => {
                var system = (TrackingSystem)sender;
                foreach (int pos in positions)
                {
                    var entry            = JsonString.CreateDict();
                    IPoseTracker tracker = system.GetTracker(pos);
                    if (tracker == null)
                    {
                        entry.AddTerminal("inuse", "false");
                    }
                    else if (tracker is P3CapTracker)
                    {
                        var capTracker             = (P3CapTracker)tracker;
                        EquipmentSettings settings = capTracker.GetSettings();
                        entry.AddTerminal("inuse", "true");
                        entry.AddJsonString("settings", EquipmentSettings.ToJson(settings));
                    }
                    data.AddJsonString(JsonString.Stringify(pos), entry);
                }
                readySignal.Set();
            });
            readySignal.WaitOne();
            lock (dataSync) {
                responseSubject.AddJsonString("data", data);
            }
            return(HttpStatusCode.OK);
        }
Exemplo n.º 7
0
        public HttpStatusCode Respond(JsonString subject, JsonString response)
        {
            if (subject == null)
            {
                throw new ArgumentNullException("subject");
            }
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            int    sensorStart = -2;
            int    sensorEnd   = 0;
            bool   isGetRequest;
            string type = JsonString.ParseString(subject.GetTerminal("type", "error"), "error");

            if (type.Equals("get"))
            {
                isGetRequest = true;
            }
            else if (type.Equals("post"))
            {
                isGetRequest = false;
            }
            else
            {
                return(HttpStatusCode.BadRequest);
            }

            string position = JsonString.ParseString(subject.GetTerminal("position", "all"), "all");

            if (position.Equals("all"))
            {
                sensorStart = 0;
                sensorEnd   = 15;               // TODO replace with actual capacity
            }
            else
            {
                sensorStart = JsonString.ParseInt(position, -1);
                sensorEnd   = sensorStart;
            }
            if (sensorStart < 0)
            {
                return(HttpStatusCode.NotFound);
            }

            var responseSubject = JsonString.CreateDict();

            responseSubject.AddTerminal("type", JsonString.StringifyString("post"));
            responseSubject.AddTerminal("topic", JsonString.StringifyString("camera"));
            responseSubject.AddTerminal("position", JsonString.StringifyString(position));
            response.AddJsonString("subject", responseSubject);

            if (isGetRequest)
            {
                return(RespondGet(subject, responseSubject, sensorStart, sensorEnd));
            }
            else
            {
                if (sensorStart != sensorEnd)
                {
                    return(HttpStatusCode.BadRequest);
                }
                HttpStatusCode status = RespondPost(subject, responseSubject, sensorStart);
                // not only send the result to one recipient but create an update for all clients
                if (status == HttpStatusCode.OK)
                {
                    var update = new JsonString(response);
                    update.RemoveTerminal("requestId");
                    update.AddTerminal("target", "\"all\"");
                    server.PostUpdate(update);
                }
                return(status);
            }
        }
Exemplo n.º 8
0
        private HttpStatusCode RespondPost(JsonString requestSubject, JsonString responseSubject, int sensorIndex)
        {
            object dataSync = new object();
            // first read the data from the data array
            JsonString data = requestSubject.GetJsonString("data");

            if (data == null || data.Type != JsonStringType.Array || data.Array.Count < 1)
            {
                return(HttpStatusCode.BadRequest);
            }
            var targetMap = new Dictionary <int, EquipmentSettings>();

            for (int i = 0; i <= 0; i++)
            {
                JsonString sensor = data.GetJsonString(0);
                if (sensor == null)
                {
                    return(HttpStatusCode.BadRequest);
                }
                bool used = JsonString.ParseBool(sensor.GetTerminal("inuse", "false"), false);
                if (used)
                {
                    JsonString jSettings = sensor.GetJsonString("settings");
                    if (jSettings == null)
                    {
                        return(HttpStatusCode.BadRequest);
                    }
                    var settings = EquipmentSettings.FromJson(jSettings, typeof(SensorProperty));
                    targetMap.Add(sensorIndex + i, settings);
                }
            }

            // secondly satisfy the request
            var status      = HttpStatusCode.OK;
            var resultMap   = new Dictionary <int, EquipmentSettings>();
            var readySignal = new ManualResetEvent(false);

            CaptureSystem.Instance.Invoke((object sender, EventArgs args) => {
                var system = (CaptureSystem)sender;
                for (int iSource = sensorIndex; iSource <= sensorIndex; iSource++)
                {
                    // first determine which operations to perform
                    int iTarget     = iSource;
                    bool connect    = false;
                    bool disconnect = false;
                    bool start      = false;
                    bool stop       = false;
                    bool apply      = false;


                    var entry          = data.GetJsonString(0);
                    ISensorBase sensor = system.GetSensor(sensorIndex);
                    EquipmentSettings sourceSettings = null;
                    SensorType sourceType            = SensorType.Webcam;
                    if (sensor != null)
                    {
                        sourceSettings = ((WebcamCapture)sensor).GetSettings();
                        int iType      = sourceSettings.GetInteger(SensorProperty.Type, -1);
                        if (iType > -1)
                        {
                            sourceType = (SensorType)iType;
                        }
                    }
                    EquipmentSettings targetSettings = null;
                    SensorType targetType            = SensorType.Webcam;
                    if (targetMap.TryGetValue(iSource, out targetSettings))
                    {
                        int iType = targetSettings.GetInteger(SensorProperty.Type, -1);
                        if (iType > -1)
                        {
                            targetType = (SensorType)iType;
                        }
                    }
                    if (sourceSettings == null && targetSettings != null)
                    {
                        connect = true;
                    }
                    else if (sourceSettings != null && targetSettings == null)
                    {
                        disconnect = true;
                    }
                    else if (sourceSettings == null && targetSettings == null)
                    {
                        // nothing to do
                    }
                    else
                    {
                        if (sourceType != targetType)
                        {
                            disconnect = true;
                            connect    = true;
                        }
                        apply = true;
                    }
                    if (targetSettings != null)
                    {
                        int iTargetCapturing = targetSettings.GetInteger(SensorProperty.Capturing, -1);
                        if (iTargetCapturing < 0)
                        {
                            // ignore if not available
                        }
                        else if (iTargetCapturing != 0)
                        {
                            start = true;
                        }
                        else
                        {
                            stop = true;
                        }
                    }
                    // TODO make restrictions or otherwise cover remaining possible cases
                    bool success = true;
                    // perform the operations which were activated above
                    if (disconnect && success)
                    {
                        if (system.DisconnectSensor(iSource))
                        {
                            LogManager.Instance.LogMessage(this, "Disconnected sensor " + iSource);
                            sensor = null;
                            // already removed from result map
                        }
                        else
                        {
                            // nothing changed
                            LogManager.Instance.LogError(this, "Failed to disconnect sensor " + iSource);
                            resultMap[iSource] = sourceSettings;
                            success            = false;
                        }
                    }
                    if (connect && success)
                    {
                        sensor    = new WebcamCapture(targetSettings);
                        int iNext = system.ConnectSensor(sensor, iTarget);
                        if (iNext == iTarget)
                        {
                            LogManager.Instance.LogMessage(this, "Connected sensor " + iNext);
                            targetSettings     = ((WebcamCapture)sensor).GetSettings();
                            resultMap[iTarget] = targetSettings;
                        }
                        else if (iNext < 0)
                        {
                            // failed, leave result map entry empty
                            LogManager.Instance.LogError(this, "Failed to connect new sensor");
                            sensor  = null;
                            success = false;
                        }
                        else
                        {
                            LogManager.Instance.LogMessage(this, "Connected sensor " + iNext);
                            // sensor connected with different index, which we can accept
                            iTarget          = iNext;
                            resultMap[iNext] = targetSettings;
                            targetSettings   = ((WebcamCapture)sensor).GetSettings();
                        }
                    }

                    if (stop && success)
                    {
                        if (system.StopSensor(iTarget))
                        {
                            LogManager.Instance.LogMessage(this, "Stopped sensor " + iTarget);
                        }
                        else
                        {
                            targetSettings = ((WebcamCapture)sensor).GetSettings();
                            success        = false;
                            LogManager.Instance.LogError(this, "Failed to stop sensor " + iTarget);
                        }
                        resultMap[iTarget] = targetSettings;
                    }
                    if (apply && success)
                    {
                        if (sensor != null)
                        {
                            if (((WebcamCapture)sensor).ApplySettings(targetSettings))
                            {
                                LogManager.Instance.LogMessage(this, "Applied new settings to sensor " + iTarget);
                            }
                            else
                            {
                                LogManager.Instance.LogError(this, "Failed to apply new settings to sensor " + iTarget);
                            }
                            targetSettings     = ((WebcamCapture)sensor).GetSettings();
                            resultMap[iTarget] = targetSettings;
                        }
                    }

                    if (start && success)
                    {
                        if (system.StartSensor(iSource))
                        {
                            LogManager.Instance.LogMessage(this, "Started sensor " + iSource);
                            targetSettings     = ((WebcamCapture)sensor).GetSettings();
                            resultMap[iTarget] = targetSettings;
                        }
                        else
                        {
                            LogManager.Instance.LogError(this, "Failed to start sensor " + iSource);
                            targetSettings     = ((WebcamCapture)sensor).GetSettings();
                            resultMap[iTarget] = targetSettings;
                            success            = false;
                        }
                    }
                    if (!success)
                    {
                        status = HttpStatusCode.InternalServerError;
                    }
                }
                readySignal.Set();
            });
            // lastly create an update for all clients
            if (!readySignal.WaitOne(10000))
            {
                return(HttpStatusCode.InternalServerError);
            }
            if (status != HttpStatusCode.OK)
            {
                return(status);
            }
            //var responseSubject = new JsonString(subject);
            {
                var updateData = JsonString.CreateArray();
                {
                    for (int i = sensorIndex; i <= sensorIndex; i++)
                    {
                        var entry = JsonString.CreateDict();
                        EquipmentSettings settings;
                        if (resultMap.TryGetValue(i, out settings))
                        {
                            entry.AddTerminal("inuse", "true");
                            entry.AddJsonString("settings", EquipmentSettings.ToJson(settings));
                        }
                        else
                        {
                            entry.AddTerminal("inuse", "false");
                        }
                        updateData.AddJsonString(string.Empty, entry);
                    }
                }
                responseSubject.AddJsonString("data", updateData);
            }
            return(HttpStatusCode.OK);
        }
Exemplo n.º 9
0
        public override HttpStatusCode Respond(JsonString subject, JsonString response)
        {
            if (subject == null)
            {
                throw new ArgumentNullException("subject");
            }
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }
            // read properties from the request
            string topic = JsonString.ParseString(subject.GetTerminal("topic", string.Empty), string.Empty);

            if (!topic.Equals("sensorCapture"))
            {
                return(HttpStatusCode.BadRequest);
            }
            int positionStart, positionEnd;

            if (!ReadPosition(subject, out positionStart, out positionEnd))
            {
                return(HttpStatusCode.BadRequest);
            }
            if (positionStart != positionEnd)
            {
                // not supported
                return(HttpStatusCode.BadRequest);
            }
            var template = new JsonString(response);

            template.RemoveTerminal("requestId");
            var responseSubject = JsonString.CreateDict();

            {
                responseSubject.AddTerminal("type", "\"post\"");
                responseSubject.AddTerminal("topic", "\"sensorCapture\"");
                responseSubject.AddTerminal("position", JsonString.Stringify(positionStart));
                responseSubject.AddJsonString("data", JsonString.CreateArray());
            }

            response.AddJsonString("subject", responseSubject);

            // the client can request optional information
            // captured images can take a lot of bandwidth and are there off by default
            int  timeout      = 10000;
            bool includeImage = false;
            var  dataArray    = subject.GetJsonString("data");

            if (dataArray != null)
            {
                var data = dataArray.GetJsonString(0);
                if (data != null)
                {
                    timeout      = JsonString.ParseInt(data.GetTerminal("timeout", ""), (int)timeout);
                    includeImage = JsonString.ParseBool(data.GetTerminal("includeImage", "false"), false);
                }
            }

            // try to get sensor data
            // here we create an observer-relay pair that relays captured data to explicitly requesting clients
            // a request will be active for a couple of seconds, then the client has to resend it
            // the sensor observer generates data when the webcam is active
            // which is send to the client through LiveWire subscription (relay)

            // TODO advance this functionality
            // TODO distinguish between different types of requests (start/stop/only for live stats e.g. fps/+image data)

            // TODO need a lock here too?
            int    iSensor                = positionStart;
            var    readySignal            = new AutoResetEvent(false);
            object sync                   = new object();
            ulong  relayID                = LiveCaptureSubscription.GenerateSubscriptionID(clientOrigin, SensorType.Webcam, iSensor);
            LiveCaptureSubscription relay = new LiveCaptureSubscription(relayID);

            HttpStatusCode status = HttpStatusCode.InternalServerError;


            CaptureSystem.Instance.Invoke((object sender, EventArgs args) => {
                var system = (CaptureSystem)sender;
                // make sure the sensor is started
                // and subscribe to it if successful
                ISensorBase sensor = system.GetSensor(iSensor);
                if (sensor == null || sensor.SensorType != SensorType.Webcam)
                {
                    lock (sync) {
                        status = HttpStatusCode.NotFound;
                    }
                    readySignal.Set();
                    return;
                }
                lock (sync) {
                    // when the observer times out its subscription to camera events should end
                    // in order to save resources
                    // the observer cancels the relay in the process
                    var observer             = new WebcamCaptureObserver(timeout, includeImage, clientOrigin, relay, iSensor, template);
                    IDisposable subscription = system.ObserveSensor(positionStart).Subscribe(observer);
                    observer.Cancelled      += delegate {
                        subscription.Dispose();
                    };
                    LogManager.Instance.LogMessage(this, string.Format("Subscribed client {0} to webcam {1} as {2}",
                                                                       clientOrigin, iSensor, relayID));
                    status = HttpStatusCode.OK;
                }
                readySignal.Set();
            });
            // cancellation makes sure that a client is only fed by one observer-relay pair at a time
            // search for conflicting subscriptions and cancel them
            // conflicts have the same ID as generated above
            var activeConsumers = server.GetSubscriptions(clientOrigin);

            foreach (var c in activeConsumers)
            {
                if (c.SubscriptionID == relayID)
                {
                    c.Cancel();
                    LogManager.Instance.LogMessage(this, string.Format("Replaced webcam video subscription {0} for client {1}",
                                                                       relayID, clientOrigin));
                }
            }
            // wait for the external operation above to finish
            // starting a webcam can take a few seconds
            if (!readySignal.WaitOne(10000))
            {
                relay.Dispose();
                return(HttpStatusCode.InternalServerError);
            }
            // since we have no synchronization other than on readySignal we make use of an additional lock
            // otherwise the ready signal could be set, while we see an old status code value
            // TODO check validity of statement above
            lock (sync) {
                if (status != HttpStatusCode.OK)
                {
                    relay.Dispose();
                    return(status);
                }
                if (!server.Subscribe(clientOrigin, relay))
                {
                    relay.Dispose();
                    return(HttpStatusCode.InternalServerError);
                }
                return(HttpStatusCode.OK);
            }
            // TODO create an update in case the sensor was started
        }