4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ja-young Gu <jygu@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
29 #include "user_request.h"
37 struct private_object_data {
38 struct tcore_ps_operations *ops;
42 /* 1 ~ UMTS_PS_MAX_CID */
43 struct p_callid_type cid[PS_MAX_CID + 1];
44 //CoreObject *cid[PS_MAX_CID + 1];
49 static void _clone_ps_operations(struct private_object_data *po, struct tcore_ps_operations *ps_ops)
51 if(ps_ops->activate_context) {
52 po->ops->activate_context = ps_ops->activate_context;
54 if(ps_ops->deactivate_context) {
55 po->ops->deactivate_context = ps_ops->deactivate_context;
61 static TReturn _dispatcher(CoreObject *o, UserRequest *ur)
63 enum tcore_request_command command;
64 struct private_object_data *po = NULL;
67 return TCORE_RETURN_EINVAL;
69 po = tcore_object_ref_object(o);
71 return TCORE_RETURN_ENOSYS;
73 command = tcore_user_request_get_command(ur);
79 return TCORE_RETURN_SUCCESS;
82 static void _clone_hook(CoreObject *src, CoreObject *dest)
84 struct private_object_data *src_po = NULL;
85 struct private_object_data *dest_po = NULL;
90 dest_po = calloc(1, sizeof(struct private_object_data));
92 tcore_object_link_object(dest, NULL);
96 src_po = tcore_object_ref_object(src);
97 dest_po->ops = src_po->ops;
99 tcore_object_link_object(dest, dest_po);
102 static void _free_hook(CoreObject *o)
104 struct private_object_data *po = NULL;
107 po = tcore_object_ref_object(o);
111 if (po->context_list) {
112 for (list = po->context_list; list; list = list->next) {
119 g_slist_free(po->context_list);
120 po->context_list = NULL;
124 tcore_object_link_object(o, NULL);
127 static gboolean _ps_is_active_context(CoreObject *o, CoreObject *ps_context)
129 GSList *contexts = NULL;
130 CoreObject *s_context = NULL;
132 struct private_object_data *po = NULL;
134 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
136 po = tcore_object_ref_object(o);
138 for (idx_cid = 0; idx_cid < PS_MAX_CID; idx_cid++) {
139 if (po->cid[idx_cid].cid != 0) {
140 contexts = po->cid[idx_cid].contexts;
141 if (contexts == NULL)
144 for (; contexts != NULL; contexts = g_slist_next(contexts)) {
145 s_context = contexts->data;
146 if (s_context == NULL)
149 if (ps_context == s_context) {
150 dbg("find contexts(%p) in cid(%d)",
151 ps_context, idx_cid);
158 dbg("cannot find contexts(%p) ", ps_context);
162 static gboolean _ps_is_duplicated_apn(CoreObject *o, CoreObject *ps_context)
164 GSList *contexts = NULL;
165 CoreObject *s_context = NULL;
166 gchar *t_apn = NULL, *s_apn = NULL;
169 struct private_object_data *po = NULL;
171 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
173 po = tcore_object_ref_object(o);
174 t_apn = tcore_context_get_apn(ps_context);
176 for (idx_cid = 0; idx_cid < PS_MAX_CID; idx_cid++) {
177 if (po->cid[idx_cid].cid != 0) {
178 contexts = po->cid[idx_cid].contexts;
179 if (contexts == NULL)
182 for (; contexts != NULL; contexts = g_slist_next(contexts)) {
183 s_context = contexts->data;
184 if (s_context == NULL)
187 if (ps_context == s_context)
190 s_apn = tcore_context_get_apn(s_context);
192 if (g_strcmp0(t_apn, s_apn) == 0) {
193 dbg("target and source have same APN");
194 tcore_context_cp_service_info(
195 ps_context, s_context);
210 void tcore_ps_override_ops(CoreObject *o, struct tcore_ps_operations *ps_ops)
212 struct private_object_data *po = NULL;
214 CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
216 po = (struct private_object_data *)tcore_object_ref_object(o);
222 _clone_ps_operations(po, ps_ops);
228 CoreObject *tcore_ps_new(TcorePlugin *p,
229 struct tcore_ps_operations *ops, TcoreHal *hal)
231 CoreObject *o = NULL;
232 struct private_object_data *po = NULL;
237 o = tcore_object_new(p, hal);
241 po = calloc(1, sizeof(struct private_object_data));
243 tcore_object_free(o);
249 tcore_object_set_type(o, CORE_OBJECT_TYPE_PS);
250 tcore_object_link_object(o, po);
251 tcore_object_set_free_hook(o, _free_hook);
252 tcore_object_set_clone_hook(o, _clone_hook);
253 tcore_object_set_dispatcher(o, _dispatcher);
258 void tcore_ps_free(CoreObject *o)
260 struct private_object_data *po = NULL;
262 CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
264 po = tcore_object_ref_object(o);
269 tcore_object_link_object(o, po);
270 tcore_object_free(o);
273 TReturn tcore_ps_add_context(CoreObject *o, CoreObject *ctx_o)
275 struct private_object_data *po = NULL;
277 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
278 CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
280 po = tcore_object_ref_object(o);
282 return TCORE_RETURN_EINVAL;
284 po->context_list = g_slist_insert(po->context_list, ctx_o, 0);
286 return TCORE_RETURN_SUCCESS;
289 TReturn tcore_ps_remove_context(CoreObject *o, CoreObject *ctx_o)
291 struct private_object_data *po = NULL;
293 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
294 CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
296 po = tcore_object_ref_object(o);
298 return TCORE_RETURN_EINVAL;
300 tcore_ps_clear_context_id(o, ctx_o);
301 po->context_list = g_slist_remove(po->context_list, ctx_o);
303 return TCORE_RETURN_SUCCESS;
306 TReturn tcore_ps_set_online(CoreObject *o, gboolean state)
308 struct private_object_data *po = NULL;
310 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
312 po = tcore_object_ref_object(o);
314 return TCORE_RETURN_EINVAL;
317 dbg("ps status = %d", po->online);
319 return TCORE_RETURN_SUCCESS;
322 CoreObject *tcore_ps_ref_context_by_role(CoreObject *o, enum co_context_role role)
324 struct private_object_data *po = NULL;
329 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
331 po = tcore_object_ref_object(o);
335 p = tcore_object_ref_plugin(o);
339 if (po->context_list) {
340 for (list = po->context_list; list; list = list->next) {
348 if (tcore_object_get_type(pdp_o) != CORE_OBJECT_TYPE_PS_CONTEXT)
351 if (tcore_context_get_role(pdp_o) == role)
359 GSList *tcore_ps_ref_context_by_id(CoreObject *o, unsigned int id)
361 struct private_object_data *po = NULL;
363 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
365 po = tcore_object_ref_object(o);
369 if (id == 0 || id > PS_MAX_CID)
372 if (po->cid[id].cid != id)
375 return po->cid[id].contexts;
378 TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned int cid)
380 struct private_object_data *po = NULL;
383 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
384 CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
386 po = tcore_object_ref_object(o);
388 return TCORE_RETURN_EINVAL;
391 /* Automatic assign */
392 for (idx = 1; idx <= PS_MAX_CID; idx++) {
393 if (po->cid[idx].cid == 0) {
394 po->cid[idx].cid = idx;
395 po->cid[idx].contexts = g_slist_append(po->cid[idx].contexts, context);
396 dbg("assign contexts(%p) in cid(%d)", context, idx);
397 return tcore_context_set_id(context, idx);
400 dbg("cid[%d] is not null", idx);
404 dbg("can't find empty cid");
408 if (po->cid[cid].cid == cid) {
409 po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, context);
410 return tcore_context_set_id(context, cid);
413 dbg("cid[%d] is not null", cid);
417 return TCORE_RETURN_PS_CID_ERROR;
420 TReturn tcore_ps_clear_context_id(CoreObject *o, CoreObject *context)
422 struct private_object_data *po = NULL;
425 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
426 CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
428 po = tcore_object_ref_object(o);
430 return TCORE_RETURN_EINVAL;
432 i = tcore_context_get_id(context);
434 return TCORE_RETURN_PS_CID_ERROR;
438 return TCORE_RETURN_PS_CID_ERROR;
440 po->cid[i].contexts = g_slist_remove(po->cid[i].contexts, context);
441 cnt = g_slist_length(po->cid[i].contexts);
445 return tcore_context_set_id(context, 0);
448 TReturn tcore_ps_define_context(CoreObject *o, CoreObject *ps_context, void *user_data)
451 struct private_object_data *po = NULL;
453 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
455 po = tcore_object_ref_object(o);
457 return TCORE_RETURN_EINVAL;
460 return TCORE_RETURN_EINVAL;
462 rv = _ps_is_active_context(o, ps_context);
464 return TCORE_RETURN_SUCCESS;
466 rv = _ps_is_duplicated_apn(o, ps_context);
469 cid = tcore_context_get_id(ps_context);
470 po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, ps_context);
471 return TCORE_RETURN_SUCCESS;
474 if (tcore_context_get_id(ps_context) == 0) {
475 if (tcore_ps_assign_context_id(o, ps_context, 0) != TCORE_RETURN_SUCCESS)
476 return TCORE_RETURN_PS_CID_ERROR;
479 dbg("contexts(%p), cid = %d", ps_context, tcore_context_get_id(ps_context));
481 return po->ops->define_context(o, ps_context, user_data);
484 TReturn tcore_ps_activate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
487 struct private_object_data *po = NULL;
488 enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
490 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
492 po = tcore_object_ref_object(o);
494 return TCORE_RETURN_EINVAL;
497 dbg("ps network is not online !");
498 return TCORE_RETURN_PS_NETWORK_NOT_READY;
502 return TCORE_RETURN_EINVAL;
504 rv = _ps_is_active_context(o, ps_context);
507 dbg("it is not defined context");
508 return TCORE_RETURN_EINVAL;
511 rv = _ps_is_duplicated_apn(o, ps_context);
513 dbg("context activation is already requested for the same apn(%s)",
514 tcore_context_get_apn(ps_context));
515 return TCORE_RETURN_SUCCESS;
518 context_state = tcore_context_get_state(ps_context);
520 if (context_state == CONTEXT_STATE_ACTIVATED)
521 return TCORE_RETURN_SUCCESS;
522 else if (context_state == CONTEXT_STATE_ACTIVATING)
523 return TCORE_RETURN_SUCCESS;
524 else if (context_state == CONTEXT_STATE_DEACTIVATING)
525 return TCORE_RETURN_PS_DEACTIVATING;
528 dbg("cid = %d", tcore_context_get_id(ps_context));
530 tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATING);
531 return po->ops->activate_context(o, ps_context, user_data);
534 TReturn tcore_ps_deactivate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
537 struct private_object_data *po = NULL;
538 enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
540 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
542 po = tcore_object_ref_object(o);
544 return TCORE_RETURN_EINVAL;
547 dbg("ps network is not online !");
548 return TCORE_RETURN_PS_NETWORK_NOT_READY;
552 return TCORE_RETURN_EINVAL;
554 rv = _ps_is_active_context(o, ps_context);
556 return TCORE_RETURN_EINVAL;
558 rv = _ps_is_duplicated_apn(o, ps_context);
561 cid = tcore_context_get_id(ps_context);
562 po->cid[cid].contexts = g_slist_remove(po->cid[cid].contexts, ps_context);
563 tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
564 return TCORE_RETURN_SUCCESS;
567 context_state = tcore_context_get_state(ps_context);
568 if (context_state == CONTEXT_STATE_DEACTIVATED)
569 return TCORE_RETURN_SUCCESS;
570 else if (context_state == CONTEXT_STATE_DEACTIVATING)
571 return TCORE_RETURN_SUCCESS;
572 else if (context_state == CONTEXT_STATE_ACTIVATING)
573 return TCORE_RETURN_PS_ACTIVATING;
575 tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATING);
576 return po->ops->deactivate_context(o, ps_context, user_data);
579 TReturn tcore_ps_deactivate_contexts(CoreObject *o)
581 GSList *contexts = NULL;
582 CoreObject *context = NULL;
584 struct private_object_data *po = NULL;
586 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
588 po = tcore_object_ref_object(o);
590 return TCORE_RETURN_EINVAL;
593 dbg("ps network is not online !");
594 return TCORE_RETURN_PS_NETWORK_NOT_READY;
597 for (index = 0; index < PS_MAX_CID; index++) {
598 if (po->cid[index].cid != 0) {
599 contexts = po->cid[index].contexts;
600 if (contexts == NULL)
603 for (; contexts != NULL; contexts = g_slist_next(contexts)) {
604 context = contexts->data;
608 tcore_ps_deactivate_context(o, context, NULL);
613 return TCORE_RETURN_SUCCESS;