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