blob: ac0a765c60b65734abadde52c52b16bc76884cd2 [file] [log] [blame]
ANT-Shaned494ba32013-11-15 11:19:05 -07001/*
2 * ANT Stack
3 *
4 * Copyright 2011 Dynastream Innovations
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* FILE NAME: ant_native_chardev.c
21*
22* BRIEF:
23* This file provides the VFS implementation of ant_native.h
24* VFS could be Character Device, TTY, etc.
25*
26*
27\******************************************************************************/
28
29#include <errno.h>
30#include <fcntl.h> /* for open() */
31#include <linux/ioctl.h> /* For hard reset */
32#include <pthread.h>
33#include <dlfcn.h> /* needed for runtime dll loading. */
34#include <stdint.h> /* for uint64_t */
35#include <sys/eventfd.h> /* For eventfd() */
36#include <unistd.h> /* for read(), write(), and close() */
Kiran Kelageri0736d4b2015-08-04 14:49:15 -070037#include <string.h>
ANT-Shaned494ba32013-11-15 11:19:05 -070038
39#include "ant_types.h"
40#include "ant_native.h"
41#include "ant_version.h"
42
43#include "antradio_power.h"
44#include "ant_rx_chardev.h"
45#include "ant_hci_defines.h"
46#include "ant_log.h"
Kiran Kelageri0736d4b2015-08-04 14:49:15 -070047#include "bt_vendor_qcom.h" /* used by qualcomms code to call into libbt-vendor.so */
ANT-Shaned494ba32013-11-15 11:19:05 -070048#include <cutils/properties.h> /* used by qualcomms additions for logging. */
49// The following functions are dummy implementations of the callbacks required by libbt-vendor.
Michael Bestasb17c84b2018-09-04 20:13:05 +030050static void vendor_fwcfg_cb(bt_vendor_op_result_t result __unused) {
ANT-Shaned494ba32013-11-15 11:19:05 -070051}
Michael Bestasb17c84b2018-09-04 20:13:05 +030052static void vendor_scocfg_cb(bt_vendor_op_result_t result __unused) {
ANT-Shaned494ba32013-11-15 11:19:05 -070053}
Michael Bestasb17c84b2018-09-04 20:13:05 +030054static void vendor_lpm_vnd_cb(bt_vendor_op_result_t result __unused) {
ANT-Shaned494ba32013-11-15 11:19:05 -070055}
Michael Bestasb17c84b2018-09-04 20:13:05 +030056static void* vendor_alloc(int size __unused) {
ANT-Shaned494ba32013-11-15 11:19:05 -070057 return NULL;
58}
Michael Bestasb17c84b2018-09-04 20:13:05 +030059static void vendor_dealloc(void *p_buf __unused) {
ANT-Shaned494ba32013-11-15 11:19:05 -070060}
Michael Bestasb17c84b2018-09-04 20:13:05 +030061static uint8_t vendor_xmit_cb(uint16_t opcode __unused, void *p_buf __unused,
62 tINT_CMD_CBACK p_cback __unused) {
ANT-Shaned494ba32013-11-15 11:19:05 -070063 return 0;
64}
Michael Bestasb17c84b2018-09-04 20:13:05 +030065static void vendor_epilog_cb(bt_vendor_op_result_t result __unused) {
ANT-Shaned494ba32013-11-15 11:19:05 -070066}
67
68// This struct is used to regsiter the dummy callbacks with libbt-vendor
69bt_vendor_interface_t *vendor_interface=NULL;
70static const bt_vendor_callbacks_t vendor_callbacks = {
71 sizeof(bt_vendor_callbacks_t),
72 vendor_fwcfg_cb,
73 vendor_scocfg_cb,
74 vendor_lpm_vnd_cb,
75 vendor_alloc,
76 vendor_dealloc,
77 vendor_xmit_cb,
78 vendor_epilog_cb
79};
80
81#if ANT_HCI_SIZE_SIZE > 1
82#include "ant_utils.h" // Put HCI Size value across multiple bytes
83#endif
84
85#define MESG_BROADCAST_DATA_ID ((ANT_U8)0x4E)
86#define MESG_ACKNOWLEDGED_DATA_ID ((ANT_U8)0x4F)
87#define MESG_BURST_DATA_ID ((ANT_U8)0x50)
88#define MESG_EXT_BROADCAST_DATA_ID ((ANT_U8)0x5D)
89#define MESG_EXT_ACKNOWLEDGED_DATA_ID ((ANT_U8)0x5E)
90#define MESG_EXT_BURST_DATA_ID ((ANT_U8)0x5F)
91#define MESG_ADV_BURST_DATA_ID ((ANT_U8)0x72)
92
93static ant_rx_thread_info_t stRxThreadInfo;
94static pthread_mutex_t stEnabledStatusLock = PTHREAD_MUTEX_INITIALIZER;
95static pthread_mutex_t stFlowControlLock = PTHREAD_MUTEX_INITIALIZER;
96static pthread_cond_t stFlowControlCond = PTHREAD_COND_INITIALIZER;
97ANTNativeANTStateCb g_fnStateCallback;
98
99static const uint64_t EVENT_FD_PLUS_ONE = 1L;
100
101static void ant_channel_init(ant_channel_info_t *pstChnlInfo, const char *pcCharDevName);
102
103////////////////////////////////////////////////////////////////////
104// ant_init
105//
106// Initialises the native environment.
107//
108// Parameters:
109// -
110//
111// Returns:
112// ANT_STATUS_SUCCESS if intialize completed, else ANT_STATUS_FAILED
113//
114// Psuedocode:
115/*
116Set variables to defaults
117Initialise each supported path to chip
118Setup eventfd object.
119RESULT = ANT_STATUS_SUCCESS if no problems else ANT_STATUS_FAILED
120*/
121////////////////////////////////////////////////////////////////////
122ANTStatus ant_init(void)
123{
124 ANTStatus status = ANT_STATUS_FAILED;
125 ANT_FUNC_START();
126
127 stRxThreadInfo.stRxThread = 0;
128 stRxThreadInfo.ucRunThread = 0;
129 stRxThreadInfo.ucChipResetting = 0;
130 stRxThreadInfo.pstEnabledStatusLock = &stEnabledStatusLock;
131 g_fnStateCallback = 0;
132
133#ifdef ANT_DEVICE_NAME // Single transport path
134 ant_channel_init(&stRxThreadInfo.astChannels[SINGLE_CHANNEL], ANT_DEVICE_NAME);
135#else // Separate data/command paths
136 ant_channel_init(&stRxThreadInfo.astChannels[COMMAND_CHANNEL], ANT_COMMANDS_DEVICE_NAME);
137 ant_channel_init(&stRxThreadInfo.astChannels[DATA_CHANNEL], ANT_DATA_DEVICE_NAME);
138#endif // Separate data/command paths
139
140 // Make the eventfd. Want it non blocking so that we can easily reset it by reading.
141 stRxThreadInfo.iRxShutdownEventFd = eventfd(0, EFD_NONBLOCK);
142
143 // Check for error case
144 if(stRxThreadInfo.iRxShutdownEventFd == -1)
145 {
146 ANT_ERROR("ANT init failed. Could not create event fd. Reason: %s", strerror(errno));
147 } else {
148 status = ANT_STATUS_SUCCESS;
149 }
150
151 ANT_FUNC_END();
152 return status;
153}
154
155////////////////////////////////////////////////////////////////////
156// ant_deinit
157//
158// clean up eventfd object
159//
160// Parameters:
161// -
162//
163// Returns:
164// ANT_STATUS_SUCCESS
165//
166// Psuedocode:
167/*
168RESULT = SUCCESS
169*/
170////////////////////////////////////////////////////////////////////
171ANTStatus ant_deinit(void)
172{
173 ANTStatus result_status = ANT_STATUS_FAILED;
174 ANT_FUNC_START();
175
176 if(close(stRxThreadInfo.iRxShutdownEventFd) < 0)
177 {
178 ANT_ERROR("Could not close eventfd in deinit. Reason: %s", strerror(errno));
179 } else {
180 result_status = ANT_STATUS_SUCCESS;
181 }
182
183 ANT_FUNC_END();
184 return result_status;
185}
186
187
188////////////////////////////////////////////////////////////////////
189// ant_enable_radio
190//
191// Powers on the ANT part and initialises the transport to the chip.
192// Changes occur in part implementing ant_enable() call
193//
194// Parameters:
195// -
196//
197// Returns:
198// Success:
199// ANT_STATUS_SUCCESS
200// Failures:
201// ANT_STATUS_TRANSPORT_INIT_ERR if could not enable
202// ANT_STATUS_FAILED if failed to get mutex or init rx thread
203//
204// Psuedocode:
205/*
206LOCK enable_LOCK
207 State callback: STATE = ENABLING
208 ant enable
209 IF ant_enable success
210 State callback: STATE = ENABLED
211 RESULT = SUCCESS
212 ELSE
213 ant disable
214 State callback: STATE = Current state
215 RESULT = FAILURE
216 ENDIF
217UNLOCK
218*/
219////////////////////////////////////////////////////////////////////
220ANTStatus ant_enable_radio(void)
221{
222 int iLockResult;
223 ANTStatus result_status = ANT_STATUS_FAILED;
224 ANT_FUNC_START();
225
226 ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
227 iLockResult = pthread_mutex_lock(&stEnabledStatusLock);
228 if(iLockResult) {
229 ANT_ERROR("enable failed to get state lock: %s", strerror(iLockResult));
230 goto out;
231 }
232 ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);
233
234 if (g_fnStateCallback) {
235 g_fnStateCallback(RADIO_STATUS_ENABLING);
236 }
237
238 if (ant_enable() < 0) {
239 ANT_ERROR("ant enable failed: %s", strerror(errno));
240
241 ant_disable();
242
243 if (g_fnStateCallback) {
244 g_fnStateCallback(ant_radio_enabled_status());
245 }
246 } else {
247 if (g_fnStateCallback) {
248 g_fnStateCallback(RADIO_STATUS_ENABLED);
249 }
250
251 result_status = ANT_STATUS_SUCCESS;
252 }
253
254 ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
255 pthread_mutex_unlock(&stEnabledStatusLock);
256 ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
257
258out:
259 ANT_FUNC_END();
260 return result_status;
261}
262
263////////////////////////////////////////////////////////////////////
264// ant_radio_hard_reset
265//
266// IF SUPPORTED triggers a hard reset of the chip providing ANT functionality.
267//
268// Parameters:
269// -
270//
271// Returns:
272// Success:
273// ANT_STATUS_SUCCESS
274// Failures:
275// ANT_STATUS_NOT_SUPPORTED if the chip can't hard reset
276// ANT_STATUS_FAILED if failed to get mutex or enable
277//
278// Psuedocode:
279/*
280IF Hard Reset not supported
281 RESULT = NOT SUPPORTED
282ELSE
283 LOCK enable_LOCK
284 IF Lock failed
285 RESULT = FAILED
286 ELSE
287 Set Flag Rx thread that chip is resetting
288 FOR each path to chip
289 Send Reset IOCTL to path
290 ENDFOR
291 ant disable
292 ant enable
293 IF ant_enable success
294 State callback: STATE = RESET
295 RESULT = SUCCESS
296 ELSE
297 State callback: STATE = DISABLED
298 RESULT = FAILURE
299 ENDIF
300 Clear Flag Rx thread that chip is resetting
301 UNLOCK
302ENDIF
303*/
304////////////////////////////////////////////////////////////////////
305ANTStatus ant_radio_hard_reset(void)
306{
307 ANTStatus result_status = ANT_STATUS_NOT_SUPPORTED;
308 ANT_FUNC_START();
309
310#ifdef ANT_IOCTL_RESET
311 ant_channel_type eChannel;
312 int iLockResult;
313
314 result_status = ANT_STATUS_FAILED;
315
316 ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
317 iLockResult = pthread_mutex_lock(&stEnabledStatusLock);
318 if(iLockResult) {
319 ANT_ERROR("enable failed to get state lock: %s", strerror(iLockResult));
320 goto out;
321 }
322 ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);
323
324 stRxThreadInfo.ucChipResetting = 1;
325 if (g_fnStateCallback)
326 g_fnStateCallback(RADIO_STATUS_RESETTING);
327
328#ifdef ANT_IOCTL_RESET_PARAMETER
329 ioctl(stRxThreadInfo.astChannels[0].iFd, ANT_IOCTL_RESET, ANT_IOCTL_RESET_PARAMETER);
330#else
331 ioctl(stRxThreadInfo.astChannels[0].iFd, ANT_IOCTL_RESET);
332#endif // ANT_IOCTL_RESET_PARAMETER
333
334 ant_disable();
335
336 if (ant_enable()) { /* failed */
337 if (g_fnStateCallback)
338 g_fnStateCallback(RADIO_STATUS_DISABLED);
339 } else { /* success */
340 if (g_fnStateCallback)
341 g_fnStateCallback(RADIO_STATUS_RESET);
342 result_status = ANT_STATUS_SUCCESS;
343 }
344 stRxThreadInfo.ucChipResetting = 0;
345
346 ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
347 pthread_mutex_unlock(&stEnabledStatusLock);
348 ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
349out:
350#endif // ANT_IOCTL_RESET
351
352 ANT_FUNC_END();
353 return result_status;
354}
355
356////////////////////////////////////////////////////////////////////
357// ant_disable_radio
358//
359// Powers off the ANT part and closes the transport to the chip.
360//
361// Parameters:
362// -
363//
364// Returns:
365// Success:
366// ANT_STATUS_SUCCESS
367// Failures:
368// ANT_STATUS_FAILED if failed to get mutex
369//
370// Psuedocode:
371/*
372LOCK enable_LOCK
373 State callback: STATE = DISABLING
374 ant disable
375 State callback: STATE = Current state
376 RESULT = SUCCESS
377UNLOCK
378*/
379////////////////////////////////////////////////////////////////////
380ANTStatus ant_disable_radio(void)
381{
382 int iLockResult;
383 ANTStatus ret = ANT_STATUS_FAILED;
384 ANT_FUNC_START();
385
386 ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
387 iLockResult = pthread_mutex_lock(&stEnabledStatusLock);
388 if(iLockResult) {
389 ANT_ERROR("disable failed to get state lock: %s", strerror(iLockResult));
390 goto out;
391 }
392 ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);
393
394 if (g_fnStateCallback) {
395 g_fnStateCallback(RADIO_STATUS_DISABLING);
396 }
397
398 ant_disable();
399
400 if (g_fnStateCallback) {
401 g_fnStateCallback(ant_radio_enabled_status());
402 }
403
404 ret = ANT_STATUS_SUCCESS;
405
406 ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
407 pthread_mutex_unlock(&stEnabledStatusLock);
408 ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
409
410out:
411 ANT_FUNC_END();
412 return ret;
413}
414
415////////////////////////////////////////////////////////////////////
416// ant_radio_enabled_status
417//
418// Gets the current chip/transport state; either disabled, disabling,
419// enabling, enabled, or resetting. Determines this on the fly by checking
420// if Rx thread is running and how many of the paths for the ANT chip have
421// open VFS files.
422//
423// Parameters:
424// -
425//
426// Returns:
427// The current radio status (ANTRadioEnabledStatus)
428//
429// Psuedocode:
430/*
431IF Thread Resetting Flag is set
432 RESULT = Resetting
433ELSE
434 COUNT the number of open files
435 IF Thread Run Flag is Not Set
436 IF there are open files OR Rx thread exists
437 RESULT = Disabling
438 ELSE
439 RESULT = Disabled
440 ENDIF
441 ELSE
442 IF All files are open (all paths) AND Rx thread exists
443 RESULT = ENABLED
444 ELSE IF there are open files (Not 0 open files) AND Rx thread exists
445 RESULT = UNKNOWN
446 ELSE (0 open files or Rx thread does not exist [while Thread Run set])
447 RESULT = ENABLING
448 ENDIF
449 ENDIF
450ENDIF
451*/
452////////////////////////////////////////////////////////////////////
453ANTRadioEnabledStatus ant_radio_enabled_status(void)
454{
455 ant_channel_type eChannel;
456 int iOpenFiles = 0;
457 int iOpenThread;
458 ANTRadioEnabledStatus uiRet = RADIO_STATUS_UNKNOWN;
459 ANT_FUNC_START();
460
461 if (stRxThreadInfo.ucChipResetting) {
462 uiRet = RADIO_STATUS_RESETTING;
463 goto out;
464 }
465
466 for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) {
467 if (stRxThreadInfo.astChannels[eChannel].iFd != -1) {
468 iOpenFiles++;
469 }
470 }
471
472 iOpenThread = (stRxThreadInfo.stRxThread) ? 1 : 0;
473
474 if (!stRxThreadInfo.ucRunThread) {
475 if (iOpenFiles || iOpenThread) {
476 uiRet = RADIO_STATUS_DISABLING;
477 } else {
478 uiRet = RADIO_STATUS_DISABLED;
479 }
480 } else {
481 if ((iOpenFiles == NUM_ANT_CHANNELS) && iOpenThread) {
482 uiRet = RADIO_STATUS_ENABLED;
483 } else if (!iOpenFiles && iOpenThread) {
484 uiRet = RADIO_STATUS_UNKNOWN;
485 } else {
486 uiRet = RADIO_STATUS_ENABLING;
487 }
488 }
489
490out:
491 ANT_DEBUG_D("get radio enabled status returned %d", uiRet);
492
493 ANT_FUNC_END();
494 return uiRet;
495}
496
497////////////////////////////////////////////////////////////////////
498// set_ant_rx_callback
499//
500// Sets which function to call when an ANT message is received.
501//
502// Parameters:
503// rx_callback_func the ANTNativeANTEventCb function to be used for
504// received messages (from all transport paths).
505//
506// Returns:
507// ANT_STATUS_SUCCESS
508//
509// Psuedocode:
510/*
511FOR each transport path
512 Path Rx Callback = rx_callback_func
513ENDFOR
514*/
515////////////////////////////////////////////////////////////////////
516ANTStatus set_ant_rx_callback(ANTNativeANTEventCb rx_callback_func)
517{
518 ANTStatus status = ANT_STATUS_SUCCESS;
519 ANT_FUNC_START();
520
521#ifdef ANT_DEVICE_NAME // Single transport path
522 stRxThreadInfo.astChannels[SINGLE_CHANNEL].fnRxCallback = rx_callback_func;
523#else // Separate data/command paths
524 stRxThreadInfo.astChannels[COMMAND_CHANNEL].fnRxCallback = rx_callback_func;
525 stRxThreadInfo.astChannels[DATA_CHANNEL].fnRxCallback = rx_callback_func;
526#endif // Separate data/command paths
527
528 ANT_FUNC_END();
529 return status;
530}
531
532////////////////////////////////////////////////////////////////////
533// set_ant_state_callback
534//
535// Sets which function to call when an ANT state change occurs.
536//
537// Parameters:
538// state_callback_func the ANTNativeANTStateCb function to be used
539// for received state changes.
540//
541// Returns:
542// ANT_STATUS_SUCCESS
543//
544// Psuedocode:
545/*
546 State Callback = state_callback_func
547*/
548////////////////////////////////////////////////////////////////////
549ANTStatus set_ant_state_callback(ANTNativeANTStateCb state_callback_func)
550{
551 ANTStatus status = ANT_STATUS_SUCCESS;
552 ANT_FUNC_START();
553
554 g_fnStateCallback = state_callback_func;
555
556 ANT_FUNC_END();
557 return status;
558}
559
560////////////////////////////////////////////////////////////////////
561// ant_tx_message_flowcontrol_wait
562//
563// Sends an ANT message to the chip and waits for a CTS signal
564//
565// Parameters:
566// eTxPath device to transmit message on
567// eFlowMessagePath device that receives CTS
568// ucMessageLength the length of the message
569// pucMesg pointer to the message data
570//
571// Returns:
572// Success:
573// ANT_STATUS_SUCCESS
574// Failure:
575// ANT_STATUS_NOT_ENABLED
576//
577// Psuedocode:
578/*
579 LOCK flow control
580 IF Lock failed
581 RESULT = FAILED
582 ELSE
583 SET flowMessagePath Flow Control response as FLOW_STOP
584 WRITE txBuffer to txPath (only length of packet part)
585 IF Wrote less then 0 bytes
586 Log error
587 RESULT = FAILED
588 ELSE IF Didn't write 'length of packet' bytes
589 Log error
590 RESULT = FAILED
591 ELSE
592 IF flowMessagePath Flow Control response is not FLOW_GO
593 WAIT until flowMessagePath Flow Control response is FLOW_GO, UNTIL FLOW_GO Wait Timeout seconds (10) from Now
594 IF error Waiting
595 IF error is Timeout
596 RESULT = HARDWARE ERROR
597 ELSE
598 RESULT = FAILED
599 ENDIF
600 ELSE
601 RESULT = SUCCESS
602 ENDIF
603 ELSE
604 RESULT = SUCCESS;
605 ENDIF
606 ENDIF
607 UNLOCK flow control
608 ENDIF
609*/
610////////////////////////////////////////////////////////////////////
611ANTStatus ant_tx_message_flowcontrol_wait(ant_channel_type eTxPath, ant_channel_type eFlowMessagePath, ANT_U8 ucMessageLength, ANT_U8 *pucTxMessage)
612{
613 int iMutexResult;
614 int iResult;
615 struct timespec stTimeout;
616 int iCondWaitResult;
617 ANTStatus status = ANT_STATUS_FAILED;
618 ANT_FUNC_START();
619
620 ANT_DEBUG_V("getting stFlowControlLock in %s", __FUNCTION__);
621 iMutexResult = pthread_mutex_lock(&stFlowControlLock);
622 if (iMutexResult) {
623 ANT_ERROR("failed to lock flow control mutex during tx: %s", strerror(iMutexResult));
624 goto out;
625 }
626 ANT_DEBUG_V("got stFlowControlLock in %s", __FUNCTION__);
627
628 stRxThreadInfo.astChannels[eFlowMessagePath].ucFlowControlResp = ANT_FLOW_STOP;
629
630#ifdef ANT_FLOW_RESEND
631 // Store Tx message so can resend it from Rx thread
632 stRxThreadInfo.astChannels[eFlowMessagePath].ucResendMessageLength = ucMessageLength;
633 stRxThreadInfo.astChannels[eFlowMessagePath].pucResendMessage = pucTxMessage;
634#endif // ANT_FLOW_RESEND
635
636 iResult = write(stRxThreadInfo.astChannels[eTxPath].iFd, pucTxMessage, ucMessageLength);
637 if (iResult < 0) {
638 ANT_ERROR("failed to write data message to device: %s", strerror(errno));
639 } else if (iResult != ucMessageLength) {
640 ANT_ERROR("bytes written and message size don't match up");
641 } else {
642 stTimeout.tv_sec = time(0) + ANT_FLOW_GO_WAIT_TIMEOUT_SEC;
643 stTimeout.tv_nsec = 0;
644
645 while (stRxThreadInfo.astChannels[eFlowMessagePath].ucFlowControlResp != ANT_FLOW_GO) {
646 iCondWaitResult = pthread_cond_timedwait(&stFlowControlCond, &stFlowControlLock, &stTimeout);
647 if (iCondWaitResult) {
648 ANT_ERROR("failed to wait for flow control response: %s", strerror(iCondWaitResult));
649
650 if (iCondWaitResult == ETIMEDOUT) {
651 status = ANT_STATUS_HARDWARE_ERR;
652
653#ifdef ANT_FLOW_RESEND
654 // Clear Tx message so will stop resending it from Rx thread
655 stRxThreadInfo.astChannels[eFlowMessagePath].ucResendMessageLength = 0;
656 stRxThreadInfo.astChannels[eFlowMessagePath].pucResendMessage = NULL;
657#endif // ANT_FLOW_RESEND
658 }
659 goto wait_error;
660 }
661 }
662
663 status = ANT_STATUS_SUCCESS;
664 }
665
666wait_error:
667 ANT_DEBUG_V("releasing stFlowControlLock in %s", __FUNCTION__);
668 pthread_mutex_unlock(&stFlowControlLock);
669 ANT_DEBUG_V("released stFlowControlLock in %s", __FUNCTION__);
670
671out:
672 ANT_FUNC_END();
673 return status;
674}
675
676////////////////////////////////////////////////////////////////////
677// ant_tx_message_flowcontrol_none
678//
679// Sends an ANT message to the chip without waiting for flow control
680//
681// Parameters:
682// eTxPath device to transmit on
683// ucMessageLength the length of the message
684// pucMesg pointer to the message data
685//
686// Returns:
687// Success:
688// ANT_STATUS_SUCCESS
689// Failure:
690// ANT_STATUS_NOT_ENABLED
691//
692// Psuedocode:
693/*
694 WRITE txBuffer to Tx Path (only length of packet part)
695 IF Wrote less then 0 bytes
696 Log error
697 RESULT = FAILED
698 ELSE IF Didn't write 'length of packet' bytes
699 Log error
700 RESULT = FAILED
701 ELSE
702 RESULT = SUCCESS
703 ENDIF
704*/
705////////////////////////////////////////////////////////////////////
706ANTStatus ant_tx_message_flowcontrol_none(ant_channel_type eTxPath, ANT_U8 ucMessageLength, ANT_U8 *pucTxMessage)
707{
708 int iResult;
709 ANTStatus status = ANT_STATUS_FAILED;\
710 ANT_FUNC_START();
711
712 iResult = write(stRxThreadInfo.astChannels[eTxPath].iFd, pucTxMessage, ucMessageLength);
713 if (iResult < 0) {
714 ANT_ERROR("failed to write message to device: %s", strerror(errno));
715 } else if (iResult != ucMessageLength) {
716 ANT_ERROR("bytes written and message size don't match up");
717 } else {
718 status = ANT_STATUS_SUCCESS;
719 }
720
721 ANT_FUNC_END();
722 return status;
723}
724
725////////////////////////////////////////////////////////////////////
726// ant_tx_message
727//
728// Frames ANT data and decides which flow control method to use for sending the
729// ANT message to the chip
730//
731// Parameters:
732// ucLen the length of the message
733// pucMesg pointer to the message data
734//
735// Returns:
736// Success:
737// ANT_STATUS_SUCCESS
738// Failure:
739// ANT_STATUS_NOT_ENABLED
740//
741// Psuedocode:
742/*
743IF not enabled
744 RESULT = BT NOT INITIALIZED
745ELSE
746 Create txBuffer, MAX HCI Message Size large
747 PUT ucLen in txBuffer AT ANT HCI Size Offset (0)
748 COPY pucMesg to txBuffer AT ANT HCI Header Size (1) <- ? Not at offset?
749 LOG txBuffer as a serial Tx (only length of packet part)
750 IF is a data message
751 Tx message on Data Path with FLOW_GO/FLOW_STOP flow control (ant_tx_message_flowcontrol_go_stop())
752 ELSE
753 Tx message on Command Path with no flow control (ant_tx_message_flowcontrol_none())
754 ENDIF
755ENDIF
756*/
757////////////////////////////////////////////////////////////////////
758ANTStatus ant_tx_message(ANT_U8 ucLen, ANT_U8 *pucMesg)
759{
760 // During a tx we must prepend a packet type byte. Thus HCI_PACKET_TYPE_SIZE is added
761 // to all offsets when writing into the tx buffer.
762 ANTStatus status = ANT_STATUS_FAILED;
763 // TODO ANT_HCI_MAX_MSG_SIZE is transport (driver) dependent.
764 ANT_U8 txBuffer[HCI_PACKET_TYPE_SIZE + ANT_HCI_MAX_MSG_SIZE];
765 // TODO Message length can be greater than ANT_U8 can hold.
766 // Not changed as ANT_SERIAL takes length as ANT_U8.
767 ANT_U8 txMessageLength = HCI_PACKET_TYPE_SIZE + ucLen + ANT_HCI_HEADER_SIZE;
768 ANT_FUNC_START();
769
770 if (ant_radio_enabled_status() != RADIO_STATUS_ENABLED) {
771 status = ANT_STATUS_FAILED_BT_NOT_INITIALIZED;
772 goto out;
773 }
774
775#if ANT_HCI_OPCODE_SIZE == 1
776 txBuffer[HCI_PACKET_TYPE_SIZE + ANT_HCI_OPCODE_OFFSET] = ANT_HCI_OPCODE_TX;
777#elif ANT_HCI_OPCODE_SIZE > 1
778#error "Specified ANT_HCI_OPCODE_SIZE not currently supported"
779#endif
780
781#if ANT_HCI_SIZE_SIZE == 1
782 txBuffer[HCI_PACKET_TYPE_SIZE + ANT_HCI_SIZE_OFFSET] = ucLen;
783#elif ANT_HCI_SIZE_SIZE == 2
784 ANT_UTILS_StoreLE16(txBuffer + HCI_PACKET_TYPE_SIZE + ANT_HCI_SIZE_OFFSET, (ANT_U16)ucLen);
785#else
786#error "Specified ANT_HCI_SIZE_SIZE not currently supported"
787#endif
788
789 memcpy(txBuffer + HCI_PACKET_TYPE_SIZE + ANT_HCI_HEADER_SIZE, pucMesg, ucLen);
790
791// We no longer do the serial logging here because the packet type byte is not yet written.
792//ANT_SERIAL(txBuffer, txMessageLength, 'T');
793
794// We only do this if we are using single physical and logical channels.
795#if defined(ANT_DEVICE_NAME) && (HCI_PACKET_TYPE_SIZE == 0) // Single transport path
796 ANT_SERIAL(txBuffer, txMessageLength, 'T');
797 status = ant_tx_message_flowcontrol_wait(SINGLE_CHANNEL, SINGLE_CHANNEL, txMessageLength, txBuffer);
798#else // Separate data/command paths
799 // Each path follows this structure:
800 // write the packet type if needed.
801 // log the packet
802 // Send using the appropriate physical channel, waiting for flow control for data commands.
803 switch (txBuffer[HCI_PACKET_TYPE_SIZE + ANT_HCI_DATA_OFFSET + ANT_MSG_ID_OFFSET]) {
804 case MESG_BROADCAST_DATA_ID:
805 case MESG_ACKNOWLEDGED_DATA_ID:
806 case MESG_BURST_DATA_ID:
807 case MESG_EXT_BROADCAST_DATA_ID:
808 case MESG_EXT_ACKNOWLEDGED_DATA_ID:
809 case MESG_EXT_BURST_DATA_ID:
810 case MESG_ADV_BURST_DATA_ID:
811 ANT_DEBUG_V("Data Path");
812 #if HCI_PACKET_TYPE_SIZE == 1
813 txBuffer[0] = ANT_DATA_TYPE_PACKET;
814 #elif HCI_PACKET_TYPE_SIZE > 1
815 #error "Specified HCI_PACKET_TYPE_SIZE not supported"
816 #endif
817 ANT_SERIAL(txBuffer, txMessageLength, 'T');
818 #ifdef ANT_DEVICE_NAME
819 status = ant_tx_message_flowcontrol_wait(SINGLE_CHANNEL, SINGLE_CHANNEL, txMessageLength, txBuffer);
820 #else
821 status = ant_tx_message_flowcontrol_wait(DATA_CHANNEL, COMMAND_CHANNEL, txMessageLength, txBuffer);
822 #endif
823 break;
824 default:
825 ANT_DEBUG_V("Control Path");
826 #if HCI_PACKET_TYPE_SIZE == 1
827 txBuffer[0] = ANT_CMD_TYPE_PACKET;
828 #elif HCI_PACKET_TYPE_SIZE > 1
829 #error "Specified HCI_PACKET_TYPE_SIZE not supported"
830 #endif
831 ANT_SERIAL(txBuffer, txMessageLength, 'T');
832 #ifdef ANT_DEVICE_NAME
833 status = ant_tx_message_flowcontrol_none(SINGLE_CHANNEL, txMessageLength, txBuffer);
834 #else
835 status = ant_tx_message_flowcontrol_none(COMMAND_CHANNEL, txMessageLength, txBuffer);
836 #endif
837 }
838#endif // Separate data/command paths
839
840out:
841 ANT_FUNC_END();
842 return status;
843}
844
845//----------------- TODO Move these somewhere for multi transport path / dedicated channel support:
846
847static void ant_channel_init(ant_channel_info_t *pstChnlInfo, const char *pcCharDevName)
848{
849 ANT_FUNC_START();
850
851 // TODO Don't need to store, only accessed when trying to open:
852 // Is however useful for logs.
853 pstChnlInfo->pcDevicePath = pcCharDevName;
854
855 // This is the only piece of info that needs to be stored per channel
856 pstChnlInfo->iFd = -1;
857
858 // TODO Only 1 of these (not per-channel) is actually ever used:
859 pstChnlInfo->fnRxCallback = NULL;
860 pstChnlInfo->ucFlowControlResp = ANT_FLOW_GO;
861#ifdef ANT_FLOW_RESEND
862 pstChnlInfo->ucResendMessageLength = 0;
863 pstChnlInfo->pucResendMessage = NULL;
864#endif // ANT_FLOW_RESEND
865 // TODO Only used when Flow Control message received, so must only be Command path Rx thread
866 pstChnlInfo->pstFlowControlCond = &stFlowControlCond;
867 pstChnlInfo->pstFlowControlLock = &stFlowControlLock;
868
869 ANT_FUNC_END();
870}
871
872// This function is used as an alternative to opening the char device directly.
873// It is needed as libbt-vendor does the power up/down control for us when we open/close the file descriptor.
874int init_transport_bdroid(int on) {
875
876 void *so_handle;
877 unsigned char bdaddr[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
878 int fd[CH_MAX], powerstate, ret;
879
880 if (on) {
881 so_handle = dlopen("libbt-vendor.so", RTLD_NOW);
882 if (!so_handle)
883 {
884 ALOGE("Failed to load vendor component");
885 return -1;
886 }
887
888 vendor_interface = (bt_vendor_interface_t *) dlsym(so_handle, "BLUETOOTH_VENDOR_LIB_INTERFACE");
889 if (!vendor_interface)
890 {
891 ALOGE("Failed to accesst bt vendor interface");
892 return -1;
893 }
894
895 vendor_interface->init(&vendor_callbacks, bdaddr);
896
897 ALOGI("Turn On BT power");
898 powerstate = BT_VND_PWR_ON;
899 ret = vendor_interface->op(BT_VND_OP_POWER_CTRL, &powerstate);
900 if (ret < 0)
901 {
902 ALOGE("Failed to turn on power from bt vendor interface");
903 return -1;
904 }
905 /*call ANT_USERIAL_OPEN to get ANT handle*/
906 ret = vendor_interface->op(BT_VND_OP_ANT_USERIAL_OPEN, fd);
907 ALOGE("ret value: %d", ret);
908 if (ret != 1)
909 {
910 ALOGE("Failed to get fd from bt vendor interface");
911 return -1;
912 } else {
913 ALOGE("FD: %x", fd[0]);
914 return fd[0];
915 }
916 } else {
917 if (vendor_interface) {
918 ALOGE("Close and cleanup the interfaces");
919 int ret = vendor_interface->op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL);
ANT-Shaned494ba32013-11-15 11:19:05 -0700920 ALOGE("ret value: %d", ret);
921 ALOGI("Turn off BT power");
922 powerstate = BT_VND_PWR_OFF;
923 ret = vendor_interface->op(BT_VND_OP_POWER_CTRL, &powerstate);
924 if (ret < 0)
925 {
926 ALOGE("Failed to turn off power from bt vendor interface");
927 return -1;
928 }
929 vendor_interface->cleanup();
930 vendor_interface = NULL;
931 return 0;
932 } else {
933
934 ALOGE("Not able to find vendor interface handle");
935 return -1;
936 }
937 }
938}
939
940static void ant_disable_channel(ant_channel_info_t *pstChnlInfo)
941{
942 ANT_FUNC_START();
943 if (!pstChnlInfo) {
944 ANT_ERROR("null channel info passed to channel disable function");
945 goto out;
946 }
947 if (pstChnlInfo->iFd != -1) {
948 // Use the new init_transport function instead of open() to get our fd.
949 if (init_transport_bdroid(0) < 0) {
950 ANT_ERROR("failed to close channel %s(%#x): %s", pstChnlInfo->pcDevicePath, pstChnlInfo->iFd, strerror(errno));
951 }
952
953 pstChnlInfo->iFd = -1; //TODO can this overwrite a still valid fd?
954 } else {
955 ANT_DEBUG_D("%s file is already closed", pstChnlInfo->pcDevicePath);
956 }
957
958out:
959 ANT_FUNC_END();
960}
961
962static int ant_enable_channel(ant_channel_info_t *pstChnlInfo)
963{
964 int iRet = -1;
965 ANT_FUNC_START();
966 if (!pstChnlInfo) {
967 ANT_ERROR("null channel info passed to channel enable function");
968 errno = EINVAL;
969 goto out;
970 }
971 if (pstChnlInfo->iFd == -1) {
972 // Use the init_transport function to release our fd instead of close()
973 pstChnlInfo->iFd = init_transport_bdroid(1);
974 if (pstChnlInfo->iFd < 0) {
975 ANT_ERROR("failed to open dev %s: %s", pstChnlInfo->pcDevicePath, strerror(errno));
976 goto out;
977 }
978 } else {
979 ANT_DEBUG_D("%s is already enabled", pstChnlInfo->pcDevicePath);
980 }
981 iRet = 0;
982out:
983 ANT_FUNC_END();
984 return iRet;
985}
986
987//----------------------------------------------------------------------- This is antradio_power.h:
988
989int ant_enable(void)
990{
991 int iRet = -1;
992 ant_channel_type eChannel;
993 ANT_FUNC_START();
994
995 // Reset the shutdown signal.
996 uint64_t counter;
997 ssize_t result = read(stRxThreadInfo.iRxShutdownEventFd, &counter, sizeof(counter));
998 // EAGAIN result indicates that the counter was already 0 in non-blocking mode.
999 if(result < 0 && errno != EAGAIN)
1000 {
1001 ANT_ERROR("Could not clear shutdown signal in enable. Reason: %s", strerror(errno));
1002 goto out;
1003 }
1004
1005 stRxThreadInfo.ucRunThread = 1;
1006
1007 for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) {
1008 if (ant_enable_channel(&stRxThreadInfo.astChannels[eChannel]) < 0) {
1009 ANT_ERROR("failed to enable channel %s: %s",
1010 stRxThreadInfo.astChannels[eChannel].pcDevicePath,
1011 strerror(errno));
1012 goto out;
1013 }
1014 }
1015
1016 if (stRxThreadInfo.stRxThread == 0) {
1017 if (pthread_create(&stRxThreadInfo.stRxThread, NULL, fnRxThread, &stRxThreadInfo) < 0) {
1018 ANT_ERROR("failed to start rx thread: %s", strerror(errno));
1019 goto out;
1020 }
1021 } else {
1022 ANT_DEBUG_D("rx thread is already running");
1023 }
1024
1025 if (!stRxThreadInfo.ucRunThread) {
1026 ANT_ERROR("rx thread crashed during init");
1027 goto out;
1028 }
1029
1030 iRet = 0;
1031
1032out:
1033 ANT_FUNC_END();
1034 return iRet;
1035}
1036
1037int ant_disable(void)
1038{
1039 int iRet = -1;
1040 ant_channel_type eChannel;
1041 ANT_FUNC_START();
1042
1043 stRxThreadInfo.ucRunThread = 0;
1044
1045 if (stRxThreadInfo.stRxThread != 0) {
1046 ANT_DEBUG_I("Sending shutdown signal to rx thread.");
1047 if(write(stRxThreadInfo.iRxShutdownEventFd, &EVENT_FD_PLUS_ONE, sizeof(EVENT_FD_PLUS_ONE)) < 0)
1048 {
1049 ANT_ERROR("failed to signal rx thread with eventfd. Reason: %s", strerror(errno));
1050 goto out;
1051 }
1052 ANT_DEBUG_I("Waiting for rx thread to finish.");
1053 if (pthread_join(stRxThreadInfo.stRxThread, NULL) < 0) {
1054 ANT_ERROR("failed to join rx thread: %s", strerror(errno));
1055 goto out;
1056 }
1057 } else {
1058 ANT_DEBUG_D("rx thread is not running");
1059 }
1060
1061 for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) {
1062 ant_disable_channel(&stRxThreadInfo.astChannels[eChannel]);
1063 }
1064
1065 iRet = 0;
1066
1067out:
1068 stRxThreadInfo.stRxThread = 0;
1069 ANT_FUNC_END();
1070 return iRet;
1071}
1072
1073//---------------------------------------------------------
1074
1075const char *ant_get_lib_version()
1076{
1077 return "libantradio.so: "ANT_CHIP_NAME". Version "
1078 LIBANT_STACK_MAJOR"."LIBANT_STACK_MINOR"."LIBANT_STACK_INCRE;
1079}