2 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "MmsPluginConnManWrapper.h"
20 #include "MmsPluginDebug.h"
21 #include "MmsPluginHttp.h"
22 #include "net_connection.h"
23 #include "MmsPluginUtil.h"
25 #define MMS_CONTEXT_INVOKE_WAIT_TIME 30
26 #define MMS_CONNECTION_API_WAIT_TIME 420
29 static MsgCndVar g_cv;
30 static connection_h g_connection = NULL;
31 static connection_profile_h g_profile = NULL;
33 void __connection_profile_print(connection_profile_h profile)
36 char *profile_id = NULL;
37 char *profile_name = NULL;
38 char *interface_name = NULL;
39 char *ip_address = NULL;
40 char *subnet_mask = NULL;
41 char *gateway_address = NULL;
42 char *dns_address = NULL;
43 char *proxy_address = NULL;
45 char *user_name = NULL;
46 char *password = NULL;
47 char *home_url = NULL;
50 connection_profile_type_e profile_type;
51 connection_profile_state_e profile_state;
52 connection_ip_config_type_e ip_type = CONNECTION_IP_CONFIG_TYPE_NONE;
53 connection_proxy_type_e proxy_type;
54 connection_cellular_service_type_e service_type = CONNECTION_CELLULAR_SERVICE_TYPE_UNKNOWN;
55 connection_cellular_auth_type_e auth_type = CONNECTION_CELLULAR_AUTH_TYPE_NONE;
57 MSG_DEBUG("**************************************************************************************************");
58 ret = connection_profile_get_id(profile, &profile_id);
59 MSG_DEBUG("return value of connection_profile_get_id [%d]", ret);
60 MSG_SEC_INFO("Profile Id = [%s]", profile_id);
62 ret = connection_profile_get_name(profile, &profile_name);
63 MSG_SEC_INFO("Profile Name = [%s]", profile_name);
65 ret = connection_profile_get_type(profile, &profile_type);
67 if (profile_type == CONNECTION_PROFILE_TYPE_CELLULAR) {
68 MSG_SEC_INFO("Profile Type = [CELLULAR]");
69 } else if (profile_type == CONNECTION_PROFILE_TYPE_WIFI) {
70 MSG_SEC_INFO("Profile Type = [WIFI]");
71 } else if (profile_type == CONNECTION_PROFILE_TYPE_ETHERNET) {
72 MSG_SEC_INFO("Profile Type = [ETHERNET]");
73 } else if (profile_type == CONNECTION_PROFILE_TYPE_BT) {
74 MSG_SEC_INFO("Profile Type = [BT]");
76 MSG_SEC_INFO("Profile Type = Unknown [%d]", profile_type);
79 ret = connection_profile_get_network_interface_name(profile, &interface_name);
80 MSG_SEC_INFO("Profile Interface Name = [%s]", interface_name);
82 ret = connection_profile_get_state(profile, &profile_state);
83 if (profile_state == CONNECTION_PROFILE_STATE_DISCONNECTED) {
84 MSG_SEC_INFO("Profile State = [DISCONNECTED]");
85 } else if (profile_state == CONNECTION_PROFILE_STATE_ASSOCIATION) {
86 MSG_SEC_INFO("Profile State = [ASSOCIATION]");
87 } else if (profile_state == CONNECTION_PROFILE_STATE_CONFIGURATION) {
88 MSG_SEC_INFO("Profile State = [CONFIGURATION]");
89 } else if (profile_state == CONNECTION_PROFILE_STATE_CONNECTED) {
90 MSG_SEC_INFO("Profile State = [CONNECTED]");
92 MSG_SEC_INFO("Profile State = Unknown [%d]", profile_state);
95 ret = connection_profile_get_ip_config_type(profile, CONNECTION_ADDRESS_FAMILY_IPV4, &ip_type);
96 MSG_SEC_INFO("Profile Ip Config Type = [%d]", ip_type);
98 ret = connection_profile_get_ip_address(profile, CONNECTION_ADDRESS_FAMILY_IPV4, &ip_address);
99 MSG_SEC_INFO("Profile Ip Address = [%s]", ip_address);
101 ret = connection_profile_get_subnet_mask(profile, CONNECTION_ADDRESS_FAMILY_IPV4, &subnet_mask);
102 MSG_SEC_INFO("Profile Subnet Mask = [%s]", subnet_mask);
104 ret = connection_profile_get_gateway_address(profile, CONNECTION_ADDRESS_FAMILY_IPV4, &gateway_address);
105 MSG_SEC_INFO("Profile Gateway Address = [%s]", gateway_address);
107 ret = connection_profile_get_dns_address(profile, 1, CONNECTION_ADDRESS_FAMILY_IPV4, &dns_address);
108 MSG_SEC_INFO("Profile Dns Address = [%s]", dns_address);
110 ret = connection_profile_get_proxy_type(profile, &proxy_type);
111 MSG_SEC_INFO("Profile Proxy Type = [%d]", proxy_type);
113 ret = connection_profile_get_proxy_address(profile, CONNECTION_ADDRESS_FAMILY_IPV4, &proxy_address);
114 MSG_SEC_INFO("Profile Proxy Address = [%s]", proxy_address);
116 ret = connection_profile_get_cellular_service_type(profile, &service_type);
117 if (service_type == CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET) {
118 MSG_SEC_INFO("Profile Service Type = [INTERNET]");
119 } else if (service_type == CONNECTION_CELLULAR_SERVICE_TYPE_MMS) {
120 MSG_SEC_INFO("Profile Service Type = [MMS]");
121 } else if (service_type == CONNECTION_CELLULAR_SERVICE_TYPE_PREPAID_INTERNET) {
122 MSG_SEC_INFO("Profile Service Type = [PREPAID_INTERNET]");
123 } else if (service_type == CONNECTION_CELLULAR_SERVICE_TYPE_PREPAID_MMS) {
124 MSG_SEC_INFO("Profile Service Type = [PREPAID_MMS]");
125 } else if (service_type == CONNECTION_CELLULAR_SERVICE_TYPE_TETHERING) {
126 MSG_SEC_INFO("Profile Service Type = [TETHERING]");
127 } else if (service_type == CONNECTION_CELLULAR_SERVICE_TYPE_APPLICATION) {
128 MSG_SEC_INFO("Profile Service Type = [APPLICATION]");
130 MSG_SEC_INFO("Profile Service Type = [Unknown][%d]", service_type);
133 ret = connection_profile_get_cellular_apn(profile, &apn);
134 MSG_SEC_INFO("Profile Apn = [%s]", apn);
136 ret = connection_profile_get_cellular_auth_info(profile, &auth_type, &user_name, &password);
137 MSG_SEC_INFO("Profile Auth Type = [%d]", &auth_type);
138 MSG_SEC_INFO("Profile Auth Name = [%s]", &user_name);
139 MSG_SEC_INFO("Profile Auth Passward = [%s]", &password);
141 ret = connection_profile_get_cellular_home_url(profile, &home_url);
142 MSG_SEC_INFO("Profile Home Url = [%s]", home_url);
144 ret = connection_profile_is_cellular_roaming(profile, &is_roaming);
145 MSG_SEC_INFO("Profile Roaming = [%d]", is_roaming);
146 MSG_DEBUG("**************************************************************************************************");
148 MSG_FREE(profile_id);
149 MSG_FREE(profile_name);
150 MSG_FREE(interface_name);
151 MSG_FREE(ip_address);
152 MSG_FREE(subnet_mask);
153 MSG_FREE(gateway_address);
154 MSG_FREE(dns_address);
155 MSG_FREE(proxy_address);
162 static void __connection_type_changed_cb(connection_type_e type, void* user_data)
164 MSG_INFO("Type changed callback, connection type : %d", type);
167 static void __connection_ip_changed_cb(const char* ipv4_address, const char* ipv6_address, void* user_data)
169 MSG_INFO("IP changed callback, IPv4 address : %s, IPv6 address : %s",
170 ipv4_address, (ipv6_address ? ipv6_address : "NULL"));
173 static void __connection_proxy_changed_cb(const char* ipv4_address, const char* ipv6_address, void* user_data)
175 MSG_INFO("Proxy changed callback, IPv4 address : %s, IPv6 address : %s",
176 ipv4_address, (ipv6_address ? ipv6_address : "NULL"));
179 static void __connection_profile_opened_cb(connection_error_e result, void* user_data)
181 if (result == CONNECTION_ERROR_NONE || result == CONNECTION_ERROR_ALREADY_EXISTS)
182 MSG_INFO("Connection open Succeeded [%d]", result);
184 MSG_ERR("Connection open Failed, err : %d", result);
186 MmsPluginCmAgent *cmAgent = MmsPluginCmAgent::instance();
188 cmAgent->connection_profile_open_callback(result, user_data);
191 static void __connection_profile_closed_cb(connection_error_e result, void* user_data)
193 if (result == CONNECTION_ERROR_NONE)
194 MSG_INFO("Connection close Succeeded");
196 MSG_ERR("Connection close Failed, err : %d", result);
198 MmsPluginCmAgent *cmAgent = MmsPluginCmAgent::instance();
200 cmAgent->connection_profile_close_callback(result, user_data);
204 void __connection_profile_state_changed_cb(connection_profile_state_e state, void* user_data)
206 MmsPluginCmAgent *cmAgent = MmsPluginCmAgent::instance();
208 cmAgent->connection_profile_state_changed_cb(state, user_data);
211 static gboolean __connection_create(void *pVoid)
216 bool *ret_val = (bool *)pVoid;
219 MSG_INFO("connection already exist");
222 int err = connection_create(&g_connection);
224 if (CONNECTION_ERROR_NONE == err && g_connection) {
225 connection_cellular_state_e cellular_state;
226 connection_type_e net_state;
228 err = connection_get_cellular_state(g_connection, &cellular_state);
230 err = connection_get_type(g_connection, &net_state);
232 if (cellular_state == CONNECTION_CELLULAR_STATE_AVAILABLE
233 || cellular_state == CONNECTION_CELLULAR_STATE_CONNECTED) {
234 MSG_INFO("Client registration success [%p], cellular_state [%d], net_state [%d]", g_connection, cellular_state, net_state);
236 err = connection_set_type_changed_cb(g_connection, __connection_type_changed_cb, NULL);
238 err = connection_set_ip_address_changed_cb(g_connection, __connection_ip_changed_cb, NULL);
240 err = connection_set_proxy_address_changed_cb(g_connection, __connection_proxy_changed_cb, NULL);
244 MSG_INFO("Client registration Failed, cellular state [%d], net_state [%d]", cellular_state, net_state);
245 connection_destroy(g_connection);
249 MSG_WARN("Client registration failed %d", err);
261 static gboolean __connection_destroy(void *pVoid)
267 if (g_connection != NULL) {
268 rv = connection_destroy(g_connection);
270 MSG_INFO("connection destory !!");
272 MSG_ERR("Cannot connection destroy : Handle is NULL");
273 rv = CONNECTION_ERROR_INVALID_OPERATION;
276 MSG_DEBUG("return value of connection destroy [%d]", rv);
282 static gboolean __connection_profile_open(void *pVoid)
286 int netOpenResult = MSG_CM_ERR_NONE;
287 int *ret_val = (int *)pVoid;
291 MSG_WARN("connection profile Already exist!!, It will destroy");
292 connection_profile_unset_state_changed_cb(g_profile);
293 connection_profile_destroy(g_profile);
297 err = connection_get_default_cellular_service_profile(g_connection, CONNECTION_CELLULAR_SERVICE_TYPE_MMS, &g_profile);
299 if (err != CONNECTION_ERROR_NONE) {
300 MSG_ERR("connection_get_default_cellular_service_profile Failed!! [%d]", err);
301 netOpenResult = MSG_CM_ERR_UNKNOWN;
303 err = connection_profile_set_state_changed_cb(g_profile, __connection_profile_state_changed_cb, g_profile);
305 if (connection_open_profile(g_connection, g_profile, __connection_profile_opened_cb, NULL) != CONNECTION_ERROR_NONE) {
306 MSG_ERR("Connection open Failed!!");
307 netOpenResult = MSG_CM_ERR_UNKNOWN;
312 *ret_val = netOpenResult;
313 MSG_DEBUG("[%d]", netOpenResult);
321 static gboolean __connection_profile_close(void *pVoid)
325 int netOpenResult = MSG_CM_ERR_NONE;
327 int *ret_val = (int *)pVoid;
330 connection_profile_unset_state_changed_cb(g_profile);
332 if (connection_close_profile(g_connection, g_profile, __connection_profile_closed_cb, NULL) != CONNECTION_ERROR_NONE) {
333 MSG_ERR("Connection close Failed!!");
334 netOpenResult = MSG_CM_ERR_UNKNOWN;
337 connection_profile_destroy(g_profile);
342 *ret_val = netOpenResult;
351 void context_invoke_end_cb(gpointer data)
355 MSG_INFO("@@ SIGNAL @@");
363 * Network api should run at g_main_loop to receive callback
365 void context_invoke(GSourceFunc func, void *ret)
373 g_main_context_invoke_full(NULL, G_PRIORITY_DEFAULT, func, ret, context_invoke_end_cb);
375 MSG_INFO("@@ WAIT @@");
377 time_ret = g_cv.timedwait(g_mx.pMsgMutex(), MMS_CONTEXT_INVOKE_WAIT_TIME);
381 if (time_ret == ETIMEDOUT) {
382 MSG_INFO("@@ WAKE by timeout@@");
384 MSG_INFO("@@ WAKE by signal@@");
390 MmsPluginCmAgent *MmsPluginCmAgent::pInstance = NULL;
392 MmsPluginCmAgent *MmsPluginCmAgent::instance()
395 pInstance = new MmsPluginCmAgent();
400 MmsPluginCmAgent::MmsPluginCmAgent()
405 waitProfileOpen = false;
408 interface_name = NULL;
409 proxy_address = NULL;
410 dns_address_list = NULL;
414 MmsPluginCmAgent::~MmsPluginCmAgent()
417 MSG_FREE(interface_name);
418 MSG_FREE(proxy_address);
419 MSG_FREE(dns_address_list);
422 bool MmsPluginCmAgent::open()
426 int netOpenResult = MSG_CM_ERR_NONE;
427 int bConnection = false;
431 /* create connection */
432 context_invoke(__connection_create, &bConnection);
434 if (bConnection == false || g_connection == NULL) {
435 MSG_ERR("Failed __connection_create");
440 MSG_WARN("connection profile already exist");
441 /* TODO:: get data; */
445 waitProfileOpen = true;
447 context_invoke(__connection_profile_open, &netOpenResult);
449 if (netOpenResult != MSG_CM_ERR_NONE) {
450 MSG_ERR("Failed __connection_profile_open. [%d]", netOpenResult);
454 MSG_INFO("## WAITING UNTIL __connection_profile_state CONNECT. ##");
456 time_ret = cv.timedwait(mx.pMsgMutex(), MMS_CONNECTION_API_WAIT_TIME); /* isCmOpened will changed by processCBdatas */
458 if (time_ret == ETIMEDOUT) {
459 MSG_WARN("## WAKE by timeout ##");
461 MSG_INFO("## WAKE by SIGNAL ##");
464 if (isCmOpened == false) {
475 context_invoke(__connection_profile_close, NULL);
476 context_invoke(__connection_destroy, NULL);
483 void MmsPluginCmAgent::close()
489 int netOpenResult = MSG_CM_ERR_NONE;
494 if (g_profile == NULL) {
495 MSG_INFO("connection profile is NULL");
499 context_invoke(__connection_profile_close, &netOpenResult);
501 if (netOpenResult != MSG_CM_ERR_NONE) {
502 MSG_ERR("Failed __connection_profile_close. [%d]", netOpenResult);
506 MSG_INFO("## WAITING UNTIL connection_profile_close_callback ##");
508 time_ret = cv.timedwait(mx.pMsgMutex(), MMS_CONNECTION_API_WAIT_TIME);
510 if (time_ret == ETIMEDOUT) {
511 MSG_WARN("## WAKE by timeout ##");
513 MSG_INFO("## WAKE by SIGNAL ##");
519 context_invoke(__connection_destroy, NULL);
524 MSG_FREE(this->home_url);
525 MSG_FREE(this->interface_name);
526 MSG_FREE(this->proxy_address);
527 MSG_FREE(this->dns_address_list);
534 /* profile open callback */
535 void MmsPluginCmAgent::connection_profile_open_callback(connection_error_e result, void* user_data)
539 connection_cellular_state_e state;
540 connection_profile_h profile = NULL;
541 connection_profile_state_e profile_state;
542 int err = CONNECTION_ERROR_NONE;
544 if (result == CONNECTION_ERROR_NONE || result == CONNECTION_ERROR_ALREADY_EXISTS) {
545 err = connection_get_cellular_state(g_connection, &state);
547 MSG_INFO("connection_get_cellular_state ret [%d], state [%d]", err, state);
549 err = connection_get_default_cellular_service_profile(g_connection, CONNECTION_CELLULAR_SERVICE_TYPE_MMS, &profile);
550 if (err != CONNECTION_ERROR_NONE || profile == NULL) {
551 MSG_ERR("Failed connection_get_default_cellular_service_profile. err [%d], profile [%p]", err, profile);
552 goto __SIGNAL_RETURN;
555 err = connection_profile_get_state(profile, &profile_state);
557 MSG_DEBUG("profile state [%d]", profile_state);
559 if (profile_state == CONNECTION_PROFILE_STATE_CONNECTED && waitProfileOpen == true) {
560 __connection_profile_print(profile);
562 MSG_FREE(this->home_url);
563 MSG_FREE(this->interface_name);
564 MSG_FREE(this->proxy_address);
565 MSG_FREE(this->dns_address_list);
567 err = connection_profile_get_cellular_home_url(profile, &this->home_url);
568 if (err != CONNECTION_ERROR_NONE) {
569 MSG_ERR("Failed connection_profile_get_cellular_home_url");
572 err = connection_profile_get_network_interface_name(profile, &this->interface_name);
573 if (err != CONNECTION_ERROR_NONE) {
574 MSG_ERR("Failed connection_profile_get_cellular_home_url");
577 err = connection_profile_get_proxy_address(profile, CONNECTION_ADDRESS_FAMILY_IPV4, &this->proxy_address);
578 if (err != CONNECTION_ERROR_NONE) {
579 MSG_ERR("Failed connection_profile_get_cellular_home_url");
584 goto __SIGNAL_RETURN; /* open success */
587 goto __NO_SIGNAL_RETURN; /* Just open success */
590 MSG_ERR("connection open profile Failed!! [%d]", result);
592 goto __SIGNAL_RETURN;
595 __NO_SIGNAL_RETURN: /* Just Open */
597 connection_profile_destroy(profile);
601 __SIGNAL_RETURN: /* Error or Already connected */
603 connection_profile_destroy(profile);
605 if (waitProfileOpen == true) { /* open fail */
606 waitProfileOpen = false;
607 MSG_INFO("## SIGNAL ##");
615 void MmsPluginCmAgent::connection_profile_close_callback(connection_error_e result, void* user_data)
618 MSG_INFO("result [%d]", result);
619 MSG_INFO("## SIGNAL ##");
625 void MmsPluginCmAgent::connection_profile_state_changed_cb(connection_profile_state_e state, void* user_data)
632 connection_profile_h profile = NULL;
634 MSG_INFO("state [%d]", state);
636 if (state != CONNECTION_PROFILE_STATE_CONNECTED) {
638 goto __NO_SIGNAL_RETURN;
641 if (isCmOpened == true) {
642 MSG_INFO("already opened");
643 goto __SIGNAL_RETURN;
646 /* Should get profile to get latest profile info*/
647 err = connection_get_default_cellular_service_profile(g_connection, CONNECTION_CELLULAR_SERVICE_TYPE_MMS, &profile);
648 if (err != CONNECTION_ERROR_NONE || profile == NULL) {
649 MSG_ERR("Failed connection_get_default_cellular_service_profile. err [%d], profile [%p]", err, profile);
650 goto __SIGNAL_RETURN;
653 if (state == CONNECTION_PROFILE_STATE_CONNECTED) {
654 __connection_profile_print(profile);
656 MSG_FREE(this->home_url);
657 MSG_FREE(this->interface_name);
658 MSG_FREE(this->proxy_address);
659 MSG_FREE(this->dns_address_list);
661 err = connection_profile_get_cellular_home_url(profile, &this->home_url);
662 if (err != CONNECTION_ERROR_NONE) {
663 MSG_ERR("Failed connection_profile_get_cellular_home_url");
666 err = connection_profile_get_network_interface_name(profile, &this->interface_name);
667 if (err != CONNECTION_ERROR_NONE) {
668 MSG_ERR("Failed connection_profile_get_cellular_home_url");
671 err = connection_profile_get_proxy_address(profile, CONNECTION_ADDRESS_FAMILY_IPV4, &this->proxy_address);
672 if (err != CONNECTION_ERROR_NONE) {
673 MSG_ERR("Failed connection_profile_get_cellular_home_url");
677 goto __SIGNAL_RETURN;
680 __NO_SIGNAL_RETURN: /* Default */
684 __SIGNAL_RETURN: /* Error or connected */
686 connection_profile_destroy(profile);
688 if (waitProfileOpen == true) {
689 waitProfileOpen = false;
690 MSG_INFO("## SIGNAL ##");
697 bool MmsPluginCmAgent::getInterfaceName(const char **deviceName)
702 if (deviceName == NULL)
705 *deviceName = interface_name;
710 bool MmsPluginCmAgent::getHomeUrl(const char **homeURL)
724 bool MmsPluginCmAgent::getProxyAddr(const char **proxyAddr)
729 if (proxyAddr == NULL)
732 *proxyAddr = proxy_address;
738 bool MmsPluginCmAgent::getDnsAddrList(const char **dnsAddrList)
743 if (dnsAddrList == NULL)
746 *dnsAddrList = dns_address_list;