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->define_context) {
52 po->ops->define_context = ps_ops->define_context;
54 if(ps_ops->activate_context) {
55 po->ops->activate_context = ps_ops->activate_context;
57 if(ps_ops->deactivate_context) {
58 po->ops->deactivate_context = ps_ops->deactivate_context;
64 static TReturn _dispatcher(CoreObject *o, UserRequest *ur)
66 enum tcore_request_command command;
67 struct private_object_data *po = NULL;
70 return TCORE_RETURN_EINVAL;
72 po = tcore_object_ref_object(o);
74 return TCORE_RETURN_ENOSYS;
76 command = tcore_user_request_get_command(ur);
82 return TCORE_RETURN_SUCCESS;
85 static void _clone_hook(CoreObject *src, CoreObject *dest)
87 struct private_object_data *src_po = NULL;
88 struct private_object_data *dest_po = NULL;
93 dest_po = calloc(1, sizeof(struct private_object_data));
95 tcore_object_link_object(dest, NULL);
99 src_po = tcore_object_ref_object(src);
100 dest_po->ops = src_po->ops;
102 tcore_object_link_object(dest, dest_po);
105 static void _free_hook(CoreObject *o)
107 struct private_object_data *po = NULL;
110 po = tcore_object_ref_object(o);
114 if (po->context_list) {
115 for (list = po->context_list; list; list = list->next) {
122 g_slist_free(po->context_list);
123 po->context_list = NULL;
127 tcore_object_link_object(o, NULL);
130 static gboolean _ps_is_active_context(CoreObject *o, CoreObject *ps_context)
132 GSList *contexts = NULL;
133 CoreObject *s_context = NULL;
135 struct private_object_data *po = NULL;
137 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
139 po = tcore_object_ref_object(o);
141 for (idx_cid = 0; idx_cid < PS_MAX_CID; idx_cid++) {
142 if (po->cid[idx_cid].cid != 0) {
143 contexts = po->cid[idx_cid].contexts;
144 if (contexts == NULL)
147 for (; contexts != NULL; contexts = g_slist_next(contexts)) {
148 s_context = contexts->data;
149 if (s_context == NULL)
152 if (ps_context == s_context) {
153 dbg("find contexts(%p) in cid(%d)",
154 ps_context, idx_cid);
161 dbg("cannot find contexts(%p) ", ps_context);
165 static gboolean _ps_is_duplicated_apn(CoreObject *o, CoreObject *ps_context)
167 GSList *contexts = NULL;
168 CoreObject *s_context = NULL;
169 gchar *t_apn = NULL, *s_apn = NULL;
172 struct private_object_data *po = NULL;
174 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
176 po = tcore_object_ref_object(o);
177 t_apn = tcore_context_get_apn(ps_context);
179 for (idx_cid = 0; idx_cid < PS_MAX_CID; idx_cid++) {
180 if (po->cid[idx_cid].cid != 0) {
181 contexts = po->cid[idx_cid].contexts;
182 if (contexts == NULL)
185 for (; contexts != NULL; contexts = g_slist_next(contexts)) {
186 s_context = contexts->data;
187 if (s_context == NULL)
190 if (ps_context == s_context)
193 s_apn = tcore_context_get_apn(s_context);
195 if (g_strcmp0(t_apn, s_apn) == 0) {
196 dbg("target and source have same APN");
197 tcore_context_cp_service_info(
198 ps_context, s_context);
213 void tcore_ps_override_ops(CoreObject *o, struct tcore_ps_operations *ps_ops)
215 struct private_object_data *po = NULL;
217 CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
219 po = (struct private_object_data *)tcore_object_ref_object(o);
225 _clone_ps_operations(po, ps_ops);
231 CoreObject *tcore_ps_new(TcorePlugin *p,
232 struct tcore_ps_operations *ops, TcoreHal *hal)
234 CoreObject *o = NULL;
235 struct private_object_data *po = NULL;
240 o = tcore_object_new(p, hal);
244 po = calloc(1, sizeof(struct private_object_data));
246 tcore_object_free(o);
252 tcore_object_set_type(o, CORE_OBJECT_TYPE_PS);
253 tcore_object_link_object(o, po);
254 tcore_object_set_free_hook(o, _free_hook);
255 tcore_object_set_clone_hook(o, _clone_hook);
256 tcore_object_set_dispatcher(o, _dispatcher);
261 void tcore_ps_free(CoreObject *o)
263 struct private_object_data *po = NULL;
265 CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
267 po = tcore_object_ref_object(o);
272 tcore_object_link_object(o, po);
273 tcore_object_free(o);
276 TReturn tcore_ps_add_context(CoreObject *o, CoreObject *ctx_o)
278 struct private_object_data *po = NULL;
280 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
281 CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
283 po = tcore_object_ref_object(o);
285 return TCORE_RETURN_EINVAL;
287 po->context_list = g_slist_insert(po->context_list, ctx_o, 0);
289 return TCORE_RETURN_SUCCESS;
292 TReturn tcore_ps_remove_context(CoreObject *o, CoreObject *ctx_o)
294 struct private_object_data *po = NULL;
296 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
297 CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
299 po = tcore_object_ref_object(o);
301 return TCORE_RETURN_EINVAL;
303 tcore_ps_clear_context_id(o, ctx_o);
304 po->context_list = g_slist_remove(po->context_list, ctx_o);
306 return TCORE_RETURN_SUCCESS;
309 TReturn tcore_ps_set_online(CoreObject *o, gboolean state)
311 struct private_object_data *po = NULL;
313 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
315 po = tcore_object_ref_object(o);
317 return TCORE_RETURN_EINVAL;
320 dbg("ps status = %d", po->online);
322 return TCORE_RETURN_SUCCESS;
325 CoreObject *tcore_ps_ref_context_by_role(CoreObject *o, enum co_context_role role)
327 struct private_object_data *po = NULL;
332 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
334 po = tcore_object_ref_object(o);
338 p = tcore_object_ref_plugin(o);
342 if (po->context_list) {
343 for (list = po->context_list; list; list = list->next) {
351 if (tcore_object_get_type(pdp_o) != CORE_OBJECT_TYPE_PS_CONTEXT)
354 if (tcore_context_get_role(pdp_o) == role)
362 GSList *tcore_ps_ref_context_by_id(CoreObject *o, unsigned int id)
364 struct private_object_data *po = NULL;
366 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
368 po = tcore_object_ref_object(o);
372 if (id == 0 || id > PS_MAX_CID)
375 if (po->cid[id].cid != id)
378 return po->cid[id].contexts;
381 TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned int cid)
383 struct private_object_data *po = NULL;
386 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
387 CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
389 po = tcore_object_ref_object(o);
391 return TCORE_RETURN_EINVAL;
394 /* Automatic assign */
395 for (idx = 1; idx <= PS_MAX_CID; idx++) {
396 if (po->cid[idx].cid == 0) {
397 po->cid[idx].cid = idx;
398 po->cid[idx].contexts = g_slist_append(po->cid[idx].contexts, context);
399 dbg("assign contexts(%p) in cid(%d)", context, idx);
400 return tcore_context_set_id(context, idx);
403 dbg("cid[%d] is not null", idx);
407 dbg("can't find empty cid");
411 if (po->cid[cid].cid == cid) {
412 po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, context);
413 return tcore_context_set_id(context, cid);
416 dbg("cid[%d] is not null", cid);
420 return TCORE_RETURN_PS_CID_ERROR;
423 TReturn tcore_ps_clear_context_id(CoreObject *o, CoreObject *context)
425 struct private_object_data *po = NULL;
428 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
429 CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
431 po = tcore_object_ref_object(o);
433 return TCORE_RETURN_EINVAL;
435 i = tcore_context_get_id(context);
437 return TCORE_RETURN_PS_CID_ERROR;
441 return TCORE_RETURN_PS_CID_ERROR;
443 po->cid[i].contexts = g_slist_remove(po->cid[i].contexts, context);
444 cnt = g_slist_length(po->cid[i].contexts);
448 return tcore_context_set_id(context, 0);
451 TReturn tcore_ps_define_context(CoreObject *o, CoreObject *ps_context, void *user_data)
454 struct private_object_data *po = NULL;
456 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
458 po = tcore_object_ref_object(o);
460 return TCORE_RETURN_EINVAL;
463 return TCORE_RETURN_EINVAL;
465 rv = _ps_is_active_context(o, ps_context);
467 return TCORE_RETURN_SUCCESS;
469 rv = _ps_is_duplicated_apn(o, ps_context);
472 cid = tcore_context_get_id(ps_context);
473 po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, ps_context);
474 return TCORE_RETURN_SUCCESS;
477 if (tcore_context_get_id(ps_context) == 0) {
478 if (tcore_ps_assign_context_id(o, ps_context, 0) != TCORE_RETURN_SUCCESS)
479 return TCORE_RETURN_PS_CID_ERROR;
482 dbg("contexts(%p), cid = %d", ps_context, tcore_context_get_id(ps_context));
484 return po->ops->define_context(o, ps_context, user_data);
487 TReturn tcore_ps_activate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
490 struct private_object_data *po = NULL;
491 enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
493 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
495 po = tcore_object_ref_object(o);
497 return TCORE_RETURN_EINVAL;
500 dbg("ps network is not online !");
501 return TCORE_RETURN_PS_NETWORK_NOT_READY;
505 return TCORE_RETURN_EINVAL;
507 rv = _ps_is_active_context(o, ps_context);
510 dbg("it is not defined context");
511 return TCORE_RETURN_EINVAL;
514 rv = _ps_is_duplicated_apn(o, ps_context);
516 dbg("context activation is already requested for the same apn(%s)",
517 tcore_context_get_apn(ps_context));
518 return TCORE_RETURN_SUCCESS;
521 context_state = tcore_context_get_state(ps_context);
523 if (context_state == CONTEXT_STATE_ACTIVATED)
524 return TCORE_RETURN_SUCCESS;
525 else if (context_state == CONTEXT_STATE_ACTIVATING)
526 return TCORE_RETURN_SUCCESS;
527 else if (context_state == CONTEXT_STATE_DEACTIVATING)
528 return TCORE_RETURN_PS_DEACTIVATING;
531 dbg("cid = %d", tcore_context_get_id(ps_context));
533 tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATING);
534 return po->ops->activate_context(o, ps_context, user_data);
537 TReturn tcore_ps_deactivate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
540 struct private_object_data *po = NULL;
541 enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
543 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
545 po = tcore_object_ref_object(o);
547 return TCORE_RETURN_EINVAL;
550 dbg("ps network is not online !");
551 return TCORE_RETURN_PS_NETWORK_NOT_READY;
555 return TCORE_RETURN_EINVAL;
557 rv = _ps_is_active_context(o, ps_context);
559 return TCORE_RETURN_EINVAL;
561 rv = _ps_is_duplicated_apn(o, ps_context);
564 cid = tcore_context_get_id(ps_context);
565 po->cid[cid].contexts = g_slist_remove(po->cid[cid].contexts, ps_context);
566 tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
567 return TCORE_RETURN_SUCCESS;
570 context_state = tcore_context_get_state(ps_context);
571 if (context_state == CONTEXT_STATE_DEACTIVATED)
572 return TCORE_RETURN_SUCCESS;
573 else if (context_state == CONTEXT_STATE_DEACTIVATING)
574 return TCORE_RETURN_SUCCESS;
575 else if (context_state == CONTEXT_STATE_ACTIVATING)
576 return TCORE_RETURN_PS_ACTIVATING;
578 tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATING);
579 return po->ops->deactivate_context(o, ps_context, user_data);
582 TReturn tcore_ps_deactivate_contexts(CoreObject *o)
584 GSList *contexts = NULL;
585 CoreObject *context = NULL;
587 struct private_object_data *po = NULL;
589 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
591 po = tcore_object_ref_object(o);
593 return TCORE_RETURN_EINVAL;
596 dbg("ps network is not online !");
597 return TCORE_RETURN_PS_NETWORK_NOT_READY;
600 for (index = 0; index < PS_MAX_CID; index++) {
601 if (po->cid[index].cid != 0) {
602 contexts = po->cid[index].contexts;
603 if (contexts == NULL)
606 for (; contexts != NULL; contexts = g_slist_next(contexts)) {
607 context = contexts->data;
611 tcore_ps_deactivate_context(o, context, NULL);
616 return TCORE_RETURN_SUCCESS;