OSDN Git Service

Prevent integer overflows during GATT signing am: b335ee9496
[android-x86/system-bt.git] / utils / src / bt_utils.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18
19 /************************************************************************************
20  *
21  *  Filename:      bt_utils.c
22  *
23  *  Description:   Miscellaneous helper functions
24  *
25  *
26  ***********************************************************************************/
27
28 #define LOG_TAG "bt_utils"
29
30 #include "bt_utils.h"
31
32 #include <errno.h>
33 #include <pthread.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <sys/resource.h>
37 #include <unistd.h>
38
39 #include <utils/ThreadDefs.h>
40 #include <cutils/sched_policy.h>
41
42 // TODO(armansito): cutils/properties.h is only being used to pull-in runtime
43 // settings on Android. Remove this conditional include once we have a generic
44 // way to obtain system properties.
45 #if !defined(OS_GENERIC)
46 #include <cutils/properties.h>
47 #endif  // !defined(OS_GENERIC)
48
49 #include "bt_types.h"
50 #include "btcore/include/module.h"
51 #include "osi/include/compat.h"
52 #include "osi/include/log.h"
53
54 /*******************************************************************************
55 **  Type definitions for callback functions
56 ********************************************************************************/
57 static pthread_once_t g_DoSchedulingGroupOnce[TASK_HIGH_MAX];
58 static BOOLEAN g_DoSchedulingGroup[TASK_HIGH_MAX];
59 static pthread_mutex_t         gIdxLock;
60 static int g_TaskIdx;
61 static int g_TaskIDs[TASK_HIGH_MAX];
62 #define INVALID_TASK_ID  (-1)
63
64 static future_t *init(void) {
65   int i;
66   pthread_mutexattr_t lock_attr;
67
68   for(i = 0; i < TASK_HIGH_MAX; i++) {
69     g_DoSchedulingGroupOnce[i] = PTHREAD_ONCE_INIT;
70     g_DoSchedulingGroup[i] = TRUE;
71     g_TaskIDs[i] = INVALID_TASK_ID;
72   }
73
74   pthread_mutexattr_init(&lock_attr);
75   pthread_mutex_init(&gIdxLock, &lock_attr);
76   return NULL;
77 }
78
79 static future_t *clean_up(void) {
80   pthread_mutex_destroy(&gIdxLock);
81   return NULL;
82 }
83
84 EXPORT_SYMBOL const module_t bt_utils_module = {
85   .name = BT_UTILS_MODULE,
86   .init = init,
87   .start_up = NULL,
88   .shut_down = NULL,
89   .clean_up = clean_up,
90   .dependencies = {
91     NULL
92   }
93 };
94
95 // TODO(armansito): Remove this conditional code once there is a generic way
96 // to obtain system properties. System properties are only available on
97 // Android. Don't do the following check if this is a generic build.
98 #if !defined(OS_GENERIC)
99 /*****************************************************************************
100 **
101 ** Function        check_do_scheduling_group
102 **
103 ** Description     check if it is ok to change schedule group
104 **
105 ** Returns         void
106 **
107 *******************************************************************************/
108 static void check_do_scheduling_group(void) {
109     char buf[PROPERTY_VALUE_MAX];
110     int len = property_get("debug.sys.noschedgroups", buf, "");
111     if (len > 0) {
112         int temp;
113         if (sscanf(buf, "%d", &temp) == 1) {
114             g_DoSchedulingGroup[g_TaskIdx] = temp == 0;
115         }
116     }
117 }
118 #endif  // !defined(OS_GENERIC)
119
120 /*****************************************************************************
121 **
122 ** Function        raise_priority_a2dp
123 **
124 ** Description     Raise task priority for A2DP streaming
125 **
126 ** Returns         void
127 **
128 *******************************************************************************/
129 void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
130     int rc = 0;
131     int tid = gettid();
132     int priority = ANDROID_PRIORITY_AUDIO;
133
134     pthread_mutex_lock(&gIdxLock);
135     g_TaskIdx = high_task;
136
137     // TODO(armansito): Remove this conditional check once we find a solution
138     // for system/core on non-Android platforms.
139 #if defined(OS_GENERIC)
140     rc = -1;
141 #else  // !defined(OS_GENERIC)
142     pthread_once(&g_DoSchedulingGroupOnce[g_TaskIdx], check_do_scheduling_group);
143     if (g_DoSchedulingGroup[g_TaskIdx]) {
144         // set_sched_policy does not support tid == 0
145         rc = set_sched_policy(tid, SP_AUDIO_SYS);
146     }
147 #endif  // defined(OS_GENERIC)
148
149     g_TaskIDs[high_task] = tid;
150     pthread_mutex_unlock(&gIdxLock);
151
152     if (rc) {
153         LOG_WARN(LOG_TAG, "failed to change sched policy, tid %d, err: %d", tid, errno);
154     }
155
156     // always use urgent priority for HCI worker thread until we can adjust
157     // its prio individually. All other threads can be dynamically adjusted voa
158     // adjust_priority_a2dp()
159
160     priority = ANDROID_PRIORITY_URGENT_AUDIO;
161
162     if (setpriority(PRIO_PROCESS, tid, priority) < 0) {
163         LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid, priority);
164     }
165 }
166
167 /*****************************************************************************
168 **
169 ** Function        adjust_priority_a2dp
170 **
171 ** Description     increase the a2dp consumer task priority temporarily when start
172 **                 audio playing, to avoid overflow the audio packet queue, restore
173 **                 the a2dp consumer task priority when stop audio playing.
174 **
175 ** Returns         void
176 **
177 *******************************************************************************/
178 void adjust_priority_a2dp(int start) {
179     int priority = start ? ANDROID_PRIORITY_URGENT_AUDIO : ANDROID_PRIORITY_AUDIO;
180     int tid;
181     int i;
182
183     for (i = 0; i < TASK_HIGH_MAX; i++)
184     {
185         tid = g_TaskIDs[i];
186         if (tid != INVALID_TASK_ID)
187         {
188             if (setpriority(PRIO_PROCESS, tid, priority) < 0)
189             {
190                 LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid, priority);
191             }
192         }
193     }
194 }