[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/combo_tool/mtkcombotool.bbappend b/meta/meta-mediatek-ivt/recipes-connectivity/combo_tool/mtkcombotool.bbappend
new file mode 100644
index 0000000..ed610de
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/combo_tool/mtkcombotool.bbappend
@@ -0,0 +1,6 @@
+do_compile_append() {
+	if [ -f ${B}/wmtd.service ]; then
+	        sed -i "s/nvram_daemon.service//g" ${B}/wmtd.service
+	fi
+}
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0004-connman-add-telephony-plugin.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0004-connman-add-telephony-plugin.patch
new file mode 100644
index 0000000..798ac25
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0004-connman-add-telephony-plugin.patch
@@ -0,0 +1,1310 @@
+From 15caddb6dfbfdf5d5ccf397a6f63b04be92dfb9a Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Wed, 7 Jun 2017 11:18:40 +0800
+Subject: [PATCH 4/9] connman: add telephony plugin
+
+Add telephony plugin for connman
+Test: test ok on 2635
+
+Change-Id: I3747104037b9b0bb4f57e58b24fa083cb322783c
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00003518
+---
+ plugins/telephony.c | 1285 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 1285 insertions(+)
+ create mode 100644 plugins/telephony.c
+
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+new file mode 100644
+index 0000000..2e49b34
+--- /dev/null
++++ b/plugins/telephony.c
+@@ -0,0 +1,1285 @@
++/*
++ *
++ *  Connection Manager
++ *
++ *  Copyright (C) 2007-2013  Intel Corporation. All rights reserved.
++ *  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
++ *  Copyright (C) 2011-2014  BMW Car IT GmbH.
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2 as
++ *  published by the Free Software Foundation.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <errno.h>
++#include <stdlib.h>
++
++#include <gdbus.h>
++#include <string.h>
++#include <stdint.h>
++#include <stdio.h>
++//getpid()
++#include <sys/types.h>
++#include <unistd.h>
++
++//syscall(224) for gettid
++#include <sys/syscall.h>
++
++
++
++#define CONNMAN_API_SUBJECT_TO_CHANGE
++#include <connman/plugin.h>
++#include <connman/device.h>
++#include <connman/network.h>
++#include <connman/inet.h>
++#include <connman/dbus.h>
++#include <connman/log.h>
++#include <connman/technology.h>
++
++
++
++#define TELEPHONY_SERVICE   "mtk.telephony"
++#define TELEPHONY_DATA_INTERFACE    "mtk.telephony.Data"
++#define TELEPHONY_DATA_PATH     "/mtk/telephony/data"
++
++#define SIGNAL_PDNSTATUSUNSOL       "PDNStatusUnsol"
++
++#define METHODC_SETUPDATACALL   "Setupdatacall"
++#define METHODC_DEACTIVEDATACALL    "Deactivedatacall"
++
++#define TIMEOUT 40000
++#define INTERNETPDNINDEX 1000
++#define INTERFACENAME 16
++
++
++static DBusConnection *connection;
++
++static struct modem_data *modem;
++static struct network_context *context;
++
++enum ConnmanPDNStatusType{
++    ConnmanPDNStatusUnknow = 0,
++    ConnmanPDNStatusConnected,
++    ConnmanPDNStatusDisconnected,
++    ConnmanPDNStatusTrying,
++    ConnmanPDNStatusMax
++};
++
++enum PdnState{
++    IDLE,
++    CONNECTING,
++    CONNECTED,
++    DISCONNECTING,
++    DISCONNECTED,
++    RETRYING,
++    FAILED
++};
++
++enum DBusType{
++    DMethodUnknow = -1,
++    DMethodCallSetupdatacall = 0,
++    DMethodDeactivedatacall,
++    DSignalPDNStatusUnsol = 10,
++    DMethodMax
++};
++
++
++struct network_context {
++    char *path;
++    int active;
++    enum ConnmanPDNStatusType pdnStatus;
++    int status;
++    int index;
++    int cid;
++    char ifname[16];
++    int mtu;
++    struct connman_network *network;
++
++    enum connman_ipconfig_method ipv4_method;
++    struct connman_ipaddress *ipv4_address;
++    char *ipv4_nameservers;
++
++    enum connman_ipconfig_method ipv6_method;
++    struct connman_ipaddress *ipv6_address;
++    char *ipv6_nameservers;
++};
++
++struct modem_data {
++    char *path;
++
++    struct connman_device *device;
++
++    bool enabled;
++
++    /* pending calls */
++    DBusPendingCall *call_setup_data_call;
++    DBusPendingCall *call_deactive_data_call;
++};
++
++struct DataCallResponse
++{
++    int reserve_word;
++    int active;
++    int status;
++    int cid;
++    char* type;
++    char* ifname;
++    char* addresses;
++    char* dnses;
++    char* gateway;
++    char* pcscf;
++    int mtu;
++};
++
++#if 1
++
++static char *get_ident(const char *path)
++{
++    char *pos;
++
++    if (*path != '/')
++        return NULL;
++
++    pos = strrchr(path, '/');
++    if (!pos)
++        return NULL;
++
++    return pos + 1;
++}
++
++static int extract_gatway(char *gatways, struct network_context *context)
++{
++    char *p = NULL;
++    char ipv4[16] = {};
++    char ipv6[32] = {};
++    int lengh;
++    //example: gateways=10.164.2.8 FE80:0000:0000:0000:2Cc3:323c:F968:93d8
++    if (!gatways || !context)
++    {
++        DBG("Invalid arguments.");
++        return -1;
++    }
++
++    p = strtok(gatways, " ");
++    DBG("p[%s].", p);
++
++    while (p)
++    {
++        //ipv4 address
++        if (strchr(p, '.'))
++        {
++            snprintf(ipv4, 15, "%s", p);
++        }
++        else if (strchr(p, ':'))  //ipv6 address
++        {
++            snprintf(ipv6, 31, "%s", p);
++        }
++        else{
++            DBG("Invalid dns[%s].", p);
++        }
++        p = strtok(NULL, " ");
++
++    }
++
++    DBG("ipv4[%s] ipv6[%s]", ipv4, ipv6);
++
++    if (strlen(ipv4) != 0)
++    {
++        DBG("ipv4[%s].", ipv4);
++
++        if (context->ipv4_address)
++        {
++            connman_ipaddress_free(context->ipv4_address);
++            context->ipv4_address = NULL;
++        }
++
++        context->ipv4_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
++
++        connman_ipaddress_set_ipv4(context->ipv4_address, NULL, NULL, ipv4);
++    }
++
++    if (strlen(ipv6) != 0)
++    {
++        DBG("ipv6[%s].", ipv6);
++
++        if (context->ipv6_address)
++        {
++            connman_ipaddress_free(context->ipv6_address);
++            context->ipv6_address = NULL;
++        }
++
++        context->ipv6_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
++
++        connman_ipaddress_set_ipv6(context->ipv6_address, NULL, 0, ipv6);
++    }
++
++}
++
++
++
++static int extract_dns(char *dnses, struct network_context *context)
++{
++    char *p = NULL;
++    char ipv4[256] = {};
++    char ipv6[256] = {};
++    int lengh;
++
++
++
++    //example: dnses = "10.164.2.8 FE80:0000:0000:0000:2Cc3:323c:F968:93d8 10.164.2.7"
++    if (!dnses || !context)
++    {
++        DBG("Invalid arguments.");
++        return -1;
++    }
++
++    p = strtok(dnses, " ");
++
++    DBG("p[%s]", p);
++    while (p)
++    {
++        //ipv4 address
++        if (strchr(p, '.'))
++        {
++            snprintf(&ipv4[strlen(ipv4)], 256-strlen(ipv4), "%s ", p);
++        }
++        else if (strchr(p, ':'))  //ipv6 address
++        {
++            snprintf(&ipv6[strlen(ipv6)], 256-strlen(ipv6), "%s ", p);
++        }
++        else{
++            DBG("Invalid dns[%s].", p);
++        }
++        p = strtok(NULL, " ");
++
++    }
++
++    DBG("ipv4[%s] ipv6[%s]", ipv4, ipv6);
++
++    if (strlen(ipv4) != 0)
++    {
++        //set  the closing  char ' ' to '\0'
++        if (ipv4[strlen(ipv4)] == ' ' )
++            ipv4[strlen(ipv4)] = '\0';
++
++        if(context->ipv4_nameservers)
++        {
++            g_free(context->ipv4_nameservers);
++            context->ipv4_nameservers = NULL;
++
++        }
++
++        lengh = strlen(ipv6) + 1;
++        context->ipv6_nameservers = g_strdup(ipv6);
++        DBG("context->ipv4_nameservers[%s].", context->ipv6_nameservers);
++    }
++
++    if (strlen(ipv6) != 0)
++    {
++        //set  the closing  char ' ' to '\0'
++        if (ipv6[strlen(ipv6)] == ' ' )
++            ipv6[strlen(ipv6)] = '\0';
++
++
++        if(context->ipv6_nameservers)
++        {
++            g_free(context->ipv6_nameservers);
++            context->ipv6_nameservers = NULL;
++
++        }
++
++        lengh = strlen(ipv6) + 1;
++        context->ipv6_nameservers = g_strdup(ipv6);
++        DBG("context->ipv4_nameservers[%s].", context->ipv6_nameservers);
++
++    }
++
++    return 0;
++}
++
++
++
++
++static int extract_dbus_info( struct DataCallResponse *dataCallResponse, struct network_context *context, enum DBusType dbusType)
++{
++
++    if ((NULL == dataCallResponse) || NULL == context)
++    {
++        DBG("Invalid arguments.");
++        return -1;
++    }
++
++    DBG("dataCallResponse[%p] context[%p] dbusType[%d]", dataCallResponse, context, dbusType);
++
++    switch(dbusType){
++        case DMethodCallSetupdatacall:
++        {
++            context->active = dataCallResponse->active;
++            context->status = dataCallResponse->status;
++            context->cid = dataCallResponse->cid;
++
++            DBG("context->active[%d] context->status[%d] context->cid[%d]", context->active, context->status, context->cid);
++
++            if (dataCallResponse->ifname)
++            {
++                strncpy(context->ifname, dataCallResponse->ifname, INTERFACENAME);
++                DBG("context->ifname[%s]", context->ifname);
++            }
++
++            if (dataCallResponse->dnses)
++            {
++                DBG("dataCallResponse->dnses[%s]", dataCallResponse->dnses);
++                extract_dns(dataCallResponse->dnses, context);
++            }
++
++            if (dataCallResponse->gateway)
++            {
++                DBG("dataCallResponse->gateway[%s]", dataCallResponse->gateway);
++                extract_gatway(dataCallResponse->gateway, context);
++            }
++
++            context->mtu = dataCallResponse->mtu;
++            break;
++        }
++        case DMethodDeactivedatacall:
++        {
++            context->active = dataCallResponse->active;
++            context->status = dataCallResponse->status;
++            context->cid = dataCallResponse->cid;
++            break;
++        }
++        case DSignalPDNStatusUnsol:
++        {
++            //need to add later
++            break;
++        }
++    }
++
++}
++
++
++
++static struct network_context *network_context_alloc(const char *path)
++{
++    struct network_context *context;
++
++    context = g_try_new0(struct network_context, 1);
++    if (!context)
++        return NULL;
++
++    DBG("PID[%u] TID[%u] Alloc[%p]", getpid(), syscall(224), context);
++
++    context->path = g_strdup(path);
++    context->index = -1;
++    context->pdnStatus = ConnmanPDNStatusUnknow;
++
++    context->ipv4_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
++    context->ipv4_address = NULL;
++    context->ipv4_nameservers = NULL;
++
++    context->ipv6_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
++    context->ipv6_address = NULL;
++    context->ipv6_nameservers = NULL;
++
++    return context;
++}
++
++
++static void network_context_free()
++{
++    g_free(context->path);
++
++    connman_ipaddress_free(context->ipv4_address);
++    g_free(context->ipv4_nameservers);
++
++    connman_ipaddress_free(context->ipv6_address);
++    g_free(context->ipv6_nameservers);
++
++    g_free(context);
++    context = NULL;
++}
++
++
++static void create_device(struct modem_data *modem)
++{
++    struct connman_device *device;
++    //char *ident = NULL;
++
++    DBG("%s", modem->path);
++
++
++    //if (!connman_dbus_validate_ident(ident))
++    //  ident = connman_dbus_encode_string(ident);
++    //else
++    //  ident = g_strdup(ident);
++
++    device = connman_device_create("telephony", CONNMAN_DEVICE_TYPE_CELLULAR);
++    if (!device)
++        return;
++
++    DBG("device[%p]", device);
++
++    connman_device_set_ident(device, "d607d111becc");
++
++    connman_device_set_string(device, "Path", modem->path);
++
++    connman_device_set_data(device, modem);
++
++    if (connman_device_register(device) < 0) {
++        connman_error("Failed to register cellular device");
++        connman_device_unref(device);
++        return;
++    }
++
++    modem->device = device;
++
++    connman_device_set_powered(modem->device, TRUE);
++}
++
++static void destroy_device(struct modem_data *modem)
++{
++    DBG("%s", modem->path);
++
++    connman_device_set_powered(modem->device, false);
++
++    connman_device_unregister(modem->device);
++    connman_device_unref(modem->device);
++
++    modem->device = NULL;
++}
++
++static void add_network(struct modem_data *modem,
++            struct network_context *context)
++{
++    const char *group;
++    struct connman_service *service;
++    int index;
++
++    DBG("%s", modem->path);
++
++    if (context->network)
++        return;
++
++    context->network = connman_network_create(context->path,
++                    CONNMAN_NETWORK_TYPE_CELLULAR);
++    if (!context->network)
++        return;
++
++
++
++    connman_network_set_data(context->network, modem);
++
++    connman_network_set_string(context->network, "Path",
++                    context->path);
++
++
++    connman_network_set_name(context->network, "Cellular");
++
++    group = get_ident(context->path);
++    connman_network_set_group(context->network, group);
++
++    DBG("network[%p] group[%s]", context->network, group);
++
++
++
++    if (connman_device_add_network(modem->device, context->network) < 0) {
++        connman_network_unref(context->network);
++        context->network = NULL;
++        return;
++    }
++
++    service = connman_service_lookup_from_network(context->network);
++
++    DBG("service1[%p]", service);
++
++    if (service)
++    {
++        DBG("connman_network_set_index to -1");
++        connman_network_set_index(context->network, -1);
++        connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
++        connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
++
++    }
++}
++
++static void set_connected(struct modem_data *modem,
++            struct network_context *context)
++{
++    struct connman_service *service;
++    bool setip = false;
++    enum connman_ipconfig_method method;
++    char *nameservers;
++    int index;
++
++
++
++    index = connman_inet_ifindex(context->ifname);//context->index;
++    connman_inet_ifup(index);//ZY it will makred
++    DBG("ifname[%s] index[%d]", context->ifname, index);
++
++    service = connman_service_lookup_from_network(context->network);
++    if (!service)
++    {
++        DBG("NULL service");
++        return;
++    }
++
++    connman_service_create_ip4config(service, index);
++     connman_network_set_index(context->network, index);
++    connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
++
++
++
++
++    //connman_ipaddress_set_ipv4(context->ipv4_address, "172.168.0.100", "255.255.255.0", "172.168.0.100");
++
++
++    connman_network_set_ipaddress(context->network,context->ipv4_address);
++    connman_network_set_nameservers(context->network, context->ipv4_nameservers);
++
++
++
++    connman_network_set_connected(context->network, true);
++    context->pdnStatus = ConnmanPDNStatusConnected;
++
++}
++
++
++static void set_disconnected(struct network_context *context)
++{
++    DBG("%s", context->path);
++
++    if (context->network)
++        connman_network_set_connected(context->network, false);
++
++    if (context) {
++        g_free(context->ipv4_nameservers);
++        context->ipv4_nameservers = NULL;
++        if (context->ipv4_method != CONNMAN_IPCONFIG_METHOD_OFF)
++            context->ipv4_method =
++                    CONNMAN_IPCONFIG_METHOD_UNKNOWN;
++
++        g_free(context->ipv6_nameservers);
++        context->ipv6_nameservers = NULL;
++        if (context->ipv6_method != CONNMAN_IPCONFIG_METHOD_OFF)
++            context->ipv6_method =
++                    CONNMAN_IPCONFIG_METHOD_UNKNOWN;
++    }
++
++    context->pdnStatus = ConnmanPDNStatusDisconnected;
++}
++
++
++
++
++static void remove_network(struct modem_data *modem,
++        struct network_context *context)
++{
++    DBG("%s", modem->path);
++
++    if (!context || !context->network)
++        return;
++
++    DBG("network %p", context->network);
++
++    if (modem->device)
++        connman_device_remove_network(modem->device, context->network);
++    connman_network_unref(context->network);
++    context->network = NULL;
++}
++
++
++
++static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
++{
++    DBusMessage *reply;
++    DBusError error;
++    char *content;
++    dbus_bool_t     ret;
++    struct DataCallResponse dataCallResponse = {};
++
++
++    modem->call_setup_data_call = NULL;
++
++
++    DBG("");
++
++    dbus_error_init(&error);
++
++    reply = dbus_pending_call_steal_reply(call);
++
++
++    dbus_error_init( &error );
++
++    ret = dbus_message_get_args( reply, &error,
++            DBUS_TYPE_INT32, &dataCallResponse.active,
++            DBUS_TYPE_INT32, &dataCallResponse.status,
++            DBUS_TYPE_INT32, &dataCallResponse.cid,
++            DBUS_TYPE_STRING, &dataCallResponse.type,
++            DBUS_TYPE_STRING, &dataCallResponse.ifname,
++            DBUS_TYPE_STRING, &dataCallResponse.addresses,
++            DBUS_TYPE_STRING, &dataCallResponse.dnses,
++            DBUS_TYPE_STRING, &dataCallResponse.gateway,
++            DBUS_TYPE_INT32, &dataCallResponse.mtu,
++            DBUS_TYPE_INVALID );
++
++    if (FALSE == ret)
++    {
++        DBG("%s:%s", error.name, error.message);
++        dbus_message_unref(reply);
++        dbus_pending_call_unref(call);
++        return;
++    }
++
++    DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
++    DBG("type[%d] ifname[%s] addresses[%s]", dataCallResponse.type, dataCallResponse.ifname, dataCallResponse.addresses);
++    DBG("dnses[%s] gateway[%s] mtu[%d]", dataCallResponse.dnses, dataCallResponse.gateway , dataCallResponse.mtu);
++
++    extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
++
++    #if 1
++
++    if (context->active == CONNECTED)
++    {
++        set_connected(modem, context);
++    }else{
++        set_disconnected(context);
++    }
++    #endif
++
++
++    dbus_message_unref(reply);
++    dbus_pending_call_unref(call);
++}
++
++
++static void deactive_datacall_reply(DBusPendingCall *call, void *user_data)
++{
++    DBusMessage *reply;
++    DBusError error;
++    char *content;
++    dbus_bool_t     ret;
++    struct DataCallResponse dataCallResponse = {};
++
++    DBG("");
++
++    modem->call_deactive_data_call = NULL;
++
++    dbus_error_init(&error);
++
++    reply = dbus_pending_call_steal_reply(call);
++
++
++    dbus_error_init( &error );
++
++    ret = dbus_message_get_args(reply, &error,
++                   DBUS_TYPE_INT32, &dataCallResponse.active,
++                   DBUS_TYPE_INT32, &dataCallResponse.status,
++                   DBUS_TYPE_INT32, &dataCallResponse.cid,
++                   DBUS_TYPE_INVALID);
++
++    if (FALSE == ret)
++    {
++        DBG("%s:%s", error.name, error.message);
++        dbus_message_unref(reply);
++        dbus_pending_call_unref(call);
++        return;
++    }
++
++    DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
++
++    extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
++
++    if (context->active == DISCONNECTED)
++    {
++        set_disconnected(context);
++    }
++
++    dbus_message_unref(reply);
++
++    dbus_pending_call_unref(call);
++}
++
++
++static void send_method_call(DBusConnection * connection, enum DBusType dbusType)
++{
++    DBusError err;
++    DBusMessage * msg, *reply;
++    DBusMessageIter    arg;
++    DBusPendingCall * pending;
++    dbus_bool_t * stat;
++    dbus_uint32_t * level;
++    dbus_int32_t id = 1;
++    DBusError error;
++    char *pdn = "Internet";
++    struct DataCallResponse dataCallResponse = {};
++    int ret;
++
++    dbus_error_init(&err);
++
++
++    DBG("methodType[%d]", dbusType);
++
++    switch(dbusType){
++        case DMethodCallSetupdatacall:
++        {
++            DBG("modem->call_setup_data_call[%p]", modem->call_setup_data_call);
++            if (modem->call_setup_data_call) {
++                DBG("Cancel pending SetProperty");
++                dbus_pending_call_cancel(modem->call_setup_data_call);
++                dbus_pending_call_unref(modem->call_setup_data_call);
++                modem->call_setup_data_call = NULL;
++            }
++
++            DBG("methodType1");
++            msg = dbus_message_new_method_call (TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_SETUPDATACALL);
++            if(msg == NULL){
++                DBG("MessageNULL");
++               return;
++            }
++            DBG("methodType2");
++
++            dbus_message_iter_init_append(msg, &arg);
++            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_INT32, &id)){
++               DBG("dbus_message_iter_append_basic Out of Memory!");
++           }
++
++            DBG("methodType3 pdn[%p] &pdn[%p]", pdn, &pdn);
++           if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_STRING, &pdn)){
++               DBG("dbus_message_iter_append_basic Out of Memory!");
++           }
++
++            DBG("methodType4");
++            if(!dbus_connection_send_with_reply (connection, msg, &modem->call_setup_data_call, TIMEOUT)){
++              DBG("dbus_connection_send_with_reply Out of Memory!");
++           }
++
++            DBG("methodType5");
++
++            if (!modem->call_setup_data_call) {
++                connman_error("D-Bus connection not available");
++                dbus_message_unref(msg);
++                return;
++            }
++
++            DBG("dbus_message_unref1");
++            dbus_message_unref(msg);
++
++            #if 1
++
++            dbus_pending_call_set_notify(modem->call_setup_data_call,
++                    setup_datacall_reply, NULL, NULL);
++            #else
++
++
++            dbus_pending_call_block (modem->call_setup_data_call);
++
++            reply =dbus_pending_call_steal_reply (modem->call_setup_data_call);
++            if (msg == NULL)
++            {
++                DBG("ReplyNull!");
++                dbus_message_unref(reply);
++                return;
++            }
++
++
++
++            ret = dbus_message_get_args( reply, &err,
++                   DBUS_TYPE_INT32, &dataCallResponse.active,
++                   DBUS_TYPE_INT32, &dataCallResponse.status,
++                   DBUS_TYPE_INT32, &dataCallResponse.cid,
++                   DBUS_TYPE_STRING, &dataCallResponse.type,
++                   DBUS_TYPE_STRING, &dataCallResponse.ifname,
++                   DBUS_TYPE_STRING, &dataCallResponse.addresses,
++                   DBUS_TYPE_STRING, &dataCallResponse.dnses,
++                   DBUS_TYPE_STRING, &dataCallResponse.gateway,
++                   DBUS_TYPE_INT32, &dataCallResponse.mtu,
++                   DBUS_TYPE_INVALID );
++
++            if (FALSE == ret)
++            {
++                DBG("error.nam[%s]: error.message[%s]", error.name, error.message);
++                dbus_message_unref(msg);
++                dbus_pending_call_unref(modem->call_setup_data_call);
++                modem->call_setup_data_call = NULL;
++                dbus_message_unref(reply);
++                return;
++            }
++
++            DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
++            DBG("type[%s] ifname[%s] addresses[%s]", dataCallResponse.type, dataCallResponse.ifname, dataCallResponse.addresses);
++            DBG("dnses[%s] gateway[%s] mtu[%d]", dataCallResponse.dnses, dataCallResponse.gateway , dataCallResponse.mtu);
++
++            extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
++
++            if (context->active == CONNECTED)
++            {
++                set_connected(modem, context);
++            }
++
++
++            dbus_message_unref(reply);
++            dbus_pending_call_unref(modem->call_setup_data_call);
++            modem->call_setup_data_call = NULL;
++
++            #endif
++            break;
++
++        }
++
++        case DMethodDeactivedatacall:
++        {
++            DBG("modem->call_deactive_data_call[%p]", modem->call_deactive_data_call);
++            if (modem->call_deactive_data_call) {
++                DBG("Cancel pending SetProperty");
++                dbus_pending_call_cancel(modem->call_deactive_data_call);
++                dbus_pending_call_unref(modem->call_deactive_data_call);
++                modem->call_deactive_data_call = NULL;
++            }
++
++            DBG("DMethodDeactivedatacall");
++
++            msg = dbus_message_new_method_call(TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_DEACTIVEDATACALL);
++            if(msg == NULL){
++            DBG("MessageNULL");
++               return;
++           }
++
++            dbus_message_iter_init_append(msg, &arg);
++            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_INT32, &id)){
++               DBG("dbus_message_iter_append_basic Out of Memory!");
++           }
++
++           if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_STRING, &pdn)){
++               DBG("dbus_message_iter_append_basic Out of Memory!");
++           }
++
++            if(!dbus_connection_send_with_reply (connection, msg, &modem->call_deactive_data_call, TIMEOUT)){
++              DBG("dbus_connection_send_with_reply Out of Memory!");
++           }
++
++            dbus_message_unref(msg);
++
++            #if 1
++
++            dbus_pending_call_set_notify(modem->call_deactive_data_call,
++                    deactive_datacall_reply, NULL, NULL);
++            #else
++
++
++            dbus_pending_call_block (modem->call_deactive_data_call);
++
++            reply =dbus_pending_call_steal_reply (modem->call_deactive_data_call);
++            if (msg == NULL)
++            {
++                DBG("ReplyNull!");
++                dbus_message_unref(reply);
++                return;
++            }
++
++
++
++            ret = dbus_message_get_args(reply, &err,
++                   DBUS_TYPE_INT32, &dataCallResponse.active,
++                   DBUS_TYPE_INT32, &dataCallResponse.status,
++                   DBUS_TYPE_INT32, &dataCallResponse.cid,
++                   DBUS_TYPE_INVALID);
++
++            if (FALSE == ret)
++            {
++                DBG("error.name [%s]: error.message[%s]", error.name, error.message);
++                dbus_message_unref(msg);
++                dbus_pending_call_unref(modem->call_deactive_data_call);
++                modem->call_deactive_data_call = NULL;
++                dbus_message_unref(reply);
++                return;
++            }
++
++            DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
++
++            extract_dbus_info(&dataCallResponse, context, DMethodDeactivedatacall);
++
++            if (context->active == DISCONNECTED)
++            {
++                set_disconnected(context);
++            }else{
++
++            }
++
++
++            dbus_message_unref(reply);
++            dbus_pending_call_unref(modem->call_deactive_data_call);
++            modem->call_deactive_data_call = NULL;
++
++            #endif
++            break;
++
++        }
++        default:
++        {
++            break;
++        }
++    }
++
++    DBG("methodType6");
++
++}
++
++#endif
++
++
++
++static void remove_modem()
++{
++    void * test;
++    DBG("modem[%p]", modem);
++    if(!modem)
++    {
++        return;
++    }
++
++    DBG("");
++
++    if (modem->call_setup_data_call) {
++        dbus_pending_call_cancel(modem->call_setup_data_call);
++        dbus_pending_call_unref(modem->call_setup_data_call);
++    }
++
++    if (modem->call_deactive_data_call) {
++        dbus_pending_call_cancel(modem->call_deactive_data_call);
++        dbus_pending_call_unref(modem->call_deactive_data_call);
++    }
++
++//    if (modem->device)
++//      destroy_device(modem);
++
++    test = calloc(16, 1024);
++    if (!test)
++        DBG("test memory fail");
++
++
++    DBG("test[%p]", test);
++    memset(test, 1, 16*1024);
++
++    g_free(modem->path);
++    DBG("PID[%u] TID[%u] Alloc[%p]", getpid(), syscall(224), modem->path);
++
++    g_free(modem);
++
++    DBG("PID[%u] TID[%u] Alloc[%p]", getpid(), syscall(224), modem);
++    modem = NULL;
++}
++
++static void add_modem(const char *path, DBusMessageIter *prop)
++{
++    remove_modem();
++
++    modem = g_try_new0(struct modem_data, 1);
++    if (!modem)
++    {
++        DBG("out of memory");
++        return;
++    }
++
++    DBG("PID[%u] TID[%u] Alloc[%p]", getpid(), syscall(224), modem);
++
++    modem->path = g_strdup(path);
++    modem->enabled = TRUE;
++}
++
++
++static int network_probe(struct connman_network *network)
++ {
++
++    DBG("");
++
++    return 0;
++}
++
++
++static void network_remove(struct connman_network *network)
++{
++
++    DBG("");
++}
++
++static int network_connect(struct connman_network *network)
++{
++
++    DBG("");
++    connection = connman_dbus_get_connection();
++    if (!connection)
++        return -EIO;
++
++    send_method_call(connection, DMethodCallSetupdatacall);
++
++    return 0;
++}
++
++static int network_disconnect(struct connman_network *network)
++{
++
++    DBG("");
++    connection = connman_dbus_get_connection();
++    if (!connection)
++        return -EIO;
++
++    send_method_call(connection, DMethodDeactivedatacall);
++
++    return 0;
++}
++
++static struct connman_network_driver network_driver = {
++    .name       = "cellular",
++    .type       = CONNMAN_NETWORK_TYPE_CELLULAR,
++    .probe     = network_probe,
++    .remove    = network_remove,
++    .connect    = network_connect,
++    .disconnect = network_disconnect,
++};
++
++static int modem_probe(struct connman_device *device)
++{
++
++    DBG("");
++
++    return 0;
++}
++
++static void modem_remove(struct connman_device *device)
++{
++
++    DBG("");
++}
++
++static int modem_enable(struct connman_device *device)
++{
++    DBG("");
++    return 0;
++}
++
++static int modem_disable(struct connman_device *device)
++{
++    DBG("");
++    return 0;
++}
++
++static struct connman_device_driver modem_driver = {
++    .name       = "modem",
++    .type       = CONNMAN_DEVICE_TYPE_CELLULAR,
++    .probe     = modem_probe,
++    .remove    = modem_remove,
++    .enable    = modem_enable,
++    .disable    = modem_disable,
++};
++
++static int tech_probe(struct connman_technology *technology)
++{
++    return 0;
++}
++
++static void tech_remove(struct connman_technology *technology)
++{
++}
++
++static struct connman_technology_driver tech_driver = {
++    .name       = "cellular",
++    .type       = CONNMAN_SERVICE_TYPE_CELLULAR,
++    .probe     = tech_probe,
++    .remove    = tech_remove,
++};
++
++static void set_property_reply(DBusPendingCall *call, void *user_data)
++{
++    DBusMessage *reply;
++    DBusError error;
++    bool success = true;
++
++
++    modem->call_setup_data_call = NULL;
++
++    dbus_error_init(&error);
++
++    reply = dbus_pending_call_steal_reply(call);
++
++    if (dbus_set_error_from_message(&error, reply)) {
++        connman_error("Failed to change property: %s %s",
++                error.name, error.message);
++        dbus_error_free(&error);
++        success = false;
++    }
++
++}
++
++static void telephony_connect(DBusConnection *conn, void *user_data)
++{
++    DBG("");
++
++    add_modem(TELEPHONY_DATA_PATH, NULL);
++    create_device(modem);
++
++    if (context)
++    {
++        network_context_free();
++    }
++
++    context = network_context_alloc(modem->path);
++    add_network(modem, context);
++}
++
++
++
++
++static void telephony_disconnect(DBusConnection *conn, void *user_data)
++{
++    DBG("");
++
++    remove_modem(modem);
++}
++
++static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
++                void *user_data)
++{
++     DBusError error;
++    DBusMessageIter iter;
++    int ret;
++    struct DataCallResponse dataCallResponse = {};
++
++
++    DBG("");
++
++    dbus_error_init(&error);
++    if (!dbus_message_iter_init(message, &iter))
++    {
++        DBG("dbus_message_iter_init fail");
++        return TRUE;
++    }
++
++    ret = dbus_message_get_args( message, &error,
++                   DBUS_TYPE_INT32, &dataCallResponse.active,
++                   DBUS_TYPE_INT32, &dataCallResponse.status,
++                   DBUS_TYPE_INT32, &dataCallResponse.cid,
++                   DBUS_TYPE_STRING, &dataCallResponse.type,
++                   DBUS_TYPE_STRING, &dataCallResponse.ifname,
++                   DBUS_TYPE_STRING, &dataCallResponse.addresses,
++                   DBUS_TYPE_STRING, &dataCallResponse.dnses,
++                   DBUS_TYPE_STRING, &dataCallResponse.gateway,
++                   DBUS_TYPE_INT32, &dataCallResponse.mtu,
++                   DBUS_TYPE_INVALID );
++
++        if (FALSE == ret)
++        {
++            DBG("error.nam[%s]: error.message[%s]", error.name, error.message);
++            dbus_message_unref(message);
++            return FALSE;
++        }
++
++        DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
++
++        extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
++
++        DBG("context->pdnStatus[%d] active[%d] status[%d] cid[%d]", context->pdnStatus, dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
++
++        if ((context->pdnStatus == ConnmanPDNStatusConnected) && (context->active == DISCONNECTED))
++        {
++            DBG("set_disconnected");
++            set_disconnected(context);
++        }
++
++        return TRUE;
++}
++
++static guint watch;
++static guint pdn_status_watch;
++
++
++static int telephony_init(void)
++{
++    int err;
++
++    DBG("");
++
++    connection = connman_dbus_get_connection();
++    if (!connection)
++        return -EIO;
++
++    watch = g_dbus_add_service_watch(connection,
++                    TELEPHONY_SERVICE, telephony_connect,
++                    telephony_disconnect, NULL, NULL);
++
++    pdn_status_watch = g_dbus_add_signal_watch(connection, TELEPHONY_SERVICE, NULL,
++                        TELEPHONY_DATA_INTERFACE,
++                        SIGNAL_PDNSTATUSUNSOL,
++                        pdn_status_unsol,
++                        NULL, NULL);
++
++    if (watch == 0 || pdn_status_watch == 0) {
++        err = -EIO;
++
++        goto remove;
++    }
++
++    err = connman_network_driver_register(&network_driver);
++    if (err < 0)
++        goto remove;
++
++    err = connman_device_driver_register(&modem_driver);
++    if (err < 0) {
++        connman_network_driver_unregister(&network_driver);
++        goto remove;
++    }
++
++    err = connman_technology_driver_register(&tech_driver);
++    if (err < 0) {
++        connman_device_driver_unregister(&modem_driver);
++        connman_network_driver_unregister(&network_driver);
++        goto remove;
++    }
++
++    return 0;
++
++ remove:
++    g_dbus_remove_watch(connection, pdn_status_watch);
++    g_dbus_remove_watch(connection, watch);
++
++    dbus_connection_unref(connection);
++
++}
++
++static void  telephony_exit(void)
++{
++    DBG("");
++
++
++    remove_modem(modem);
++
++    connman_technology_driver_unregister(&tech_driver);
++    connman_device_driver_unregister(&modem_driver);
++    connman_network_driver_unregister(&network_driver);
++
++    g_dbus_remove_watch(connection, pdn_status_watch);
++    g_dbus_remove_watch(connection, watch);
++
++    dbus_connection_unref(connection);
++}
++
++
++
++
++ CONNMAN_PLUGIN_DEFINE(ofono, "oFono telephony plugin", VERSION,
++        CONNMAN_PLUGIN_PRIORITY_DEFAULT, telephony_init, telephony_exit)
++
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0005-connman-build-plugin-telephon.c.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0005-connman-build-plugin-telephon.c.patch
new file mode 100644
index 0000000..98ddb3a
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0005-connman-build-plugin-telephon.c.patch
@@ -0,0 +1,49 @@
+From 5a687895e7d16b19e04757cf54ee252c9cbb8064 Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Wed, 7 Jun 2017 15:20:26 +0800
+Subject: [PATCH 5/9] connman: build plugin/telephon.c
+
+Build plugin/telephon.c
+Test: test ok on 2635
+
+Change-Id: Iedcd442dfd0564b033f922d69d8f4e3bfc2cfb5e
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00003518
+---
+ Makefile.plugins | 4 ++++
+ configure.ac     | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/Makefile.plugins b/Makefile.plugins
+index e90ad19..8b4182d 100644
+--- a/Makefile.plugins
++++ b/Makefile.plugins
+@@ -50,6 +50,10 @@ builtin_modules += ofono
+ builtin_sources += plugins/mcc.h plugins/ofono.c
+ endif
+ 
++if TELEPHONY
++builtin_modules += telephony
++builtin_sources += plugins/telephony.c
++endif
+ if DUNDEE
+ builtin_modules += dundee
+ builtin_sources += plugins/dundee.c
+diff --git a/configure.ac b/configure.ac
+index 740e599..38becc1 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -328,6 +328,10 @@ AC_ARG_ENABLE(ofono, AC_HELP_STRING([--disable-ofono],
+ 					[enable_ofono=${enableval}])
+ AM_CONDITIONAL(OFONO, test "${enable_ofono}" != "no")
+ 
++AC_ARG_ENABLE(telephony, AC_HELP_STRING([--disable-telephony],
++				[disable Telephony support]),
++					[enable_telephony=${enableval}])
++AM_CONDITIONAL(TELEPHONY, test "${enable_telephony}" != "no")
+ AC_ARG_ENABLE(dundee, AC_HELP_STRING([--disable-dundee],
+ 				[disable dundee support (Bluetooth DUN)]),
+ 					[enable_dundee=${enableval}])
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0006-connman-disable-cellular-network-from-auto-connect.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0006-connman-disable-cellular-network-from-auto-connect.patch
new file mode 100644
index 0000000..3fff2cc
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0006-connman-disable-cellular-network-from-auto-connect.patch
@@ -0,0 +1,30 @@
+From 006642a4e8d7979d985349c2e5e0f81e3bdbf928 Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Wed, 7 Jun 2017 17:17:51 +0800
+Subject: [PATCH 6/9] connman: disable cellular network from auto connect
+
+Disable cellular network from auto connect
+Test: test ok on 2635
+
+Change-Id: I3c740fafac4e063e07e91f6c7cac8be3d46f01aa
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00003518
+---
+ src/main.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/src/main.c b/src/main.c
+index e46fa7b..3c4ee62 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -48,7 +48,6 @@
+ static char *default_auto_connect[] = {
+ 	"wifi",
+ 	"ethernet",
+-	"cellular",
+ 	NULL
+ };
+ 
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0007-connman-set-ccmnix-interface-to-cellular-type.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0007-connman-set-ccmnix-interface-to-cellular-type.patch
new file mode 100644
index 0000000..d445ed9
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0007-connman-set-ccmnix-interface-to-cellular-type.patch
@@ -0,0 +1,83 @@
+From 1ed85c130edbb94a6cdd9e13f9be7fe56e02ed7a Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Wed, 7 Jun 2017 17:23:38 +0800
+Subject: [PATCH 7/9] connman: set ccmnix interface to cellular type
+
+Set ccmnix interface to cellular type
+Test: test ok on 2635
+
+Change-Id: I010670cedb232b06904704dd2fdfd9e721e79121
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00003518
+---
+ Makefile.plugins |  1 +
+ configure.ac     |  1 +
+ src/rtnl.c       | 14 ++++++++++----
+ 3 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/Makefile.plugins b/Makefile.plugins
+index 8b4182d..e1e4a19 100644
+--- a/Makefile.plugins
++++ b/Makefile.plugins
+@@ -54,6 +54,7 @@ if TELEPHONY
+ builtin_modules += telephony
+ builtin_sources += plugins/telephony.c
+ endif
++
+ if DUNDEE
+ builtin_modules += dundee
+ builtin_sources += plugins/dundee.c
+diff --git a/configure.ac b/configure.ac
+index 38becc1..c475b02 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -332,6 +332,7 @@ AC_ARG_ENABLE(telephony, AC_HELP_STRING([--disable-telephony],
+ 				[disable Telephony support]),
+ 					[enable_telephony=${enableval}])
+ AM_CONDITIONAL(TELEPHONY, test "${enable_telephony}" != "no")
++
+ AC_ARG_ENABLE(dundee, AC_HELP_STRING([--disable-dundee],
+ 				[disable dundee support (Bluetooth DUN)]),
+ 					[enable_dundee=${enableval}])
+diff --git a/src/rtnl.c b/src/rtnl.c
+index d1b851f..aad4a75 100644
+--- a/src/rtnl.c
++++ b/src/rtnl.c
+@@ -119,7 +119,7 @@ static bool wext_interface(char *ifname)
+ static void read_uevent(struct interface_data *interface)
+ {
+ 	char *filename, *name, line[128];
+-	bool found_devtype;
++	bool found_devtype = false;
+ 	FILE *f;
+ 
+ 	name = connman_inet_ifname(interface->index);
+@@ -127,7 +127,12 @@ static void read_uevent(struct interface_data *interface)
+ 	if (ether_blacklisted(name)) {
+ 		interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
+ 		interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
+-	} else {
++	}else if (strncmp(name, "ccmni", 5) == 0){
++		interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
++		interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
++		found_devtype = true;
++	}
++	else {
+ 		interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
+ 		interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
+ 	}
+@@ -144,8 +149,9 @@ static void read_uevent(struct interface_data *interface)
+ 		goto out;
+ 	}
+ 
+-	found_devtype = false;
+-	while (fgets(line, sizeof(line), f)) {
++	//found_devtype = false;
++	DBG("name[%s] line[%s] found_devtype[%d]", name, line, found_devtype);
++	while ((fgets(line, sizeof(line), f)) && (true != found_devtype )) {
+ 		char *pos;
+ 
+ 		pos = strchr(line, '\n');
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0008-connman-not-set-ip-for-ccmnix-interface.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0008-connman-not-set-ip-for-ccmnix-interface.patch
new file mode 100644
index 0000000..3894a66
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0008-connman-not-set-ip-for-ccmnix-interface.patch
@@ -0,0 +1,26 @@
+diff --git a/src/ipconfig.c b/src/ipconfig.c
+index bae988c..afec0cd 100644
+--- a/src/ipconfig.c
++++ b/src/ipconfig.c
+@@ -1303,6 +1303,7 @@ enum connman_ipconfig_method __connman_ipconfig_get_method(
+ 
+ int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
+ {
++	char *name = NULL;
+ 	switch (ipconfig->method) {
+ 	case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ 	case CONNMAN_IPCONFIG_METHOD_OFF:
+@@ -1311,6 +1312,13 @@ int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
+ 	case CONNMAN_IPCONFIG_METHOD_FIXED:
+ 	case CONNMAN_IPCONFIG_METHOD_DHCP:
+ 	case CONNMAN_IPCONFIG_METHOD_MANUAL:
++		name = connman_inet_ifname(ipconfig->index);
++		if ((name != NULL) && (strncmp(name, "ccmni", 5) == 0))
++		{
++			DBG("name[%s]", name);
++			g_free(name);
++			break;
++		}
+ 		if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
+ 			return connman_inet_set_address(ipconfig->index,
+ 							ipconfig->address);
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0009-connman-enable-log-for-debug.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0009-connman-enable-log-for-debug.patch
new file mode 100644
index 0000000..07165c3
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0009-connman-enable-log-for-debug.patch
@@ -0,0 +1,13 @@
+diff --git a/src/connman.service.in b/src/connman.service.in
+index dab48bc..33e1805 100644
+--- a/src/connman.service.in
++++ b/src/connman.service.in
+@@ -12,7 +12,7 @@ Conflicts=systemd-resolved.service
+ Type=dbus
+ BusName=net.connman
+ Restart=on-failure
+-ExecStart=@sbindir@/connmand -n
++ExecStart=@sbindir@/connmand -d -n --nobacktrace
+ StandardOutput=null
+ CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SYS_TIME CAP_SYS_MODULE
+ ProtectHome=true
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0010-connman-telephony-plugin-rename-telephony-plugin.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0010-connman-telephony-plugin-rename-telephony-plugin.patch
new file mode 100644
index 0000000..84c2650
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0010-connman-telephony-plugin-rename-telephony-plugin.patch
@@ -0,0 +1,39 @@
+From 7a281b52137a944805510888e0b74167473a990a Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Mon, 12 Jun 2017 15:19:13 +0800
+Subject: [PATCH 10/10] connman telephony plugin: rename telephony plugin
+
+rename telephony plugin
+Test: test ok on 2635
+
+Change-Id: I12c17491f8778c8bd92db2dd9b3934602f419f75
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00003518
+---
+ plugins/telephony.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index 2e49b34..ef9cf34 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -528,7 +528,7 @@ static void set_connected(struct modem_data *modem,
+ 
+ 
+     index = connman_inet_ifindex(context->ifname);//context->index;
+-    connman_inet_ifup(index);//ZY it will makred
++    //connman_inet_ifup(index);//ZY it will makred
+     DBG("ifname[%s] index[%d]", context->ifname, index);
+ 
+     service = connman_service_lookup_from_network(context->network);
+@@ -1280,6 +1280,6 @@ static void  telephony_exit(void)
+ 
+ 
+ 
+- CONNMAN_PLUGIN_DEFINE(ofono, "oFono telephony plugin", VERSION,
++ CONNMAN_PLUGIN_DEFINE(telephony, "oFono telephony plugin", VERSION,
+         CONNMAN_PLUGIN_PRIORITY_DEFAULT, telephony_init, telephony_exit)
+ 
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0011-connman-data-for-sdk-server.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0011-connman-data-for-sdk-server.patch
new file mode 100644
index 0000000..6f93b3a
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0011-connman-data-for-sdk-server.patch
@@ -0,0 +1,376 @@
+From 2239b3614b2c2dbf9f5b6a37dd961f30da67953b Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Mon, 26 Jun 2017 17:04:55 +0800
+Subject: [PATCH 11/11] connman: data for sdk server
+
+data for sdk server
+Test: test ok on 2635
+
+Change-Id: I6ebc89f8933e62e906b600feda10d61abec0bd6a
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00003518
+---
+ plugins/telephony.c | 198 ++++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 123 insertions(+), 75 deletions(-)
+
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index ef9cf34..a781b21 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -56,10 +56,9 @@
+ #define TELEPHONY_DATA_INTERFACE    "mtk.telephony.Data"
+ #define TELEPHONY_DATA_PATH     "/mtk/telephony/data"
+ 
+-#define SIGNAL_PDNSTATUSUNSOL       "PDNStatusUnsol"
++#define SIGNAL_INTERNET_STATUS_CHANGED       "InternetStatusChanged"
+ 
+-#define METHODC_SETUPDATACALL   "Setupdatacall"
+-#define METHODC_DEACTIVEDATACALL    "Deactivedatacall"
++#define METHODC_ENABLE_DATA   "enableData"
+ 
+ #define TIMEOUT 40000
+ #define INTERNETPDNINDEX 1000
+@@ -132,17 +131,34 @@ struct modem_data {
+ 
+ struct DataCallResponse
+ {
+-    int reserve_word;
+-    int active;
+-    int status;
+-    int cid;
+-    char* type;
+-    char* ifname;
+-    char* addresses;
+-    char* dnses;
+-    char* gateway;
+-    char* pcscf;
+-    int mtu;
++    int             netId;     /* net id */
++    int             active;     /* A SDK_PdnState*/
++    int             status;     /* A RIL_DataCallFailCause in file ril.h, 0 which is PDP_FAIL_NONE if no error */
++    int             cid;        /* Context ID, uniquely identifies this call */
++    char *          apnType;    /* APN_TYPE_* */
++    char *          type;       /* One of the PDP_type values in TS 27.007 section 10.1.1.
++                                   For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is
++                                   PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported
++                                   such as "IP" or "IPV6" */
++    char *          ifname;     /* The network interface name */
++    char *          addresses;  /* A space-delimited list of addresses with optional "/" prefix length,
++                                   e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64".
++                                   May not be empty, typically 1 IPv4 or 1 IPv6 or
++                                   one of each. If the prefix length is absent the addresses
++                                   are assumed to be point to point with IPv4 having a prefix
++                                   length of 32 and IPv6 128. */
++    char *          dnses;      /* A space-delimited list of DNS server addresses,
++                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
++                                   May be empty. */
++    char *          gateways;   /* A space-delimited list of default gateway addresses,
++                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
++                                   May be empty in which case the addresses represent point
++                                   to point connections. */
++    char *          pcscf;    /* the Proxy Call State Control Function address
++                                 via PCO(Protocol Configuration Option) for IMS client. */
++    int             mtu;        /* MTU received from network
++                                   Value <= 0 means network has either not sent a value or
++                                   sent an invalid value */
+ };
+ 
+ #if 1
+@@ -346,10 +362,10 @@ static int extract_dbus_info( struct DataCallResponse *dataCallResponse, struct
+                 extract_dns(dataCallResponse->dnses, context);
+             }
+ 
+-            if (dataCallResponse->gateway)
++            if (dataCallResponse->gateways)
+             {
+-                DBG("dataCallResponse->gateway[%s]", dataCallResponse->gateway);
+-                extract_gatway(dataCallResponse->gateway, context);
++                DBG("dataCallResponse->gateway[%s]", dataCallResponse->gateways);
++                extract_gatway(dataCallResponse->gateways, context);
+             }
+ 
+             context->mtu = dataCallResponse->mtu;
+@@ -603,14 +619,74 @@ static void remove_network(struct modem_data *modem,
+ }
+ 
+ 
++static void get_dbus_info(DBusMessage *message, struct DataCallResponse *dataCallResponseenum, enum DBusType dbusType)
++{
++   DBusMessageIter iter;
++   DBusMessageIter subiter;
++
++   int message_type;
++   if ((message == NULL) && (dataCallResponseenum == NULL))
++   {
++       DBG("NULL");
++       return;
++   }
++
++  dbus_message_iter_init (message, &iter);
++
++  dbus_message_iter_recurse (&iter, &subiter);
++
++  int type = dbus_message_iter_get_arg_type (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->netId);
++
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->active);
++
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->status);
++
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->cid);
++
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->apnType);
+ 
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->type);
++
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->ifname);
++
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->addresses);
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->dnses);
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->gateways);
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->pcscf);
++  dbus_message_iter_next (&subiter);
++
++  dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->mtu);
++}
+ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+ {
+     DBusMessage *reply;
+-    DBusError error;
+     char *content;
+     dbus_bool_t     ret;
+     struct DataCallResponse dataCallResponse = {};
++    DBusMessageIter iter, subStructIter;
++    int arrayCount;
+ 
+ 
+     modem->call_setup_data_call = NULL;
+@@ -618,22 +694,29 @@ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+ 
+     DBG("");
+ 
+-    dbus_error_init(&error);
+ 
+     reply = dbus_pending_call_steal_reply(call);
+ 
++    get_dbus_info(reply, &dataCallResponse, DMethodCallSetupdatacall);
+ 
++    #if 0
+     dbus_error_init( &error );
+ 
++    dbus_message_iter_recurse(&iter, &subStructIter);
++
++
+     ret = dbus_message_get_args( reply, &error,
++            DBUS_TYPE_INT32, &dataCallResponse.netId,
+             DBUS_TYPE_INT32, &dataCallResponse.active,
+             DBUS_TYPE_INT32, &dataCallResponse.status,
+             DBUS_TYPE_INT32, &dataCallResponse.cid,
++            DBUS_TYPE_STRING, &dataCallResponse.apnType,
+             DBUS_TYPE_STRING, &dataCallResponse.type,
+             DBUS_TYPE_STRING, &dataCallResponse.ifname,
+             DBUS_TYPE_STRING, &dataCallResponse.addresses,
+             DBUS_TYPE_STRING, &dataCallResponse.dnses,
+-            DBUS_TYPE_STRING, &dataCallResponse.gateway,
++            DBUS_TYPE_STRING, &dataCallResponse.gateways,
++            DBUS_TYPE_STRING, &dataCallResponse.pcscf,
+             DBUS_TYPE_INT32, &dataCallResponse.mtu,
+             DBUS_TYPE_INVALID );
+ 
+@@ -644,10 +727,11 @@ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+         dbus_pending_call_unref(call);
+         return;
+     }
++    #endif
+ 
+     DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
+-    DBG("type[%d] ifname[%s] addresses[%s]", dataCallResponse.type, dataCallResponse.ifname, dataCallResponse.addresses);
+-    DBG("dnses[%s] gateway[%s] mtu[%d]", dataCallResponse.dnses, dataCallResponse.gateway , dataCallResponse.mtu);
++    DBG("type[%s] ifname[%s] addresses[%s]", dataCallResponse.type, dataCallResponse.ifname, dataCallResponse.addresses);
++    DBG("dnses[%s] gateway[%s] mtu[%d]", dataCallResponse.dnses, dataCallResponse.gateways , dataCallResponse.mtu);
+ 
+     extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
+ 
+@@ -670,7 +754,6 @@ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+ static void deactive_datacall_reply(DBusPendingCall *call, void *user_data)
+ {
+     DBusMessage *reply;
+-    DBusError error;
+     char *content;
+     dbus_bool_t     ret;
+     struct DataCallResponse dataCallResponse = {};
+@@ -679,26 +762,11 @@ static void deactive_datacall_reply(DBusPendingCall *call, void *user_data)
+ 
+     modem->call_deactive_data_call = NULL;
+ 
+-    dbus_error_init(&error);
+ 
+     reply = dbus_pending_call_steal_reply(call);
+ 
++    get_dbus_info(reply, &dataCallResponse, DMethodDeactivedatacall);
+ 
+-    dbus_error_init( &error );
+-
+-    ret = dbus_message_get_args(reply, &error,
+-                   DBUS_TYPE_INT32, &dataCallResponse.active,
+-                   DBUS_TYPE_INT32, &dataCallResponse.status,
+-                   DBUS_TYPE_INT32, &dataCallResponse.cid,
+-                   DBUS_TYPE_INVALID);
+-
+-    if (FALSE == ret)
+-    {
+-        DBG("%s:%s", error.name, error.message);
+-        dbus_message_unref(reply);
+-        dbus_pending_call_unref(call);
+-        return;
+-    }
+ 
+     DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
+ 
+@@ -717,19 +785,16 @@ static void deactive_datacall_reply(DBusPendingCall *call, void *user_data)
+ 
+ static void send_method_call(DBusConnection * connection, enum DBusType dbusType)
+ {
+-    DBusError err;
+     DBusMessage * msg, *reply;
+     DBusMessageIter    arg;
+     DBusPendingCall * pending;
+     dbus_bool_t * stat;
+     dbus_uint32_t * level;
+-    dbus_int32_t id = 1;
+-    DBusError error;
+-    char *pdn = "Internet";
++    dbus_bool_t status = false;
++    char *pdn = "default";
+     struct DataCallResponse dataCallResponse = {};
+     int ret;
+ 
+-    dbus_error_init(&err);
+ 
+ 
+     DBG("methodType[%d]", dbusType);
+@@ -746,15 +811,15 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+             }
+ 
+             DBG("methodType1");
+-            msg = dbus_message_new_method_call (TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_SETUPDATACALL);
++            msg = dbus_message_new_method_call (TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_ENABLE_DATA);
+             if(msg == NULL){
+                 DBG("MessageNULL");
+                return;
+             }
+             DBG("methodType2");
+-
++            status = true;
+             dbus_message_iter_init_append(msg, &arg);
+-            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_INT32, &id)){
++            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_BOOLEAN, &status)){
+                DBG("dbus_message_iter_append_basic Out of Memory!");
+            }
+ 
+@@ -852,15 +917,17 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+             }
+ 
+             DBG("DMethodDeactivedatacall");
++            status = false;
+ 
+-            msg = dbus_message_new_method_call(TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_DEACTIVEDATACALL);
++            msg = dbus_message_new_method_call(TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_ENABLE_DATA);
+             if(msg == NULL){
+             DBG("MessageNULL");
+                return;
+            }
+ 
++           status = false;
+             dbus_message_iter_init_append(msg, &arg);
+-            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_INT32, &id)){
++            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_INT32, &status)){
+                DBG("dbus_message_iter_append_basic Out of Memory!");
+            }
+ 
+@@ -1154,7 +1221,6 @@ static void telephony_disconnect(DBusConnection *conn, void *user_data)
+ static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
+                 void *user_data)
+ {
+-     DBusError error;
+     DBusMessageIter iter;
+     int ret;
+     struct DataCallResponse dataCallResponse = {};
+@@ -1162,31 +1228,8 @@ static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
+ 
+     DBG("");
+ 
+-    dbus_error_init(&error);
+-    if (!dbus_message_iter_init(message, &iter))
+-    {
+-        DBG("dbus_message_iter_init fail");
+-        return TRUE;
+-    }
+ 
+-    ret = dbus_message_get_args( message, &error,
+-                   DBUS_TYPE_INT32, &dataCallResponse.active,
+-                   DBUS_TYPE_INT32, &dataCallResponse.status,
+-                   DBUS_TYPE_INT32, &dataCallResponse.cid,
+-                   DBUS_TYPE_STRING, &dataCallResponse.type,
+-                   DBUS_TYPE_STRING, &dataCallResponse.ifname,
+-                   DBUS_TYPE_STRING, &dataCallResponse.addresses,
+-                   DBUS_TYPE_STRING, &dataCallResponse.dnses,
+-                   DBUS_TYPE_STRING, &dataCallResponse.gateway,
+-                   DBUS_TYPE_INT32, &dataCallResponse.mtu,
+-                   DBUS_TYPE_INVALID );
+-
+-        if (FALSE == ret)
+-        {
+-            DBG("error.nam[%s]: error.message[%s]", error.name, error.message);
+-            dbus_message_unref(message);
+-            return FALSE;
+-        }
++    get_dbus_info(message, &dataCallResponse, DMethodDeactivedatacall);
+ 
+         DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
+ 
+@@ -1200,6 +1243,11 @@ static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
+             set_disconnected(context);
+         }
+ 
++    if ((context->pdnStatus == ConnmanPDNStatusDisconnected) && (context->active == CONNECTED))
++    {
++        DBG("set_connected");
++        set_connected(modem, context);
++    }
+         return TRUE;
+ }
+ 
+@@ -1223,7 +1271,7 @@ static int telephony_init(void)
+ 
+     pdn_status_watch = g_dbus_add_signal_watch(connection, TELEPHONY_SERVICE, NULL,
+                         TELEPHONY_DATA_INTERFACE,
+-                        SIGNAL_PDNSTATUSUNSOL,
++                        SIGNAL_INTERNET_STATUS_CHANGED,
+                         pdn_status_unsol,
+                         NULL, NULL);
+ 
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0011-connmand-sync-code-fixed-assert-when-get-method-call.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0011-connmand-sync-code-fixed-assert-when-get-method-call.patch
new file mode 100644
index 0000000..5d6127a
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0011-connmand-sync-code-fixed-assert-when-get-method-call.patch
@@ -0,0 +1,741 @@
+From 5dbf2151b0f9afe9a399916207690290418b415a Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Wed, 19 Jul 2017 17:06:42 +0800
+Subject: [PATCH 11/11] connmand: sync code & fixed assert when get method call
+ response timeout
+
+sync code & fixed assert when get method call response timeout
+Test: test ok on 2635
+
+Change-Id: Ic3121cd7f8226791a572145134b9e90af4242624
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00005977
+---
+ plugins/telephony.c | 436 +++++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 296 insertions(+), 140 deletions(-)
+
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index ef9cf34..a1a3d7c 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -56,10 +56,12 @@
+ #define TELEPHONY_DATA_INTERFACE    "mtk.telephony.Data"
+ #define TELEPHONY_DATA_PATH     "/mtk/telephony/data"
+ 
+-#define SIGNAL_PDNSTATUSUNSOL       "PDNStatusUnsol"
++#define SIGNAL_INTERNET_STATUS_CHANGED       "InternetStatusChanged"
++
++#define METHODC_ENABLE_DATA   "enableData"
++
++
+ 
+-#define METHODC_SETUPDATACALL   "Setupdatacall"
+-#define METHODC_DEACTIVEDATACALL    "Deactivedatacall"
+ 
+ #define TIMEOUT 40000
+ #define INTERNETPDNINDEX 1000
+@@ -97,6 +99,18 @@ enum DBusType{
+     DMethodMax
+ };
+ 
++struct ipv4_info{
++    char *address;
++    char *netmask;
++    char *gateway;
++};
++
++struct ipv6_info{
++    char *address;
++    int prefix;
++    char *gateway;
++};
++
+ 
+ struct network_context {
+     char *path;
+@@ -110,11 +124,13 @@ struct network_context {
+     struct connman_network *network;
+ 
+     enum connman_ipconfig_method ipv4_method;
++    struct ipv4_info ipv4_info;
+     struct connman_ipaddress *ipv4_address;
+     char *ipv4_nameservers;
+ 
+     enum connman_ipconfig_method ipv6_method;
+     struct connman_ipaddress *ipv6_address;
++    struct ipv6_info ipv6_info;
+     char *ipv6_nameservers;
+ };
+ 
+@@ -132,19 +148,38 @@ struct modem_data {
+ 
+ struct DataCallResponse
+ {
+-    int reserve_word;
+-    int active;
+-    int status;
+-    int cid;
+-    char* type;
+-    char* ifname;
+-    char* addresses;
+-    char* dnses;
+-    char* gateway;
+-    char* pcscf;
+-    int mtu;
++    int             netId;     /* net id */
++    int             active;     /* A SDK_PdnState*/
++    int             status;     /* A RIL_DataCallFailCause in file ril.h, 0 which is PDP_FAIL_NONE if no error */
++    int             cid;        /* Context ID, uniquely identifies this call */
++    char *          apnType;    /* APN_TYPE_* */
++    char *          type;       /* One of the PDP_type values in TS 27.007 section 10.1.1.
++                                   For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is
++                                   PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported
++                                   such as "IP" or "IPV6" */
++    char *          ifname;     /* The network interface name */
++    char *          addresses;  /* A space-delimited list of addresses with optional "/" prefix length,
++                                   e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64".
++                                   May not be empty, typically 1 IPv4 or 1 IPv6 or
++                                   one of each. If the prefix length is absent the addresses
++                                   are assumed to be point to point with IPv4 having a prefix
++                                   length of 32 and IPv6 128. */
++    char *          dnses;      /* A space-delimited list of DNS server addresses,
++                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
++                                   May be empty. */
++    char *          gateways;   /* A space-delimited list of default gateway addresses,
++                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
++                                   May be empty in which case the addresses represent point
++                                   to point connections. */
++    char *          pcscf;    /* the Proxy Call State Control Function address
++                                 via PCO(Protocol Configuration Option) for IMS client. */
++    int             mtu;        /* MTU received from network
++                                   Value <= 0 means network has either not sent a value or
++                                   sent an invalid value */
+ };
+ 
++
++
+ #if 1
+ 
+ static char *get_ident(const char *path)
+@@ -175,7 +210,7 @@ static int extract_gatway(char *gatways, struct network_context *context)
+     }
+ 
+     p = strtok(gatways, " ");
+-    DBG("p[%s].", p);
++    DBG("p[%s]", p);
+ 
+     while (p)
+     {
+@@ -189,7 +224,7 @@ static int extract_gatway(char *gatways, struct network_context *context)
+             snprintf(ipv6, 31, "%s", p);
+         }
+         else{
+-            DBG("Invalid dns[%s].", p);
++            DBG("Invalid gatway[%s].", p);
+         }
+         p = strtok(NULL, " ");
+ 
+@@ -199,37 +234,99 @@ static int extract_gatway(char *gatways, struct network_context *context)
+ 
+     if (strlen(ipv4) != 0)
+     {
+-        DBG("ipv4[%s].", ipv4);
++        DBG("ipv4[%s]", ipv4);
+ 
+-        if (context->ipv4_address)
++        if (context->ipv4_info.gateway)
+         {
+-            connman_ipaddress_free(context->ipv4_address);
+-            context->ipv4_address = NULL;
++             g_free(context->ipv4_info.gateway);
++             context->ipv4_info.gateway = NULL;
+         }
+ 
+-        context->ipv4_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
+-
+-        connman_ipaddress_set_ipv4(context->ipv4_address, NULL, NULL, ipv4);
++        context->ipv4_info.gateway = g_strdup(ipv4);
++        DBG("context->ipv4_info.gateway[%s]", context->ipv4_info.gateway);
+     }
+ 
+     if (strlen(ipv6) != 0)
+     {
+         DBG("ipv6[%s].", ipv6);
+ 
+-        if (context->ipv6_address)
++        if (context->ipv6_info.gateway)
+         {
+-            connman_ipaddress_free(context->ipv6_address);
+-            context->ipv6_address = NULL;
++             g_free(context->ipv6_info.gateway);
++             context->ipv6_info.gateway = NULL;
+         }
+ 
+-        context->ipv6_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
+-
+-        connman_ipaddress_set_ipv6(context->ipv6_address, NULL, 0, ipv6);
++        context->ipv6_info.gateway = g_strdup(ipv6);
++        DBG("context->ipv6_info.gateway[%s]", context->ipv6_info.gateway);
+     }
+ 
+ }
+ 
++static int extract_addresses(char *addresses, struct network_context *context)
++{
++    char *p = NULL;
++    char ipv4[20] = {};
++    char ipv6[40] = {};
+ 
++    //example: addresses=10.164.2.8/16 FE80:0000:0000:0000:2Cc3:323c:F968:93d8/64
++    if (!addresses || !context)
++    {
++        DBG("Invalid arguments.");
++        return -1;
++    }
++
++    p = strtok(addresses, " ");
++    DBG("p[%s]", p);
++
++    while (p)
++    {
++        //ipv4 address
++        if (strchr(p, '.'))
++        {
++            snprintf(ipv4, 19, "%s", p);
++        }
++        else if (strchr(p, ':'))  //ipv6 address
++        {
++            snprintf(ipv6, 39, "%s", p);
++        }
++        else{
++            DBG("Invalid gatway[%s].", p);
++        }
++        p = strtok(NULL, " ");
++
++    }
++
++    DBG("ipv4[%s] ipv6[%s]", ipv4, ipv6);
++
++    if (strlen(ipv4) != 0)
++    {
++        DBG("ipv4[%s]", ipv4);
++
++        if (context->ipv4_info.address)
++        {
++             g_free(context->ipv4_info.address);
++             context->ipv4_info.address = NULL;
++        }
++
++        context->ipv4_info.address = g_strdup(ipv4);
++        DBG("context->ipv4_info.address[%s]", context->ipv4_info.address);
++    }
++
++    if (strlen(ipv6) != 0)
++    {
++        DBG("ipv6[%s].", ipv6);
++
++        if (context->ipv6_info.address)
++        {
++             g_free(context->ipv6_info.address);
++             context->ipv6_info.address = NULL;
++        }
++
++        context->ipv6_info.gateway = g_strdup(ipv6);
++        DBG("context->ipv6_info.address[%s]", context->ipv6_info.address);
++    }
++
++}
+ 
+ static int extract_dns(char *dnses, struct network_context *context)
+ {
+@@ -283,9 +380,9 @@ static int extract_dns(char *dnses, struct network_context *context)
+ 
+         }
+ 
+-        lengh = strlen(ipv6) + 1;
+-        context->ipv6_nameservers = g_strdup(ipv6);
+-        DBG("context->ipv4_nameservers[%s].", context->ipv6_nameservers);
++        lengh = strlen(ipv4) + 1;
++        context->ipv4_nameservers = g_strdup(ipv4);
++        DBG("context->ipv4_nameservers[%s]", context->ipv4_nameservers);
+     }
+ 
+     if (strlen(ipv6) != 0)
+@@ -304,7 +401,7 @@ static int extract_dns(char *dnses, struct network_context *context)
+ 
+         lengh = strlen(ipv6) + 1;
+         context->ipv6_nameservers = g_strdup(ipv6);
+-        DBG("context->ipv4_nameservers[%s].", context->ipv6_nameservers);
++        DBG("context->ipv6_nameservers[%s].", context->ipv6_nameservers);
+ 
+     }
+ 
+@@ -346,10 +443,16 @@ static int extract_dbus_info( struct DataCallResponse *dataCallResponse, struct
+                 extract_dns(dataCallResponse->dnses, context);
+             }
+ 
+-            if (dataCallResponse->gateway)
++            if (dataCallResponse->gateways)
+             {
+-                DBG("dataCallResponse->gateway[%s]", dataCallResponse->gateway);
+-                extract_gatway(dataCallResponse->gateway, context);
++                DBG("dataCallResponse->gateway[%s]", dataCallResponse->gateways);
++                extract_gatway(dataCallResponse->gateways, context);
++            }
++
++            if (dataCallResponse->addresses)
++            {
++                DBG("dataCallResponse->addresses[%s]", dataCallResponse->addresses);
++                extract_addresses(dataCallResponse->addresses, context);
+             }
+ 
+             context->mtu = dataCallResponse->mtu;
+@@ -489,6 +592,7 @@ static void add_network(struct modem_data *modem,
+ 
+     connman_network_set_name(context->network, "Cellular");
+ 
++
+     group = get_ident(context->path);
+     connman_network_set_group(context->network, group);
+ 
+@@ -509,10 +613,9 @@ static void add_network(struct modem_data *modem,
+     if (service)
+     {
+         DBG("connman_network_set_index to -1");
+-        connman_network_set_index(context->network, -1);
+-        connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+-        connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+-
++        //connman_network_set_index(context->network, -1);
++        //connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_OFF);
++        //connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_OFF);
+     }
+ }
+ 
+@@ -538,23 +641,32 @@ static void set_connected(struct modem_data *modem,
+         return;
+     }
+ 
+-    connman_service_create_ip4config(service, index);
+-     connman_network_set_index(context->network, index);
+-    connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+ 
+ 
+ 
+ 
+-    //connman_ipaddress_set_ipv4(context->ipv4_address, "172.168.0.100", "255.255.255.0", "172.168.0.100");
++    DBG("context->ipv4_info.address[%s] context->ipv4_info.gateway[%s]", context->ipv4_info.address, context->ipv4_info.gateway);
++    if (context->ipv4_address)
++    {
++        connman_ipaddress_free(context->ipv4_address);
++        context->ipv4_address = NULL;
++    }
++    context->ipv4_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
++
++    connman_ipaddress_set_ipv4(context->ipv4_address, context->ipv4_info.address, "255.0.0.0", context->ipv4_info.gateway);
+ 
+ 
+     connman_network_set_ipaddress(context->network,context->ipv4_address);
+     connman_network_set_nameservers(context->network, context->ipv4_nameservers);
+ 
++    connman_service_create_ip4config(service, index);
++    connman_network_set_index(context->network, index);
++    connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+ 
+ 
+     connman_network_set_connected(context->network, true);
+     context->pdnStatus = ConnmanPDNStatusConnected;
++    DBG("");
+ 
+ }
+ 
+@@ -579,7 +691,8 @@ static void set_disconnected(struct network_context *context)
+             context->ipv6_method =
+                     CONNMAN_IPCONFIG_METHOD_UNKNOWN;
+     }
+-
++    connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_DHCP);
++    connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_AUTO);
+     context->pdnStatus = ConnmanPDNStatusDisconnected;
+ }
+ 
+@@ -603,63 +716,112 @@ static void remove_network(struct modem_data *modem,
+ }
+ 
+ 
++static void get_dbus_info(DBusMessage *message, struct DataCallResponse *dataCallResponseenum, enum DBusType dbusType)
++{
++    DBusMessageIter iter;
++    DBusMessageIter subiter;
++
++    int message_type;
++    if ((message == NULL) && (dataCallResponseenum == NULL))
++    {
++        DBG("NULL");
++        return;
++    }
++
++    DBG("");
++
++    dbus_message_iter_init (message, &iter);
++
++    dbus_message_iter_recurse (&iter, &subiter);
++
++    int type = dbus_message_iter_get_arg_type (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->netId);
++
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->active);
++
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->status);
++
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->cid);
++
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->apnType);
++
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->type);
++
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->ifname);
++
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->addresses);
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->dnses);
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->gateways);
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->pcscf);
++    dbus_message_iter_next (&subiter);
++
++    dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->mtu);
++    DBG("end");
++}
++
+ 
+ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+ {
+     DBusMessage *reply;
+-    DBusError error;
+     char *content;
+     dbus_bool_t     ret;
+     struct DataCallResponse dataCallResponse = {};
+-
+-
+-    modem->call_setup_data_call = NULL;
+-
++    DBusMessageIter iter, subStructIter;
++    int arrayCount;
++    DBusError error;
+ 
+     DBG("");
+ 
++    modem->call_setup_data_call = NULL;
+     dbus_error_init(&error);
+ 
+     reply = dbus_pending_call_steal_reply(call);
+ 
+-
+-    dbus_error_init( &error );
+-
+-    ret = dbus_message_get_args( reply, &error,
+-            DBUS_TYPE_INT32, &dataCallResponse.active,
+-            DBUS_TYPE_INT32, &dataCallResponse.status,
+-            DBUS_TYPE_INT32, &dataCallResponse.cid,
+-            DBUS_TYPE_STRING, &dataCallResponse.type,
+-            DBUS_TYPE_STRING, &dataCallResponse.ifname,
+-            DBUS_TYPE_STRING, &dataCallResponse.addresses,
+-            DBUS_TYPE_STRING, &dataCallResponse.dnses,
+-            DBUS_TYPE_STRING, &dataCallResponse.gateway,
+-            DBUS_TYPE_INT32, &dataCallResponse.mtu,
+-            DBUS_TYPE_INVALID );
+-
+-    if (FALSE == ret)
+-    {
+-        DBG("%s:%s", error.name, error.message);
++    if (dbus_set_error_from_message(&error, reply)) {
++		DBG("Failed to get response: %s %s",
++				error.name, error.message);
+         dbus_message_unref(reply);
+         dbus_pending_call_unref(call);
+-        return;
+-    }
++        dbus_error_free(&error);
++		return;
++	}
++
++    get_dbus_info(reply, &dataCallResponse, DMethodCallSetupdatacall);
+ 
+     DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
+-    DBG("type[%d] ifname[%s] addresses[%s]", dataCallResponse.type, dataCallResponse.ifname, dataCallResponse.addresses);
+-    DBG("dnses[%s] gateway[%s] mtu[%d]", dataCallResponse.dnses, dataCallResponse.gateway , dataCallResponse.mtu);
++    DBG("type[%s] ifname[%s] addresses[%s]", dataCallResponse.type, dataCallResponse.ifname, dataCallResponse.addresses);
++    DBG("dnses[%s] gateway[%s] mtu[%d]", dataCallResponse.dnses, dataCallResponse.gateways , dataCallResponse.mtu);
+ 
+     extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
+ 
+-    #if 1
+ 
+     if (context->active == CONNECTED)
+     {
+         set_connected(modem, context);
+-    }else{
++    }else if (context->active == DISCONNECTED){
+         set_disconnected(context);
+     }
+-    #endif
+ 
+ 
+     dbus_message_unref(reply);
+@@ -670,35 +832,30 @@ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+ static void deactive_datacall_reply(DBusPendingCall *call, void *user_data)
+ {
+     DBusMessage *reply;
+-    DBusError error;
+     char *content;
+     dbus_bool_t     ret;
+     struct DataCallResponse dataCallResponse = {};
++    DBusError error;
+ 
+-    DBG("");
+ 
+-    modem->call_deactive_data_call = NULL;
++    DBG("");
+ 
+     dbus_error_init(&error);
+ 
+-    reply = dbus_pending_call_steal_reply(call);
+-
+-
+-    dbus_error_init( &error );
++    modem->call_deactive_data_call = NULL;
+ 
+-    ret = dbus_message_get_args(reply, &error,
+-                   DBUS_TYPE_INT32, &dataCallResponse.active,
+-                   DBUS_TYPE_INT32, &dataCallResponse.status,
+-                   DBUS_TYPE_INT32, &dataCallResponse.cid,
+-                   DBUS_TYPE_INVALID);
++    reply = dbus_pending_call_steal_reply(call);
+ 
+-    if (FALSE == ret)
+-    {
+-        DBG("%s:%s", error.name, error.message);
++    if (dbus_set_error_from_message(&error, reply)) {
++		DBG("Failed to get response: %s %s",
++				error.name, error.message);
+         dbus_message_unref(reply);
+         dbus_pending_call_unref(call);
+-        return;
+-    }
++        dbus_error_free(&error);
++		return;
++	}
++
++    get_dbus_info(reply, &dataCallResponse, DMethodDeactivedatacall);
+ 
+     DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
+ 
+@@ -717,21 +874,16 @@ static void deactive_datacall_reply(DBusPendingCall *call, void *user_data)
+ 
+ static void send_method_call(DBusConnection * connection, enum DBusType dbusType)
+ {
+-    DBusError err;
+     DBusMessage * msg, *reply;
+     DBusMessageIter    arg;
+     DBusPendingCall * pending;
+     dbus_bool_t * stat;
+     dbus_uint32_t * level;
+-    dbus_int32_t id = 1;
+-    DBusError error;
+-    char *pdn = "Internet";
++    dbus_bool_t status = false;
++    char *pdn = "default";
+     struct DataCallResponse dataCallResponse = {};
+     int ret;
+ 
+-    dbus_error_init(&err);
+-
+-
+     DBG("methodType[%d]", dbusType);
+ 
+     switch(dbusType){
+@@ -746,15 +898,15 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+             }
+ 
+             DBG("methodType1");
+-            msg = dbus_message_new_method_call (TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_SETUPDATACALL);
++            msg = dbus_message_new_method_call (TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_ENABLE_DATA);
+             if(msg == NULL){
+                 DBG("MessageNULL");
+                return;
+             }
+             DBG("methodType2");
+-
++            status = true;
+             dbus_message_iter_init_append(msg, &arg);
+-            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_INT32, &id)){
++            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_BOOLEAN, &status)){
+                DBG("dbus_message_iter_append_basic Out of Memory!");
+            }
+ 
+@@ -781,6 +933,18 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+ 
+             #if 1
+ 
++            #if 0 //error
++            if (!dbus_pending_call_get_completed(modem->call_setup_data_call))
++            {
++                DBG("time out");
++                dbus_pending_call_cancel(modem->call_setup_data_call);
++                dbus_pending_call_unref(modem->call_setup_data_call);
++                modem->call_setup_data_call = NULL;
++
++            }
++            #endif
++
++
+             dbus_pending_call_set_notify(modem->call_setup_data_call,
+                     setup_datacall_reply, NULL, NULL);
+             #else
+@@ -852,15 +1016,18 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+             }
+ 
+             DBG("DMethodDeactivedatacall");
++            status = false;
+ 
+-            msg = dbus_message_new_method_call(TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_DEACTIVEDATACALL);
++            msg = dbus_message_new_method_call(TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_ENABLE_DATA);
+             if(msg == NULL){
+             DBG("MessageNULL");
+                return;
+            }
+ 
++           status = false;
++
+             dbus_message_iter_init_append(msg, &arg);
+-            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_INT32, &id)){
++            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_BOOLEAN, &status)){
+                DBG("dbus_message_iter_append_basic Out of Memory!");
+            }
+ 
+@@ -1025,7 +1192,12 @@ static int network_connect(struct connman_network *network)
+     if (!connection)
+         return -EIO;
+ 
+-    send_method_call(connection, DMethodCallSetupdatacall);
++    DBG("context->pdnStatus zy[%d]", context->pdnStatus);
++    if (context->pdnStatus != ConnmanPDNStatusConnected)
++    {
++        DBG("send_method_call");
++        send_method_call(connection, DMethodCallSetupdatacall);
++    }
+ 
+     return 0;
+ }
+@@ -1038,7 +1210,9 @@ static int network_disconnect(struct connman_network *network)
+     if (!connection)
+         return -EIO;
+ 
+-    send_method_call(connection, DMethodDeactivedatacall);
++    DBG("context->pdnStatus[%d]", context->pdnStatus);
++    if (context->pdnStatus == ConnmanPDNStatusConnected)
++        send_method_call(connection, DMethodDeactivedatacall);
+ 
+     return 0;
+ }
+@@ -1154,7 +1328,6 @@ static void telephony_disconnect(DBusConnection *conn, void *user_data)
+ static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
+                 void *user_data)
+ {
+-     DBusError error;
+     DBusMessageIter iter;
+     int ret;
+     struct DataCallResponse dataCallResponse = {};
+@@ -1162,45 +1335,28 @@ static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
+ 
+     DBG("");
+ 
+-    dbus_error_init(&error);
+-    if (!dbus_message_iter_init(message, &iter))
+-    {
+-        DBG("dbus_message_iter_init fail");
+-        return TRUE;
+-    }
+ 
+-    ret = dbus_message_get_args( message, &error,
+-                   DBUS_TYPE_INT32, &dataCallResponse.active,
+-                   DBUS_TYPE_INT32, &dataCallResponse.status,
+-                   DBUS_TYPE_INT32, &dataCallResponse.cid,
+-                   DBUS_TYPE_STRING, &dataCallResponse.type,
+-                   DBUS_TYPE_STRING, &dataCallResponse.ifname,
+-                   DBUS_TYPE_STRING, &dataCallResponse.addresses,
+-                   DBUS_TYPE_STRING, &dataCallResponse.dnses,
+-                   DBUS_TYPE_STRING, &dataCallResponse.gateway,
+-                   DBUS_TYPE_INT32, &dataCallResponse.mtu,
+-                   DBUS_TYPE_INVALID );
++    get_dbus_info(message, &dataCallResponse, DMethodDeactivedatacall);
+ 
+-        if (FALSE == ret)
+-        {
+-            DBG("error.nam[%s]: error.message[%s]", error.name, error.message);
+-            dbus_message_unref(message);
+-            return FALSE;
+-        }
++    DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
+ 
+-        DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
++    extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
+ 
+-        extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
++    DBG("context->pdnStatus[%d] active[%d] status[%d] cid[%d]", context->pdnStatus, dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
+ 
+-        DBG("context->pdnStatus[%d] active[%d] status[%d] cid[%d]", context->pdnStatus, dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
++    if ((context->pdnStatus == ConnmanPDNStatusConnected) && (context->active == DISCONNECTED))
++    {
++        DBG("set_disconnected");
++        set_disconnected(context);
++    }
+ 
+-        if ((context->pdnStatus == ConnmanPDNStatusConnected) && (context->active == DISCONNECTED))
+-        {
+-            DBG("set_disconnected");
+-            set_disconnected(context);
+-        }
++    if ((context->pdnStatus == ConnmanPDNStatusDisconnected) && (context->active == CONNECTED))
++    {
++        DBG("set_connected");
++        set_connected(modem, context);
++    }
+ 
+-        return TRUE;
++    return TRUE;
+ }
+ 
+ static guint watch;
+@@ -1223,7 +1379,7 @@ static int telephony_init(void)
+ 
+     pdn_status_watch = g_dbus_add_signal_watch(connection, TELEPHONY_SERVICE, NULL,
+                         TELEPHONY_DATA_INTERFACE,
+-                        SIGNAL_PDNSTATUSUNSOL,
++                        SIGNAL_INTERNET_STATUS_CHANGED,
+                         pdn_status_unsol,
+                         NULL, NULL);
+ 
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0012-connman-fix-setup-datacall-deactivate-datacall-issue.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0012-connman-fix-setup-datacall-deactivate-datacall-issue.patch
new file mode 100644
index 0000000..496494d
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0012-connman-fix-setup-datacall-deactivate-datacall-issue.patch
@@ -0,0 +1,375 @@
+From 06243ce76462375498c976de2e40e4aad6ebedb1 Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Sat, 1 Jul 2017 17:13:19 +0800
+Subject: [PATCH 12/12] connman: fix setup datacall/deactivate datacall issue
+
+Fix setup datacall/deactivate datacall issue
+Test: test ok on 2635
+
+Change-Id: Id37d0aab225628cc65073380d15ee02a06a7b788
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00003518
+---
+ plugins/telephony.c | 160 ++++++++++++++++++++++++++++++++++++++++++----------
+ src/ipconfig.c      |   6 ++
+ src/network.c       |   1 +
+ 3 files changed, 138 insertions(+), 29 deletions(-)
+
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index a781b21..e0ad234 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -96,6 +96,18 @@ enum DBusType{
+     DMethodMax
+ };
+ 
++struct ipv4_info{
++    char *address;
++    char *netmask;
++    char *gateway;
++};
++
++struct ipv6_info{
++    char *address;
++    int prefix;
++    char *gateway;
++};
++
+ 
+ struct network_context {
+     char *path;
+@@ -109,11 +121,13 @@ struct network_context {
+     struct connman_network *network;
+ 
+     enum connman_ipconfig_method ipv4_method;
++    struct ipv4_info ipv4_info;
+     struct connman_ipaddress *ipv4_address;
+     char *ipv4_nameservers;
+ 
+     enum connman_ipconfig_method ipv6_method;
+     struct connman_ipaddress *ipv6_address;
++    struct ipv6_info ipv6_info;
+     char *ipv6_nameservers;
+ };
+ 
+@@ -191,7 +205,7 @@ static int extract_gatway(char *gatways, struct network_context *context)
+     }
+ 
+     p = strtok(gatways, " ");
+-    DBG("p[%s].", p);
++    DBG("p[%s]", p);
+ 
+     while (p)
+     {
+@@ -205,7 +219,7 @@ static int extract_gatway(char *gatways, struct network_context *context)
+             snprintf(ipv6, 31, "%s", p);
+         }
+         else{
+-            DBG("Invalid dns[%s].", p);
++            DBG("Invalid gatway[%s].", p);
+         }
+         p = strtok(NULL, " ");
+ 
+@@ -215,37 +229,99 @@ static int extract_gatway(char *gatways, struct network_context *context)
+ 
+     if (strlen(ipv4) != 0)
+     {
+-        DBG("ipv4[%s].", ipv4);
++        DBG("ipv4[%s]", ipv4);
+ 
+-        if (context->ipv4_address)
++        if (context->ipv4_info.gateway)
+         {
+-            connman_ipaddress_free(context->ipv4_address);
+-            context->ipv4_address = NULL;
++             g_free(context->ipv4_info.gateway);
++             context->ipv4_info.gateway = NULL;
+         }
+ 
+-        context->ipv4_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
+-
+-        connman_ipaddress_set_ipv4(context->ipv4_address, NULL, NULL, ipv4);
++        context->ipv4_info.gateway = g_strdup(ipv4);
++        DBG("context->ipv4_info.gateway[%s]", context->ipv4_info.gateway);
+     }
+ 
+     if (strlen(ipv6) != 0)
+     {
+         DBG("ipv6[%s].", ipv6);
+ 
+-        if (context->ipv6_address)
++        if (context->ipv6_info.gateway)
+         {
+-            connman_ipaddress_free(context->ipv6_address);
+-            context->ipv6_address = NULL;
++             g_free(context->ipv6_info.gateway);
++             context->ipv6_info.gateway = NULL;
+         }
+ 
+-        context->ipv6_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
+-
+-        connman_ipaddress_set_ipv6(context->ipv6_address, NULL, 0, ipv6);
++        context->ipv6_info.gateway = g_strdup(ipv6);
++        DBG("context->ipv6_info.gateway[%s]", context->ipv6_info.gateway);
+     }
+ 
+ }
+ 
++static int extract_addresses(char *addresses, struct network_context *context)
++{
++    char *p = NULL;
++    char ipv4[20] = {};
++    char ipv6[40] = {};
++
++    //example: addresses=10.164.2.8/16 FE80:0000:0000:0000:2Cc3:323c:F968:93d8/64
++    if (!addresses || !context)
++    {
++        DBG("Invalid arguments.");
++        return -1;
++    }
++
++    p = strtok(addresses, " ");
++    DBG("p[%s]", p);
++
++    while (p)
++    {
++        //ipv4 address
++        if (strchr(p, '.'))
++        {
++            snprintf(ipv4, 19, "%s", p);
++        }
++        else if (strchr(p, ':'))  //ipv6 address
++        {
++            snprintf(ipv6, 39, "%s", p);
++        }
++        else{
++            DBG("Invalid gatway[%s].", p);
++        }
++        p = strtok(NULL, " ");
++
++    }
++
++    DBG("ipv4[%s] ipv6[%s]", ipv4, ipv6);
++
++    if (strlen(ipv4) != 0)
++    {
++        DBG("ipv4[%s]", ipv4);
++
++        if (context->ipv4_info.address)
++        {
++             g_free(context->ipv4_info.address);
++             context->ipv4_info.address = NULL;
++        }
++
++        context->ipv4_info.address = g_strdup(ipv4);
++        DBG("context->ipv4_info.address[%s]", context->ipv4_info.address);
++    }
++
++    if (strlen(ipv6) != 0)
++    {
++        DBG("ipv6[%s].", ipv6);
+ 
++        if (context->ipv6_info.address)
++        {
++             g_free(context->ipv6_info.address);
++             context->ipv6_info.address = NULL;
++        }
++
++        context->ipv6_info.gateway = g_strdup(ipv6);
++        DBG("context->ipv6_info.address[%s]", context->ipv6_info.address);
++    }
++
++}
+ 
+ static int extract_dns(char *dnses, struct network_context *context)
+ {
+@@ -299,9 +375,9 @@ static int extract_dns(char *dnses, struct network_context *context)
+ 
+         }
+ 
+-        lengh = strlen(ipv6) + 1;
+-        context->ipv6_nameservers = g_strdup(ipv6);
+-        DBG("context->ipv4_nameservers[%s].", context->ipv6_nameservers);
++        lengh = strlen(ipv4) + 1;
++        context->ipv4_nameservers = g_strdup(ipv4);
++        DBG("context->ipv4_nameservers[%s]", context->ipv4_nameservers);
+     }
+ 
+     if (strlen(ipv6) != 0)
+@@ -320,7 +396,7 @@ static int extract_dns(char *dnses, struct network_context *context)
+ 
+         lengh = strlen(ipv6) + 1;
+         context->ipv6_nameservers = g_strdup(ipv6);
+-        DBG("context->ipv4_nameservers[%s].", context->ipv6_nameservers);
++        DBG("context->ipv6_nameservers[%s].", context->ipv6_nameservers);
+ 
+     }
+ 
+@@ -368,6 +444,11 @@ static int extract_dbus_info( struct DataCallResponse *dataCallResponse, struct
+                 extract_gatway(dataCallResponse->gateways, context);
+             }
+ 
++            if (dataCallResponse->addresses)
++            {
++                DBG("dataCallResponse->addresses[%s]", dataCallResponse->addresses);
++                extract_addresses(dataCallResponse->addresses, context);
++            }
+             context->mtu = dataCallResponse->mtu;
+             break;
+         }
+@@ -505,6 +586,7 @@ static void add_network(struct modem_data *modem,
+ 
+     connman_network_set_name(context->network, "Cellular");
+ 
++
+     group = get_ident(context->path);
+     connman_network_set_group(context->network, group);
+ 
+@@ -525,9 +607,9 @@ static void add_network(struct modem_data *modem,
+     if (service)
+     {
+         DBG("connman_network_set_index to -1");
+-        connman_network_set_index(context->network, -1);
+-        connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+-        connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
++        //connman_network_set_index(context->network, -1);
++        //connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_OFF);
++        //connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_OFF);
+ 
+     }
+ }
+@@ -554,23 +636,33 @@ static void set_connected(struct modem_data *modem,
+         return;
+     }
+ 
+-    connman_service_create_ip4config(service, index);
+-     connman_network_set_index(context->network, index);
+-    connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+ 
+ 
+ 
+ 
+-    //connman_ipaddress_set_ipv4(context->ipv4_address, "172.168.0.100", "255.255.255.0", "172.168.0.100");
++    DBG("context->ipv4_info.address[%s] context->ipv4_info.gateway[%s]", context->ipv4_info.address, context->ipv4_info.gateway);
++    if (context->ipv4_address)
++    {
++        connman_ipaddress_free(context->ipv4_address);
++        context->ipv4_address = NULL;
++    }
++    context->ipv4_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
++
++    connman_ipaddress_set_ipv4(context->ipv4_address, context->ipv4_info.address, "255.0.0.0", context->ipv4_info.gateway);
+ 
+ 
+     connman_network_set_ipaddress(context->network,context->ipv4_address);
+     connman_network_set_nameservers(context->network, context->ipv4_nameservers);
+ 
++    connman_service_create_ip4config(service, index);
++    connman_network_set_index(context->network, index);
++    connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
++
+ 
+ 
+     connman_network_set_connected(context->network, true);
+     context->pdnStatus = ConnmanPDNStatusConnected;
++    DBG("");
+ 
+ }
+ 
+@@ -595,7 +687,8 @@ static void set_disconnected(struct network_context *context)
+             context->ipv6_method =
+                     CONNMAN_IPCONFIG_METHOD_UNKNOWN;
+     }
+-
++    connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_DHCP);
++    connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_AUTO);
+     context->pdnStatus = ConnmanPDNStatusDisconnected;
+ }
+ 
+@@ -631,6 +724,7 @@ static void get_dbus_info(DBusMessage *message, struct DataCallResponse *dataCal
+        return;
+    }
+ 
++   DBG("");
+   dbus_message_iter_init (message, &iter);
+ 
+   dbus_message_iter_recurse (&iter, &subiter);
+@@ -678,6 +772,7 @@ static void get_dbus_info(DBusMessage *message, struct DataCallResponse *dataCal
+   dbus_message_iter_next (&subiter);
+ 
+   dbus_message_iter_get_basic (&subiter, &dataCallResponseenum->mtu);
++  DBG("end");
+ }
+ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+ {
+@@ -927,7 +1022,7 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+ 
+            status = false;
+             dbus_message_iter_init_append(msg, &arg);
+-            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_INT32, &status)){
++            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_BOOLEAN, &status)){
+                DBG("dbus_message_iter_append_basic Out of Memory!");
+            }
+ 
+@@ -1092,7 +1187,12 @@ static int network_connect(struct connman_network *network)
+     if (!connection)
+         return -EIO;
+ 
+-    send_method_call(connection, DMethodCallSetupdatacall);
++    DBG("context->pdnStatus[%d]", context->pdnStatus);
++    if (context->pdnStatus != ConnmanPDNStatusConnected)
++    {
++        DBG("send_method_call");
++        send_method_call(connection, DMethodCallSetupdatacall);
++    }
+ 
+     return 0;
+ }
+@@ -1105,6 +1205,8 @@ static int network_disconnect(struct connman_network *network)
+     if (!connection)
+         return -EIO;
+ 
++    DBG("context->pdnStatus[%d]", context->pdnStatus);
++    if (context->pdnStatus == ConnmanPDNStatusConnected)
+     send_method_call(connection, DMethodDeactivedatacall);
+ 
+     return 0;
+diff --git a/src/ipconfig.c b/src/ipconfig.c
+index 6f25ba3..3e08a32 100644
+--- a/src/ipconfig.c
++++ b/src/ipconfig.c
+@@ -511,6 +511,7 @@ update:
+ 			lower_down = true;
+ 	}
+ 
++    DBG("ipdevice->flags[%d] flags[%d]", ipdevice->flags, flags);
+ 	ipdevice->flags = flags;
+ 
+ 	str = g_string_new(NULL);
+@@ -2286,6 +2287,11 @@ int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
+ 	const char *method;
+ 	char *key;
+ 
++    if (strncmp(identifier, "cellular", 8) == 0)
++    {
++        DBG("no need to save ipconfig for cellular");
++        return 0;
++    }
+ 	method = __connman_ipconfig_method2string(ipconfig->method);
+ 
+ 	DBG("ipconfig %p identifier %s method %s", ipconfig, identifier,
+diff --git a/src/network.c b/src/network.c
+index 08cf407..cdc648e 100644
+--- a/src/network.c
++++ b/src/network.c
+@@ -1624,6 +1624,7 @@ int connman_network_set_ipaddress(struct connman_network *network,
+ 	if (!ipconfig)
+ 		return -EINVAL;
+ 
++    DBG("local[%s] gateway[%s]", ipaddress->local, ipaddress->gateway);
+ 	__connman_ipconfig_set_local(ipconfig, ipaddress->local);
+ 	__connman_ipconfig_set_peer(ipconfig, ipaddress->peer);
+ 	__connman_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast);
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0012-connman-set-timeout-to-DBUS_TIMEOUT_INFINITE.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0012-connman-set-timeout-to-DBUS_TIMEOUT_INFINITE.patch
new file mode 100644
index 0000000..9f31856
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0012-connman-set-timeout-to-DBUS_TIMEOUT_INFINITE.patch
@@ -0,0 +1,31 @@
+From 82c6accf7fcebd2ddf426e9875fd165f0a23658c Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Fri, 28 Jul 2017 09:26:45 +0800
+Subject: [PATCH 12/14] connman: set timeout to DBUS_TIMEOUT_INFINITE
+
+set timeout to DBUS_TIMEOUT_INFINITE
+Test: test ok on 2635
+
+Change-Id: I5ec5e2d156ed0a29496237558e5c14738ff2fa87
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00006184
+---
+ plugins/telephony.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index a1a3d7c..ea1ce56 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -916,7 +916,7 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+            }
+ 
+             DBG("methodType4");
+-            if(!dbus_connection_send_with_reply (connection, msg, &modem->call_setup_data_call, TIMEOUT)){
++            if(!dbus_connection_send_with_reply (connection, msg, &modem->call_setup_data_call, DBUS_TIMEOUT_INFINITE)){
+               DBG("dbus_connection_send_with_reply Out of Memory!");
+            }
+ 
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0013-connman-not-to-save-load-config-information-for-cell.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0013-connman-not-to-save-load-config-information-for-cell.patch
new file mode 100644
index 0000000..5165fdd
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0013-connman-not-to-save-load-config-information-for-cell.patch
@@ -0,0 +1,47 @@
+From a0bab8ada8d927da681242c9d6f07f93749ab44f Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Fri, 28 Jul 2017 09:34:06 +0800
+Subject: [PATCH 13/14] connman: not to save/load config information for
+ cellular network
+
+not to save/load config information for cellular network
+Test: test ok on 2635
+
+Change-Id: Iccc0733f5f4ef507800959357d688a1e9da54931
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00006198
+---
+ src/storage.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/src/storage.c b/src/storage.c
+index 7d03130..eacdbf6 100644
+--- a/src/storage.c
++++ b/src/storage.c
+@@ -247,6 +247,11 @@ GKeyFile *connman_storage_load_service(const char *service_id)
+ 	gchar *pathname;
+ 	GKeyFile *keyfile = NULL;
+ 
++    if (strncmp(service_id, "cellular", 8) == 0)
++    {
++        DBG("service_id[%s]", service_id);
++        return NULL;
++    }
+ 	pathname = g_strdup_printf("%s/%s/%s", STORAGEDIR, service_id, SETTINGS);
+ 	if (!pathname)
+ 		return NULL;
+@@ -261,6 +266,11 @@ int __connman_storage_save_service(GKeyFile *keyfile, const char *service_id)
+ {
+ 	int ret = 0;
+ 	gchar *pathname, *dirname;
++    if (strncmp(service_id, "cellular", 8) == 0)
++    {
++        DBG("service_id[%s]", service_id);
++        return NULL;
++    }
+ 
+ 	dirname = g_strdup_printf("%s/%s", STORAGEDIR, service_id);
+ 	if (!dirname)
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0014-connman-disable-connman-to-clear-ip-address-when-dis.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0014-connman-disable-connman-to-clear-ip-address-when-dis.patch
new file mode 100644
index 0000000..b586e28
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0014-connman-disable-connman-to-clear-ip-address-when-dis.patch
@@ -0,0 +1,36 @@
+diff --git a/src/ipconfig.c b/src/ipconfig.c
+index afec0cd..db39e8e 100644
+--- a/src/ipconfig.c
++++ b/src/ipconfig.c
+@@ -1317,6 +1317,7 @@ int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
+ 		{
+ 			DBG("name[%s]", name);
+ 			g_free(name);
++			name = NULL;
+ 			break;
+ 		}
+ 		if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
+@@ -1357,7 +1358,7 @@ int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig)
+ int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
+ {
+ 	int err;
+-
++	char *name = NULL;
+ 	if (!ipconfig)
+ 		return 0;
+ 
+@@ -1369,6 +1370,14 @@ int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
+ 	case CONNMAN_IPCONFIG_METHOD_FIXED:
+ 	case CONNMAN_IPCONFIG_METHOD_DHCP:
+ 	case CONNMAN_IPCONFIG_METHOD_MANUAL:
++		name = connman_inet_ifname(ipconfig->index);
++		if ((name != NULL) && (strncmp(name, "ccmni", 5) == 0))
++		{
++			DBG("name[%s]", name);
++			g_free(name);
++			name = NULL;
++			break;
++		}
+ 		if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
+ 			err = connman_inet_clear_address(ipconfig->index,
+ 							ipconfig->address);
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0015-connman-set-ipv6-route-and-dns.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0015-connman-set-ipv6-route-and-dns.patch
new file mode 100644
index 0000000..7666d28
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0015-connman-set-ipv6-route-and-dns.patch
@@ -0,0 +1,247 @@
+From 1b5cc5a70d55c10d438a5fc5c6da23d15a73ced4 Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Mon, 7 Aug 2017 15:12:48 +0800
+Subject: [PATCH 15/15] connman: set ipv6 route and dns
+
+set ipv6 route and dns
+Test: test ok 0n 2635
+
+Change-Id: I358acb1a7cbd58dc11c2615ebe4386feeab0021e
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00006200
+---
+ plugins/telephony.c | 144 +++++++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 125 insertions(+), 19 deletions(-)
+ mode change 100644 => 100755 plugins/telephony.c
+
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+old mode 100644
+new mode 100755
+index ea1ce56..81388cb
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -200,7 +200,7 @@ static int extract_gatway(char *gatways, struct network_context *context)
+ {
+     char *p = NULL;
+     char ipv4[16] = {};
+-    char ipv6[32] = {};
++    char ipv6[42] = {};
+     int lengh;
+     //example: gateways=10.164.2.8 FE80:0000:0000:0000:2Cc3:323c:F968:93d8
+     if (!gatways || !context)
+@@ -221,7 +221,7 @@ static int extract_gatway(char *gatways, struct network_context *context)
+         }
+         else if (strchr(p, ':'))  //ipv6 address
+         {
+-            snprintf(ipv6, 31, "%s", p);
++            snprintf(ipv6, 41, "%s", p);
+         }
+         else{
+             DBG("Invalid gatway[%s].", p);
+@@ -266,7 +266,7 @@ static int extract_addresses(char *addresses, struct network_context *context)
+ {
+     char *p = NULL;
+     char ipv4[20] = {};
+-    char ipv6[40] = {};
++    char ipv6[42] = {};
+ 
+     //example: addresses=10.164.2.8/16 FE80:0000:0000:0000:2Cc3:323c:F968:93d8/64
+     if (!addresses || !context)
+@@ -287,7 +287,7 @@ static int extract_addresses(char *addresses, struct network_context *context)
+         }
+         else if (strchr(p, ':'))  //ipv6 address
+         {
+-            snprintf(ipv6, 39, "%s", p);
++            snprintf(ipv6, 41, "%s", p);
+         }
+         else{
+             DBG("Invalid gatway[%s].", p);
+@@ -322,7 +322,7 @@ static int extract_addresses(char *addresses, struct network_context *context)
+              context->ipv6_info.address = NULL;
+         }
+ 
+-        context->ipv6_info.gateway = g_strdup(ipv6);
++        context->ipv6_info.address = g_strdup(ipv6);
+         DBG("context->ipv6_info.address[%s]", context->ipv6_info.address);
+     }
+ 
+@@ -474,6 +474,80 @@ static int extract_dbus_info( struct DataCallResponse *dataCallResponse, struct
+ 
+ }
+ 
++static int clear_context_pdn_info(struct network_context *context)
++{
++    context->status = -1;
++    context->index = -1;
++    context->cid = -1;
++    context->mtu = 1500;
++    context->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF;
++    context->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF;
++
++    memset(context->ifname, 0, sizeof(context->ifname));
++
++
++    //clear ipv4 info
++    if (context->ipv4_info.address)
++    {
++        g_free(context->ipv4_info.address);
++        context->ipv4_info.address = NULL;
++    }
++
++    if (context->ipv4_info.netmask)
++    {
++        g_free(context->ipv4_info.netmask);
++        context->ipv4_info.netmask = NULL;
++    }
++
++    if (context->ipv4_info.gateway)
++    {
++        g_free(context->ipv4_info.gateway);
++        context->ipv4_info.gateway = NULL;
++    }
++
++    //clear ipv6 info
++    if (context->ipv6_info.address)
++    {
++        g_free(context->ipv6_info.address);
++        context->ipv6_info.address = NULL;
++    }
++
++    context->ipv6_info.prefix = 0;
++
++    if (context->ipv6_info.gateway)
++    {
++        g_free(context->ipv6_info.gateway);
++        context->ipv6_info.gateway = NULL;
++    }
++
++    //free ipv4 address
++    if (context->ipv4_address)
++    {
++        connman_ipaddress_free(context->ipv4_address);
++        context->ipv4_address = NULL;
++    }
++
++    if (context->ipv4_nameservers)
++    {
++        g_free(context->ipv4_nameservers);
++        context->ipv4_nameservers = NULL;
++    }
++
++    if (context->ipv6_address)
++    {
++        connman_ipaddress_free(context->ipv6_address);
++        context->ipv6_address = NULL;
++    }
++
++    if (context->ipv6_nameservers)
++    {
++        g_free(context->ipv6_nameservers);
++        context->ipv6_nameservers = NULL;
++    }
++
++}
++
++
+ 
+ 
+ static struct network_context *network_context_alloc(const char *path)
+@@ -644,24 +718,55 @@ static void set_connected(struct modem_data *modem,
+ 
+ 
+ 
+-
+-    DBG("context->ipv4_info.address[%s] context->ipv4_info.gateway[%s]", context->ipv4_info.address, context->ipv4_info.gateway);
+-    if (context->ipv4_address)
++    //set ipv4
++    if (context->ipv4_info.gateway)
+     {
+-        connman_ipaddress_free(context->ipv4_address);
+-        context->ipv4_address = NULL;
++        DBG("context->ipv4_info.address[%s] context->ipv4_info.gateway[%s]", context->ipv4_info.address, context->ipv4_info.gateway);
++        if (context->ipv4_address)
++        {
++            connman_ipaddress_free(context->ipv4_address);
++            context->ipv4_address = NULL;
++        }
++        context->ipv4_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
++
++        connman_ipaddress_set_ipv4(context->ipv4_address, context->ipv4_info.address, "255.0.0.0", context->ipv4_info.gateway);
++
++
++        connman_network_set_ipaddress(context->network,context->ipv4_address);
++
++        connman_service_create_ip4config(service, index);
++        connman_network_set_index(context->network, index);
++        connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+     }
+-    context->ipv4_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
+ 
+-    connman_ipaddress_set_ipv4(context->ipv4_address, context->ipv4_info.address, "255.0.0.0", context->ipv4_info.gateway);
++    // set ipv4 nameserver
++    if (context->ipv4_nameservers)
++        connman_network_set_nameservers(context->network, context->ipv4_nameservers);
++
++    //set ipv6
++    if (context->ipv6_info.gateway)
++    {
++        DBG("context->ipv6_info.address[%s] context->ipv6_info.gateway[%s]", context->ipv6_info.address, context->ipv6_info.gateway);
++        if (context->ipv6_address)
++        {
++            connman_ipaddress_free(context->ipv6_address);
++            context->ipv6_address = NULL;
++        }
++        context->ipv6_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
++
++        connman_ipaddress_set_ipv6(context->ipv6_address, context->ipv6_info.address, 64, context->ipv6_info.gateway);
++
+ 
++        connman_network_set_ipaddress(context->network,context->ipv6_address);
+ 
+-    connman_network_set_ipaddress(context->network,context->ipv4_address);
+-    connman_network_set_nameservers(context->network, context->ipv4_nameservers);
++        connman_service_create_ip6config(service, index);
++        connman_network_set_index(context->network, index);
++        connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
++    }
+ 
+-    connman_service_create_ip4config(service, index);
+-    connman_network_set_index(context->network, index);
+-    connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
++    // set ipv6 nameserver
++    if (context->ipv6_nameservers)
++        connman_network_set_nameservers(context->network, context->ipv6_nameservers);
+ 
+ 
+     connman_network_set_connected(context->network, true);
+@@ -794,6 +899,7 @@ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+     DBG("");
+ 
+     modem->call_setup_data_call = NULL;
++    clear_context_pdn_info(context);
+     dbus_error_init(&error);
+ 
+     reply = dbus_pending_call_steal_reply(call);
+@@ -813,6 +919,7 @@ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+     DBG("type[%s] ifname[%s] addresses[%s]", dataCallResponse.type, dataCallResponse.ifname, dataCallResponse.addresses);
+     DBG("dnses[%s] gateway[%s] mtu[%d]", dataCallResponse.dnses, dataCallResponse.gateways , dataCallResponse.mtu);
+ 
++
+     extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
+ 
+ 
+@@ -1170,10 +1277,9 @@ static void add_modem(const char *path, DBusMessageIter *prop)
+ 
+ 
+ static int network_probe(struct connman_network *network)
+- {
++{
+ 
+     DBG("");
+-
+     return 0;
+ }
+ 
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0016-connman-access-null-pointer-for-some-timing.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0016-connman-access-null-pointer-for-some-timing.patch
new file mode 100644
index 0000000..faca759
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0016-connman-access-null-pointer-for-some-timing.patch
@@ -0,0 +1,260 @@
+From 88fae9898b16d91017723368686425c997073d01 Mon Sep 17 00:00:00 2001
+From: ZY Zheng <zy.zheng@mediatek.com>
+Date: Tue, 29 Aug 2017 10:50:42 +0800
+Subject: [PATCH 16/16] connman: access null pointer for some timing
+
+1.access null pointer for some timing
+2.remove rebundant log
+Test: test ok on 2635
+
+Change-Id: I4089df70e8cb679db8a2ae3da59e158868df066f
+Signed-off-by: ZY Zheng <zy.zheng@mediatek.com>
+CR-Id: AUTO00006773
+---
+ plugins/telephony.c | 151 ++++++----------------------------------------------
+ 1 file changed, 15 insertions(+), 136 deletions(-)
+ mode change 100755 => 100644 plugins/telephony.c
+
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+old mode 100755
+new mode 100644
+index 81388cb..ad19660
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -705,7 +705,6 @@ static void set_connected(struct modem_data *modem,
+ 
+ 
+     index = connman_inet_ifindex(context->ifname);//context->index;
+-    //connman_inet_ifup(index);//ZY it will makred
+     DBG("ifname[%s] index[%d]", context->ifname, index);
+ 
+     service = connman_service_lookup_from_network(context->network);
+@@ -996,133 +995,66 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+     switch(dbusType){
+         case DMethodCallSetupdatacall:
+         {
+-            DBG("modem->call_setup_data_call[%p]", modem->call_setup_data_call);
++
++            if (!modem)
++                return;
++
+             if (modem->call_setup_data_call) {
++                DBG("modem->call_setup_data_call[%p]", modem->call_setup_data_call);
+                 DBG("Cancel pending SetProperty");
+                 dbus_pending_call_cancel(modem->call_setup_data_call);
+                 dbus_pending_call_unref(modem->call_setup_data_call);
+                 modem->call_setup_data_call = NULL;
+             }
+ 
+-            DBG("methodType1");
+             msg = dbus_message_new_method_call (TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_ENABLE_DATA);
+             if(msg == NULL){
+                 DBG("MessageNULL");
+                return;
+             }
+-            DBG("methodType2");
++
+             status = true;
+             dbus_message_iter_init_append(msg, &arg);
+             if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_BOOLEAN, &status)){
+                DBG("dbus_message_iter_append_basic Out of Memory!");
+-           }
++            }
+ 
+-            DBG("methodType3 pdn[%p] &pdn[%p]", pdn, &pdn);
+            if(!dbus_message_iter_append_basic(&arg, DBUS_TYPE_STRING, &pdn)){
+                DBG("dbus_message_iter_append_basic Out of Memory!");
+-           }
++            }
+ 
+-            DBG("methodType4");
+             if(!dbus_connection_send_with_reply (connection, msg, &modem->call_setup_data_call, DBUS_TIMEOUT_INFINITE)){
+               DBG("dbus_connection_send_with_reply Out of Memory!");
+-           }
++            }
+ 
+-            DBG("methodType5");
+ 
+             if (!modem->call_setup_data_call) {
+                 connman_error("D-Bus connection not available");
+                 dbus_message_unref(msg);
+                 return;
+-            }
++             }
+ 
+-            DBG("dbus_message_unref1");
+             dbus_message_unref(msg);
+ 
+-            #if 1
+-
+-            #if 0 //error
+-            if (!dbus_pending_call_get_completed(modem->call_setup_data_call))
+-            {
+-                DBG("time out");
+-                dbus_pending_call_cancel(modem->call_setup_data_call);
+-                dbus_pending_call_unref(modem->call_setup_data_call);
+-                modem->call_setup_data_call = NULL;
+-
+-            }
+-            #endif
+-
+-
+             dbus_pending_call_set_notify(modem->call_setup_data_call,
+                     setup_datacall_reply, NULL, NULL);
+-            #else
+-
+-
+-            dbus_pending_call_block (modem->call_setup_data_call);
+-
+-            reply =dbus_pending_call_steal_reply (modem->call_setup_data_call);
+-            if (msg == NULL)
+-            {
+-                DBG("ReplyNull!");
+-                dbus_message_unref(reply);
+-                return;
+-            }
+-
+-
+-
+-            ret = dbus_message_get_args( reply, &err,
+-                   DBUS_TYPE_INT32, &dataCallResponse.active,
+-                   DBUS_TYPE_INT32, &dataCallResponse.status,
+-                   DBUS_TYPE_INT32, &dataCallResponse.cid,
+-                   DBUS_TYPE_STRING, &dataCallResponse.type,
+-                   DBUS_TYPE_STRING, &dataCallResponse.ifname,
+-                   DBUS_TYPE_STRING, &dataCallResponse.addresses,
+-                   DBUS_TYPE_STRING, &dataCallResponse.dnses,
+-                   DBUS_TYPE_STRING, &dataCallResponse.gateway,
+-                   DBUS_TYPE_INT32, &dataCallResponse.mtu,
+-                   DBUS_TYPE_INVALID );
+-
+-            if (FALSE == ret)
+-            {
+-                DBG("error.nam[%s]: error.message[%s]", error.name, error.message);
+-                dbus_message_unref(msg);
+-                dbus_pending_call_unref(modem->call_setup_data_call);
+-                modem->call_setup_data_call = NULL;
+-                dbus_message_unref(reply);
+-                return;
+-            }
+-
+-            DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
+-            DBG("type[%s] ifname[%s] addresses[%s]", dataCallResponse.type, dataCallResponse.ifname, dataCallResponse.addresses);
+-            DBG("dnses[%s] gateway[%s] mtu[%d]", dataCallResponse.dnses, dataCallResponse.gateway , dataCallResponse.mtu);
+-
+-            extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
+-
+-            if (context->active == CONNECTED)
+-            {
+-                set_connected(modem, context);
+-            }
+-
+-
+-            dbus_message_unref(reply);
+-            dbus_pending_call_unref(modem->call_setup_data_call);
+-            modem->call_setup_data_call = NULL;
+-
+-            #endif
+             break;
+ 
+         }
+ 
+         case DMethodDeactivedatacall:
+         {
+-            DBG("modem->call_deactive_data_call[%p]", modem->call_deactive_data_call);
++            if (!modem)
++                return;
++
+             if (modem->call_deactive_data_call) {
++                DBG("modem->call_deactive_data_call[%p]", modem->call_deactive_data_call);
+                 DBG("Cancel pending SetProperty");
+                 dbus_pending_call_cancel(modem->call_deactive_data_call);
+                 dbus_pending_call_unref(modem->call_deactive_data_call);
+                 modem->call_deactive_data_call = NULL;
+             }
+ 
+-            DBG("DMethodDeactivedatacall");
+             status = false;
+ 
+             msg = dbus_message_new_method_call(TELEPHONY_SERVICE, TELEPHONY_DATA_PATH, TELEPHONY_DATA_INTERFACE, METHODC_ENABLE_DATA);
+@@ -1148,58 +1080,8 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+ 
+             dbus_message_unref(msg);
+ 
+-            #if 1
+-
+             dbus_pending_call_set_notify(modem->call_deactive_data_call,
+                     deactive_datacall_reply, NULL, NULL);
+-            #else
+-
+-
+-            dbus_pending_call_block (modem->call_deactive_data_call);
+-
+-            reply =dbus_pending_call_steal_reply (modem->call_deactive_data_call);
+-            if (msg == NULL)
+-            {
+-                DBG("ReplyNull!");
+-                dbus_message_unref(reply);
+-                return;
+-            }
+-
+-
+-
+-            ret = dbus_message_get_args(reply, &err,
+-                   DBUS_TYPE_INT32, &dataCallResponse.active,
+-                   DBUS_TYPE_INT32, &dataCallResponse.status,
+-                   DBUS_TYPE_INT32, &dataCallResponse.cid,
+-                   DBUS_TYPE_INVALID);
+-
+-            if (FALSE == ret)
+-            {
+-                DBG("error.name [%s]: error.message[%s]", error.name, error.message);
+-                dbus_message_unref(msg);
+-                dbus_pending_call_unref(modem->call_deactive_data_call);
+-                modem->call_deactive_data_call = NULL;
+-                dbus_message_unref(reply);
+-                return;
+-            }
+-
+-            DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
+-
+-            extract_dbus_info(&dataCallResponse, context, DMethodDeactivedatacall);
+-
+-            if (context->active == DISCONNECTED)
+-            {
+-                set_disconnected(context);
+-            }else{
+-
+-            }
+-
+-
+-            dbus_message_unref(reply);
+-            dbus_pending_call_unref(modem->call_deactive_data_call);
+-            modem->call_deactive_data_call = NULL;
+-
+-            #endif
+             break;
+ 
+         }
+@@ -1208,9 +1090,6 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+             break;
+         }
+     }
+-
+-    DBG("methodType6");
+-
+ }
+ 
+ #endif
+@@ -1298,7 +1177,7 @@ static int network_connect(struct connman_network *network)
+     if (!connection)
+         return -EIO;
+ 
+-    DBG("context->pdnStatus zy[%d]", context->pdnStatus);
++    DBG("context->pdnStatus [%d]", context->pdnStatus);
+     if (context->pdnStatus != ConnmanPDNStatusConnected)
+     {
+         DBG("send_method_call");
+-- 
+1.9.1
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0017-connman-can_not_disconnect_after_telephony_reboot.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0017-connman-can_not_disconnect_after_telephony_reboot.patch
new file mode 100644
index 0000000..d613b93
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0017-connman-can_not_disconnect_after_telephony_reboot.patch
@@ -0,0 +1,38 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index ad19660..47ad084 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -1098,7 +1098,6 @@ static void send_method_call(DBusConnection * connection, enum DBusType dbusType
+
+ static void remove_modem()
+ {
+-    void * test;
+     DBG("modem[%p]", modem);
+     if(!modem)
+     {
+@@ -1120,14 +1119,6 @@ static void remove_modem()
+ //    if (modem->device)
+ //      destroy_device(modem);
+
+-    test = calloc(16, 1024);
+-    if (!test)
+-        DBG("test memory fail");
+-
+-
+-    DBG("test[%p]", test);
+-    memset(test, 1, 16*1024);
+-
+     g_free(modem->path);
+     DBG("PID[%u] TID[%u] Alloc[%p]", getpid(), syscall(224), modem->path);
+
+@@ -1306,6 +1297,10 @@ static void telephony_connect(DBusConnection *conn, void *user_data)
+ static void telephony_disconnect(DBusConnection *conn, void *user_data)
+ {
+     DBG("");
++    if (context)
++    {
++		remove_network(modem, context);
++    }
+
+     remove_modem(modem);
+ }
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0018-connman-service_start_after_network.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0018-connman-service_start_after_network.patch
new file mode 100644
index 0000000..ada2aa3
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0018-connman-service_start_after_network.patch
@@ -0,0 +1,15 @@
+diff --git a/src/connman.service.in b/src/connman.service.in
+index 33e1805..7ce4536 100644
+--- a/src/connman.service.in
++++ b/src/connman.service.in
+@@ -3,8 +3,8 @@ Description=Connection service
+ DefaultDependencies=false
+ Conflicts=shutdown.target
+ RequiresMountsFor=@localstatedir@/lib/connman
+-After=dbus.service network-pre.target systemd-sysusers.service
+-Before=network.target multi-user.target shutdown.target
++After=dbus.service network-pre.target systemd-sysusers.service network.target
++Before=multi-user.target shutdown.target
+ Wants=network.target
+ Conflicts=systemd-resolved.service
+ 
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0019-connman-add-ethernet-tethering.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0019-connman-add-ethernet-tethering.patch
new file mode 100644
index 0000000..3e0244e
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0019-connman-add-ethernet-tethering.patch
@@ -0,0 +1,13 @@
+diff --git a/src/technology.c b/src/technology.c
+index 660af52..7be02e1 100644
+--- a/src/technology.c
++++ b/src/technology.c
+@@ -109,7 +109,7 @@ static void rfkill_check(gpointer key, gpointer value, gpointer user_data)
+ bool
+ connman_technology_is_tethering_allowed(enum connman_service_type type)
+ {
+-	static char *allowed_default[] = { "wifi", "bluetooth", "gadget",
++	static char *allowed_default[] = { "wifi", "bluetooth", "gadget", "ethernet",
+ 					   NULL };
+ 	const char *type_str = __connman_service_type2string(type);
+ 	char **allowed;
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0020-connman-fix-dns-setting.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0020-connman-fix-dns-setting.patch
new file mode 100644
index 0000000..bcd3942
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0020-connman-fix-dns-setting.patch
@@ -0,0 +1,42 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index 47ad084..a92e605 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -738,10 +738,6 @@ static void set_connected(struct modem_data *modem,
+         connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+     }
+ 
+-    // set ipv4 nameserver
+-    if (context->ipv4_nameservers)
+-        connman_network_set_nameservers(context->network, context->ipv4_nameservers);
+-
+     //set ipv6
+     if (context->ipv6_info.gateway)
+     {
+@@ -762,11 +758,21 @@ static void set_connected(struct modem_data *modem,
+         connman_network_set_index(context->network, index);
+         connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+     }
+-
+-    // set ipv6 nameserver
+-    if (context->ipv6_nameservers)
+-        connman_network_set_nameservers(context->network, context->ipv6_nameservers);
+-
++	/* Set the nameservers */
++	if (context->ipv4_nameservers &&
++		    context->ipv6_nameservers) {
++		nameservers = g_strdup_printf("%s %s",
++				    context->ipv4_nameservers,
++				    context->ipv6_nameservers);
++		connman_network_set_nameservers(context->network, nameservers);
++		g_free(nameservers);
++	} else if (context->ipv4_nameservers) {
++		connman_network_set_nameservers(context->network,
++				    context->ipv4_nameservers);
++	} else if (context->ipv6_nameservers) {
++		connman_network_set_nameservers(context->network,
++				    context->ipv6_nameservers);
++	}
+ 
+     connman_network_set_connected(context->network, true);
+     context->pdnStatus = ConnmanPDNStatusConnected;
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0021-connman-fix-ipv6-route.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0021-connman-fix-ipv6-route.patch
new file mode 100644
index 0000000..a8fa489
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0021-connman-fix-ipv6-route.patch
@@ -0,0 +1,60 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index a92e605..2284ea3 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -132,15 +132,12 @@ struct network_context {
+     struct connman_ipaddress *ipv6_address;
+     struct ipv6_info ipv6_info;
+     char *ipv6_nameservers;
++    int ipv6rule;
+ };
+-
+ struct modem_data {
+     char *path;
+-
+     struct connman_device *device;
+-
+     bool enabled;
+-
+     /* pending calls */
+     DBusPendingCall *call_setup_data_call;
+     DBusPendingCall *call_deactive_data_call;
+@@ -177,11 +174,8 @@ struct DataCallResponse
+                                    Value <= 0 means network has either not sent a value or
+                                    sent an invalid value */
+ };
+-
+-
+-
++int rule_num;
+ #if 1
+-
+ static char *get_ident(const char *path)
+ {
+     char *pos;
+@@ -758,6 +752,13 @@ static void set_connected(struct modem_data *modem,
+         connman_network_set_index(context->network, index);
+         connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+     }
++    if(context->ifname!=NULL && strncmp(context->ifname, "ccmni", 5)==0)
++    {
++        rule_num=context->ifname[5]-48+1002;
++        __connman_inet_add_fwmark_rule(rule_num,AF_INET6,0);
++        context->ipv6rule=1;
++        DBG("set IPv6 ip rule %d\n",rule_num);
++    }
+ 	/* Set the nameservers */
+ 	if (context->ipv4_nameservers &&
+ 		    context->ipv6_nameservers) {
+@@ -801,6 +802,11 @@ static void set_disconnected(struct network_context *context)
+             context->ipv6_method =
+                     CONNMAN_IPCONFIG_METHOD_UNKNOWN;
+     }
++    if(context->ipv6rule==1)
++    {
++        __connman_inet_del_fwmark_rule(rule_num,AF_INET6,0);
++        context->ipv6rule=0;
++    }
+     connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_DHCP);
+     connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_AUTO);
+     context->pdnStatus = ConnmanPDNStatusDisconnected;
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0022-connman-fix-pdn-change.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0022-connman-fix-pdn-change.patch
new file mode 100644
index 0000000..ea906a4
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0022-connman-fix-pdn-change.patch
@@ -0,0 +1,50 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index 2284ea3..6a97ad5 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -1319,6 +1319,7 @@ static void telephony_disconnect(DBusConnection *conn, void *user_data)
+ 
+ static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
+                 void *user_data)
++#if 0
+ {
+     DBusMessageIter iter;
+     int ret;
+@@ -1350,6 +1351,37 @@ static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
+ 
+     return TRUE;
+ }
++#endif
++{
++    DBusMessageIter iter;
++    int ret;
++    struct DataCallResponse dataCallResponse = {};
++
++
++    DBG("");
++    modem->call_setup_data_call = NULL;
++    clear_context_pdn_info(context);
++
++
++    get_dbus_info(message, &dataCallResponse, DMethodCallSetupdatacall);
++
++    DBG("active[%d] status[%d] cid[%d]", dataCallResponse.active, dataCallResponse.status, dataCallResponse.cid);
++    DBG("type[%s] ifname[%s] addresses[%s]", dataCallResponse.type, dataCallResponse.ifname, dataCallResponse.addresses);
++    DBG("dnses[%s] gateway[%s] mtu[%d]", dataCallResponse.dnses, dataCallResponse.gateways , dataCallResponse.mtu);
++
++
++    extract_dbus_info(&dataCallResponse, context, DMethodCallSetupdatacall);
++
++
++    if (context->active == CONNECTED)
++    {
++        set_connected(modem, context);
++    }else if (context->active == DISCONNECTED){
++        set_disconnected(context);
++    }
++
++    return TRUE;
++}
+ 
+ static guint watch;
+ static guint pdn_status_watch;
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0023-connman-ipv6-tethering.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0023-connman-ipv6-tethering.patch
new file mode 100644
index 0000000..1cff01f
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0023-connman-ipv6-tethering.patch
@@ -0,0 +1,247 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index 6a97ad5..f7fc942 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -176,6 +176,41 @@ struct DataCallResponse
+ };
+ int rule_num;
+ #if 1
++
++int get_pdnstatus_is_connected(void)
++{
++	return (context->pdnStatus==ConnmanPDNStatusConnected);
++}
++
++int get_ipv6_prefix_address(char *prefix_address,int *prefix_len)
++{
++	DBG("context->ipv6_info.prefix %d context->ipv6_info.address %s",context->ipv6_info.prefix,context->ipv6_info.address);
++	if(context->ipv6_info.prefix!=0 && context->ipv6_info.address!=NULL)
++	{
++		*prefix_len=context->ipv6_info.prefix;
++		int i=0,j=0;
++		for(i=0;i<strlen(context->ipv6_info.address);i++)
++		{
++
++			prefix_address[i]=context->ipv6_info.address[i];
++			if(context->ipv6_info.address[i]==':')
++				j++;
++			if(j>=context->ipv6_info.prefix/16){
++				prefix_address[i+1]=':';
++				prefix_address[i+2]='\0';
++				break;
++			}
++		}
++		return 0;
++	}
++	else
++	{
++		*prefix_len=0;
++		prefix_address=NULL;
++	}
++	return -1;
++}
++
+ static char *get_ident(const char *path)
+ {
+     char *pos;
+@@ -259,8 +294,10 @@ static int extract_gatway(char *gatways, struct network_context *context)
+ static int extract_addresses(char *addresses, struct network_context *context)
+ {
+     char *p = NULL;
++	char *q=NULL;
+     char ipv4[20] = {};
+     char ipv6[42] = {};
++	int prefix=0;
+ 
+     //example: addresses=10.164.2.8/16 FE80:0000:0000:0000:2Cc3:323c:F968:93d8/64
+     if (!addresses || !context)
+@@ -281,7 +318,10 @@ static int extract_addresses(char *addresses, struct network_context *context)
+         }
+         else if (strchr(p, ':'))  //ipv6 address
+         {
+-            snprintf(ipv6, 41, "%s", p);
++            q=strtok(p,"/");
++            snprintf(ipv6, 41, "%s", q);
++			q=strtok(NULL,"/");
++			prefix=atoi(q);
+         }
+         else{
+             DBG("Invalid gatway[%s].", p);
+@@ -317,6 +357,7 @@ static int extract_addresses(char *addresses, struct network_context *context)
+         }
+ 
+         context->ipv6_info.address = g_strdup(ipv6);
++		context->ipv6_info.prefix = prefix;
+         DBG("context->ipv6_info.address[%s]", context->ipv6_info.address);
+     }
+ 
+@@ -686,7 +727,7 @@ static void add_network(struct modem_data *modem,
+         //connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_OFF);
+     }
+ }
+-
++extern 	int __connman_ipv6_tethering_setup();
+ static void set_connected(struct modem_data *modem,
+             struct network_context *context)
+ {
+@@ -778,6 +819,7 @@ static void set_connected(struct modem_data *modem,
+     connman_network_set_connected(context->network, true);
+     context->pdnStatus = ConnmanPDNStatusConnected;
+     DBG("");
++	__connman_ipv6_tethering_setup();
+ 
+ }
+ 
+@@ -1379,7 +1421,7 @@ static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
+     }else if (context->active == DISCONNECTED){
+         set_disconnected(context);
+     }
+-
++	__connman_ipv6_tethering_setup();
+     return TRUE;
+ }
+ 
+diff --git a/src/tethering.c b/src/tethering.c
+index f3cb36f..8544967 100644
+--- a/src/tethering.c
++++ b/src/tethering.c
+@@ -74,6 +74,116 @@ struct connman_private_network {
+ 	char *secondary_dns;
+ };
+ 
++static void radvd_onoff(bool onoff)
++{
++	if(onoff){
++		system("radvd -C /var/lib/connman/radvd.conf");
++	}else{
++		system("killall radvd");
++	}
++}
++
++static int write_radvd_conf(char *prefix, int prefix_len,char *dnsaddr)
++{
++	FILE *fp=NULL;
++	fp=fopen("/var/lib/connman/radvd.conf","w");
++	if(fp==NULL)
++		return -1;
++	/*
++	interface tether
++	{
++        AdvSendAdvert on;
++        MinRtrAdvInterval 3;
++        MaxRtrAdvInterval 5;
++        AdvManagedFlag off;
++        AdvOtherConfigFlag off;
++        AdvDefaultPreference high;
++        prefix 2409:894c:c36:54a3::/64{
++                AdvValidLifetime 3600;
++                AdvPreferredLifetime 3600;
++        };
++        RDNSS 2409:894c:c36:54a3::bb{
++                AdvRDNSSLifetime 3600;
++        };
++	};
++	*/
++	fprintf(fp,"interface %s\n",BRIDGE_NAME);
++	fprintf(fp,"{\n");
++	fprintf(fp,"  AdvSendAdvert on;\n");
++	fprintf(fp,"  MinRtrAdvInterval 3;\n");
++	fprintf(fp,"  MaxRtrAdvInterval 5;\n");
++	fprintf(fp,"  AdvManagedFlag off;\n");
++	fprintf(fp,"  AdvOtherConfigFlag off;\n");
++	fprintf(fp,"  AdvDefaultPreference high;\n");
++	fprintf(fp,"  prefix %s/%d{\n",prefix,prefix_len);
++	fprintf(fp,"    AdvValidLifetime 3600;\n");
++	fprintf(fp,"    AdvPreferredLifetime 3600;\n");
++	fprintf(fp,"  };\n");
++	fprintf(fp,"  RDNSS %s{\n",dnsaddr);
++	fprintf(fp,"    AdvRDNSSLifetime 3600;\n");
++	fprintf(fp,"  };\n");
++	fprintf(fp,"};\n");
++	fclose(fp);
++	return 0;
++}
++bool writeToFile(const char* filename, const char* value) {
++    int fd = open(filename, O_WRONLY);
++    if (fd < 0) {
++        return false;
++    }
++
++    int len = strlen(value);
++    if (write(fd, value, len) != len) {
++        close(fd);
++        return false;
++    }
++    close(fd);
++    return true;
++}
++
++int __connman_ipv6_tethering_setup()
++{
++	if(tethering_enabled && get_pdnstatus_is_connected())
++	{
++		radvd_onoff(false);
++		char prefix[INET6_ADDRSTRLEN + 1];
++		int prefix_len=0;
++		int index;
++		struct in6_addr src;
++		char addr_str[INET6_ADDRSTRLEN + 1];
++		index = connman_inet_ifindex(BRIDGE_NAME);
++		int ret = __connman_inet_get_interface_ll_address(index,AF_INET6,&src);
++		if(ret<0){
++			DBG("get interface link local address fail");
++			return -1;
++		}
++		inet_ntop(AF_INET6, &src, addr_str, INET6_ADDRSTRLEN);
++		DBG("ret %d address %s",ret,addr_str);
++
++		ret = get_ipv6_prefix_address(prefix,&prefix_len);
++		DBG("ret %d prefix %s %d",ret,prefix,prefix_len);
++		if(ret<0){
++			DBG("get interface prefix fail");
++			return -1;
++		}
++		//enable forwarding
++		writeToFile("/proc/sys/net/ipv6/conf/all/forwarding","1");
++		//set tether ip address
++		writeToFile("/proc/sys/net/ipv6/conf/tether/accept_ra","0");
++		char buffer[256];
++		sprintf(buffer,"ip -6 addr add %sbb/%d dev tether",prefix,prefix_len);
++		system(buffer);
++		//write radvd conf
++		write_radvd_conf(prefix,prefix_len,addr_str);
++		//enable radvd
++		radvd_onoff(true);
++	}else{
++		radvd_onoff(false);
++		writeToFile("/proc/sys/net/ipv6/conf/all/forwarding","0");
++	}
++}
++
++
+ const char *__connman_tethering_get_bridge(void)
+ {
+ 	int sk, err;
+@@ -276,11 +386,13 @@ int __connman_tethering_set_enabled(void)
+ 		__sync_fetch_and_sub(&tethering_enabled, 1);
+ 		return -EOPNOTSUPP;
+ 	}
+-
++#if 0
+ 	err = __connman_ipv6pd_setup(BRIDGE_NAME);
+ 	if (err < 0 && err != -EINPROGRESS)
+ 		DBG("Cannot setup IPv6 prefix delegation %d/%s", err,
+ 			strerror(-err));
++#endif
++	__connman_ipv6_tethering_setup();
+ 
+ 	DBG("tethering started");
+ 
+@@ -317,6 +429,7 @@ void __connman_tethering_set_disabled(void)
+ 	private_network_primary_dns = NULL;
+ 	g_free(private_network_secondary_dns);
+ 	private_network_secondary_dns = NULL;
++	__connman_ipv6_tethering_setup();
+ 
+ 	DBG("tethering stopped");
+ }
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0024-connman-telephony-pdn-disconnect.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0024-connman-telephony-pdn-disconnect.patch
new file mode 100644
index 0000000..1534077
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0024-connman-telephony-pdn-disconnect.patch
@@ -0,0 +1,13 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index f7fc942..9cbf0f0 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -1418,7 +1418,7 @@ static gboolean pdn_status_unsol(DBusConnection *conn, DBusMessage *message,
+     if (context->active == CONNECTED)
+     {
+         set_connected(modem, context);
+-    }else if (context->active == DISCONNECTED){
++    }else{
+         set_disconnected(context);
+     }
+ 	__connman_ipv6_tethering_setup();
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0025-connman-fix-null-pointer.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0025-connman-fix-null-pointer.patch
new file mode 100644
index 0000000..f20f796
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0025-connman-fix-null-pointer.patch
@@ -0,0 +1,15 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index 9cbf0f0..4accfa7 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -951,7 +951,9 @@ static void setup_datacall_reply(DBusPendingCall *call, void *user_data)
+ 
+     DBG("");
+ 
+-    modem->call_setup_data_call = NULL;
++	if(modem != NULL){
++        modem->call_setup_data_call = NULL;
++	}
+     clear_context_pdn_info(context);
+     dbus_error_init(&error);
+ 
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0026-connman-fix-null-pointer_2.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0026-connman-fix-null-pointer_2.patch
new file mode 100644
index 0000000..ebac7bf
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0026-connman-fix-null-pointer_2.patch
@@ -0,0 +1,14 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index 4accfa7..311c426 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -321,7 +321,8 @@ static int extract_addresses(char *addresses, struct network_context *context)
+             q=strtok(p,"/");
+             snprintf(ipv6, 41, "%s", q);
+ 			q=strtok(NULL,"/");
+-			prefix=atoi(q);
++			if( q!=NULL )
++				prefix=atoi(q);
+         }
+         else{
+             DBG("Invalid gatway[%s].", p);
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0027-connman-fix-wispr-SIGSEGV.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0027-connman-fix-wispr-SIGSEGV.patch
new file mode 100644
index 0000000..1ef109e
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0027-connman-fix-wispr-SIGSEGV.patch
@@ -0,0 +1,26 @@
+diff --git a/src/service.c b/src/service.c
+index 2289d54..3e9a356 100644
+--- a/src/service.c
++++ b/src/service.c
+@@ -6325,7 +6325,7 @@ int __connman_service_disconnect(struct connman_service *service)
+ 	service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
+ 	service->proxy = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
+ 
+-	connman_agent_cancel(service);
++	__connman_wispr_stop(service);
+ 
+ 	reply_pending(service, ECONNABORTED);
+ 
+diff --git a/src/wispr.c b/src/wispr.c
+index 03b38bb..ce45a65 100644
+--- a/src/wispr.c
++++ b/src/wispr.c
+@@ -978,7 +978,7 @@ void __connman_wispr_stop(struct connman_service *service)
+ 
+ 	if (!wispr_portal_list)
+ 		return;
+-
++	connman_agent_cancel(service);
+ 	index = __connman_service_get_index(service);
+ 	if (index < 0)
+ 		return;
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0028-connman-change-tethering-ip.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0028-connman-change-tethering-ip.patch
new file mode 100644
index 0000000..3b831ce
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0028-connman-change-tethering-ip.patch
@@ -0,0 +1,13 @@
+diff --git a/src/ippool.c b/src/ippool.c
+index 8a645da..6d61d0c 100644
+--- a/src/ippool.c
++++ b/src/ippool.c
+@@ -435,7 +435,7 @@ int __connman_ippool_init(void)
+ {
+ 	DBG("");
+ 
+-	block_16_bits = ntohl(inet_addr("192.168.0.0"));
++	block_16_bits = ntohl(inet_addr("192.168.42.0"));
+ 	block_20_bits = ntohl(inet_addr("172.16.0.0"));
+ 	block_24_bits = ntohl(inet_addr("10.0.0.0"));
+ 	subnet_mask_24 = ntohl(inet_addr("255.255.255.0"));
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0029-connman-fix-ipv6-ping.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0029-connman-fix-ipv6-ping.patch
new file mode 100644
index 0000000..0f5442a
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0029-connman-fix-ipv6-ping.patch
@@ -0,0 +1,94 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index 311c426..98a2c2e 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -67,7 +67,7 @@
+ #define INTERNETPDNINDEX 1000
+ #define INTERFACENAME 16
+ 
+-
++#define NETID 8000
+ static DBusConnection *connection;
+ 
+ static struct modem_data *modem;
+@@ -132,7 +132,6 @@ struct network_context {
+     struct connman_ipaddress *ipv6_address;
+     struct ipv6_info ipv6_info;
+     char *ipv6_nameservers;
+-    int ipv6rule;
+ };
+ struct modem_data {
+     char *path;
+@@ -174,7 +173,6 @@ struct DataCallResponse
+                                    Value <= 0 means network has either not sent a value or
+                                    sent an invalid value */
+ };
+-int rule_num;
+ #if 1
+ 
+ int get_pdnstatus_is_connected(void)
+@@ -737,7 +735,7 @@ static void set_connected(struct modem_data *modem,
+     enum connman_ipconfig_method method;
+     char *nameservers;
+     int index;
+-
++    char buffer[256];
+ 
+ 
+     index = connman_inet_ifindex(context->ifname);//context->index;
+@@ -794,12 +792,16 @@ static void set_connected(struct modem_data *modem,
+         connman_network_set_index(context->network, index);
+         connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_FIXED);
+     }
+-    if(context->ifname!=NULL && strncmp(context->ifname, "ccmni", 5)==0)
++    if(context->ifname!=NULL)
+     {
+-        rule_num=context->ifname[5]-48+1002;
+-        __connman_inet_add_fwmark_rule(rule_num,AF_INET6,0);
+-        context->ipv6rule=1;
+-        DBG("set IPv6 ip rule %d\n",rule_num);
++        sprintf(buffer,"ndc network create %d",NETID);
++        system(buffer);
++        memset(buffer, 0, sizeof(buffer));
++        sprintf(buffer,"ndc network interface add %d %s",NETID,context->ifname);
++        system(buffer);
++        memset(buffer, 0, sizeof(buffer));
++        sprintf(buffer,"ndc network default set %d",NETID);
++        system(buffer);
+     }
+ 	/* Set the nameservers */
+ 	if (context->ipv4_nameservers &&
+@@ -828,10 +830,21 @@ static void set_connected(struct modem_data *modem,
+ static void set_disconnected(struct network_context *context)
+ {
+     DBG("%s", context->path);
++    char buffer[256];
+ 
+     if (context->network)
+         connman_network_set_connected(context->network, false);
+ 
++    if(context->ifname!=NULL)
++    {
++        system("ndc network default clear ");
++        sprintf(buffer,"ndc network interface add %d %s",NETID,context->ifname);
++        system(buffer);
++        memset(buffer, 0, sizeof(buffer));
++        sprintf(buffer,"ndc network destroy %d",NETID);
++        system(buffer);
++    }
++
+     if (context) {
+         g_free(context->ipv4_nameservers);
+         context->ipv4_nameservers = NULL;
+@@ -845,11 +858,6 @@ static void set_disconnected(struct network_context *context)
+             context->ipv6_method =
+                     CONNMAN_IPCONFIG_METHOD_UNKNOWN;
+     }
+-    if(context->ipv6rule==1)
+-    {
+-        __connman_inet_del_fwmark_rule(rule_num,AF_INET6,0);
+-        context->ipv6rule=0;
+-    }
+     connman_network_set_ipv4_method(context->network, CONNMAN_IPCONFIG_METHOD_DHCP);
+     connman_network_set_ipv6_method(context->network, CONNMAN_IPCONFIG_METHOD_AUTO);
+     context->pdnStatus = ConnmanPDNStatusDisconnected;
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0030-connman-fix-crash.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0030-connman-fix-crash.patch
new file mode 100644
index 0000000..e332e4c
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0030-connman-fix-crash.patch
@@ -0,0 +1,19 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index 98a2c2e..e04ec51 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -177,9 +177,13 @@ struct DataCallResponse
+ 
+ int get_pdnstatus_is_connected(void)
+ {
+-	return (context->pdnStatus==ConnmanPDNStatusConnected);
++    if(context!=NULL)
++	    return (context->pdnStatus==ConnmanPDNStatusConnected);
++    else
++        return 0;
+ }
+ 
++
+ int get_ipv6_prefix_address(char *prefix_address,int *prefix_len)
+ {
+ 	DBG("context->ipv6_info.prefix %d context->ipv6_info.address %s",context->ipv6_info.prefix,context->ipv6_info.address);
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0031-connman-change-message-type.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0031-connman-change-message-type.patch
new file mode 100644
index 0000000..1dea507
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0031-connman-change-message-type.patch
@@ -0,0 +1,13 @@
+diff --git a/plugins/telephony.c b/plugins/telephony.c
+index e04ec51..e65d2a3 100644
+--- a/plugins/telephony.c
++++ b/plugins/telephony.c
+@@ -56,7 +56,7 @@
+ #define TELEPHONY_DATA_INTERFACE    "mtk.telephony.Data"
+ #define TELEPHONY_DATA_PATH     "/mtk/telephony/data"
+ 
+-#define SIGNAL_INTERNET_STATUS_CHANGED       "InternetStatusChanged"
++#define SIGNAL_INTERNET_STATUS_CHANGED       "default"
+ 
+ #define METHODC_ENABLE_DATA   "enableData"
+ 
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0032-connman-fix-ipv6-tethering.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0032-connman-fix-ipv6-tethering.patch
new file mode 100644
index 0000000..9f5abda
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/0032-connman-fix-ipv6-tethering.patch
@@ -0,0 +1,25 @@
+diff --git a/src/tethering.c b/src/tethering.c
+index 8544967..e358729 100644
+--- a/src/tethering.c
++++ b/src/tethering.c
+@@ -172,6 +172,7 @@ int __connman_ipv6_tethering_setup()
+ 		writeToFile("/proc/sys/net/ipv6/conf/tether/accept_ra","0");
+ 		char buffer[256];
+ 		sprintf(buffer,"ip -6 addr add %sbb/%d dev tether",prefix,prefix_len);
++        __connman_inet_add_fwmark_rule(1030, AF_INET6, 0);
+ 		system(buffer);
+ 		//write radvd conf
+ 		write_radvd_conf(prefix,prefix_len,addr_str);
+@@ -180,10 +181,12 @@ int __connman_ipv6_tethering_setup()
+ 	}else{
+ 		radvd_onoff(false);
+ 		writeToFile("/proc/sys/net/ipv6/conf/all/forwarding","0");
++        __connman_inet_del_fwmark_rule(1030, AF_INET6, 0);
+ 	}
+ }
+ 
+ 
++
+ const char *__connman_tethering_get_bridge(void)
+ {
+ 	int sk, err;
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/apmode.patch b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/apmode.patch
new file mode 100644
index 0000000..27510f1
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman/apmode.patch
@@ -0,0 +1,13 @@
+diff --git a/plugins/wifi.c b/plugins/wifi.c
+index 09869ad..84ce176 100644
+--- a/plugins/wifi.c
++++ b/plugins/wifi.c
+@@ -735,7 +735,7 @@ static void wifi_newlink(unsigned flags, unsigned change, void *user_data)
+ 			DBG("interface down");
+ 	}
+ 
+-	if ((wifi->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
++	if (((wifi->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP))||(wifi->index==connman_inet_ifindex("ap0"))) {
+ 		if (flags & IFF_LOWER_UP) {
+ 			DBG("carrier on");
+ 
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman_%.bbappend b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman_%.bbappend
new file mode 100644
index 0000000..79658eb
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/connman/connman_%.bbappend
@@ -0,0 +1,50 @@
+FILESEXTRAPATHS_append := ":${THISDIR}/${PN}"
+
+SRC_URI += "\
+            file://apmode.patch \
+            file://0004-connman-add-telephony-plugin.patch \
+            file://0005-connman-build-plugin-telephon.c.patch \
+            file://0006-connman-disable-cellular-network-from-auto-connect.patch \
+            file://0007-connman-set-ccmnix-interface-to-cellular-type.patch \
+            file://0008-connman-not-set-ip-for-ccmnix-interface.patch \
+            file://0009-connman-enable-log-for-debug.patch \
+            file://0010-connman-telephony-plugin-rename-telephony-plugin.patch \
+            file://0011-connmand-sync-code-fixed-assert-when-get-method-call.patch \
+            file://0012-connman-set-timeout-to-DBUS_TIMEOUT_INFINITE.patch \
+            file://0013-connman-not-to-save-load-config-information-for-cell.patch \
+            file://0014-connman-disable-connman-to-clear-ip-address-when-dis.patch \
+            file://0015-connman-set-ipv6-route-and-dns.patch \
+            file://0016-connman-access-null-pointer-for-some-timing.patch \
+            file://0017-connman-can_not_disconnect_after_telephony_reboot.patch \
+            file://0018-connman-service_start_after_network.patch \
+            file://0019-connman-add-ethernet-tethering.patch \
+            file://0020-connman-fix-dns-setting.patch \
+            file://0021-connman-fix-ipv6-route.patch \
+            file://0022-connman-fix-pdn-change.patch \
+            file://0023-connman-ipv6-tethering.patch \
+            file://0024-connman-telephony-pdn-disconnect.patch \
+            file://0025-connman-fix-null-pointer.patch \
+            file://0026-connman-fix-null-pointer_2.patch \
+            file://0027-connman-fix-wispr-SIGSEGV.patch \
+            file://0028-connman-change-tethering-ip.patch \
+            file://0029-connman-fix-ipv6-ping.patch \
+            file://0030-connman-fix-crash.patch \
+            file://0031-connman-change-message-type.patch \
+            file://0032-connman-fix-ipv6-tethering.patch \
+            "
+
+EXTRA_OECONF += "\
+	--enable-telephony \
+"
+
+PACKAGECONFIG[3g] = "--disable-ofono, --disable-ofono, , "
+PACKAGECONFIG[bluez] = "--disable-bluetooth, --disable-bluetooth"
+PACKAGECONFIG[wispr] = "--disable-wispr,--disable-wispr, ,"
+FILES_${PN}-client = ""
+
+do_install_append() {
+	if ${@bb.utils.contains('IMAGE_FEATURES','read-only-rootfs','true','false',d)}; then
+		sed -i -e 's:\/var\/run\/connman\/resolv.conf:..\/var\/run\/connman\/resolv.conf:g' ${D}${sysconfdir}/tmpfiles.d/connman_resolvconf.conf
+	fi
+}
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/libipsecims/libipsecims_1.0.0.bb b/meta/meta-mediatek-ivt/recipes-connectivity/libipsecims/libipsecims_1.0.0.bb
new file mode 100644
index 0000000..ab27b6f
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/libipsecims/libipsecims_1.0.0.bb
@@ -0,0 +1,24 @@
+DESCRIPTION = "new ipsec so"
+LICENSE = "MediaTekProprietary"
+LIC_FILES_CHKSUM = "file://MediatekProprietary;md5=e1696b147d49d491bcb4da1a57173fff"
+
+inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/connectivity/libipsecims"
+
+DEPENDS = "platform-libs libsncfg libcap"
+PR = "r0"
+
+S = "${WORKONSRC}/src"
+inherit pkgconfig
+
+INSANE_SKIP_${PN} += "installed-vs-shipped"
+INSANE_SKIP_${PN} += "dev-so"
+SOLIBS = ".so.*"
+SOLIBSDEV = ".so"
+FILES_${PN}="... ${libdir}/lib*${SOLIBS} ${libdir}/lib*${SOLIBSDEV} ..."
+FILES_${PN}-dev="${includedir}"
+
+do_install() {
+	make  DEST_DIR="${D}" install
+}
+
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/pingnetid/pingnetid_1.0.0.bb b/meta/meta-mediatek-ivt/recipes-connectivity/pingnetid/pingnetid_1.0.0.bb
new file mode 100644
index 0000000..db506df
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/pingnetid/pingnetid_1.0.0.bb
@@ -0,0 +1,20 @@
+DESCRIPTION = "pingnetid"
+LICENSE = "LICENSE"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"
+PR = "r0"
+
+DEPENDS += "platform-libs"
+inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/connectivity/pingnetid"
+
+do_compile() {
+ cd ${S} && make
+}
+
+INSANE_SKIP_${PN} = "ldflags"
+
+do_install() {
+	install -d ${D}${base_bindir}/
+	install -m 0755 ${S}/ping_netid ${D}${base_bindir}/
+	install -m 0755 ${S}/ping6_netid ${D}${base_bindir}/
+}
diff --git a/meta/meta-mediatek-ivt/recipes-connectivity/wpa-supplicant/wpa-supplicant_%.bbappend b/meta/meta-mediatek-ivt/recipes-connectivity/wpa-supplicant/wpa-supplicant_%.bbappend
new file mode 100644
index 0000000..1af2740
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-connectivity/wpa-supplicant/wpa-supplicant_%.bbappend
@@ -0,0 +1 @@
+PACKAGECONFIG = "openssl"
\ No newline at end of file