Support multiple registration for HID device
[platform/core/connectivity/bluetooth-agent.git] / hid-agent / bluetooth-hid-manager.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include "bluetooth-hid-agent.h"
19 #include "bluetooth-hid-manager.h"
20
21 static GSList *sender_list;
22 static bt_hid_state_t hid_state;
23
24 static const char *__bt_hid_state2str(bt_hid_state_t state)
25 {
26         switch (state) {
27         case BT_HID_STATE_UNAVAILABLE:
28                 return "UNAVAILABLE";
29         case BT_HID_STATE_DISCONNECTED:
30                 return "DISCONNECTED";
31         case BT_HID_STATE_CONNECTING:
32                 return "CONNECTING";
33         case BT_HID_STATE_CONNECTED:
34                 return "CONNECTED";
35         case BT_HID_STATE_DISCONNECTING:
36                 return "DISCONNECTING";
37         }
38
39         return NULL;
40 }
41
42 static gboolean __bt_hid_check_for_callpath(const char *call_sender)
43 {
44         GSList *s_list = sender_list;
45         char *sender;
46
47         DBG_SECURE("sender is  = %s\n", call_sender);
48
49         if (call_sender == NULL) {
50                 ERR("Invalid Parameters");
51                 return FALSE;
52         }
53
54         /*check if the call is already registered*/
55         DBG("Checking if the call is already registered");
56         while (s_list != NULL) {
57                 sender = s_list->data;
58
59                 if (sender == NULL)
60                         break;
61
62                 if (g_strcmp0(sender, call_sender) == 0) {
63                         DBG("sender path and call path match... so return true");
64                         return TRUE;
65                 }
66
67                 s_list = s_list->next;
68         }
69
70         INFO("Sender [%s] is not registered", call_sender);
71         return FALSE;
72 }
73
74 bt_hid_agent_error_t _bt_hid_register_application(gboolean register_flag,
75                 const char *sender)
76 {
77         char *sender_name;
78
79         if (sender == NULL)
80                 return BT_HID_AGENT_ERROR_INVALID_PARAM;
81
82         if (register_flag == TRUE) {
83                 if (__bt_hid_check_for_callpath(sender) == TRUE) {
84                         ERR("Already registered [sender:%s]", sender);
85                         return BT_HID_AGENT_ERROR_ALREADY_EXIST;
86                 }
87
88                 INFO("Registered [sender:%s]", sender);
89
90                 /* add the call path to the sender list */
91                 sender_name = g_strdup(sender);
92                 sender_list = g_slist_append(sender_list, sender_name);
93         } else {
94                 /*remove the call from senders list */
95                 GSList *s_list = sender_list;
96
97                 while (s_list != NULL) {
98                         sender_name = s_list->data;
99
100                         if (sender_name == NULL)
101                                 return BT_HID_AGENT_ERROR_NOT_AVAILABLE;
102
103                         if (g_strcmp0(sender_name, sender) == 0) {
104                                 sender_list = g_slist_remove(sender_list, sender_name);
105                                 g_free(sender_name);
106
107                                 if (sender_list == NULL && hid_state == BT_HID_STATE_CONNECTED)
108                                         _bt_hid_disconnect_profile();
109
110                                 INFO("Unregistered [sender:%s]", sender);
111
112                                 return BT_HID_AGENT_ERROR_NONE;
113                         }
114                         s_list = s_list->next;
115                 }
116
117                 return BT_HID_AGENT_ERROR_NOT_AVAILABLE;
118         }
119
120         return BT_HID_AGENT_ERROR_NONE;
121 }
122
123 void _bt_hid_set_profile_state(bt_hid_state_t new_state)
124 {
125         INFO_C("state changed [%s] =>[%s]", __bt_hid_state2str(hid_state),
126                                         __bt_hid_state2str(new_state));
127         hid_state = new_state;
128
129         switch (new_state) {
130         case BT_HID_STATE_UNAVAILABLE:
131         case BT_HID_STATE_DISCONNECTED:
132                 break;
133         case BT_HID_STATE_CONNECTED:
134                 if (sender_list == NULL)
135                         _bt_hid_disconnect_profile();
136                 break;
137         case BT_HID_STATE_CONNECTING:
138         case BT_HID_STATE_DISCONNECTING:
139         default:
140                 break;
141         }
142 }
143
144 bt_hid_state_t _bt_hid_get_profile_state(void)
145 {
146         return hid_state;
147 }
148
149 const GSList* _bt_hid_get_sender_list(void)
150 {
151         return sender_list;
152 }