コード例 #1
0
        /// <summary>
        /// A client calls this method to start a new sniffer measurement at the specified location (with the specified start time).
        /// </summary>
        /// <param name="clientMac">The client requesting the sniffer measurement</param>
        /// <param name="vertexId">The id of the vertex where the user is located</param>
        /// <param name="startMeasTime">The start time of the measurement (as specified by the user)</param>
        private bool StartMeasuring(string clientMac, Vertex vertex)
        {
            if (clientMac == null || vertex == null)
            {
                return(false);
            }

            if (context == null || LoadedBuildings == null)
            {
                LoadRadioMap(); //Ja, eller bare opdater det lokale radio map hver gang en bruger foretager en maaling
                return(false);
            }

            //Create new sniffer measurement
            SnifferWifiMeasurement newMeas = new SnifferWifiMeasurement();

            newMeas.meas_time_start = DateTime.Now;

            //Add sniffer-meas to vertex
            vertex.SnifferWifiMeasurements.Add(newMeas);
            newMeas.Vertex = vertex;

            //Add measurement to 'currently building' datastructures.
            currentOfflineMeasurements.TryAdd(clientMac, newMeas);
            currentMeasuringClients.TryAdd(clientMac, vertex);

            return(true);
        }
コード例 #2
0
        private static Building getNearestAPMatchBuilding(SnifferWifiMeasurement meas)
        {
            if (LoadedBuildings == null)
            {
                return(null);
            }
            if (meas == null)
            {
                return(null);
            }

            Building bestMatch = null;
            //find best match by matching number of common APs
            int maxCommonAPs = 0;

            foreach (Building curBuilding in LoadedBuildings)
            {
                int commonAPs = getNumberOfIdenticalMacs(meas.getMACs(), curBuilding);
                if (commonAPs > maxCommonAPs)
                {
                    maxCommonAPs = commonAPs;
                    bestMatch    = curBuilding;
                }
            }
            return(bestMatch);
        }
コード例 #3
0
 public static bool containsMac(this SnifferWifiMeasurement source, string mac)
 {
     foreach (SnifferHistogram h in source.SnifferHistograms)
     {
         if (h.Mac.Equals(mac))
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #4
0
        public static List <string> getMACs(this SnifferWifiMeasurement source)
        {
            List <String> result = new List <string>();

            foreach (SnifferHistogram h in source.SnifferHistograms)
            {
                if (!result.Contains(h.Mac))
                {
                    result.Add(h.Mac);
                }
            }
            return(result);
        }
コード例 #5
0
        /// <summary>
        /// A sniffer entry (sniffer-mac, client-mac, rssi, and time) is added to currently built measurements.
        /// The procedures is the same for online and offline measurements - the only difference is that we do not track changes to
        /// online measurements as we are not interested in saving them persistently (at least not at the present time)
        /// </summary>
        /// <param name="snifferMac">The sniffer's mac address</param>
        /// <param name="clientMac">The client's mac adress</param>
        /// <param name="rssi">The client's rssi as measured by the sniffer</param>
        /// <param name="mode">'Offline' or 'Online' to help distinguish whether we want to save the data persistently</param>
        /// <param name="time">The time the sniffer entry was made. </param>
        private static void addToMeasurement(string snifferMac, string clientMac, int rssi, DateTime time)
        {
            Mode mode;

            //First, determine the mode.
            if (currentOfflineMeasurements.ContainsKey(clientMac))
            {
                mode = Mode.Offline;
            }
            else if (currentOnlineMeasurements.ContainsKey(clientMac))
            {
                mode = Mode.Online;
            }
            else
            {
                return; //Unknown client mac
            }
            ConcurrentDictionary <string, SnifferWifiMeasurement> dic = getMeasurementDictionary(mode);

            SnifferWifiMeasurement curWifiMeasurement = dic[clientMac];

            //Update end meas time (even more may come..)
            curWifiMeasurement.meas_time_end = time;

            //Add or update histogram with snifferMac, rssi value
            SnifferHistogram curHist = curWifiMeasurement.SnifferHistograms.FirstOrDefault(h => h.Mac == snifferMac && h.value == rssi);

            if (curHist == null) //insert new histogram
            {
                curHist       = new SnifferHistogram();
                curHist.Mac   = snifferMac;
                curHist.value = rssi;
                curHist.count = 0;
                curWifiMeasurement.SnifferHistograms.Add(curHist);
                curHist.SnifferWifiMeasurement = curWifiMeasurement;

                if (mode == Mode.Offline)
                {
                    context.AddRelatedObject(curWifiMeasurement, "SnifferHistograms", curHist);
                }
            }
            curHist.count++; //yet another count for this rssi value

            //In the offline mode we actually save the data.
            if (mode == Mode.Offline)
            {
                context.UpdateObject(curWifiMeasurement);
                context.UpdateObject(curHist);
            }
        }
コード例 #6
0
        //We are not too concerned with decimal numbers, so we return the avg as an int
        //(Moreover, this is a legacy from the WinMobile client and the Streamspin server)
        public static double getAvgDbM(this SnifferWifiMeasurement source, string mac)
        {
            int totalVal   = 0;
            int totalCount = 0; //the total number of distinct values

            //calculate the total
            foreach (SnifferHistogram sniff in source.SnifferHistograms)
            {
                if (sniff.Mac == mac)
                {
                    totalVal   += sniff.value * sniff.count;
                    totalCount += sniff.count;
                }
            }

            return(totalVal / totalCount);
        }
コード例 #7
0
        public EstimateResult compare(IEnumerable <Vertex> vertices, SnifferWifiMeasurement measurement)
        {
            measurement = getNStrongestAPMeasurement(measurement, 7);

            if (vertices == null || measurement == null)
            {
                return(null);
            }

            bcs = WifiPosEngine.BestCandidateSet; //new BCS(5); //bcs.clear();

            double         curDist;               //distance of current vertice in search space
            EstimateResult result = new EstimateResult(null, double.MaxValue);

            foreach (Vertex curVertex in vertices)                                          //sammenlign med hver Vertex
            {
                foreach (SnifferWifiMeasurement curFP in curVertex.SnifferWifiMeasurements) //sammenlign med hvert fingerprint (usually only one - otherwise use more intelligent approach)
                {
                    curDist = 0;
                    foreach (String mac in measurement.getMACs())             //all APs in sample
                    {
                        if (curFP.containsMac(mac))
                        {
                            curDist += Math.Pow((measurement.getAvgDbM(mac) - curFP.getAvgDbM(mac)), 2);
                        }
                        else
                        {
                            curDist += Math.Pow((measurement.getAvgDbM(mac) - MISSING_MAC_PENALTY), 2);
                        }
                    }

                    curDist = Math.Sqrt(curDist);
                    if (curDist < result.getDistance())
                    {
                        result.setDistance(curDist);
                        result.setVertex(curVertex);
                    }
                    bcs.add(curVertex, curDist);             //add to best candidate set - which will take care of only using the best estimates.
                }
            }
            //The following only yields a local error estimate within the primary- or secondary
            //vertices and may thus not be appropriate
            result.setErrorEstimate(Math.Ceiling(bcs.getMaxDistance()));
            return(result);
        }
コード例 #8
0
        //Public visibility so we can test it (directly) via unit tests
        public static SnifferWifiMeasurement getNStrongestAPMeasurement(SnifferWifiMeasurement measurement, int n)
        {
            if (measurement.getMACs().Count < n)
            {
                return(measurement);
            }

            SortedDictionary <double, String> strongestAPs = new SortedDictionary <double, String>();

            //Find the n strongest macs
            //
            foreach (String mac in measurement.getMACs())     //all APs in sample
            {
                double curMacVal = measurement.getAvgDbM(mac);
                while (strongestAPs.ContainsKey(curMacVal))
                {
                    curMacVal += 0.0001;
                }

                strongestAPs.Add(curMacVal, mac);

                //NB: TreeMap sorts members in ascending order!
                //Thus, we remove from the head to keep the strongest values
                if (strongestAPs.Count > n)
                {
                    strongestAPs.Remove(strongestAPs.First().Key);
                }
            }

            //Create new measurement containing n strongest macs
            SnifferWifiMeasurement result = new SnifferWifiMeasurement();

            foreach (double d in strongestAPs.Keys)
            {
                SnifferHistogram h = new SnifferHistogram();
                h.Mac   = strongestAPs[d];
                h.value = (int)d;
                h.count = 1;
                result.SnifferHistograms.Add(h);
                //result.addValue(strongestAPs.get(d), (int)d);
            }
            return(result);
        }
コード例 #9
0
        public bool StartWifiPositioning(string clientMac)
        {
            if (clientMac == null)
            {
                return(false);
            }

            //Create new sniffer measurement
            DateTime time = DateTime.Now;
            SnifferWifiMeasurement newMeas = new SnifferWifiMeasurement();

            newMeas.meas_time_start = DateTime.Now;

            //Add measurement to 'currently building' datastructures.
            currentOnlineMeasurements.TryAdd(clientMac, newMeas);
            //add client to 'currently positioning' and set initial location = null.
            currentPositioningClients.TryAdd(clientMac, null);                //no 'last position'
            //add engine for user
            currentWifiPosEngines.TryAdd(clientMac, new WifiPosEngine(null)); //unknown building

            return(true);
        }
コード例 #10
0
 public void AddToSnifferWifiMeasurements(SnifferWifiMeasurement snifferWifiMeasurement)
 {
     base.AddObject("SnifferWifiMeasurements", snifferWifiMeasurement);
 }
コード例 #11
0
 public static SnifferWifiMeasurement CreateSnifferWifiMeasurement(int ID, int vertex_ID)
 {
     SnifferWifiMeasurement snifferWifiMeasurement = new SnifferWifiMeasurement();
     snifferWifiMeasurement.ID = ID;
     snifferWifiMeasurement.Vertex_ID = vertex_ID;
     return snifferWifiMeasurement;
 }
コード例 #12
0
        public int SaveMeasurement(string clientMac)
        {
            const int error  = -1;
            int       result = error; //change if success

            if (clientMac == null)
            {
                return(error);
            }

            if (!(savedMeasuringClients.ContainsKey(clientMac) && savedOfflineMeasurements.ContainsKey(clientMac)))
            {
                return(error);
            }

            //Remove the measurement from from the 'current' list.
            SnifferWifiMeasurement curWifi = savedOfflineMeasurements[clientMac];
            Vertex curVertex = savedMeasuringClients[clientMac];

            savedOfflineMeasurements.Remove(clientMac);
            savedMeasuringClients.Remove(clientMac);

            Building curBuilding = LoadedBuildings.First(b => b.ID == curVertex.Building_ID);

            //save changes persistently
            try
            {
                //Notify context about changes
                radiomapEntities localContext = new radiomapEntities(radiomapUri);
                if (curVertex.ID <= UNBOUND_ID_STARTVALUE) //unbound location
                {
                    AbsoluteLocation absLoc = curVertex.AbsoluteLocations.First();
                    localContext.AttachTo("Buildings", curBuilding);
                    localContext.AddRelatedObject(curBuilding, "Vertices", curVertex);
                    localContext.AddRelatedObject(curVertex, "AbsoluteLocations", absLoc);
                }
                else
                {
                    localContext.AttachTo("Vertices", curVertex);
                    result = curVertex.ID;
                }
                localContext.AddRelatedObject(curVertex, "SnifferWifiMeasurements", curWifi);
                foreach (SnifferHistogram curHist in curWifi.SnifferHistograms)
                {
                    localContext.AddRelatedObject(curWifi, "SnifferHistograms", curHist);
                }

                //save to database
                DataServiceResponse response = localContext.SaveChanges(SaveChangesOptions.Batch);

                // Enumerate the returned responses. If a new vertex, add it to the current building and return its id.
                foreach (ChangeOperationResponse change in response)
                {
                    // Get the descriptor for the entity.
                    EntityDescriptor descriptor = change.Descriptor as EntityDescriptor;

                    if (descriptor != null)
                    {
                        if (descriptor.Entity is SnifferWifiMeasurement)
                        {
                            //Yes, the measurement got saved
                            Console.WriteLine("Measurement saved."); //dummy statement
                        }
                        else if (descriptor.Entity is Vertex)
                        {
                            Vertex newVertex = descriptor.Entity as Vertex;
                            curBuilding.Vertices.Add(newVertex);
                            result = newVertex.ID;
                        }
                    }
                }

                return(result);
            }
            catch (DataServiceRequestException)
            {
                return(error);
            }
        }
コード例 #13
0
 private static Building getCorrectBuilding(SnifferWifiMeasurement meas)
 {
     //consider strategy pattern
     return(getNearestAPMatchBuilding(meas));
 }
コード例 #14
0
        public EstimateResult getEstimate(SnifferWifiMeasurement currentMeasurement)
        {
            //Check ready state
            if (mCurrentBuilding == null)
            {
                return(null);
            }

            //Maintain primary and secondary search space
            //Cf OfflineClientPocketPCUF
            if (secondarySearchSpace == null)
            {
                secondarySearchSpace = mCurrentBuilding.Vertices; // mGraph.getVertices();
            }
            EstimateResult primaryEstimate   = new EstimateResult(null, Double.MaxValue);
            EstimateResult secondaryEstimate = new EstimateResult(null, Double.MaxValue);

            BestCandidateSet = new BCS(5); //candidates are added in the compare methods below

            //measurement is compared with primary search space (adjacent vertices to previous estimated vertex)
            //and secondary search space (non-connected nodes or the full graph)
            if (prevBestEstimateVertex != null)
            {
                primaryEstimate = mPosAlgorithm.compare(prevBestEstimateVertex.adjacentVertices(), currentMeasurement);
            }
            secondaryEstimate = mPosAlgorithm.compare(secondarySearchSpace, currentMeasurement);

            //Changed to accomodate hyper, where we return null if online meas only has one mac
            //Vertex best = null;
            EstimateResult bestEstimate = null;

            if (primaryEstimate != null)
            {
                bestEstimate = primaryEstimate;
            }
            if (secondaryEstimate != null)
            {
                //The primary estimate may be overriden by a secondary if it is better for the second time in a row
                if (secondaryEstimate.getDistance() < primaryEstimate.getDistance())
                {
                    numSecondaryBest++;
                    if (numSecondaryBest >= 2 || prevBestEstimateVertex == null)
                    {
                        numSecondaryBest = 0;
                        bestEstimate     = secondaryEstimate; //.getVertex();
                    }
                }
                else
                {
                    numSecondaryBest = 0;
                }
            }
            prevBestEstimateVertex = bestEstimate.getVertex();

            //Currently, the error estimate is also calculated in the compare methods,
            //but we override that logic here since this implementation considers the global
            //candidates - not just the local primary- or secondary candidates.
            //We throw in an extra 5 meters to account for movement
            double error = Math.Ceiling(BestCandidateSet.getMaxDistance()); //  + 5;

            bestEstimate.setErrorEstimate(error);

            return(bestEstimate);
        }