Update AG and HF agent codes from wearable product
[platform/core/connectivity/bluetooth-agent.git] / ag-agent / bluetooth-ag-handler.c
index 2a761d3..82270a8 100644 (file)
  * limitations under the License.
  *
  */
+#include <stdbool.h>
+#include <bundle_internal.h>
+#include <bluetooth.h>
+#include <bluetooth_internal.h>
 #include "bluetooth-ag-agent.h"
 #include "bluetooth-ag-handler.h"
 #include "vconf.h"
 #include "vconf-keys.h"
+#include <syspopup_caller.h>
 
 extern bt_ag_status_t ag;
 extern GSList *active_devices;
@@ -549,6 +554,7 @@ static int __bt_headset_set_gain(bt_ag_info_t *hs, uint16_t gain, char type)
                }
                property = "SpeakerGain";
                slconn->speaker_gain = gain;
+               _bt_ag_agent_set_last_speaker_gain(gain);
                break;
        case BT_HFP_MICROPHONE_GAIN:
                if (slconn->microphone_gain == gain) {
@@ -895,6 +901,11 @@ int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf)
        else
                enable = TRUE;
 
+       if (remote_dev_path)
+               g_free(remote_dev_path);
+
+       remote_dev_path = g_strdup(hs->path);
+
        _bt_hfp_voice_dial_request(enable, hs);
 
        slconn->is_voice_recognition_running = enable;
@@ -905,7 +916,7 @@ int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf)
 int _bt_hfp_indicators_activation(bt_ag_info_t *hs, const char *buf)
 {
        if (strlen(buf) < 7) {
-               printf("Invalid indicator activation request\n");
+               ERR("Invalid indicator activation request\n");
                return -EINVAL;
        }
 
@@ -978,10 +989,106 @@ int _bt_select_phonebook_memory_response(void *t_device,
        return _bt_ag_send_response(t_device, err);
 }
 
-int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
+static char *__bt_get_remote_device_name(const char *device_path)
+{
+       char *name = NULL;
+       GVariant *value;
+       GVariant *result = NULL;
+       GError *err = NULL;
+       GDBusProxy *device_proxy;
+       GDBusConnection *conn;
+
+       if (device_path == NULL)
+               return NULL;
+
+       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+
+       INFO_SECURE("Device_path %s", device_path);
+       device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+                                               NULL, "org.bluez",
+                                               device_path,
+                                               BT_PROPERTIES_INTERFACE,
+                                               NULL, &err);
+
+       result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
+                       g_variant_new("(s)", "org.bluez.Device1"),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       20, NULL,
+                       &err);
+       if (err) {
+               ERR("DBus Error : %s", err->message);
+               g_clear_error(&err);
+               return NULL;
+       }
+       if (result == NULL) {
+               ERR("g_dbus_proxy_call_sync function return NULL");
+               return NULL;
+       }
+       g_variant_get(result, "(@a{sv})", &value);
+
+       if (value) {
+               GVariant *temp_value = g_variant_lookup_value(value, "Alias",
+                       G_VARIANT_TYPE_STRING);
+               g_variant_get(temp_value, "(s)", &name);
+               if (temp_value)
+                       g_variant_unref(temp_value);
+
+               if (name != NULL)
+                       INFO_SECURE("Alias Name [%s]", name);
+               else {
+                       temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
+                       g_variant_get(temp_value, "s", &name);
+                       if (temp_value)
+                               g_variant_unref(temp_value);
+                       INFO_SECURE("Name = %s", name);
+               }
+       }
+       g_variant_unref(result);
+       g_object_unref(device_proxy);
+       return name;
+}
+
+int _bt_launch_pbap_popup(const char *device_name,
+                                                       const char *agent_path)
 {
-       if (strlen(buf) < 8)
-               return -EINVAL;
+       int ret;
+       bundle *b;
+       char event_str[50 + 1];
+
+       b = bundle_create();
+       if (!b) {
+               ERR("Launching system popup failed");
+               return -1;
+       }
+
+       bundle_add(b, "device-name", device_name);
+       bundle_add(b, "agent-path", agent_path);
+
+       g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
+
+       bundle_add(b, "event-type", event_str);
+
+       ret = syspopup_launch("bt-syspopup", b);
+       if (0 > ret) {
+               ERR("Popup launch failed... %d", ret);
+       }
+
+       bundle_free(b);
+
+       INFO("_bt_agent_launch_system_popup");
+       return 0;
+}
+
+int _bt_hfp_select_phonebook_memory_status_reply(bt_ag_info_t *hs)
+{
+       const char *buf = hs->at_pbap_buf;
+       if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED
+               || hs->pbap_trusted == BT_AG_FEATURE_PBAP_CANCEL) {
+               INFO("Doesnot have Access reply with error");
+               _bt_select_phonebook_memory_response(hs,
+                       HFP_STATE_MNGR_ERR_NOT_ALLOWED);
+               return 0;
+       }
 
        if (buf[7] == '?') {
                _bt_hfp_select_phonebook_memory_status(hs);
@@ -994,10 +1101,60 @@ int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
                        return 0;
                }
                _bt_hfp_select_phonebook_memory(hs, &buf[8]);
-               return 0;
        }
 
-       return -EINVAL;
+       return 0;
+}
+
+int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
+{
+       if (strlen(buf) < 8)
+               return -EINVAL;
+       INFO("Pbap_trusted %d", hs->pbap_trusted);
+       if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_SHOW_AUTHORIZATION
+               || hs->pbap_trusted == BT_AG_FEATURE_PBAP_CANCEL) {
+               strncpy(hs->at_pbap_buf, buf, sizeof(hs->at_pbap_buf) - 1);
+               /* Adding Popup here */
+               int trust = 0;
+               bt_initialize();
+               int err = bt_device_get_profile_trusted(hs->remote_addr, 1, &trust);
+               if (err != TIZEN_ERROR_NONE) {
+                       INFO("Show authorization popup %d Error %d", trust, err);
+                       char *name = __bt_get_remote_device_name(hs->path);
+                       INFO_SECURE("remote device name %s", name);
+                       _bt_launch_pbap_popup(name,
+                               BT_AG_AGENT_OBJECT_PATH);
+                       return 0;
+               }
+               if (trust == 0) {
+                       INFO("This device has been marked as blocked");
+                       hs->pbap_trusted = BT_AG_FEATURE_PBAP_BLOCKED;
+                       return -EACCES;
+               } else
+                       hs->pbap_trusted = BT_AG_FEATURE_PBAP_ALLOWED;
+       }
+       if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_ALLOWED) {
+               INFO("Authorized from PBAP");
+               if (buf[7] == '?') {
+                       _bt_hfp_select_phonebook_memory_status(hs);
+                       return 0;
+               }
+
+               if (buf[7] == '=') {
+                       if (buf[8] == '?') {
+                               _bt_hfp_select_phonebook_memory_list(hs);
+                               return 0;
+                       }
+                       _bt_hfp_select_phonebook_memory(hs, &buf[8]);
+                       return 0;
+               }
+       } else if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED) {
+               INFO("Device is blocked");
+               /* Reply with Error */
+               return -EACCES;
+       }
+
+       return 0;
 }
 
 int _bt_read_phonebook_entries_list_response(void *t_device,
@@ -1021,7 +1178,7 @@ int _bt_read_phonebook_entries_list_response(void *t_device,
        }
 
        if (used < 1)
-               index = 0;
+               used = 1;
 
        send_err = _bt_ag_send_at(hs, "\r\n+CPBR: (%d-%d),%d,%d\r\n",
                        index, used, number_length, name_length);
@@ -1057,8 +1214,31 @@ int _bt_read_phonebook_entries_indicator(const char *name, const char *number,
        return 0;
 }
 
+int _bt_read_phonebook_entries_indicator_by_name(const char *name,
+                                       const char *number, uint32_t handle)
+{
+       int type = 129;
+       const char *pos = NULL;
+
+       pos = number;
+       while (*pos == ' ' || *pos == '\t')
+               pos++;
+
+       /* 145 means international access code, otherwise 129 is used */
+       if (*pos == '+')
+               type = 145;
+
+       _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+               "\r\n+CPBF: %d,\"%s\",%d,\"%s\"\r\n",
+               handle, number, type, name);
+       return 0;
+}
+
 int _bt_hfp_read_pb_entries(bt_ag_info_t *hs, const char *buf)
 {
+       if (hs->pbap_trusted != BT_AG_FEATURE_PBAP_ALLOWED)
+               return -EACCES;
+
        if (strlen(buf) < 8)
                return -EINVAL;
 
@@ -1097,6 +1277,10 @@ int _bt_find_phonebook_entries_status_indicator(uint32_t number_length,
 
 int _bt_hfp_find_pb_entires(bt_ag_info_t *hs, const char *buf)
 {
+       /* Check if Contact access is permitted or not */
+       if (hs->pbap_trusted != BT_AG_FEATURE_PBAP_ALLOWED)
+               return -EACCES;
+
        if (strlen(buf) < 8)
                return -EINVAL;
 
@@ -1195,7 +1379,8 @@ int _bt_hfp_apl_command(bt_ag_info_t *hs, const char *buf)
 {
        DBG("Got Apple command: %s", buf);
 
-       return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
+       /*we don't support XAPL commands*/
+       return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
 }
 
 /* convert signal strength to a RSSI level */