Code sync from tizen_2.4
[platform/core/telephony/libtcore.git] / src / co_context.c
index bab2d18..e6d460a 100644 (file)
 #include "user_request.h"
 #include "co_context.h"
 
-#define DEVNAME_LEN_MAX 16
-
 struct private_object_data {
        enum co_context_state state;
-       unsigned int id;
+       unsigned char id;
        enum co_context_role role;
+       gboolean default_profile;
+       gboolean attach_apn;
 
        char *apn;
        char *addr;
        enum co_context_type type;
        enum co_context_d_comp d_comp;
        enum co_context_h_comp h_comp;
-
+       enum co_context_tech tech_pref;
        char *username;
        char *password;
        char *dns1;
@@ -54,12 +54,22 @@ struct private_object_data {
        union tcore_ip4_type dns_primary_v4;
        union tcore_ip4_type dns_secondary_v4;
 
-       /*IPv6 will be supported*/
+       /* IPv6 will be supported */
+       char *ip_v6;
+       char *gateway_v6;
+       char *dns_primary_v6;
+       char *dns_secondary_v6;
+
+       pcscf_addr *pcscf_ipv4;
+       pcscf_addr *pcscf_ipv6;
 
        char *proxy;
        char *mmsurl;
        char *profile_name;
-       char devname[DEVNAME_LEN_MAX];
+       char devname[16];
+
+       /* Dedicated bearer information */
+       struct dedicated_bearer_info dedicated_bearer;
 };
 
 static void _free_hook(CoreObject *o)
@@ -68,12 +78,12 @@ static void _free_hook(CoreObject *o)
 
        po = tcore_object_ref_object(o);
        if (po) {
-               g_free(po);
+               free(po);
                tcore_object_link_object(o, NULL);
        }
 }
 
-CoreObject *tcore_context_new(TcorePlugin *p, TcoreHal *hal)
+CoreObject *tcore_context_new(TcorePlugin *p, const char *name, TcoreHal *hal)
 {
        CoreObject *o = NULL;
        struct private_object_data *po = NULL;
@@ -81,7 +91,7 @@ CoreObject *tcore_context_new(TcorePlugin *p, TcoreHal *hal)
        if (!p)
                return NULL;
 
-       o = tcore_object_new(p, hal);
+       o = tcore_object_new(p, name, hal);
        if (!o)
                return NULL;
 
@@ -96,6 +106,7 @@ CoreObject *tcore_context_new(TcorePlugin *p, TcoreHal *hal)
        po->h_comp = CONTEXT_H_COMP_OFF;
        po->role = CONTEXT_ROLE_UNKNOWN;
        po->auth = CONTEXT_AUTH_NONE;
+       po->tech_pref = CONTEXT_TECH_3GPP;
 
        tcore_object_set_type(o, CORE_OBJECT_TYPE_PS_CONTEXT);
        tcore_object_link_object(o, po);
@@ -106,16 +117,7 @@ CoreObject *tcore_context_new(TcorePlugin *p, TcoreHal *hal)
 
 void tcore_context_free(CoreObject *o)
 {
-       struct private_object_data *po = NULL;
-
        CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS_CONTEXT);
-
-       po = tcore_object_ref_object(o);
-       if (!po)
-               return;
-
-       g_free(po);
-       tcore_object_link_object(o, NULL);
        tcore_object_free(o);
 }
 
@@ -123,11 +125,6 @@ TReturn tcore_context_set_state(CoreObject *o, enum co_context_state state)
 {
        struct private_object_data *po = NULL;
 
-       dbg("Set State: [%s]", ((state == CONTEXT_STATE_ACTIVATED) ? "ACTIVATED"
-                                       : (state == CONTEXT_STATE_ACTIVATING) ? "ACTIVATING"
-                                       : (state == CONTEXT_STATE_DEACTIVATED) ? "DEACTIVATED"
-                                       : "DEACTIVATING"));
-
        CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
 
        po = tcore_object_ref_object(o);
@@ -152,7 +149,7 @@ enum co_context_state    tcore_context_get_state(CoreObject *o)
        return po->state;
 }
 
-TReturn tcore_context_set_id(CoreObject *o, unsigned int id)
+TReturn tcore_context_set_id(CoreObject *o, unsigned char id)
 {
        struct private_object_data *po = NULL;
 
@@ -167,7 +164,7 @@ TReturn tcore_context_set_id(CoreObject *o, unsigned int id)
        return TCORE_RETURN_SUCCESS;
 }
 
-unsigned int tcore_context_get_id(CoreObject *o)
+unsigned char  tcore_context_get_id(CoreObject *o)
 {
        struct private_object_data *po = NULL;
 
@@ -195,9 +192,8 @@ TReturn tcore_context_set_apn(CoreObject *o, const char *apn)
                po->apn = NULL;
        }
 
-       if (apn) {
+       if (apn)
                po->apn = g_strdup(apn);
-       }
 
        return TCORE_RETURN_SUCCESS;
 }
@@ -218,6 +214,43 @@ char *tcore_context_get_apn(CoreObject *o)
        return g_strdup(po->apn);
 }
 
+TReturn tcore_context_set_address(CoreObject *o, const char *addr)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       if (po->addr) {
+               free(po->addr);
+               po->addr = NULL;
+       }
+
+       if (addr)
+               po->addr = g_strdup(addr);
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_address(CoreObject *o)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return NULL;
+
+       if (!po->addr)
+               return NULL;
+
+       return g_strdup(po->addr);
+}
+
 TReturn tcore_context_set_role(CoreObject *o, enum co_context_role role)
 {
        struct private_object_data *po = NULL;
@@ -330,6 +363,34 @@ enum co_context_h_comp tcore_context_get_header_compression(CoreObject *o)
        return po->h_comp;
 }
 
+TReturn tcore_context_set_tech_preference(CoreObject *o, enum co_context_tech tech)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       po->tech_pref = tech;
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+enum co_context_tech tcore_context_get_tech_preference(CoreObject *o)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, 0);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return CONTEXT_TECH_INVALID;
+
+       return po->tech_pref;
+}
+
 TReturn tcore_context_set_username(CoreObject *o, const char *username)
 {
        struct private_object_data *po = NULL;
@@ -345,9 +406,8 @@ TReturn tcore_context_set_username(CoreObject *o, const char *username)
                po->username = NULL;
        }
 
-       if (username) {
+       if (username)
                po->username = g_strdup(username);
-       }
 
        return TCORE_RETURN_SUCCESS;
 }
@@ -383,9 +443,8 @@ TReturn tcore_context_set_password(CoreObject *o, const char *password)
                po->password = NULL;
        }
 
-       if (password) {
+       if (password)
                po->password = g_strdup(password);
-       }
 
        return TCORE_RETURN_SUCCESS;
 }
@@ -406,6 +465,122 @@ char *tcore_context_get_password(CoreObject *o)
        return g_strdup(po->password);
 }
 
+TReturn tcore_context_set_dns1(CoreObject *o, const char *dns)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       if (po->dns1) {
+               free(po->dns1);
+               po->dns1 = NULL;
+       }
+
+       if (dns)
+               po->dns1 = g_strdup(dns);
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_set_ipv6_dns1(CoreObject *o, const char *dns)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       if (po->dns_primary_v6) {
+               free(po->dns_primary_v6);
+               po->dns_primary_v6 = NULL;
+       }
+
+       if (dns)
+               po->dns_primary_v6 = g_strdup(dns);
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_dns1(CoreObject *o)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return NULL;
+
+       if (!po->dns1)
+               return NULL;
+
+       return g_strdup(po->dns1);
+}
+
+TReturn tcore_context_set_dns2(CoreObject *o, const char *dns)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       if (po->dns2) {
+               free(po->dns2);
+               po->dns2 = NULL;
+       }
+
+       if (dns)
+               po->dns2 = g_strdup(dns);
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_set_ipv6_dns2(CoreObject *o, const char *dns)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       if (po->dns_secondary_v6) {
+               free(po->dns_secondary_v6);
+               po->dns_secondary_v6 = NULL;
+       }
+
+       if (dns)
+               po->dns_secondary_v6 = g_strdup(dns);
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+char *tcore_context_get_dns2(CoreObject *o)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return NULL;
+
+       if (!po->dns2)
+               return NULL;
+
+       return g_strdup(po->dns2);
+}
+
 TReturn tcore_context_set_auth(CoreObject *o, enum co_context_auth auth)
 {
        struct private_object_data *po = NULL;
@@ -449,9 +624,8 @@ TReturn tcore_context_set_proxy(CoreObject *o, const char *proxy)
                po->apn = NULL;
        }
 
-       if (proxy) {
+       if (proxy)
                po->proxy = g_strdup(proxy);
-       }
 
        return TCORE_RETURN_SUCCESS;
 }
@@ -487,9 +661,8 @@ TReturn tcore_context_set_mmsurl(CoreObject *o, const char *mmsurl)
                po->mmsurl = NULL;
        }
 
-       if (mmsurl) {
+       if (mmsurl)
                po->mmsurl = g_strdup(mmsurl);
-       }
 
        return TCORE_RETURN_SUCCESS;
 }
@@ -525,9 +698,8 @@ TReturn tcore_context_set_profile_name(CoreObject *o, const char *profile_name)
                po->profile_name = NULL;
        }
 
-       if (profile_name) {
+       if (profile_name)
                po->profile_name = g_strdup(profile_name);
-       }
 
        return TCORE_RETURN_SUCCESS;
 }
@@ -548,35 +720,81 @@ char *tcore_context_get_profile_name(CoreObject *o)
        return g_strdup(po->profile_name);
 }
 
-TReturn tcore_context_set_devinfo(CoreObject *o, struct tnoti_ps_pdp_ipconfiguration *devinfo)
+TReturn tcore_context_set_default_profile(CoreObject *o, gboolean default_conn)
 {
        struct private_object_data *po = NULL;
 
-       dbg("Setup device information");
-
        CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
 
        po = tcore_object_ref_object(o);
-       if (!po) {
-               err("Failed to refer Object");
-               return FALSE;
-       }
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       po->default_profile = default_conn;
+
+       return TCORE_RETURN_SUCCESS;
+}
 
-       if (!devinfo) {
-               err("Device info is NULL");
+gboolean tcore_context_get_default_profile(CoreObject *o)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, FALSE);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
                return FALSE;
-       }
 
+       return po->default_profile;
+}
+
+TReturn tcore_context_set_devinfo(CoreObject *o, struct tnoti_ps_pdp_ipconfiguration *devinfo)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+
+       if (!po || !devinfo)
+               return TCORE_RETURN_EINVAL;
+
+       /* Free context resource if it was already allocated */
+       tcore_context_reset_devinfo(o);
+
+       po->ip_v6 = g_strdup((gchar *)devinfo->ipv6_address);
+       po->dns_primary_v6 = g_strdup((gchar *)devinfo->ipv6_primary_dns);
+       po->dns_secondary_v6 = g_strdup((gchar *)devinfo->ipv6_secondary_dns);
+       po->gateway_v6 = g_strdup((gchar *)devinfo->ipv6_gateway);
        memcpy(&(po->ip_v4), devinfo->ip_address, sizeof(union tcore_ip4_type));
        memcpy(&(po->dns_primary_v4), devinfo->primary_dns, sizeof(union tcore_ip4_type));
        memcpy(&(po->dns_secondary_v4), devinfo->secondary_dns, sizeof(union tcore_ip4_type));
        memcpy(&(po->gateway_v4), devinfo->gateway, sizeof(union tcore_ip4_type));
        memcpy(po->devname, devinfo->devname, sizeof(char) * 16);
 
-       msg("   IP Address: [0x%x]", po->ip_v4);
-       msg("   DNS - Primary: [0x%x] Secondary: [0x%x]", po->dns_primary_v4, po->dns_secondary_v4);
-       msg("   Gateway: [0x%x]", po->gateway_v4);
-       msg("   Device Name: [%s]", po->devname);
+       po->pcscf_ipv4 = g_try_malloc0(sizeof(pcscf_addr));
+       if (po->pcscf_ipv4) {
+               po->pcscf_ipv4->count = devinfo->pcscf_ipv4_count;
+               if (po->pcscf_ipv4->count > 0) {
+                       unsigned int i;
+                       po->pcscf_ipv4->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv4->count);
+                       if ((po->pcscf_ipv4->addr) && (devinfo->pcscf_ipv4))
+                               for (i = 0; i < po->pcscf_ipv4->count; i++)
+                                       po->pcscf_ipv4->addr[i] = g_strdup(devinfo->pcscf_ipv4[i]);
+               }
+       }
+
+       po->pcscf_ipv6 = g_try_malloc0(sizeof(pcscf_addr));
+       if (po->pcscf_ipv6) {
+               po->pcscf_ipv6->count = devinfo->pcscf_ipv6_count;
+               if (po->pcscf_ipv6->count > 0) {
+                       unsigned int i;
+                       po->pcscf_ipv6->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv6->count);
+                       if ((po->pcscf_ipv6->addr) && (devinfo->pcscf_ipv6))
+                               for (i = 0; i < po->pcscf_ipv6->count; i++)
+                                       po->pcscf_ipv6->addr[i] = g_strdup(devinfo->pcscf_ipv6[i]);
+               }
+       }
 
        return TCORE_RETURN_SUCCESS;
 }
@@ -584,14 +802,47 @@ TReturn tcore_context_set_devinfo(CoreObject *o, struct tnoti_ps_pdp_ipconfigura
 TReturn tcore_context_reset_devinfo(CoreObject *o)
 {
        struct private_object_data *po = NULL;
-
-       dbg("Reset device information");
+       unsigned int i;
 
        CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
 
        po = tcore_object_ref_object(o);
        if (!po)
-               return TCORE_RETURN_FAILURE;
+               return TCORE_RETURN_EINVAL;
+
+       if (po->ip_v6) {
+               g_free(po->ip_v6);
+               po->ip_v6 = NULL;
+       }
+
+       if (po->dns_primary_v6) {
+               g_free(po->dns_primary_v6);
+               po->dns_primary_v6 = NULL;
+       }
+
+       if (po->dns_secondary_v6) {
+               g_free(po->dns_secondary_v6);
+               po->dns_secondary_v6 = NULL;
+       }
+
+       if (po->gateway_v6) {
+               g_free(po->gateway_v6);
+               po->gateway_v6 = NULL;
+       }
+
+       if (po->pcscf_ipv4) {
+               for (i = 0; i < po->pcscf_ipv4->count; i++)
+                       g_free(po->pcscf_ipv4->addr[i]);
+               g_free(po->pcscf_ipv4);
+               po->pcscf_ipv4 = NULL;
+       }
+
+       if (po->pcscf_ipv6) {
+               for (i = 0; i < po->pcscf_ipv6->count; i++)
+                       g_free(po->pcscf_ipv6->addr[i]);
+               g_free(po->pcscf_ipv6);
+               po->pcscf_ipv6 = NULL;
+       }
 
        memset(&(po->ip_v4), 0, sizeof(union tcore_ip4_type));
        memset(&(po->dns_primary_v4), 0, sizeof(union tcore_ip4_type));
@@ -602,6 +853,68 @@ TReturn tcore_context_reset_devinfo(CoreObject *o)
        return TCORE_RETURN_SUCCESS;
 }
 
+TReturn tcore_context_set_bearer_info(CoreObject *o, struct tnoti_ps_dedicated_bearer_info *bearer_info)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       if (!bearer_info)
+               return TCORE_RETURN_EINVAL;
+
+       if (bearer_info->dedicated_bearer.num_dedicated_bearer > 0)
+               memcpy(&(po->dedicated_bearer), &(bearer_info->dedicated_bearer), sizeof(struct dedicated_bearer_info));
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_get_bearer_info(CoreObject *o, struct dedicated_bearer_info *bearer_info)
+{
+       struct private_object_data *po = NULL;
+       guchar count = 0;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       if (!bearer_info)
+               return TCORE_RETURN_EINVAL;
+
+       count = po->dedicated_bearer.num_dedicated_bearer;
+       if (count > MAX_NUM_DEDICATED_BEARER)
+               return TCORE_RETURN_EINVAL;
+
+       if (count > 0) {
+               bearer_info->num_dedicated_bearer = count;
+               bearer_info->secondary_context_id = po->dedicated_bearer.secondary_context_id;
+               memcpy(bearer_info->qos, po->dedicated_bearer.qos, count*sizeof(struct qos_parameter));
+       }
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+TReturn tcore_context_reset_bearer_info(CoreObject *o)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       if (po->dedicated_bearer.num_dedicated_bearer > 0)
+               memset(&(po->dedicated_bearer), 0, sizeof(struct dedicated_bearer_info));
+
+       return TCORE_RETURN_SUCCESS;
+}
+
 void tcore_context_cp_service_info(CoreObject *dest, CoreObject *src)
 {
        struct private_object_data *d_po = NULL;
@@ -615,56 +928,59 @@ void tcore_context_cp_service_info(CoreObject *dest, CoreObject *src)
 
        d_po->state = s_po->state;
        d_po->id = s_po->id;
+
+       d_po->ip_v6 = g_strdup(s_po->ip_v6);
+       d_po->dns_primary_v6 = g_strdup(s_po->dns_primary_v6);
+       d_po->dns_secondary_v6 = g_strdup(s_po->dns_secondary_v6);
+       d_po->gateway_v6 = g_strdup(s_po->gateway_v6);
+
        memcpy(&(d_po->ip_v4), &(s_po->ip_v4), sizeof(union tcore_ip4_type));
        memcpy(&(d_po->dns_primary_v4), &(s_po->dns_primary_v4), sizeof(union tcore_ip4_type));
        memcpy(&(d_po->dns_secondary_v4), &(s_po->dns_secondary_v4), sizeof(union tcore_ip4_type));
        memcpy(&(d_po->gateway_v4), &(s_po->gateway_v4), sizeof(union tcore_ip4_type));
        memcpy(d_po->devname, s_po->devname, sizeof(char) * 16);
-
-       return;
 }
 
-static void tcore_context_set_ipv4_atoi(unsigned char *ip4, const char *str)
+char *tcore_context_get_ipv4_addr(CoreObject *o)
 {
-       char *token = NULL;
-       char *temp = NULL;
-       int index = 0;
+       struct private_object_data *po = NULL;
 
-       temp = g_strdup(str);
-       token = strtok(temp, ".");
-       while (token != NULL) {
-               ip4[index++] = atoi(token);
-               msg("   [%c]", ip4[index-1]);
-               token = strtok(NULL, ".");
-       }
-       g_free(temp);
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return NULL;
+
+       return tcore_util_get_string_by_ip4type(po->ip_v4);
 }
 
-TReturn tcore_context_set_ipv4_addr(CoreObject *o, const char *addr)
+char *tcore_context_get_ipv4_dns1(CoreObject *o)
 {
        struct private_object_data *po = NULL;
 
-       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
 
        po = tcore_object_ref_object(o);
        if (!po)
-               return TCORE_RETURN_EINVAL;
+               return NULL;
 
-       if (po->addr) {
-               free(po->addr);
-               po->addr = NULL;
-       }
+       return tcore_util_get_string_by_ip4type(po->dns_primary_v4);
+}
 
-       if (addr) {
-               po->addr = g_strdup(addr);
-               tcore_context_set_ipv4_atoi(po->ip_v4.s, addr);
-               dbg("IP Address: [%s]", addr);
-       }
+char *tcore_context_get_ipv4_dns2(CoreObject *o)
+{
+       struct private_object_data *po = NULL;
 
-       return TCORE_RETURN_SUCCESS;
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return NULL;
+
+       return tcore_util_get_string_by_ip4type(po->dns_secondary_v4);
 }
 
-char* tcore_context_get_ipv4_addr(CoreObject *o)
+char *tcore_context_get_ipv4_gw(CoreObject *o)
 {
        struct private_object_data *po = NULL;
 
@@ -674,39 +990,39 @@ char* tcore_context_get_ipv4_addr(CoreObject *o)
        if (!po)
                return NULL;
 
-       return tcore_util_get_string_by_ip4type(po->ip_v4);
+       return tcore_util_get_string_by_ip4type(po->gateway_v4);
 }
 
-TReturn tcore_context_set_ipv4_dns(CoreObject *o, const char *dns1, const char *dns2)
+char *tcore_context_get_ipv4_devname(CoreObject *o)
 {
        struct private_object_data *po = NULL;
 
-       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
 
        po = tcore_object_ref_object(o);
        if (!po)
-               return TCORE_RETURN_EINVAL;
+               return NULL;
 
-       g_free(po->dns1);
-       po->dns1 = NULL;
+       if (po->devname[0] == 0)
+               return NULL;
 
-       g_free(po->dns2);
-       po->dns2 = NULL;
+       return g_strdup(po->devname);
+}
 
-       if (dns1) {
-               po->dns1 = g_strdup(dns1);
-               tcore_context_set_ipv4_atoi(po->dns_primary_v4.s, dns1);
-       }
+char *tcore_context_get_ipv6_addr(CoreObject *o)
+{
+       struct private_object_data *po = NULL;
 
-       if (dns2) {
-               po->dns2 = g_strdup(dns2);
-               tcore_context_set_ipv4_atoi(po->dns_secondary_v4.s, dns2);
-       }
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
 
-       return TCORE_RETURN_SUCCESS;
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return NULL;
+
+       return g_strdup(po->ip_v6);
 }
 
-char* tcore_context_get_ipv4_dns1(CoreObject *o)
+char *tcore_context_get_ipv6_dns1(CoreObject *o)
 {
        struct private_object_data *po = NULL;
 
@@ -716,10 +1032,10 @@ char* tcore_context_get_ipv4_dns1(CoreObject *o)
        if (!po)
                return NULL;
 
-       return tcore_util_get_string_by_ip4type(po->dns_primary_v4);
+       return g_strdup(po->dns_primary_v6);
 }
 
-char* tcore_context_get_ipv4_dns2(CoreObject *o)
+char *tcore_context_get_ipv6_dns2(CoreObject *o)
 {
        struct private_object_data *po = NULL;
 
@@ -729,10 +1045,10 @@ char* tcore_context_get_ipv4_dns2(CoreObject *o)
        if (!po)
                return NULL;
 
-       return tcore_util_get_string_by_ip4type(po->dns_secondary_v4);
+       return g_strdup(po->dns_secondary_v6);
 }
 
-char* tcore_context_get_ipv4_gw(CoreObject *o)
+char *tcore_context_get_ipv6_gw(CoreObject *o)
 {
        struct private_object_data *po = NULL;
 
@@ -742,29 +1058,47 @@ char* tcore_context_get_ipv4_gw(CoreObject *o)
        if (!po)
                return NULL;
 
-       return tcore_util_get_string_by_ip4type(po->gateway_v4);
+       return g_strdup(po->gateway_v6);
 }
 
-TReturn tcore_context_set_ipv4_devname(CoreObject *o, const char *name)
+pcscf_addr *tcore_context_get_pcscf_ipv4_addr(CoreObject *o)
 {
        struct private_object_data *po = NULL;
+       pcscf_addr *pcscf_tmp;
 
-       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
 
        po = tcore_object_ref_object(o);
        if (!po)
-               return TCORE_RETURN_EINVAL;
+               return NULL;
+
+       if (!po->pcscf_ipv4)
+               return NULL;
 
-       if (name) {
-               snprintf(po->devname, DEVNAME_LEN_MAX, "%s", name);
+       pcscf_tmp = g_try_malloc0(sizeof(pcscf_addr));
+       if (!pcscf_tmp)
+               return NULL;
+
+       pcscf_tmp->count = po->pcscf_ipv4->count;
+       if (pcscf_tmp->count > 0) {
+               unsigned int i;
+               pcscf_tmp->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv4->count);
+               if (!pcscf_tmp->addr) {
+                       g_free(pcscf_tmp);
+                       return NULL;
+               }
+
+               for (i = 0; i < po->pcscf_ipv4->count; i++)
+                       pcscf_tmp->addr[i] = g_strdup(po->pcscf_ipv4->addr[i]);
        }
 
-       return TCORE_RETURN_SUCCESS;
+       return pcscf_tmp;
 }
 
-char* tcore_context_get_ipv4_devname(CoreObject *o)
+pcscf_addr *tcore_context_get_pcscf_ipv6_addr(CoreObject *o)
 {
        struct private_object_data *po = NULL;
+       pcscf_addr *pcscf_tmp;
 
        CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL);
 
@@ -772,8 +1106,53 @@ char* tcore_context_get_ipv4_devname(CoreObject *o)
        if (!po)
                return NULL;
 
-       if (po->devname[0] == 0)
+       if (!po->pcscf_ipv6)
                return NULL;
 
-       return g_strdup(po->devname);
+       pcscf_tmp = g_try_malloc0(sizeof(pcscf_addr));
+       if (!pcscf_tmp)
+               return NULL;
+
+       pcscf_tmp->count = po->pcscf_ipv6->count;
+       if (pcscf_tmp->count > 0) {
+               unsigned int i;
+               pcscf_tmp->addr = g_try_malloc0(sizeof(char *) * po->pcscf_ipv6->count);
+               if (!pcscf_tmp->addr) {
+                       g_free(pcscf_tmp);
+                       return NULL;
+               }
+
+               for (i = 0; i < po->pcscf_ipv6->count; i++)
+                       pcscf_tmp->addr[i] = g_strdup(po->pcscf_ipv6->addr[i]);
+       }
+
+       return pcscf_tmp;
+}
+
+TReturn tcore_context_set_attach_apn(CoreObject *o, gboolean flag)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return TCORE_RETURN_EINVAL;
+
+       po->attach_apn = flag;
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+gboolean tcore_context_get_attach_apn(CoreObject *o)
+{
+       struct private_object_data *po = NULL;
+
+       CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, FALSE);
+
+       po = tcore_object_ref_object(o);
+       if (!po)
+               return FALSE;
+
+       return po->attach_apn;
 }