change License boilerplate
[platform/core/csapi/tizenfx.git] / src / Tizen.Location / Tizen.Location / GpsSatellite.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20
21 namespace Tizen.Location
22 {
23     /// <summary>
24     /// A class which contains the functionality for obtaining information about Gps satellites in range and in use.
25     /// </summary>
26     public class GpsSatellite
27     {
28         private int _interval = 120;
29         private Locator _locator;
30         private EventHandler<SatelliteStatusChangedEventArgs> _satelliteStatusChanged;
31         private IntPtr _handle = IntPtr.Zero;
32
33         /// <summary>
34         /// The time interval between callback updates.
35         /// Should be in the range [1~120] seconds.
36         /// </summary>
37         public int Interval
38         {
39             get
40             {
41                 Log.Info(Globals.LogTag, "Getting the Callback Interval");
42                 return _interval;
43             }
44             set
45             {
46                 Log.Info(Globals.LogTag, "Setting the Callback Interval");
47                 if (value >= 0 && value <= 120)
48                 {
49                     _interval = value;
50                     if (_satelliteStatusChanged != null)
51                     {
52                         SetSatelliteStatusChangeCallback();
53                     }
54                     else
55                     {
56                         Log.Error(Globals.LogTag, "Error Setting the Callback Interval");
57                         LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
58                     }
59                 }
60             }
61         }
62
63         /// <summary>
64         /// The NMEAData from the Satellite.
65         /// </summary>
66         public string Nmea
67         {
68             get
69             {
70                 Log.Info(Globals.LogTag, "Getting NMEAData");
71                 return GetNmea();
72             }
73         }
74
75         private string GetNmea()
76         {
77             string value = null;
78             Interop.GpsSatellite.GetNMEAData(_handle, out value);
79
80             return value;
81         }
82
83
84         /// <summary>
85         /// The Count of Active satellites.
86         /// </summary>
87         public int ActiveCount
88         {
89             get
90             {
91                 return (int)GetActiveCount();
92             }
93         }
94
95         private uint GetActiveCount()
96         {
97             Log.Info(Globals.LogTag, "Getting the ActiveCount of satellites");
98             uint numActive = 0;
99             uint numInView;
100             int timestamp;
101             Interop.GpsSatellite.GetSatelliteStatus(_handle, out numActive, out numInView, out timestamp);
102             return numActive;
103         }
104
105         /// <summary>
106         /// The Count of satellites in view.
107         /// </summary>
108         public int InViewCount
109         {
110             get
111             {
112                 return (int)GetInViewCount();
113             }
114         }
115
116         private uint GetInViewCount()
117         {
118             Log.Info(Globals.LogTag, "Getting the In view count of satellites");
119             uint numActive;
120             uint numInView = 0;
121             int timestamp;
122             Interop.GpsSatellite.GetSatelliteStatus(_handle, out numActive, out numInView, out timestamp);
123             return numInView;
124         }
125
126         /// <summary>
127         /// The list of satellites/last recorded satellites in view.
128         /// </summary>
129         public IList<SatelliteInformation> Satellites
130         {
131             get
132             {
133                 return GetSatellites();
134             }
135         }
136
137         private IList<SatelliteInformation> GetSatellites()
138         {
139             List<SatelliteInformation> satelliteList = new List<SatelliteInformation>();
140             Log.Info(Globals.LogTag, "Getting the list of satellites");
141             Interop.GpsSatellite.SatelliteStatusinfomationCallback callback = (uint azimuth, uint elevation, uint prn, uint snr, bool isActive, IntPtr userData) =>
142             {
143                 SatelliteInformation satellite = new SatelliteInformation(azimuth, elevation, prn, snr, isActive);
144                 satelliteList.Add(satellite);
145                 return true;
146             };
147             Interop.GpsSatellite.GetForEachSatelliteInView(_handle, callback, IntPtr.Zero);
148             return satelliteList;
149         }
150
151         /// <summary>
152         /// The constructor of GpsSatellite class.
153         /// <param name="locator"> Locator object initilized using Gps.</param>
154         /// </summary>
155         public GpsSatellite(Locator locator)
156         {
157             Log.Info(Globals.LogTag, "Calling GpsSatellite constructor");
158             LocationType method = locator.LocationType;
159             if (method.Equals(LocationType.Gps) || method.Equals(LocationType.Hybrid))
160             {
161                 _locator = locator;
162                 _handle = _locator.GetHandle();
163             }
164             else
165             {
166                 Log.Error(Globals.LogTag, "Error constructing GpsSatellite class");
167                 LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
168             }
169         }
170
171         /// <summary>
172         /// (event) SatelliteStatusUpdated is raised whenever satellite information is updated.
173         /// The callback will be invoked periodically (every Interval seconds).
174         /// </summary>
175         public event EventHandler<SatelliteStatusChangedEventArgs> SatelliteStatusUpdated
176         {
177             add
178             {
179                 Log.Info(Globals.LogTag, "SatelliteStatusUpdated Add called");
180                 if (_satelliteStatusChanged == null)
181                 {
182                     Log.Info(Globals.LogTag, "SetSatelliteStatusChangeCallback called");
183                     SetSatelliteStatusChangeCallback();
184                 }
185                 _satelliteStatusChanged += value;
186             }
187             remove
188             {
189                 Log.Info(Globals.LogTag, "SatelliteStatusUpdated remoove called");
190                 _satelliteStatusChanged -= value;
191                 if (_satelliteStatusChanged == null)
192                 {
193                     Log.Info(Globals.LogTag, "UnSetSatelliteStatusChangeCallback called");
194                     UnSetSatelliteStatusChangeCallback();
195                 }
196             }
197         }
198
199         private void SetSatelliteStatusChangeCallback()
200         {
201             Log.Info(Globals.LogTag, "SetSatelliteStatusChangeCallback");
202             GCHandle handle = GCHandle.Alloc(this);
203             int ret = Interop.GpsSatellite.SetSatelliteStatusChangedCallback(_handle, SatelliteStatusChangedCallback, _interval, GCHandle.ToIntPtr(handle));
204             if (((LocationError)ret != LocationError.None))
205             {
206                 Log.Error(Globals.LogTag, "Error in setting satellite status changed callback," + (LocationError)ret);
207                 LocationErrorFactory.ThrowLocationException(ret);
208             }
209         }
210
211         private void UnSetSatelliteStatusChangeCallback()
212         {
213             Log.Info(Globals.LogTag, "UnSetSatelliteStatusChangeCallback");
214             int ret = Interop.GpsSatellite.UnSetSatelliteStatusChangedCallback(_handle);
215             if (((LocationError)ret != LocationError.None))
216             {
217                 Log.Error(Globals.LogTag, "Error in Getting Unsetting satellite status changed callback," + (LocationError)ret);
218                 LocationErrorFactory.ThrowLocationException(ret);
219             }
220         }
221
222         private void SatelliteStatusChangedCallback(uint numActive, uint numInView, int timestamp, IntPtr userData)
223         {
224             Log.Info(Globals.LogTag, "Inside SatelliteStatusChangedCallback");
225             DateTime timeStamp = DateTime.Now;
226
227             if (timestamp != 0)
228             {
229                 DateTime start = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(timestamp), DateTimeKind.Utc);
230                 timeStamp = start.ToLocalTime();
231             }
232
233             _satelliteStatusChanged?.Invoke(_handle, new SatelliteStatusChangedEventArgs(numActive, numInView, timeStamp));
234         }
235     }
236
237     /// <summary>
238     /// A class which contains the information of the Satellite under consideration.
239     /// </summary>
240     public class SatelliteInformation
241     {
242         /// <summary>
243         /// Class Constructor for SatelliteInformation class.
244         /// </summary>
245         /// <param name="azimuth"> The azimuth value of the satellite in degrees.</param>
246         /// <param name="elevation"> The elevation of the satellite in meters.</param>
247         /// <param name="prn"> The Prn value of the satellite.</param>
248         /// <param name="snr"> The SNR value of the satellite in dB.</param>
249         /// <param name="isActive"> The flag signaling if satellite is in use.</param>
250         public SatelliteInformation(uint azimuth, uint elevation, uint prn, uint snr, bool isActive)
251         {
252             Azimuth = azimuth;
253             Elevation = elevation;
254             Prn = prn;
255             Snr = snr;
256             Active = isActive;
257         }
258
259         /// <summary>
260         /// The Azimuth information of the Satellite.
261         /// </summary>
262         public uint Azimuth { get; private set; }
263
264         /// <summary>
265         /// The Elevation information of the Satellite.
266         /// </summary>
267         public uint Elevation { get; private set; }
268
269         /// <summary>
270         /// The PRN of the Satellite.
271         /// </summary>
272         public uint Prn { get; private set; }
273
274         /// <summary>
275         /// The SNR of the Satellite.
276         /// </summary>
277         public uint Snr { get; private set; }
278
279         /// <summary>
280         /// The operational status of the Satellite.
281         /// </summary>
282         public bool Active { get; private set; }
283     }
284 }