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"
40 struct private_object_data {
41 struct tcore_ps_operations *ops;
46 /* 1 ~ UMTS_PS_MAX_CID */
47 struct p_callid_type cid[PS_MAX_CID + 1];
48 //CoreObject *cid[PS_MAX_CID + 1];
53 static TReturn _dispatcher(CoreObject *o, UserRequest *ur)
55 enum tcore_request_command command;
56 struct private_object_data *po = NULL;
59 return TCORE_RETURN_EINVAL;
61 po = tcore_object_ref_object(o);
63 return TCORE_RETURN_ENOSYS;
65 command = tcore_user_request_get_command(ur);
71 return TCORE_RETURN_SUCCESS;
74 static void _clone_hook(CoreObject *src, CoreObject *dest)
76 struct private_object_data *src_po = NULL;
77 struct private_object_data *dest_po = NULL;
82 dest_po = calloc(1, sizeof(struct private_object_data));
84 tcore_object_link_object(dest, NULL);
88 src_po = tcore_object_ref_object(src);
89 dest_po->ops = src_po->ops;
91 tcore_object_link_object(dest, dest_po);
94 static void _free_hook(CoreObject *o)
96 struct private_object_data *po = NULL;
99 po = tcore_object_ref_object(o);
103 if (po->context_list) {
104 for (list = po->context_list; list; list = list->next) {
111 g_slist_free(po->context_list);
112 po->context_list = NULL;
116 tcore_object_link_object(o, NULL);
119 static gboolean _ps_is_active_context(CoreObject *o, CoreObject *ps_context)
121 GSList *contexts = NULL;
122 CoreObject *s_context = NULL;
125 struct private_object_data *po = NULL;
127 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, FALSE);
129 po = tcore_object_ref_object(o);
131 for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
132 if (po->cid[idx_cid].cid == 0)
135 contexts = po->cid[idx_cid].contexts;
140 s_context = contexts->data;
142 contexts = contexts->next;
146 if (ps_context == s_context) {
147 dbg("find contexts(%p) in cid(%d)", ps_context, idx_cid);
151 contexts = contexts->next;
155 dbg("cannot find contexts(%p) ", ps_context);
160 static gboolean _ps_is_duplicated_apn(CoreObject *o, CoreObject *ps_context)
162 GSList *contexts = NULL;
163 CoreObject *s_context = NULL;
164 gchar *t_apn = NULL, *s_apn = NULL;
167 struct private_object_data *po = NULL;
169 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, FALSE);
171 po = tcore_object_ref_object(o);
172 t_apn = tcore_context_get_apn(ps_context);
174 for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
175 if (po->cid[idx_cid].cid == 0)
178 contexts = po->cid[idx_cid].contexts;
183 s_context = contexts->data;
185 contexts = contexts->next;
189 if (ps_context == s_context) {
190 contexts = contexts->next;
194 s_apn = tcore_context_get_apn(s_context);
195 if (g_strcmp0(t_apn, s_apn) == 0) {
196 dbg("target and source context have same APN");
197 tcore_context_cp_service_info(ps_context, s_context);
204 contexts = contexts->next;
212 static void _deactivate_context (gpointer context, gpointer user_data)
214 if (!context || !user_data)
217 tcore_ps_deactivate_context(user_data, context, NULL);
220 CoreObject *tcore_ps_new(TcorePlugin *p, const char *name,
221 struct tcore_ps_operations *ops, TcoreHal *hal)
223 CoreObject *o = NULL;
224 struct private_object_data *po = NULL;
229 o = tcore_object_new(p, name, hal);
233 po = calloc(1, sizeof(struct private_object_data));
235 tcore_object_free(o);
241 tcore_object_set_type(o, CORE_OBJECT_TYPE_PS);
242 tcore_object_link_object(o, po);
243 tcore_object_set_free_hook(o, _free_hook);
244 tcore_object_set_clone_hook(o, _clone_hook);
245 tcore_object_set_dispatcher(o, _dispatcher);
250 void tcore_ps_free(CoreObject *o)
252 CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
253 tcore_object_free(o);
256 void tcore_ps_set_ops(CoreObject *o, struct tcore_ps_operations *ops)
258 struct private_object_data *po = NULL;
260 CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS);
262 po = (struct private_object_data *)tcore_object_ref_object(o);
270 TReturn tcore_ps_add_context(CoreObject *o, CoreObject *ctx_o)
272 struct private_object_data *po = NULL;
274 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
275 CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
277 po = tcore_object_ref_object(o);
279 return TCORE_RETURN_EINVAL;
281 po->context_list = g_slist_insert(po->context_list, ctx_o, 0);
283 return TCORE_RETURN_SUCCESS;
286 TReturn tcore_ps_remove_context(CoreObject *o, CoreObject *ctx_o)
288 struct private_object_data *po = NULL;
290 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
291 CORE_OBJECT_CHECK_RETURN(ctx_o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
293 po = tcore_object_ref_object(o);
295 return TCORE_RETURN_EINVAL;
297 tcore_ps_clear_context_id(o, ctx_o);
298 po->context_list = g_slist_remove(po->context_list, ctx_o);
300 return TCORE_RETURN_SUCCESS;
303 TReturn tcore_ps_set_online(CoreObject *o, gboolean state)
305 struct private_object_data *po = NULL;
307 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
309 po = tcore_object_ref_object(o);
311 return TCORE_RETURN_EINVAL;
314 dbg("ps status = %d", po->online);
316 return TCORE_RETURN_SUCCESS;
319 TReturn tcore_ps_set_num_of_pdn(CoreObject *o, gint numbers)
321 struct private_object_data *po = NULL;
323 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
325 po = tcore_object_ref_object(o);
327 return TCORE_RETURN_EINVAL;
329 po->num_of_pdn = numbers;
330 dbg("ps num of pdn = %d", po->num_of_pdn);
332 return TCORE_RETURN_SUCCESS;
335 unsigned int tcore_ps_get_num_of_pdn(CoreObject *o)
337 struct private_object_data *po = NULL;
339 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
341 po = tcore_object_ref_object(o);
345 return po->num_of_pdn;
348 unsigned int tcore_ps_set_cid_active(CoreObject *o, unsigned int cid, unsigned int enable)
351 struct private_object_data *po = NULL;
353 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
358 po = tcore_object_ref_object(o);
359 for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
360 if (po->cid[idx_cid].cid == cid){
361 po->cid[idx_cid].active = enable;
369 unsigned int tcore_ps_get_cid_active(CoreObject *o, unsigned int cid)
372 struct private_object_data *po = NULL;
374 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
379 po = tcore_object_ref_object(o);
380 for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
381 if (po->cid[idx_cid].cid == cid){
382 return po->cid[idx_cid].active;
389 GSList* tcore_ps_get_active_cids(CoreObject *o)
392 GSList *active_list = NULL;
393 struct private_object_data *po = NULL;
395 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
397 po = tcore_object_ref_object(o);
399 for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
400 if (po->cid[idx_cid].active){
401 active_list = g_slist_append(active_list, &po->cid[idx_cid].cid);
408 unsigned int tcore_ps_set_cid_connected(CoreObject *o, unsigned int cid, unsigned int connected)
411 struct private_object_data *po = NULL;
413 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
418 po = tcore_object_ref_object(o);
419 for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
420 if (po->cid[idx_cid].cid == cid){
421 po->cid[idx_cid].connected = connected;
429 unsigned int tcore_ps_get_cid_connected(CoreObject *o, unsigned int cid)
432 struct private_object_data *po = NULL;
434 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
439 po = tcore_object_ref_object(o);
440 for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
441 if (po->cid[idx_cid].cid == cid){
442 return po->cid[idx_cid].connected;
449 GSList* tcore_ps_get_connected_cids(CoreObject *o)
452 GSList *active_list = NULL;
453 struct private_object_data *po = NULL;
455 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
457 po = tcore_object_ref_object(o);
459 for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) {
460 if (po->cid[idx_cid].connected){
461 active_list = g_slist_append(active_list, &po->cid[idx_cid].cid);
468 unsigned int tcore_ps_is_active_apn(CoreObject *o, const char* apn)
471 struct private_object_data *po = NULL;
473 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0);
475 po = tcore_object_ref_object(o);
477 for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++){
478 if (po->cid[idx_cid].cid == 0)
481 if (g_strcmp0((const char*)po->cid[idx_cid].apn, apn) == 0 && po->cid[idx_cid].active) {
489 CoreObject *tcore_ps_ref_context_by_role(CoreObject *o, enum co_context_role role)
491 struct private_object_data *po = NULL;
496 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
498 po = tcore_object_ref_object(o);
502 p = tcore_object_ref_plugin(o);
506 if (po->context_list) {
507 for (list = po->context_list; list; list = list->next) {
515 if (tcore_object_get_type(pdp_o) != CORE_OBJECT_TYPE_PS_CONTEXT)
518 if (tcore_context_get_role(pdp_o) == role)
526 GSList *tcore_ps_ref_context_by_id(CoreObject *o, unsigned int id)
528 struct private_object_data *po = NULL;
530 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL);
532 po = tcore_object_ref_object(o);
536 if (id == 0 || id > (unsigned int)po->num_of_pdn)
539 if (po->cid[id].cid != id)
542 return po->cid[id].contexts;
545 gboolean tcore_ps_any_context_activating_activated(CoreObject *o, int * state)
547 struct private_object_data *po = NULL;
549 gboolean ret = FALSE;
551 enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
553 po = tcore_object_ref_object(o);
557 if (po->context_list) {
558 for (list = po->context_list; list; list = list->next) {
564 if (tcore_object_get_type(pdp_o) != CORE_OBJECT_TYPE_PS_CONTEXT)
567 context_state = tcore_context_get_state(pdp_o);
569 if(CONTEXT_STATE_ACTIVATED == context_state) {
570 *state = CONTEXT_STATE_ACTIVATED;
573 else if (CONTEXT_STATE_ACTIVATING == context_state){
574 *state = CONTEXT_STATE_ACTIVATING;
578 else if (CONTEXT_STATE_DEACTIVATING == context_state){
579 *state = CONTEXT_STATE_DEACTIVATING;
589 TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned char cid)
591 struct private_object_data *po = NULL;
594 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
595 CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
597 po = tcore_object_ref_object(o);
599 return TCORE_RETURN_EINVAL;
602 /* Automatic assign */
603 for (idx = 1; idx <= po->num_of_pdn; idx++) {
604 if (po->cid[idx].cid == 0) {
605 po->cid[idx].cid = idx;
606 po->cid[idx].contexts = g_slist_append(po->cid[idx].contexts, context);
607 po->cid[idx].apn = tcore_context_get_apn(context);
608 dbg("assign contexts(%p) in cid(%d), apn(%s)", context, idx, po->cid[idx].apn);
609 return tcore_context_set_id(context, idx);
612 dbg("cid[%d] is not null", idx);
616 dbg("can't find empty cid");
620 if (po->cid[cid].cid == cid) {
621 po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, context);
622 return tcore_context_set_id(context, cid);
625 dbg("cid[%d] is not null", cid);
629 return TCORE_RETURN_PS_CID_ERROR;
632 TReturn tcore_ps_clear_context_id(CoreObject *o, CoreObject *context)
634 struct private_object_data *po = NULL;
635 unsigned char i = 0, cnt = 0;
637 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
638 CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
640 po = tcore_object_ref_object(o);
642 return TCORE_RETURN_EINVAL;
644 i = tcore_context_get_id(context);
646 return TCORE_RETURN_PS_CID_ERROR;
649 if (i > po->num_of_pdn)
650 return TCORE_RETURN_PS_CID_ERROR;
652 po->cid[i].contexts = g_slist_remove(po->cid[i].contexts, context);
653 cnt = g_slist_length(po->cid[i].contexts);
656 po->cid[i].active = FALSE;
657 po->cid[i].connected = FALSE;
658 g_free(po->cid[i].apn);
659 po->cid[i].apn = NULL;
662 return tcore_context_set_id(context, 0);
665 TReturn tcore_ps_define_context(CoreObject *o, CoreObject *ps_context, void *user_data)
668 struct private_object_data *po = NULL;
670 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
672 po = tcore_object_ref_object(o);
674 return TCORE_RETURN_EINVAL;
677 return TCORE_RETURN_EINVAL;
679 rv = _ps_is_active_context(o, ps_context);
681 return TCORE_RETURN_SUCCESS;
683 rv = _ps_is_duplicated_apn(o, ps_context);
685 unsigned char cid = 0;
686 cid = tcore_context_get_id(ps_context);
687 po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, ps_context);
688 return TCORE_RETURN_SUCCESS;
691 if (tcore_context_get_id(ps_context) == 0) {
692 if (tcore_ps_assign_context_id(o, ps_context, 0) != TCORE_RETURN_SUCCESS)
693 return TCORE_RETURN_PS_CID_ERROR;
696 dbg("contexts(%p), cid = %d", ps_context, tcore_context_get_id(ps_context));
698 return po->ops->define_context(o, ps_context, user_data);
701 TReturn tcore_ps_activate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
704 struct private_object_data *po = NULL;
705 enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
707 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
709 po = tcore_object_ref_object(o);
711 return TCORE_RETURN_EINVAL;
714 dbg("ps network is not online !");
715 return TCORE_RETURN_PS_NETWORK_NOT_READY;
719 return TCORE_RETURN_EINVAL;
721 rv = _ps_is_active_context(o, ps_context);
724 dbg("it is not defined context");
725 return TCORE_RETURN_EINVAL;
728 rv = _ps_is_duplicated_apn(o, ps_context);
730 dbg("context activation is already requested for the same apn(%s)",
731 tcore_context_get_apn(ps_context));
732 return TCORE_RETURN_SUCCESS;
735 context_state = tcore_context_get_state(ps_context);
737 if (context_state == CONTEXT_STATE_ACTIVATED){
738 dbg("Context state : CONTEXT_STATE_ACTIVATED");
739 return TCORE_RETURN_SUCCESS;
741 else if (context_state == CONTEXT_STATE_ACTIVATING){
742 dbg("Context state : CONTEXT_STATE_ACTIVATING");
743 return TCORE_RETURN_SUCCESS;
745 else if (context_state == CONTEXT_STATE_DEACTIVATING){
746 dbg("Context state : CONTEXT_STATE_DEACTIVATING");
747 return TCORE_RETURN_PS_DEACTIVATING;
750 dbg("cid = %d", tcore_context_get_id(ps_context));
752 tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATING);
753 rv = po->ops->activate_context(o, ps_context, user_data);
754 if(rv != TCORE_RETURN_SUCCESS)
755 tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
760 TReturn tcore_ps_deactivate_context(CoreObject *o, CoreObject *ps_context, void *user_data)
763 struct private_object_data *po = NULL;
764 enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED;
766 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
768 po = tcore_object_ref_object(o);
770 return TCORE_RETURN_EINVAL;
773 dbg("ps network is not online !");
774 return TCORE_RETURN_PS_NETWORK_NOT_READY;
778 return TCORE_RETURN_EINVAL;
780 rv = _ps_is_active_context(o, ps_context);
782 return TCORE_RETURN_EINVAL;
784 rv = _ps_is_duplicated_apn(o, ps_context);
786 unsigned char cid = 0;
787 cid = tcore_context_get_id(ps_context);
788 po->cid[cid].contexts = g_slist_remove(po->cid[cid].contexts, ps_context);
789 tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
790 return TCORE_RETURN_SUCCESS;
793 context_state = tcore_context_get_state(ps_context);
794 if (context_state == CONTEXT_STATE_DEACTIVATED){
795 dbg("Context State : CONTEXT_STATE_DEACTIVATED");
796 return TCORE_RETURN_SUCCESS;
798 else if (context_state == CONTEXT_STATE_DEACTIVATING){
799 dbg("Context State : CONTEXT_STATE_DEACTIVATING");
800 return TCORE_RETURN_SUCCESS;
802 else if (context_state == CONTEXT_STATE_ACTIVATING){
803 dbg("Context State :CONTEXT_STATE_ACTIVATING");
804 return TCORE_RETURN_PS_ACTIVATING;
806 tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATING);
808 rv = po->ops->deactivate_context(o, ps_context, user_data);
809 if(rv != TCORE_RETURN_SUCCESS)
810 tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATED);
815 TReturn tcore_ps_deactivate_contexts(CoreObject *o)
818 struct private_object_data *po = NULL;
819 GSList *contexts = NULL;
821 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
823 po = tcore_object_ref_object(o);
825 return TCORE_RETURN_EINVAL;
828 dbg("ps network is not online !");
829 return TCORE_RETURN_PS_NETWORK_NOT_READY;
832 for (temp_index = 1; temp_index <= po->num_of_pdn; temp_index++) {
833 if (po->cid[temp_index].cid != 0) {
834 contexts = po->cid[temp_index].contexts;
838 g_slist_foreach (contexts, _deactivate_context, o);
842 return TCORE_RETURN_SUCCESS;
845 TReturn tcore_ps_deactivate_cid(CoreObject *o, unsigned int cid)
848 struct private_object_data *po = NULL;
849 GSList *contexts = NULL;
851 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL);
853 po = tcore_object_ref_object(o);
855 return TCORE_RETURN_EINVAL;
858 dbg("ps network is not online !");
859 return TCORE_RETURN_PS_NETWORK_NOT_READY;
862 for (temp_index = 1; temp_index <= po->num_of_pdn; temp_index++) {
863 if (po->cid[temp_index].cid != 0 && po->cid[temp_index].cid == cid) {
864 contexts = po->cid[temp_index].contexts;
868 g_slist_foreach (contexts, _deactivate_context, o);
872 return TCORE_RETURN_SUCCESS;