• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2009-2018 Realtek 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  *  Filename:      poll.c
21  *
22  *  Description:   Contains host & controller handshake implementation
23  *
24  ******************************************************************************/
25 
26 #define LOG_TAG "bt_poll"
27 
28 #include <utils/Log.h>
29 #include <signal.h>
30 #include <stdlib.h>
31 #include <time.h>
32 #include "bt_hci_bdroid.h"
33 #include "rtk_poll.h"
34 
35 /******************************************************************************
36 **  Constants & Macros
37 ******************************************************************************/
38 #ifndef BTPOLL_DBG
39 #define BTPOLL_DBG false
40 #endif
41 
42 #if (BTPOLL_DBG == true)
43 #define BTPOLLDBG(param, ...)                                                                                          \
44     {                                                                                                                  \
45         HILOGD(param, ##__VA_ARGS__);                                                                                  \
46     }
47 #else
48 #define BTPOLLDBG(param, ...)                                                                                          \
49     {                                                                                                                  \
50     }
51 #endif
52 
53 #ifndef ENABLE_BT_POLL_IN_ACTIVE_MODE
54 #define ENABLE_BT_POLL_IN_ACTIVE_MODE false
55 #endif
56 
57 #ifndef DEFAULT_POLL_IDLE_TIMEOUT
58 #define DEFAULT_POLL_IDLE_TIMEOUT 2500
59 #endif
60 
61 volatile uint32_t rtkbt_heartbeat_noack_num = 0;
62 volatile uint32_t rtkbt_heartbeat_evt_seqno = 0xffffffff;
63 
64 timed_out poll_idle_timeout;
65 
66 /******************************************************************************
67 **  Externs
68 ******************************************************************************/
69 
70 /******************************************************************************
71 **  Local type definitions
72 ******************************************************************************/
73 
74 /* Poll state */
75 enum {
76     POLL_DISABLED = 0, /* initial state */
77     POLL_ENABLED,
78 };
79 
80 /* poll control block */
81 typedef struct {
82     uint8_t state; /* poll state */
83     uint8_t timer_created;
84     timer_t timer_id;
85     uint32_t timeout_ms;
86 } bt_poll_cb_t;
87 
88 /******************************************************************************
89 **  Static variables
90 ******************************************************************************/
91 
92 static bt_poll_cb_t bt_poll_cb;
93 
94 /******************************************************************************
95 **   Poll Static Functions
96 ******************************************************************************/
97 
98 /*******************************************************************************
99 **
100 ** Function         poll_timer_stop
101 **
102 ** Description      stop timer if allowed
103 **
104 ** Returns          None
105 **
106 *******************************************************************************/
poll_timer_stop(void)107 static void poll_timer_stop(void)
108 {
109     int status;
110     struct itimerspec ts;
111 
112     HILOGI("poll_timer_stop: timer_created %d", bt_poll_cb.timer_created);
113 
114     if (bt_poll_cb.timer_created == true) {
115         ts.it_value.tv_sec = 0;
116         ts.it_value.tv_nsec = 0;
117         ts.it_interval.tv_sec = 0;
118         ts.it_interval.tv_nsec = 0;
119 
120         status = timer_settime(bt_poll_cb.timer_id, 0, &ts, 0);
121         if (status == -1) {
122             HILOGE("[STOP] Failed to set poll idle timeout");
123         }
124     }
125 }
126 
127 /*****************************************************************************
128 **   POLL Interface Functions
129 *****************************************************************************/
130 
131 /*******************************************************************************
132 **
133 ** Function        poll_init
134 **
135 ** Description     Init bt poll
136 **
137 ** Returns         None
138 **
139 *******************************************************************************/
poll_init(timed_out ptr_timeout,uint32_t timeout)140 void poll_init(timed_out ptr_timeout, uint32_t timeout)
141 {
142     (void)memset_s((void *)&bt_poll_cb, sizeof(bt_poll_cb_t), 0, sizeof(bt_poll_cb_t));
143     poll_idle_timeout = ptr_timeout;
144     bt_poll_cb.state = POLL_DISABLED;
145     bt_poll_cb.timeout_ms = timeout;
146 
147     HILOGI("poll_init: state %d, timeout %d ms,timeout=%d", bt_poll_cb.state, bt_poll_cb.timeout_ms, timeout);
148 }
149 
150 /*******************************************************************************
151 **
152 ** Function        poll_cleanup
153 **
154 ** Description     Poll clean up
155 **
156 ** Returns         None
157 **
158 *******************************************************************************/
poll_cleanup(void)159 void poll_cleanup(void)
160 {
161     HILOGI("poll_cleanup: timer_created %d", bt_poll_cb.timer_created);
162 
163     if (bt_poll_cb.timer_created == true) {
164         timer_delete(bt_poll_cb.timer_id);
165     }
166 }
167 
168 /*******************************************************************************
169 **
170 ** Function        poll_enable
171 **
172 ** Description     Enalbe/Disable poll
173 **
174 ** Returns         None
175 **
176 *******************************************************************************/
poll_enable(uint8_t turn_on)177 void poll_enable(uint8_t turn_on)
178 {
179     HILOGI("poll_enable: turn_on %d, state %d", turn_on, bt_poll_cb.state);
180 
181     if ((turn_on == true) && (bt_poll_cb.state == POLL_ENABLED)) {
182         HILOGI("poll_enable: poll is already on!!!");
183         return;
184     } else if ((turn_on == false) && (bt_poll_cb.state == POLL_DISABLED)) {
185         HILOGI("poll_enable: poll is already off!!!");
186         return;
187     }
188 
189     if (turn_on == false) {
190         poll_timer_stop();
191         bt_poll_cb.state = POLL_DISABLED;
192     } else {
193         /* start poll timer when poll_timer_flush invoked first time */
194         bt_poll_cb.state = POLL_ENABLED;
195     }
196 }
197 
198 /*******************************************************************************
199 **
200 ** Function        poll_timer_flush
201 **
202 ** Description     Called to delay notifying Bluetooth chip.
203 **                 Normally this is called when there is data to be sent
204 **                 over HCI.
205 **
206 ** Returns         None
207 **
208 *******************************************************************************/
poll_timer_flush(void)209 void poll_timer_flush(void)
210 {
211     int status;
212     struct itimerspec ts;
213     struct sigevent se;
214 
215     (void)memset_s(&se, sizeof(struct sigevent), 0, sizeof(struct sigevent));
216     BTPOLLDBG("poll_timer_flush: state %d", bt_poll_cb.state);
217 
218     if (bt_poll_cb.state != POLL_ENABLED) {
219         return;
220     }
221 
222     if (bt_poll_cb.timer_created == false) {
223         se.sigev_notify = SIGEV_THREAD;
224         se.sigev_value.sival_ptr = &bt_poll_cb.timer_id;
225         se.sigev_notify_function = poll_idle_timeout;
226         se.sigev_notify_attributes = NULL;
227 
228         status = timer_create(CLOCK_MONOTONIC, &se, &bt_poll_cb.timer_id);
229         if (status == 0) {
230             bt_poll_cb.timer_created = true;
231         }
232     }
233 #if (defined(ENABLE_BT_POLL_IN_ACTIVE_MODE) && (ENABLE_BT_POLL_IN_ACTIVE_MODE == false))
234     if (bt_poll_cb.timer_created == true) {
235         ts.it_value.tv_sec = bt_poll_cb.timeout_ms / 1000L;
236         ts.it_value.tv_nsec = 1000L * 1000L * (bt_poll_cb.timeout_ms % 1000L);
237         ts.it_interval.tv_sec = 0;
238         ts.it_interval.tv_nsec = 0;
239 
240         status = timer_settime(bt_poll_cb.timer_id, 0, &ts, 0);
241         if (status == -1) {
242             HILOGE("[Flush] Failed to set poll idle timeout");
243         }
244     }
245 #endif
246 }
247