1. Change tag style for error log
[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  * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
7  *          Genie Kim <daejins.kim@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "location-signaling-util.h"
27 #include "location-common-util.h"
28 #include "location-log.h"
29 #include "location-position.h"
30
31
32 void
33 enable_signaling(LocationObject *obj, guint32 signals[LAST_SIGNAL], gboolean *prev_enabled, gboolean enabled, LocationStatus status)
34 {
35         g_return_if_fail(obj);
36         g_return_if_fail(signals);
37         g_return_if_fail(prev_enabled);
38
39         if (*prev_enabled == TRUE && enabled == FALSE) {
40                 *prev_enabled = FALSE;
41                 LOCATION_LOGD("Signal emit: SERVICE_DISABLED, status = %d", status);
42                 g_signal_emit(obj, signals[SERVICE_DISABLED], 0, LOCATION_STATUS_NO_FIX);
43                 /* g_signal_emit(obj, signals[STATUS_CHANGED], 0, LOCATION_STATUS_NO_FIX); */
44         } else if (*prev_enabled == FALSE && enabled == TRUE) {
45                 *prev_enabled = TRUE;
46                 LOCATION_LOGD("Signal emit: SERVICE_ENABLED, status = %d", status);
47                 g_signal_emit(obj, signals[SERVICE_ENABLED], 0, status);
48                 /* g_signal_emit(obj, signals[STATUS_CHANGED], 0, status); */
49         }
50 #if 0
51         } else if (*prev_enabled != enabled) {
52                 LOCATION_LOGD("Signal emit: prev_enabled = %d, enabled = %d, status = %d", *prev_enabled, enabled, status);
53                 /* g_signal_emit(obj, signals[STATUS_CHANGED], 0, status); */
54         }
55 #endif
56 }
57
58 void
59 position_velocity_signaling(LocationObject *obj,
60                                                         guint32 signals[LAST_SIGNAL],
61                                                         guint pos_interval,
62                                                         guint vel_interval,
63                                                         guint loc_interval,
64                                                         guint *pos_updated_timestamp,
65                                                         guint *vel_updated_timestamp,
66                                                         guint *loc_updated_timestamp,
67                                                         GList *prev_bound,
68                                                         LocationPosition *pos,
69                                                         LocationVelocity *vel,
70                                                         LocationAccuracy *acc)
71 {
72         g_return_if_fail(obj);
73         g_return_if_fail(signals);
74         g_return_if_fail(pos);
75
76         int index = 0;
77         int signal_type = 0;
78         gboolean is_inside = FALSE;
79         GList *boundary_list = prev_bound;
80         LocationBoundaryPrivate *priv = NULL;
81
82         if (pos && !pos->timestamp) {
83                 LOCATION_LOGW("Invalid location with timestamp, 0");
84                 return;
85         }
86
87         if (pos_interval > 0) {
88                 if (pos->timestamp - *pos_updated_timestamp >= pos_interval) {
89                         signal_type |= POSITION_UPDATED;
90                         *pos_updated_timestamp = pos->timestamp;
91                 }
92         }
93
94         if (vel_interval > 0) {
95                 if (vel && (vel->timestamp - *vel_updated_timestamp >= vel_interval)) {
96                         signal_type |= VELOCITY_UPDATED;
97                         *vel_updated_timestamp = vel->timestamp;
98                 }
99         }
100
101         if (loc_interval > 0) {
102                 if (pos->timestamp - *loc_updated_timestamp >= loc_interval) {
103                         signal_type |= LOCATION_CHANGED;
104                         *loc_updated_timestamp = pos->timestamp;
105                 }
106         }
107
108         if (signal_type != 0)
109                 g_signal_emit(obj, signals[SERVICE_UPDATED], 0, signal_type, pos, vel, acc);
110
111         if (boundary_list) {
112                 while ((priv = (LocationBoundaryPrivate *)g_list_nth_data(boundary_list, index)) != NULL) {
113                         is_inside = location_boundary_if_inside(priv->boundary, pos);
114                         if (is_inside) {
115                                 if (priv->zone_status != ZONE_STATUS_IN) {
116                                         LOCATION_LOGD("Signal emit: ZONE IN");
117                                         g_signal_emit(obj, signals[ZONE_IN], 0, priv->boundary, pos, acc);
118                                         priv->zone_status = ZONE_STATUS_IN;
119                                 }
120                         } else {
121                                 if (priv->zone_status != ZONE_STATUS_OUT) {
122                                         LOCATION_LOGD("Signal emit : ZONE_OUT");
123                                         g_signal_emit(obj, signals[ZONE_OUT], 0, priv->boundary, pos, acc);
124                                         priv->zone_status = ZONE_STATUS_OUT;
125                                 }
126                         }
127                         index++;
128                 }
129         }
130 }
131
132 void
133 distance_based_position_signaling(LocationObject *obj,
134                                                                         guint32 signals[LAST_SIGNAL],
135                                                                         gboolean enabled,
136                                                                         LocationPosition *cur_pos,
137                                                                         LocationVelocity *cur_vel,
138                                                                         LocationAccuracy *cur_acc,
139                                                                         guint min_interval,
140                                                                         gdouble min_distance,
141                                                                         gboolean *prev_enabled,
142                                                                         guint *prev_dist_timestamp,
143                                                                         LocationPosition **prev_pos,    /* prev : keeping lastest info. */
144                                                                         LocationVelocity **prev_vel,
145                                                                         LocationAccuracy **prev_acc)
146 {
147         g_return_if_fail(obj);
148         g_return_if_fail(signals);
149         g_return_if_fail(cur_pos);
150
151         if (!cur_pos->timestamp) {
152                 LOCATION_LOGE("Invalid location with timestamp, 0");
153                 return;
154         }
155
156         enable_signaling(obj, signals, prev_enabled, enabled, cur_pos->status);
157
158         if (cur_pos->timestamp - *prev_dist_timestamp >= min_interval) {
159                 g_signal_emit(obj, signals[SERVICE_UPDATED], 0, DISTANCE_UPDATED, cur_pos, cur_vel, cur_acc);
160                 *prev_dist_timestamp = cur_pos->timestamp;
161
162                 if (*prev_pos) location_position_free(*prev_pos);
163                 if (*prev_vel) location_velocity_free(*prev_vel);
164                 if (*prev_acc) location_accuracy_free(*prev_acc);
165
166                 *prev_pos = location_position_copy(cur_pos);
167                 *prev_vel = location_velocity_copy(cur_vel);
168                 *prev_acc = location_accuracy_copy(cur_acc);
169
170         } else {
171                 gulong distance;
172                 int ret = location_get_distance(*prev_pos, cur_pos, &distance);
173                 if (ret != LOCATION_ERROR_NONE) {
174                         LOCATION_LOGE("Fail to get distance");
175                         return;
176                 }
177
178                 if (distance >= min_distance) {
179                         g_signal_emit(obj, signals[SERVICE_UPDATED], 0, DISTANCE_UPDATED, cur_pos, cur_vel, cur_acc);
180                         *prev_dist_timestamp = cur_pos->timestamp;
181
182                         if (*prev_pos) location_position_free(*prev_pos);
183                         if (*prev_vel) location_velocity_free(*prev_vel);
184                         if (*prev_acc) location_accuracy_free(*prev_acc);
185
186                         *prev_pos = location_position_copy(cur_pos);
187                         *prev_vel = location_velocity_copy(cur_vel);
188                         *prev_acc = location_accuracy_copy(cur_acc);
189                 }
190         }
191 }
192
193 void
194 location_signaling(LocationObject *obj,
195                                         guint32 signals[LAST_SIGNAL],
196                                         gboolean enabled,
197                                         GList *boundary_list,
198                                         LocationPosition *cur_pos,
199                                         LocationVelocity *cur_vel,
200                                         LocationAccuracy *cur_acc,
201                                         guint pos_interval,                     /* interval : support an update interval */
202                                         guint vel_interval,
203                                         guint loc_interval,
204                                         gboolean *prev_enabled,
205                                         guint *prev_pos_timestamp,
206                                         guint *prev_vel_timestamp,
207                                         guint *prev_loc_timestamp,
208                                         LocationPosition **prev_pos,    /* prev : keeping lastest info. */
209                                         LocationVelocity **prev_vel,
210                                         LocationAccuracy **prev_acc)
211 {
212         g_return_if_fail(obj);
213         g_return_if_fail(signals);
214         g_return_if_fail(cur_pos);
215
216         if (!cur_pos->timestamp) {
217                 LOCATION_LOGD("Invalid location with timestamp, 0");
218                 return;
219         }
220
221         if (*prev_pos) location_position_free(*prev_pos);
222         if (*prev_vel) location_velocity_free(*prev_vel);
223         if (*prev_acc) location_accuracy_free(*prev_acc);
224
225         *prev_pos = location_position_copy(cur_pos);
226         *prev_vel = location_velocity_copy(cur_vel);
227         *prev_acc = location_accuracy_copy(cur_acc);
228
229         LOCATION_LOGD("status = %d", cur_pos->status);
230         enable_signaling(obj, signals, prev_enabled, enabled, cur_pos->status);
231         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);
232 }
233
234 void
235 satellite_signaling(LocationObject *obj, guint32 signals[LAST_SIGNAL], gboolean *prev_enabled,
236                                         int interval, gboolean emit, guint *updated_timestamp, LocationSatellite **prev_sat, LocationSatellite *sat)
237 {
238         g_return_if_fail(obj);
239         g_return_if_fail(signals);
240         g_return_if_fail(sat);
241
242         if (!sat->timestamp) return;
243
244         if (*prev_sat) location_satellite_free(*prev_sat);
245         *prev_sat = location_satellite_copy(sat);
246
247         if (emit && sat->timestamp - *updated_timestamp >= interval) {
248                 g_signal_emit(obj, signals[SERVICE_UPDATED], 0, SATELLITE_UPDATED, sat, NULL, NULL);
249                 *updated_timestamp = sat->timestamp;
250         }
251 }
252