cf376d388b16a7ff67def625c041a79688127fbc
[platform/core/system/batterymonitor-plugins.git] / plugin / bm-bt-plugin / src / bm_bt_plugin.c
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Contact:  Sudipto Bal <sudipto.bal@samsung.com>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <glib.h>
23 #include <pkgmgr-info.h>
24 #include <aul.h>
25 #include <bluetooth.h>
26 #include <bluetooth_internal.h>
27
28 #include "bm_bt_plugin.h"
29 #include "bm_bt_util.h"
30 #include "bm_log.h"
31
32 /*
33  * To get AppID from PID - Needs to be handled by the respective framework owners:
34  * The PID might become outdated by the time data is read, which will create problems in mapping the application.
35  * Sample API's and fucntion is provided below to get app-id based on available pid.
36  * char *strAppId = NULL;
37  * pid_t nProcessId = getpid();
38  * app_manager_get_app_id(nProcessId, &strAppId);
39  */
40 static char* get_current_appid(int pid, uid_t uid)
41 {
42         ENTER;
43         _I("getting caller appid with pid=[%d], uid=[%d]", pid, uid);
44
45         int ret = 0;
46         char appid[128] = { 0, };
47         char *appid_ret = NULL;
48
49         ret = aul_app_get_appid_bypid_for_uid(pid, appid, sizeof(appid), uid);
50
51         if (ret < 0)
52                 _E("fail to get current appid ret=[%d], appid=%s\n", ret, appid);
53
54         appid_ret = strdup(appid);
55         if (appid_ret == NULL)
56                 _E("Memory Allocation Failed");
57
58         EXIT;
59         return appid_ret;
60 }
61
62 int init()
63 {
64         ENTER;
65
66 /*      Initialize the necessary paramters and callbacks if required */
67         bt_initialize();
68         bt_adapter_init_battery_monitor(NULL, NULL);
69         EXIT;
70         return BM_PLUGIN_ERROR_NONE;
71 }
72
73 int deinit()
74 {
75         ENTER;
76
77 /*      De-initialize callbacks & parameters */
78
79         EXIT;
80         return BM_PLUGIN_ERROR_NONE;
81 }
82
83 static void free_app_list(GSList *app_list)
84 {
85         GSList *l = NULL;
86         app_time_map_st2 *app_info;
87         for (l = app_list; l != NULL; l = g_slist_next(l)){
88                 app_info = (app_time_map_st2 *)(l->data);
89                 if (app_info != NULL)
90                         free(app_info->app_id);
91         }
92         g_slist_free(app_list);
93 }
94
95 int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
96 {
97         ENTER;
98
99         bm_bluetooth_st *bluetooth_record_head = NULL;
100         bm_bluetooth_st *bluetooth_record = NULL;
101         app_time_map_st2 *app_record = NULL;
102
103         bluetooth_record = (bm_bluetooth_st *)calloc(1, sizeof(bm_bluetooth_st));
104         if (bluetooth_record == NULL) {
105                 _E("Calloc Failed");
106                 return BM_PLUGIN_ERROR_OUT_OF_MEMORY;
107         }
108
109         /* Fill bluetooth record with the values of the bm_bluetooth_st */
110         bt_battery_info_s battery_data;
111         memset(&battery_data, 0, sizeof(battery_data));
112         int ret = bt_adapter_read_battery_info(&battery_data);
113
114         if (ret != 0)
115         {
116                 _E("battery info not read");
117                 free(bluetooth_record);
118                 return BM_PLUGIN_ERROR_NO_DATA;
119         }
120
121         bluetooth_record->startTime = battery_data.session_start_time;
122         bluetooth_record->stopTime = battery_data.session_end_time;
123         bluetooth_record->scanTime = battery_data.session_scan_time;
124         bluetooth_record->connectedTime = battery_data.session_connected_time;
125
126         _I("BT usage data for battery monitor");
127         _I("startTime: %ld", bluetooth_record->startTime);
128         _I("stopTime: %ld", bluetooth_record->stopTime);
129         _I("scanTime: %u", bluetooth_record->scanTime);
130         _I("connectedTime: %u", bluetooth_record->connectedTime);
131
132         /* Getting app data */
133         GSList *app_list = NULL, *l = NULL;
134         app_list = bluetooth_record->atm_list;
135         bt_battery_app_info_s *app_info = NULL;
136
137         for (l = battery_data.atm_list; l != NULL; l = g_slist_next(l)) {
138
139                 app_record = (app_time_map_st2 *)calloc(1, sizeof(app_time_map_st2));
140                 if (app_record == NULL) {
141                         _E("Calloc Failed");
142                         free_app_list(bluetooth_record->atm_list);
143                         free(bluetooth_record);
144                         return BM_PLUGIN_ERROR_OUT_OF_MEMORY;
145                 }
146
147                 app_info = (bt_battery_app_info_s *)(l->data);
148                 if (app_info == NULL) {
149                         _E("app_info is NULL");
150                         free_app_list(bluetooth_record->atm_list);
151                         free(bluetooth_record);
152                         return BM_PLUGIN_ERROR_NO_DATA;
153                 }
154
155                 /* populate application record here with usage values */
156                 app_record->app_id = get_current_appid(app_info->pid, app_info->uid);
157                 app_record->time = app_info->time;
158                 app_record->rx = app_info->rx_bytes;
159                 app_record->tx = app_info->tx_bytes;
160
161                 /* Fill the app_record with the values of the app_time_map_st2 */
162                 app_list = g_slist_append(app_list, app_record);
163         }
164
165         /*Append BT data to head node as per design doc*/
166         bluetooth_record_head = (bm_bluetooth_st *)calloc(1, sizeof(bm_bluetooth_st));
167         if (bluetooth_record_head == NULL) {
168                 _E("Calloc Failed");
169                 free_app_list(bluetooth_record->atm_list);
170                 free(bluetooth_record);
171                 return BM_PLUGIN_ERROR_OUT_OF_MEMORY;
172         }
173         bluetooth_record_head->bt_data_list = g_slist_append(
174                                 bluetooth_record_head->bt_data_list, bluetooth_record);
175         *handle = bluetooth_record_head;
176
177         EXIT;
178         return BM_PLUGIN_ERROR_NONE;
179 }
180
181 static bm_api_st bluetooth_api = {
182         .init = init,
183         .deinit = deinit,
184         .get_feature_data = get_feature_data
185 };
186
187 int plugin_init(bm_api_st **api)
188 {
189         ENTER;
190
191         *api = &bluetooth_api;
192
193         EXIT;
194         return 0;
195 }
196
197 int plugin_deinit(void)
198 {
199         ENTER;
200
201         EXIT;
202         return 0;
203 }
204
205 BM_PLUGIN_ADD(BM_PLUGIN_ID_BLE, NAME, AUTHOR, VERSION, plugin_init, plugin_deinit);