removed wrong contacts, added authors
[platform/core/location/lbs-location.git] / location / manager / location-signaling-util.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "location-signaling-util.h"
24 #include "location-common-util.h"
25 #include "location-log.h"
26 #include "location-position.h"
27
28
29 void
30 enable_signaling(LocationObject *obj, guint32 signals[LAST_SIGNAL], gboolean *prev_enabled, gboolean enabled, LocationStatus status)
31 {
32         g_return_if_fail(obj);
33         g_return_if_fail(signals);
34         g_return_if_fail(prev_enabled);
35
36         if (*prev_enabled == TRUE && enabled == FALSE) {
37                 *prev_enabled = FALSE;
38                 LOCATION_LOGD("Signal emit: SERVICE_DISABLED, status = %d", status);
39                 g_signal_emit(obj, signals[SERVICE_DISABLED], 0, LOCATION_STATUS_NO_FIX);
40         } else if (*prev_enabled == FALSE && enabled == TRUE) {
41                 *prev_enabled = TRUE;
42                 LOCATION_LOGD("Signal emit: SERVICE_ENABLED, status = %d", status);
43                 g_signal_emit(obj, signals[SERVICE_ENABLED], 0, status);
44         }
45 }
46
47 void
48 position_velocity_signaling(LocationObject *obj, guint32 signals[LAST_SIGNAL],
49                         guint pos_interval, guint vel_interval, guint loc_interval,
50                         guint *pos_last_timestamp, guint *vel_last_timestamp, guint *loc_last_timestamp,
51                         GList *prev_bound, LocationPosition *cur_pos, LocationVelocity *cur_vel, LocationAccuracy *cur_acc)
52 {
53         g_return_if_fail(obj);
54         g_return_if_fail(signals);
55         g_return_if_fail(cur_pos);
56         g_return_if_fail(cur_vel);
57         g_return_if_fail(cur_acc);
58
59         int index = 0;
60         int signal_type = 0;
61         gboolean is_inside = FALSE;
62         GList *boundary_list = prev_bound;
63         LocationBoundaryPrivate *priv = NULL;
64
65         if (cur_pos && !cur_pos->timestamp) {
66                 LOCATION_LOGW("Invalid location with timestamp, 0");
67                 return;
68         }
69
70         if (pos_interval > 0) {
71                 if (cur_pos->timestamp - *pos_last_timestamp >= pos_interval) {
72                         signal_type |= POSITION_UPDATED;
73                         *pos_last_timestamp = cur_pos->timestamp;
74                 }
75         }
76
77         if (vel_interval > 0) {
78                 if (cur_vel->timestamp - *vel_last_timestamp >= vel_interval) {
79                         signal_type |= VELOCITY_UPDATED;
80                         *vel_last_timestamp = cur_vel->timestamp;
81                 }
82         }
83
84         if (loc_interval > 0) {
85                 if (cur_pos->timestamp - *loc_last_timestamp >= loc_interval) {
86                         signal_type |= LOCATION_CHANGED;
87                         *loc_last_timestamp = cur_pos->timestamp;
88                 }
89         }
90
91         if (signal_type != 0)
92                 g_signal_emit(obj, signals[SERVICE_UPDATED], 0, signal_type, cur_pos, cur_vel, cur_acc);
93
94         if (boundary_list) {
95                 while ((priv = (LocationBoundaryPrivate *)g_list_nth_data(boundary_list, index)) != NULL) {
96                         is_inside = location_boundary_if_inside(priv->boundary, cur_pos);
97                         if (is_inside) {
98                                 if (priv->zone_status != ZONE_STATUS_IN) {
99                                         LOCATION_LOGD("Signal emit: ZONE IN");
100                                         g_signal_emit(obj, signals[ZONE_IN], 0, priv->boundary, cur_pos, cur_acc);
101                                         priv->zone_status = ZONE_STATUS_IN;
102                                 }
103                         } else {
104                                 if (priv->zone_status != ZONE_STATUS_OUT) {
105                                         LOCATION_LOGD("Signal emit : ZONE_OUT");
106                                         g_signal_emit(obj, signals[ZONE_OUT], 0, priv->boundary, cur_pos, cur_acc);
107                                         priv->zone_status = ZONE_STATUS_OUT;
108                                 }
109                         }
110                         index++;
111                 }
112         }
113 }
114
115 void
116 distance_based_position_signaling(LocationObject *obj, guint32 signals[LAST_SIGNAL], gboolean enabled,
117                                 LocationPosition *cur_pos, LocationVelocity *cur_vel, LocationAccuracy *cur_acc,
118                                 guint min_interval, gdouble min_distance, gboolean *prev_enabled, guint *prev_dist_timestamp,
119                                 LocationPosition **prev_pos, LocationVelocity **prev_vel, LocationAccuracy **prev_acc)
120 {
121         LOC_FUNC_LOG
122         g_return_if_fail(obj);
123         g_return_if_fail(signals);
124         g_return_if_fail(cur_pos);
125
126         if (!cur_pos->timestamp) {
127                 LOCATION_LOGE("Invalid location with timestamp, 0");
128                 return;
129         }
130
131         enable_signaling(obj, signals, prev_enabled, enabled, cur_pos->status);
132
133         if (cur_pos->timestamp - *prev_dist_timestamp >= min_interval) {
134                 g_signal_emit(obj, signals[SERVICE_UPDATED], 0, DISTANCE_UPDATED, cur_pos, cur_vel, cur_acc);
135                 *prev_dist_timestamp = cur_pos->timestamp;
136
137                 if (*prev_pos) location_position_free(*prev_pos);
138                 if (*prev_vel) location_velocity_free(*prev_vel);
139                 if (*prev_acc) location_accuracy_free(*prev_acc);
140
141                 *prev_pos = location_position_copy(cur_pos);
142                 *prev_vel = location_velocity_copy(cur_vel);
143                 *prev_acc = location_accuracy_copy(cur_acc);
144
145         } else {
146                 gulong distance;
147                 int ret = location_get_distance(*prev_pos, cur_pos, &distance);
148                 if (ret != LOCATION_ERROR_NONE) {
149                         LOCATION_LOGE("Fail to get distance");
150                         return;
151                 }
152
153                 if (distance >= min_distance) {
154                         g_signal_emit(obj, signals[SERVICE_UPDATED], 0, DISTANCE_UPDATED, cur_pos, cur_vel, cur_acc);
155                         *prev_dist_timestamp = cur_pos->timestamp;
156
157                         if (*prev_pos) location_position_free(*prev_pos);
158                         if (*prev_vel) location_velocity_free(*prev_vel);
159                         if (*prev_acc) location_accuracy_free(*prev_acc);
160
161                         *prev_pos = location_position_copy(cur_pos);
162                         *prev_vel = location_velocity_copy(cur_vel);
163                         *prev_acc = location_accuracy_copy(cur_acc);
164                 }
165         }
166 }
167
168 void
169 location_signaling(LocationObject *obj, guint32 signals[LAST_SIGNAL], gboolean enabled, GList *boundary_list,
170                                         LocationPosition *cur_pos, LocationVelocity *cur_vel, LocationAccuracy *cur_acc,
171                                         guint pos_interval, guint vel_interval, guint loc_interval, gboolean *prev_enabled,
172                                         guint *prev_pos_timestamp, guint *prev_vel_timestamp, guint *prev_loc_timestamp,
173                                         LocationPosition **prev_pos, LocationVelocity **prev_vel, LocationAccuracy **prev_acc)
174 {
175         g_return_if_fail(obj);
176         g_return_if_fail(signals);
177         g_return_if_fail(cur_pos);
178         g_return_if_fail(cur_vel);
179         g_return_if_fail(cur_acc);
180
181         if (!cur_pos->timestamp) {
182                 LOCATION_LOGD("Invalid location with timestamp, 0");
183                 return;
184         }
185
186         if (*prev_pos) location_position_free(*prev_pos);
187         if (*prev_vel) location_velocity_free(*prev_vel);
188         if (*prev_acc) location_accuracy_free(*prev_acc);
189
190         *prev_pos = location_position_copy(cur_pos);
191         *prev_vel = location_velocity_copy(cur_vel);
192         *prev_acc = location_accuracy_copy(cur_acc);
193
194         enable_signaling(obj, signals, prev_enabled, enabled, cur_pos->status);
195         position_velocity_signaling(obj, signals, pos_interval, vel_interval, loc_interval, prev_pos_timestamp, prev_vel_timestamp, prev_loc_timestamp, boundary_list, cur_pos, cur_vel, cur_acc);
196 }
197
198 void
199 satellite_signaling(LocationObject *obj, guint32 signals[LAST_SIGNAL], gboolean *prev_enabled, int interval,
200                                         gboolean emit, guint *last_timestamp, LocationSatellite **prev_sat, LocationSatellite *sat)
201 {
202         g_return_if_fail(obj);
203         g_return_if_fail(signals);
204         g_return_if_fail(sat);
205
206         if (!sat->timestamp) return;
207
208         if (*prev_sat) location_satellite_free(*prev_sat);
209         *prev_sat = location_satellite_copy(sat);
210
211         if (emit && sat->timestamp - *last_timestamp >= interval) {
212                 g_signal_emit(obj, signals[SERVICE_UPDATED], 0, SATELLITE_UPDATED, sat, NULL, NULL);
213                 *last_timestamp = sat->timestamp;
214         }
215 }
216