This commit is contained in:
moyuhai
2026-06-09 16:39:17 +08:00
commit 41a602f89c
3057 changed files with 771495 additions and 0 deletions
Submodule
+1
Submodule Document added at 8506291255
+17
View File
@@ -0,0 +1,17 @@
# sbc decoder
SBC_DECODER += \
alloc.c \
bitalloc.c \
bitalloc-sbc.c \
bitstream-decode.c \
decoder-oina.c \
decoder-private.c \
decoder-sbc.c \
dequant.c \
framing.c \
framing-sbc.c \
oi_codec_version.c \
synthesis-sbc.c \
synthesis-dct8.c \
synthesis-8-generated.c \
+86
View File
@@ -0,0 +1,86 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_ASSERT_H
#define _OI_ASSERT_H
/** @file
This file provides macros and functions for compile-time and run-time assertions.
When the OI_DEBUG preprocessor value is defined, the macro OI_ASSERT is compiled into
the program, providing for a runtime assertion failure check.
C_ASSERT is a macro that can be used to perform compile time checks.
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** \addtogroup Debugging Debugging APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef OI_DEBUG
/** The macro OI_ASSERT takes a condition argument. If the asserted condition
does not evaluate to true, the OI_ASSERT macro calls the host-dependent function,
OI_AssertFail(), which reports the failure and generates a runtime error.
*/
void OI_AssertFail(const char * file, int line, const char * reason);
#define OI_ASSERT(condition) \
{ if (!(condition)) OI_AssertFail((const char *)__FILE__, __LINE__, #condition); }
#define OI_ASSERT_FAIL(msg) \
{ OI_AssertFail((const char *)__FILE__, __LINE__, (const char *)msg); }
#else
#define OI_ASSERT(condition)
#define OI_ASSERT_FAIL(msg)
#endif
/**
C_ASSERT() can be used to perform many compile-time assertions: type sizes, field offsets, etc.
An assertion failure results in compile time error C2118: negative subscript.
Unfortunately, this elegant macro doesn't work with GCC, so it's all commented out
for now. Perhaps later.....
*/
#ifndef C_ASSERT
// #define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
// #define C_ASSERT(e)
#endif
/*****************************************************************************/
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_ASSERT_H */
@@ -0,0 +1,123 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_BITSTREAM_H
#define _OI_BITSTREAM_H
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Function prototypes and macro definitions for manipulating input and output
bitstreams.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "oi_codec_sbc_private.h"
#include "oi_stddefs.h"
INLINE void OI_BITSTREAM_ReadInit(OI_BITSTREAM *bs, const OI_BYTE *buffer);
INLINE void OI_BITSTREAM_WriteInit(OI_BITSTREAM *bs, OI_BYTE *buffer);
INLINE OI_UINT32 OI_BITSTREAM_ReadUINT(OI_BITSTREAM *bs, OI_UINT bits);
INLINE OI_UINT8 OI_BITSTREAM_ReadUINT4Aligned(OI_BITSTREAM *bs);
INLINE OI_UINT8 OI_BITSTREAM_ReadUINT8Aligned(OI_BITSTREAM *bs);
INLINE void OI_BITSTREAM_WriteUINT(OI_BITSTREAM *bs,
OI_UINT16 value,
OI_UINT bits);
/*
* Use knowledge that the bitstream is aligned to optimize the write of a byte
*/
PRIVATE void OI_BITSTREAM_WriteUINT8Aligned(OI_BITSTREAM *bs,
OI_UINT8 datum);
/*
* Use knowledge that the bitstream is aligned to optimize the write pair of nibbles
*/
PRIVATE void OI_BITSTREAM_Write2xUINT4Aligned(OI_BITSTREAM *bs,
OI_UINT8 datum1,
OI_UINT8 datum2);
/** Internally the bitstream looks ahead in the stream. When
* OI_SBC_ReadScalefactors() goes to temporarily break the abstraction, it will
* need to know where the "logical" pointer is in the stream.
*/
#define OI_BITSTREAM_GetWritePtr(bs) ((bs)->ptr.w - 3)
#define OI_BITSTREAM_GetReadPtr(bs) ((bs)->ptr.r - 3)
/** This is declared here as a macro because decoder.c breaks the bitsream
* encapsulation for efficiency reasons.
*/
#define OI_BITSTREAM_READUINT(result, bits, ptr, value, bitPtr) \
do { \
OI_ASSERT((bits) <= 16); \
OI_ASSERT((bitPtr) < 16); \
OI_ASSERT((bitPtr) >= 8); \
\
result = (value) << (bitPtr); \
result >>= 32 - (bits); \
\
bitPtr += (bits); \
while (bitPtr >= 16) { \
value = (((value) << 8) | *ptr++) & 0xffffffff; \
bitPtr -= 8; \
} \
OI_ASSERT((bits == 0) || (result < (1u << (bits)))); \
} while (0)
#define OI_BITSTREAM_WRITEUINT(ptr, value, bitPtr, datum, bits) \
do {\
bitPtr -= bits;\
value |= datum << bitPtr;\
\
while (bitPtr <= 16) {\
bitPtr += 8;\
*ptr++ = (OI_UINT8)(value >> 24);\
value <<= 8;\
}\
} while (0)
#define OI_BITSTREAM_WRITEFLUSH(ptr, value, bitPtr) \
do {\
while (bitPtr < 32) {\
bitPtr += 8;\
*ptr++ = (OI_UINT8)(value >> 24);\
value <<= 8;\
}\
} while (0)
/**
@}
*/
#endif /* _OI_BITSTREAM_H */
+229
View File
@@ -0,0 +1,229 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_BT_SPEC_H
#define _OI_BT_SPEC_H
/**
* @file
*
* This file contains common definitions from the Bluetooth specification.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_stddefs.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/** The maximum number of active slaves in a piconet. */
#define OI_BT_MAX_ACTIVE_SLAVES 7
/** the number of bytes in a Bluetooth device address (BD_ADDR) */
#define OI_BD_ADDR_BYTE_SIZE 6
/**
* 48-bit Bluetooth device address
*
* Because 48-bit integers may not be supported on all platforms, the
* address is defined as an array of bytes. This array is big-endian,
* meaning that
* - array[0] contains bits 47-40,
* - array[1] contains bits 39-32,
* - array[2] contains bits 31-24,
* - array[3] contains bits 23-16,
* - array[4] contains bits 15-8, and
* - array[5] contains bits 7-0.
*/
typedef struct {
OI_UINT8 addr[OI_BD_ADDR_BYTE_SIZE] ; /**< Bluetooth device address represented as an array of 8-bit values */
} OI_BD_ADDR ;
/**
* @name Data types for working with UUIDs
* UUIDs are 16 bytes (128 bits).
*
* To avoid having to pass around 128-bit values all the time, 32-bit and 16-bit
* UUIDs are defined, along with a mapping from the shorter versions to the full
* version.
*
* @{
*/
/**
* 16-bit representation of a 128-bit UUID
*/
typedef OI_UINT16 OI_UUID16;
/**
* 32-bit representation of a 128-bit UUID
*/
typedef OI_UINT32 OI_UUID32;
/**
* number of bytes in a 128 bit UUID
*/
#define OI_BT_UUID128_SIZE 16
/**
* number of bytes in IPv6 style addresses
*/
#define OI_BT_IPV6ADDR_SIZE 16
/**
* type definition for a 128-bit UUID
*
* To simplify conversion between 128-bit UUIDs and 16-bit and 32-bit UUIDs,
* the most significant 32 bits are stored with the same endian-ness as is
* native on the target (local) device. The remainder of the 128-bit UUID is
* stored as bytes in big-endian order.
*/
typedef struct {
OI_UINT32 ms32bits; /**< most significant 32 bits of 128-bit UUID */
OI_UINT8 base[OI_BT_UUID128_SIZE - sizeof(OI_UINT32)]; /**< remainder of 128-bit UUID, array of 8-bit values */
} OI_UUID128;
/** @} */
/** number of bytes in a link key */
#define OI_BT_LINK_KEY_SIZE 16
/**
* type definition for a baseband link key
*
* Because 128-bit integers may not be supported on all platforms, we define
* link keys as an array of bytes. Unlike the Bluetooth device address,
* the link key is stored in little-endian order, meaning that
* - array[0] contains bits 0 - 7,
* - array[1] contains bits 8 - 15,
* - array[2] contains bits 16 - 23,
* - array[3] contains bits 24 - 31,
* - array[4] contains bits 32 - 39,
* - array[5] contains bits 40 - 47,
* - array[6] contains bits 48 - 55,
* - array[7] contains bits 56 - 63,
* - array[8] contains bits 64 - 71,
* - array[9] contains bits 72 - 79,
* - array[10] contains bits 80 - 87,
* - array[11] contains bits 88 - 95,
* - array[12] contains bits 96 - 103,
* - array[13] contains bits 104- 111,
* - array[14] contains bits 112- 119, and
* - array[15] contains bits 120- 127.
*/
typedef struct {
OI_UINT8 key[OI_BT_LINK_KEY_SIZE] ; /**< link key represented as an array of 8-bit values */
} OI_LINK_KEY ;
/** Out-of-band data size - C and R values are 16-bytes each */
#define OI_BT_OOB_NUM_BYTES 16
typedef struct {
OI_UINT8 value[OI_BT_OOB_NUM_BYTES] ; /**< same struct used for C and R values */
} OI_OOB_DATA ;
/**
* link key types
*/
typedef enum {
OI_LINK_KEY_TYPE_COMBO = 0, /**< combination key */
OI_LINK_KEY_TYPE_LOCAL_UNIT = 1, /**< local unit key */
OI_LINK_KEY_TYPE_REMOTE_UNIT = 2, /**< remote unit key */
OI_LINK_KEY_TYPE_DEBUG_COMBO = 3, /**< debug combination key */
OI_LINK_KEY_TYPE_UNAUTHENTICATED = 4, /**< Unauthenticated */
OI_LINK_KEY_TYPE_AUTHENTICATED = 5, /**< Authenticated */
OI_LINK_KEY_TYPE_CHANGED_COMBO = 6 /**< Changed */
} OI_BT_LINK_KEY_TYPE ;
/** amount of space allocated for a PIN (personal indentification number) in bytes */
#define OI_BT_PIN_CODE_SIZE 16
/** data type for a PIN (PINs are treated as strings, so endianness does not apply.) */
typedef struct {
OI_UINT8 pin[OI_BT_PIN_CODE_SIZE] ; /**< PIN represented as an array of 8-bit values */
} OI_PIN_CODE ;
/** maximum number of SCO connections per device, which is 3 as of version 2.0+EDR
of the Bluetooth specification (see sec 4.3 of vol 2 part B) */
#define OI_BT_MAX_SCO_CONNECTIONS 3
/** data type for clock offset */
typedef OI_UINT16 OI_BT_CLOCK_OFFSET ;
/** data type for a LM handle */
typedef OI_UINT16 OI_HCI_LM_HANDLE;
/** opaque data type for a SCO or ACL connection handle */
typedef struct _OI_HCI_CONNECTION *OI_HCI_CONNECTION_HANDLE;
/** data type for HCI Error Code, as defined in oi_hcispec.h */
typedef OI_UINT8 OI_HCI_ERROR_CODE ;
/**
* The Bluetooth device type is indicated by a 24-bit bitfield, represented as a
* 32-bit number in the stack. The bit layout and values for device class are specified
* in the file oi_bt_assigned_nos.h and in the Bluetooth "Assigned Numbers" specification
* at http://www.bluetooth.org/assigned-numbers/.
*/
typedef OI_UINT32 OI_BT_DEVICE_CLASS ;
#define OI_BT_DEV_CLASS_FORMAT_MASK 0x000003 /**< Bits 0-1 contain format type. */
#define OI_BT_DEV_CLASS_MINOR_DEVICE_MASK 0x0000FC /**< Bits 2-7 contain minor device class value. */
#define OI_BT_DEV_CLASS_MAJOR_DEVICE_MASK 0x001F00 /**< Bits 8-12 contain major device class value. */
#define OI_BT_DEV_CLASS_MAJOR_SERVICE_MASK 0xFFE000 /**< Bits 13-23 contain major service class value. */
/** There is currently only one device class format defined, type 00. */
#define OI_BT_DEV_CLASS_FORMAT_TYPE 00
/** Bit 13 in device class indicates limited discoverability mode (GAP v2.0+EDR, section 4.1.2.2) */
#define OI_BT_DEV_CLASS_LIMITED_DISCO_BIT BIT13
/** macro to test validity of the Device Class Format */
#define OI_BT_VALID_DEVICE_CLASS_FORMAT(class) (OI_BT_DEV_CLASS_FORMAT_TYPE == ((class) & OI_BT_DEV_CLASS_FORMAT_MASK))
/** the time between baseband clock ticks, currently 625 microseconds (one slot) */
#define OI_BT_TICK 625
/** some macros to convert to/from baseband clock ticks - use no floating point! */
#define OI_SECONDS_TO_BT_TICKS(secs) ((secs)*1600)
#define OI_BT_TICKS_TO_SECONDS(ticks) ((ticks)/1600)
#define OI_MSECS_TO_BT_TICKS(msecs) (((msecs)*8)/5)
#define OI_BT_TICKS_TO_MSECS(ticks) (((ticks)*5)/8)
/** EIR byte order */
#define OI_EIR_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
#ifdef __cplusplus
}
#endif
/**@}*/
/*****************************************************************************/
#endif /* _OI_BT_SPEC_H */
@@ -0,0 +1,497 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#ifndef _OI_CODEC_SBC_CORE_H
#define _OI_CODEC_SBC_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
@file
Declarations of codec functions, data types, and macros.
@ingroup codec_lib
*/
/**
@addtogroup codec_lib
@{
*/
/* Non-BM3 users of of the codec must include oi_codec_sbc_bm3defs.h prior to
* including this file, or else these includes will fail because the BM3 SDK is
* not in the include path */
#ifndef _OI_CODEC_SBC_BM3DEFS_H
#include "oi_stddefs.h"
#include "oi_status.h"
#endif
#include <stdint.h>
#define SBC_MAX_CHANNELS 2
#define SBC_MAX_BANDS 8
#define SBC_MAX_BLOCKS 16
#define SBC_MIN_BITPOOL 2 /**< Minimum size of the bit allocation pool used to encode the stream */
#define SBC_MAX_BITPOOL 250 /**< Maximum size of the bit allocation pool used to encode the stream */
#define SBC_MAX_ONE_CHANNEL_BPS 320000
#define SBC_MAX_TWO_CHANNEL_BPS 512000
#define SBC_WBS_BITRATE 62000
#define SBC_WBS_BITPOOL 27
#define SBC_WBS_NROF_BLOCKS 16
#define SBC_WBS_FRAME_LEN 62
#define SBC_WBS_SAMPLES_PER_FRAME 128
#define SBC_HEADER_LEN 4
#define SBC_MAX_FRAME_LEN (SBC_HEADER_LEN + \
((SBC_MAX_BANDS * SBC_MAX_CHANNELS / 2) + \
((SBC_MAX_BANDS + (SBC_MAX_BLOCKS * SBC_MAX_BITPOOL) + 7)/8)))
#define SBC_MAX_SAMPLES_PER_FRAME (SBC_MAX_BANDS * SBC_MAX_BLOCKS)
#define SBC_MAX_SCALEFACTOR_BYTES ((4*(SBC_MAX_CHANNELS * SBC_MAX_BANDS) + 7)/8)
#define OI_SBC_SYNCWORD 0x9c
#define OI_SBC_ENHANCED_SYNCWORD 0x9d
/**@name Sampling frequencies */
/**@{*/
#define SBC_FREQ_16000 0 /**< The sampling frequency is 16 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_FREQ_32000 1 /**< The sampling frequency is 32 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_FREQ_44100 2 /**< The sampling frequency is 44.1 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_FREQ_48000 3 /**< The sampling frequency is 48 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**@name Channel modes */
/**@{*/
#define SBC_MONO 0 /**< The mode of the encoded channel is mono. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_DUAL_CHANNEL 1 /**< The mode of the encoded channel is dual-channel. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_STEREO 2 /**< The mode of the encoded channel is stereo. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_JOINT_STEREO 3 /**< The mode of the encoded channel is joint stereo. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**@name Subbands */
/**@{*/
#define SBC_SUBBANDS_4 0 /**< The encoded stream has 4 subbands. One possible value for the @a subbands parameter of OI_CODEC_SBC_EncoderConfigure()*/
#define SBC_SUBBANDS_8 1 /**< The encoded stream has 8 subbands. One possible value for the @a subbands parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**@name Block lengths */
/**@{*/
#define SBC_BLOCKS_4 0 /**< A block size of 4 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_BLOCKS_8 1 /**< A block size of 8 blocks was used to encode the stream is. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_BLOCKS_12 2 /**< A block size of 12 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_BLOCKS_16 3 /**< A block size of 16 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**@name Bit allocation methods */
/**@{*/
#define SBC_LOUDNESS 0 /**< The bit allocation method. One possible value for the @a loudness parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_SNR 1 /**< The bit allocation method. One possible value for the @a loudness parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**
@}
@addtogroup codec_internal
@{
*/
typedef OI_INT16 SBC_BUFFER_T;
/** Used internally. */
typedef struct {
OI_UINT16 frequency; /**< The sampling frequency. Input parameter. */
OI_UINT8 freqIndex;
OI_UINT8 nrof_blocks; /**< The block size used to encode the stream. Input parameter. */
OI_UINT8 blocks;
OI_UINT8 nrof_subbands; /**< The number of subbands of the encoded stream. Input parameter. */
OI_UINT8 subbands;
OI_UINT8 mode; /**< The mode of the encoded channel. Input parameter. */
OI_UINT8 nrof_channels; /**< The number of channels of the encoded stream. */
OI_UINT8 alloc; /**< The bit allocation method. Input parameter. */
OI_UINT8 bitpool; /**< Size of the bit allocation pool used to encode the stream. Input parameter. */
OI_UINT8 crc; /**< Parity check byte used for error detection. */
OI_UINT8 join; /**< Whether joint stereo has been used. */
OI_UINT8 enhanced;
OI_UINT8 min_bitpool; /**< This value is only used when encoding. SBC_MAX_BITPOOL if variable
bitpools are disallowed, otherwise the minimum bitpool size that will
be used by the bit allocator. */
OI_UINT8 cachedInfo; /**< Information about the previous frame */
/* BK4BTSTACK_CHANGE START */
OI_UINT8 reserved_for_future_use[2];
OI_UINT8 mSBCEnabled; // default 0
/* BK4BTSTACK_CHANGE END */
} OI_CODEC_SBC_FRAME_INFO;
/** Used internally. */
typedef struct {
const OI_CHAR *codecInfo;
OI_CODEC_SBC_FRAME_INFO frameInfo;
OI_INT8 scale_factor[SBC_MAX_CHANNELS*SBC_MAX_BANDS];
OI_UINT32 frameCount;
OI_INT32 *subdata;
SBC_BUFFER_T *filterBuffer[SBC_MAX_CHANNELS];
OI_INT32 filterBufferLen;
OI_UINT filterBufferOffset;
union {
OI_UINT8 uint8[SBC_MAX_CHANNELS*SBC_MAX_BANDS];
OI_UINT32 uint32[SBC_MAX_CHANNELS*SBC_MAX_BANDS/4];
} bits;
OI_UINT8 maxBitneed; /**< Running maximum bitneed */
OI_BYTE formatByte;
OI_UINT8 pcmStride;
OI_UINT8 maxChannels;
} OI_CODEC_SBC_COMMON_CONTEXT;
/*
* A smaller value reduces RAM usage at the expense of increased CPU usage. Values in the range
* 27..50 are recommended, beyond 50 there is a diminishing return on reduced CPU usage.
*/
#define SBC_CODEC_MIN_FILTER_BUFFERS 16
#define SBC_CODEC_FAST_FILTER_BUFFERS 27
/* Expands to the number of OI_UINT32s needed to ensure enough memory to encode
* or decode streams of numChannels channels, using numBuffers buffers.
* Example:
* OI_UINT32 decoderData[CODEC_DATA_WORDS(SBC_MAX_CHANNELS, SBC_DECODER_FAST_SYNTHESIS_BUFFERS)];
* */
#define CODEC_DATA_WORDS(numChannels, numBuffers) \
((\
(sizeof(OI_INT32) * SBC_MAX_BLOCKS * numChannels * SBC_MAX_BANDS) \
+ (sizeof(SBC_BUFFER_T) * SBC_MAX_CHANNELS * SBC_MAX_BANDS * numBuffers) \
+ (sizeof (OI_UINT32) - 1) \
) / sizeof(OI_UINT32))
/** Opaque parameter to decoding functions; maintains decoder context. */
typedef struct {
OI_CODEC_SBC_COMMON_CONTEXT common;
OI_UINT8 limitFrameFormat; /* Boolean, set by OI_CODEC_SBC_DecoderLimit() */
OI_UINT8 restrictSubbands;
OI_UINT8 enhancedEnabled;
OI_UINT8 bufferedBlocks;
} OI_CODEC_SBC_DECODER_CONTEXT;
typedef struct {
OI_UINT32 data[CODEC_DATA_WORDS(1, SBC_CODEC_FAST_FILTER_BUFFERS)];
} OI_CODEC_SBC_CODEC_DATA_MONO;
typedef struct {
OI_UINT32 data[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
} OI_CODEC_SBC_CODEC_DATA_STEREO;
/**
@}
@addtogroup codec_lib
@{
*/
/**
* This function resets the decoder. The context must be reset when
* changing streams, or if the following stream parameters change:
* number of subbands, stereo mode, or frequency.
*
* @param context Pointer to the decoder context structure to be reset.
*
* @param enhanced If true, enhanced SBC operation is enabled. If enabled,
* the codec will recognize the alternative syncword for
* decoding an enhanced SBC stream. Enhancements should not
* be enabled unless the stream is known to be generated
* by an enhanced encoder, or there is a small possibility
* for decoding glitches if synchronization were to be lost.
*/
OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes,
OI_UINT8 maxChannels,
OI_UINT8 pcmStride,
OI_BOOL enhanced);
/* BK4BTSTACK_CHANGE START */
OI_STATUS OI_CODEC_mSBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes);
/* BK4BTSTACK_CHANGE END */
/**
* This function restricts the kind of SBC frames that the Decoder will
* process. Its use is optional. If used, it must be called after
* calling OI_CODEC_SBC_DecoderReset(). After it is called, any calls
* to OI_CODEC_SBC_DecodeFrame() with SBC frames that do not conform
* to the Subband and Enhanced SBC setting will be rejected with an
* OI_STATUS_INVALID_PARAMETERS return.
*
* @param context Pointer to the decoder context structure to be limited.
*
* @param enhanced If true, all frames passed to the decoder must be
* Enhanced SBC frames. If false, all frames must be
* standard SBC frames.
*
* @param subbands May be set to SBC_SUBBANDS_4 or SBC_SUBBANDS_8. All
* frames passed to the decoder must be encoded with
* the requested number of subbands.
*
*/
OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_BOOL enhanced,
OI_UINT8 subbands);
/**
* This function sets the decoder parameters for a raw decode where the decoder parameters are not
* available in the sbc data stream. OI_CODEC_SBC_DecoderReset must be called
* prior to calling this function.
*
* @param context Decoder context structure. This must be the context must be
* used each time a frame is decoded.
*
* @param enhanced Set to TRUE to enable Qualcomm proprietary
* quality enhancements.
*
* @param frequency One of SBC_FREQ_16000, SBC_FREQ_32000, SBC_FREQ_44100,
* SBC_FREQ_48000
*
* @param mode One of SBC_MONO, SBC_DUAL_CHANNEL, SBC_STEREO,
* SBC_JOINT_STEREO
*
* @param subbands One of SBC_SUBBANDS_4, SBC_SUBBANDS_8
*
* @param blocks One of SBC_BLOCKS_4, SBC_BLOCKS_8, SBC_BLOCKS_12,
* SBC_BLOCKS_16
*
* @param alloc One of SBC_LOUDNESS, SBC_SNR
*
* @param maxBitpool The maximum bitpool size for this context
*/
OI_STATUS OI_CODEC_SBC_DecoderConfigureRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_BOOL enhanced,
OI_UINT8 frequency,
OI_UINT8 mode,
OI_UINT8 subbands,
OI_UINT8 blocks,
OI_UINT8 alloc,
OI_UINT8 maxBitpool);
/**
* Decode one SBC frame. The frame has no header bytes. The context must have been previously
* initialized by calling OI_CODEC_SBC_DecoderConfigureRaw().
*
* @param context Pointer to a decoder context structure. The same context
* must be used each time when decoding from the same stream.
*
* @param bitpool The actual bitpool size for this frame. Must be <= the maxbitpool specified
* in the call to OI_CODEC_SBC_DecoderConfigureRaw(),
*
* @param frameData Address of a pointer to the SBC data to decode. This
* value will be updated to point to the next frame after
* successful decoding.
*
* @param frameBytes Pointer to a UINT32 containing the number of available
* bytes of frame data. This value will be updated to reflect
* the number of bytes remaining after a decoding operation.
*
* @param pcmData Address of an array of OI_INT16 pairs, which will be
* populated with the decoded audio data. This address
* is not updated.
*
* @param pcmBytes Pointer to a UINT32 in/out parameter. On input, it
* should contain the number of bytes available for pcm
* data. On output, it will contain the number of bytes
* written. Note that this differs from the semantics of
* frameBytes.
*/
OI_STATUS OI_CODEC_SBC_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT8 bitpool,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes);
/**
* Decode one SBC frame.
*
* @param context Pointer to a decoder context structure. The same context
* must be used each time when decoding from the same stream.
*
* @param frameData Address of a pointer to the SBC data to decode. This
* value will be updated to point to the next frame after
* successful decoding.
*
* @param frameBytes Pointer to a UINT32 containing the number of available
* bytes of frame data. This value will be updated to reflect
* the number of bytes remaining after a decoding operation.
*
* @param pcmData Address of an array of OI_INT16 pairs, which will be
* populated with the decoded audio data. This address
* is not updated.
*
* @param pcmBytes Pointer to a UINT32 in/out parameter. On input, it
* should contain the number of bytes available for pcm
* data. On output, it will contain the number of bytes
* written. Note that this differs from the semantics of
* frameBytes.
*/
OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes);
/**
* Calculate the number of SBC frames but don't decode. CRC's are not checked,
* but the Sync word is found prior to count calculation.
*
* @param frameData Pointer to the SBC data.
*
* @param frameBytes Number of bytes avaiable in the frameData buffer
*
*/
OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE *frameData,
OI_UINT32 frameBytes);
/**
* Analyze an SBC frame but don't do the decode.
*
* @param context Pointer to a decoder context structure. The same context
* must be used each time when decoding from the same stream.
*
* @param frameData Address of a pointer to the SBC data to decode. This
* value will be updated to point to the next frame after
* successful decoding.
*
* @param frameBytes Pointer to a UINT32 containing the number of available
* bytes of frame data. This value will be updated to reflect
* the number of bytes remaining after a decoding operation.
*
*/
OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes);
/* Common functions */
/**
Calculate the frame length.
@param frame The frame whose length to calculate
@return the length of an individual encoded frame in
bytes
*/
OI_UINT16 OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame);
/**
* Calculate the maximum bitpool size that fits within a given frame length.
*
* @param frame The frame to calculate the bitpool size for
* @param frameLen The frame length to fit the bitpool to
*
* @return the maximum bitpool that will fit in the specified frame length
*/
OI_UINT16 OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO *frame,
OI_UINT16 frameLen);
/**
Calculate the bit rate.
@param frame The frame whose bit rate to calculate
@return the approximate bit rate in bits per second,
assuming that stream parameters are constant
*/
OI_UINT32 OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame);
/**
Calculate decoded audio data length for one frame.
@param frame The frame whose audio data length to calculate
@return length of decoded audio data for a
single frame, in bytes
*/
OI_UINT16 OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT *common);
/**
* Get the codec version text.
*
* @return pointer to text string containing codec version text
*
*/
const OI_CHAR *OI_CODEC_Version(void);
/**
@}
@addtogroup codec_internal
@{
*/
extern const OI_CHAR* const OI_CODEC_SBC_FreqText[];
extern const OI_CHAR* const OI_CODEC_SBC_ModeText[];
extern const OI_CHAR* const OI_CODEC_SBC_SubbandsText[];
extern const OI_CHAR* const OI_CODEC_SBC_BlocksText[];
extern const OI_CHAR* const OI_CODEC_SBC_AllocText[];
/**
@}
@addtogroup codec_lib
@{
*/
#ifdef OI_DEBUG
void OI_CODEC_SBC_DumpConfig(OI_CODEC_SBC_FRAME_INFO *frameInfo);
#else
#define OI_CODEC_SBC_DumpConfig(f)
#endif
/**
@}
*/
#ifdef __cplusplus
}
#endif
#endif /* _OI_CODEC_SBC_CORE_H */
@@ -0,0 +1,237 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_CODEC_SBC_PRIVATE_H
#define _OI_CODEC_SBC_PRIVATE_H
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Function prototypes and macro definitions used internally by the codec.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#ifdef USE_RESTRICT_KEYWORD
#define RESTRICT restrict
#else
#define RESTRICT
#endif
#ifdef CODEC_DEBUG
#include <stdio.h>
#define ERROR(x) do { printf x; printf("\n"); } while (0)
#else
#define ERROR(x)
#endif
#ifdef TRACE_EXECUTION
#include <stdio.h>
#define TRACE(x) do { printf x; printf("\n"); } while (0)
#else
#define TRACE(x)
#endif
#ifndef PRIVATE
#define PRIVATE
#endif
#ifndef INLINE
#define INLINE
#endif
#include "oi_assert.h"
#include "oi_codec_sbc.h"
/* BK4BTSTACK_CHANGE START */
#ifndef OI_mSBC_SYNCWORD
#define OI_mSBC_SYNCWORD 0xad
#endif
/* BK4BTSTACK_CHANGE END */
#ifndef OI_SBC_SYNCWORD
#define OI_SBC_SYNCWORD 0x9c
#endif
#ifndef DIVIDE
#define DIVIDE(a, b) ((a) / (b))
#endif
typedef union {
OI_UINT8 uint8[SBC_MAX_BANDS];
OI_UINT32 uint32[SBC_MAX_BANDS / 4];
} BITNEED_UNION1;
typedef union {
OI_UINT8 uint8[2 * SBC_MAX_BANDS];
OI_UINT32 uint32[2 * SBC_MAX_BANDS / 4];
} BITNEED_UNION2;
static const OI_UINT16 freq_values[] = { 16000, 32000, 44100, 48000 };
static const OI_UINT8 block_values[] = { 4, 8, 12, 16 };
static const OI_UINT8 channel_values[] = { 1, 2, 2, 2 };
static const OI_UINT8 band_values[] = { 4, 8 };
#define TEST_MODE_SENTINEL "OINA"
#define TEST_MODE_SENTINEL_LENGTH 4
/** Used internally. */
typedef struct {
union {
const OI_UINT8 *r;
OI_UINT8 *w;
} ptr;
OI_UINT32 value;
OI_UINT bitPtr;
} OI_BITSTREAM;
#define VALID_INT16(x) (((x) >= OI_INT16_MIN) && ((x) <= OI_INT16_MAX))
#define VALID_INT32(x) (((x) >= OI_INT32_MIN) && ((x) <= OI_INT32_MAX))
#define DCTII_8_SHIFT_IN 0
#define DCTII_8_SHIFT_OUT 16-DCTII_8_SHIFT_IN
#define DCTII_8_SHIFT_0 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_1 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_2 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_3 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_4 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_5 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_6 (DCTII_8_SHIFT_OUT-1)
#define DCTII_8_SHIFT_7 (DCTII_8_SHIFT_OUT-2)
#define DCT_SHIFT 15
#define DCTIII_4_SHIFT_IN 2
#define DCTIII_4_SHIFT_OUT 15
#define DCTIII_8_SHIFT_IN 3
#define DCTIII_8_SHIFT_OUT 14
OI_UINT computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common,
OI_UINT8 *bitneeds,
OI_UINT ch,
OI_UINT *preferredBitpool);
void oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common,
BITNEED_UNION1 *bitneeds,
OI_UINT ch,
OI_UINT bitcount);
OI_INT adjustToFitBitpool(const OI_UINT bitpool,
OI_UINT32 *bitneeds,
const OI_UINT subbands,
OI_UINT bitcount,
OI_UINT *excess);
INLINE OI_INT allocAdjustedBits(OI_UINT8 *dest,
OI_INT bits,
OI_INT excess);
INLINE OI_INT allocExcessBits(OI_UINT8 *dest,
OI_INT excess);
PRIVATE OI_UINT32 internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame);
PRIVATE OI_UINT16 internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame);
void monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common);
typedef void (*BIT_ALLOC)(OI_CODEC_SBC_COMMON_CONTEXT *common);
PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT8 bitpool,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes);
INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes,
OI_BYTE maxChannels,
OI_BYTE pcmStride,
OI_BOOL enhanced);
INLINE OI_UINT16 OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO *frame, OI_UINT *headerLen_);
PRIVATE OI_UINT32 OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO *frame);
PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *frame);
PRIVATE OI_UINT8 OI_SBC_CalculateChecksum(OI_CODEC_SBC_FRAME_INFO *frame, OI_BYTE const *data);
PRIVATE OI_UINT8 OI_SBC_CalculateChecksum_mSBC(OI_CODEC_SBC_FRAME_INFO *frame, OI_BYTE const *data);
/* Transform functions */
PRIVATE void shift_buffer(SBC_BUFFER_T *dest, SBC_BUFFER_T *src, OI_UINT wordCount);
PRIVATE void cosineModulateSynth4(SBC_BUFFER_T * RESTRICT out, OI_INT32 const * RESTRICT in);
PRIVATE void SynthWindow40_int32_int32_symmetry_with_sum(OI_INT16 *pcm, SBC_BUFFER_T buffer[80], OI_UINT strideShift);
INLINE void dct3_4(OI_INT32 * RESTRICT out, OI_INT32 const * RESTRICT in);
PRIVATE void analyze4_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 40],
OI_INT16 *pcm,
OI_UINT strideShift,
OI_INT32 subband[4]);
INLINE void dct3_8(OI_INT32 * RESTRICT out, OI_INT32 const * RESTRICT in);
PRIVATE void analyze8_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 80],
OI_INT16 *pcm,
OI_UINT strideShift,
OI_INT32 subband[8]);
#ifdef SBC_ENHANCED
PRIVATE void analyze8_enhanced_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 112],
OI_INT16 *pcm,
OI_UINT strideShift,
OI_INT32 subband[8]);
#endif
/* Decoder functions */
INLINE void OI_SBC_ReadHeader_mSBC(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data);
INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data);
PRIVATE void OI_SBC_ReadScalefactors(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *b, OI_BITSTREAM *bs);
PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT *common, OI_BITSTREAM *ob);
PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT *common, OI_BITSTREAM *global_bs);
PRIVATE void OI_SBC_SynthFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT start_block, OI_UINT nrof_blocks);
INLINE OI_INT32 OI_SBC_Dequant(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits);
PRIVATE OI_BOOL OI_SBC_ExamineCommandPacket(OI_CODEC_SBC_DECODER_CONTEXT *context, const OI_BYTE *data, OI_UINT32 len);
PRIVATE void OI_SBC_GenerateTestSignal(OI_INT16 pcmData[][2], OI_UINT32 sampleCount);
PRIVATE void OI_SBC_ExpandFrameFields(OI_CODEC_SBC_FRAME_INFO *frame);
PRIVATE OI_STATUS OI_CODEC_SBC_Alloc(OI_CODEC_SBC_COMMON_CONTEXT *common,
OI_UINT32 *codecDataAligned,
OI_UINT32 codecDataBytes,
OI_UINT8 maxChannels,
OI_UINT8 pcmStride);
/**
@}
*/
#endif /* _OI_CODEC_SBC_PRIVATE_H */
+43
View File
@@ -0,0 +1,43 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_COMMON_H
#define _OI_COMMON_H
/**
* @file
*
* This file is used to group commonly used BLUEmagic 3.0 software
* header files.
*
* This file should be included in application source code along with the header
* files for the specific modules of the protocol stack being used.
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_bt_spec.h"
#include "oi_stddefs.h"
#include "oi_status.h"
#include "oi_time.h"
#include "oi_osinterface.h"
/*****************************************************************************/
#endif /* _OI_COMMON_H */
+542
View File
@@ -0,0 +1,542 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_CPU_DEP_H
#define _OI_CPU_DEP_H
/**
* @file
* This file contains definitions for characteristics of the target CPU and
* compiler, including primitive data types and endianness.
*
* This file defines the byte order and primitive data types for various
* CPU families. The preprocessor symbol 'CPU' must be defined to be an
* appropriate value or this header will generate a compile-time error.
*
* @note The documentation for this header file uses the x86 family of processors
* as an illustrative example for CPU/compiler-dependent data type definitions.
* Go to the source code of this header file to see the details of primitive type
* definitions for each platform.
*
* Additional information is available in the @ref data_types_docpage section.
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
/** @name Definitions indicating family of target OI_CPU_TYPE
* @{
*/
#define OI_CPU_X86 1 /**< x86 processor family */
#define OI_CPU_ARM 2 /**< ARM processor family.
@deprecated Use #OI_CPU_ARM7_LEND or
#OI_CPU_ARM7_BEND. */
#define OI_CPU_ARC 3 /**< ARC processor family.
@deprecated Use #OI_CPU_ARC_LEND or
#OI_CPU_ARC_BEND. */
#define OI_CPU_SH3 4 /**< Hitachi SH-3 processor family */
#define OI_CPU_H8 5 /**< Hitachi H8 processor family */
#define OI_CPU_MIPS 6 /**< MIPS processor family */
#define OI_CPU_SPARC 7 /**< SPARC processor family */
#define OI_CPU_M68000 8 /**< Motorola M68000 processor family */
#define OI_CPU_PPC 9 /**< PowerPC (PPC) processor family */
#define OI_CPU_SH4_7750 10 /**< Hitachi SH7750 series in SH-4 processor family */
#define OI_CPU_SH2 11 /**< Hitachi SH-2 processor family */
#define OI_CPU_ARM7_LEND 12 /**< ARM7, little-endian */
#define OI_CPU_ARM7_BEND 13 /**< ARM7, big-endian */
#define OI_CPU_GDM1202 14 /**< GCT GDM1202 */
#define OI_CPU_ARC_LEND 15 /**< ARC processor family, little-endian */
#define OI_CPU_ARC_BEND 16 /**< ARC processor family, big-endian */
#define OI_CPU_M30833F 17 /**< Mitsubishi M308 processor family */
#define OI_CPU_CR16C 18 /**< National Semiconductor 16 bit processor family */
#define OI_CPU_M64111 19 /**< Renesas M64111 processor (M32R family) */
#define OI_CPU_ARMV5_LEND 20 //*< ARM5, little-endian */
/* BK4BTSTACK_CHANGE START */
// #define OI_CPU_TYPE 12
/** @name Definitions indicating byte-wise endianness of target CPU
* @{
*/
#define OI_BIG_ENDIAN_BYTE_ORDER 0 /**< Multiple-byte values are stored in memory beginning with the most significant byte at the lowest address. */
#define OI_LITTLE_ENDIAN_BYTE_ORDER 1 /**< Multiple-byte values are stored in memory beginning with the least significant byte at the lowest address. */
#ifndef OI_CPU_TYPE
// to avoid warnigns below
#define OI_CPU_TYPE 0
#if 0
/ #error "OI_CPU_TYPE type not defined"
#else
// BK
/** @name CPU/compiler-dependent primitive data type definitions
* @{
*/
typedef int8_t OI_INT8;
typedef int16_t OI_INT16;
typedef int32_t OI_INT32;
typedef uint8_t OI_UINT8;
typedef uint16_t OI_UINT16;
typedef uint32_t OI_UINT32;
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
#ifdef __LITTLE_ENDIAN__
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
#endif
#ifdef __BIG_ENDIAN__
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
#endif
// emergency fallback
#ifndef OI_CPU_BYTE_ORDER
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
#endif
/**@}*/
#endif
/**@}*/
#endif
/* BK4BTSTACK_CHANGE STOP */
/** @name CPU/compiler-independent primitive data type definitions
* @{
*/
typedef int OI_BOOL; /**< Boolean values use native integer data type for target CPU. */
typedef int OI_INT; /**< Integer values use native integer data type for target CPU. */
typedef unsigned int OI_UINT; /**< Unsigned integer values use native unsigned integer data type for target CPU. */
typedef unsigned char OI_BYTE; /**< Raw bytes type uses native character data type for target CPU. */
/**@}*/
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_X86
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER /**< x86 platform byte ordering is little-endian */
/** @name CPU/compiler-dependent primitive data type definitions for x86 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for x86 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for x86 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for x86 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for x86 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for x86 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for x86 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARM
/* This CPU type is deprecated (removed from use). Instead, use OI_CPU_ARM7_LEND or OI_CPU_ARM7_BEND for
little-endian or big-endian configurations of the ARM7, respectively. */
#error OI_CPU_ARM is deprecated
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARC
/* This CPU type is deprecated (removed from use). Instead, use OI_CPU_ARC_LEND or OI_CPU_ARC_BEND for
little-endian or big-endian configurations of the ARC, respectively. */
#error OI_CPU_ARC is deprecated
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_SH3
/* The Hitachi SH C compiler defines _LIT or _BIG, depending on the endianness
specified to the compiler on the command line. */
#if defined(_LIT)
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER /**< If _LIT is defined, SH-3 platform byte ordering is little-endian. */
#elif defined(_BIG)
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< If _BIG is defined, SH-3 platform byte ordering is big-endian. */
#else
#error SH compiler endianness undefined
#endif
/** @name CPU/compiler-dependent primitive data type definitions for SH-3 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for SH-3 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for SH-3 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for SH-3 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for SH-3 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH-3 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH-3 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_SH2
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< SH-2 platform byte ordering is big-endian. */
/** @name CPU/compiler-dependent primitive data type definitions for SH-2 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for SH-2 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for SH-2 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for SH-2 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for SH-2 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH-2 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH-2 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_H8
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
#error basic types not defined
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_MIPS
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for MIPS processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_SPARC
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
#error basic types not defined
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_M68000
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< M68000 platform byte ordering is big-endian. */
/** @name CPU/compiler-dependent primitive data type definitions for M68000 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for M68000 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for M68000 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for M68000 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for M68000 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M68000 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M68000 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_PPC
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for PPC 8XX processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for PPC8XX processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for PPC8XX processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for PPC8XX processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for PPC8XX processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for PPC8XX processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for PPC8XX processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_SH4_7750
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< SH7750 platform byte ordering is big-endian. */
/** @name CPU/compiler-dependent primitive data type definitions for SH7750 processor series of the SH-4 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for SH7750 SH-4 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for SH7750 SH-4 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for SH7750 SH-4 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for SH7750 SH-4 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH7750 SH-4 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH7750 SH-4 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARM7_LEND
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name little-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
typedef void * OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARM7_BEND
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
/** @name big-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
typedef void * OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_GDM1202
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
typedef signed char OI_INT8; /**< 8-bit signed integer. */
typedef signed short OI_INT16; /**< 16-bit signed integer. */
typedef signed long OI_INT32; /**< 32-bit signed integer. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARC_LEND
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for ARC processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARC processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARC processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARC processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARC processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARC processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARC processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARC_BEND
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for ARC processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARC processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARC processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARC processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARC processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARC processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARC processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_M30833F
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for Mitsubishi M308 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for M308 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for M308 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for M308 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for M308 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M308 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M308 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_CR16C
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for National Semicnductor processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for CR16C processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for CR16C processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for CR16C processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for CR16C processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for CR16C processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for CR16C processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_M64111
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for Renesas M32R processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for M64111 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for M64111 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for M64111 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for M64111 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M64111 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M64111 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARMV5_LEND
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name little-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#ifndef OI_CPU_BYTE_ORDER
#error "Byte order (endian-ness) not defined"
#endif
/**@}*/
#ifdef __cplusplus
}
#endif
/*********************************************************************************/
#endif /* _OI_CPU_DEP_H */
+171
View File
@@ -0,0 +1,171 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_MODULES_H
#define _OI_MODULES_H
/**
* @file
*
* Enumeration type defining the inidivual stack components.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* This enumeration lists constants for referencing the components of
* the BLUEmagic 3.0 protocol stack, profiles, and other functionalities.
*
* In order to distinguish types of modules, items are grouped with markers to
* delineate start and end of the groups
*
* The module type is used for various purposes:
* identification in debug print statements
* access to initialization flags
* access to the configuration table
*/
typedef enum {
/* profiles and protocols --> Updates to oi_debug.c and oi_config_table.c */
/* XX --> Keep Enum values up-to-date! */
OI_MODULE_AT, /**< 00 AT command processing */
OI_MODULE_A2DP, /**< 01 Advanced Audio Distribution Profile */
OI_MODULE_AVCTP, /**< 02 Audio-Visual Control Transport Profile */
OI_MODULE_AVDTP, /**< 03 Audio-Visual Distribution Protocol */
OI_MODULE_AVRCP, /**< 04 Audio-Visual Remote Control Profile */
OI_MODULE_BIP_CLI, /**< 05 Basic Imaging Profile protocol client */
OI_MODULE_BIP_SRV, /**< 06 Basic Imaging Profile protocol server */
OI_MODULE_BNEP, /**< 07 Bluetooth Network Encapsulation Protocol */
OI_MODULE_BPP_SENDER, /**< 08 Basic Printing Profile */
OI_MODULE_BPP_PRINTER, /**< 09 Basic Printing Profile */
OI_MODULE_CTP, /**< 10 Cordless Telephony Profile */
OI_MODULE_DUN, /**< 11 Dial-Up Networking Profile */
OI_MODULE_FAX, /**< 12 Fax Profile */
OI_MODULE_FTP_CLI, /**< 13 File Transfer Profile protocol client */
OI_MODULE_FTP_SRV, /**< 14 File Transfer Profile protocol server */
OI_MODULE_HANDSFREE, /**< 15 Hands-Free Profile */
OI_MODULE_HANDSFREE_AG, /**< 16 Hands-Free Profile */
OI_MODULE_HCRP_CLI, /**< 17 Hardcopy Cable Replacement Profile */
OI_MODULE_HCRP_SRV, /**< 18 Hardcopy Cable Replacement Profile */
OI_MODULE_HEADSET, /**< 19 Headset Profile */
OI_MODULE_HEADSET_AG, /**< 20 Headset Profile */
OI_MODULE_HID, /**< 21 Human Interface Device profile */
OI_MODULE_INTERCOM, /**< 22 Intercom Profile */
OI_MODULE_OBEX_CLI, /**< 23 OBEX protocol client, Generic Object Exchange Profile */
OI_MODULE_OBEX_SRV, /**< 24 OBEX protocol server, Generic Object Exchange Profile */
OI_MODULE_OPP_CLI, /**< 25 Object Push Profile protocol client */
OI_MODULE_OPP_SRV, /**< 26 Object Push Profile protocol server */
OI_MODULE_PAN, /**< 27 PAN profile */
OI_MODULE_PBAP_CLI, /**< 28 Phonebook Access Profile client */
OI_MODULE_PBAP_SRV, /**< 29 Phonebook Access Profile server */
OI_MODULE_SAP_CLI, /**< 30 SIM Access Profile */
OI_MODULE_SAP_SRV, /**< 31 SIM Access Profile */
OI_MODULE_SPP, /**< 32 Serial Port Profile */
OI_MODULE_SYNC_CLI, /**< 33 Synchronization Profile */
OI_MODULE_SYNC_SRV, /**< 34 Synchronization Profile */
OI_MODULE_SYNC_CMD_CLI, /**< 35 Synchronization Profile */
OI_MODULE_SYNC_CMD_SRV, /**< 36 Synchronization Profile */
OI_MODULE_SYNCML, /**< 37 SyncML Profile */
OI_MODULE_TCS, /**< 38 TCS Binary */
OI_MODULE_VDP, /**< 39 Video Distribution Profile */
/* corestack components --> Updates to oi_debug.c and oi_config_table.c */
OI_MODULE_COMMON_CONFIG, /**< 40 Common configuration, module has no meaning other than for config struct */
OI_MODULE_CMDCHAIN, /**< 41 Command chaining utility */
OI_MODULE_DISPATCH, /**< 42 Dispatcher */
OI_MODULE_DATAELEM, /**< 43 Data Elements, marshaller */
OI_MODULE_DEVMGR, /**< 44 Device Manager */
OI_MODULE_DEVMGR_MODES, /**< 45 Device Manager connectability/discoverability modes */
OI_MODULE_HCI, /**< 46 Host Controller Interface command layer */
OI_MODULE_L2CAP, /**< 47 L2CAP */
OI_MODULE_MEMMGR, /**< 48 modules that do memory management */
OI_MODULE_POLICYMGR, /**< 49 Policy Manager */
OI_MODULE_RFCOMM, /**< 50 RFCOMM */
OI_MODULE_RFCOMM_SD, /**< 51 RFCOMM Service discovery */
OI_MODULE_SDP_CLI, /**< 52 Service Discovery Protocol client */
OI_MODULE_SDP_SRV, /**< 53 Service Discovery Protocol server */
OI_MODULE_SDPDB, /**< 54 Service Discovery Protocol database */
OI_MODULE_SECMGR, /**< 55 Security Manager */
OI_MODULE_SNIFFLOG, /**< 56 sniff log */
OI_MODULE_SUPPORT, /**< 57 support functions, including CThru Dispatcher, time functions, and stack initialization */
OI_MODULE_TRANSPORT, /**< 58 transport layer between HCI command layer and driver */
OI_MODULE_TEST, /**< 59 used to debug output from internal test programs */
OI_MODULE_XML, /**< 60 XML/CSS parser */
OI_MODULE_DI, /**< 61 Device Identification Profile */
// bhapi components --> Updates to oi_debug.c
OI_MODULE_BHAPI, /**< 62 BLUEmagic Host API generic */
OI_MODULE_BHCLI, /**< 63 BLUEmagic Host API client side */
OI_MODULE_BHSRV, /**< 64 BLUEmagic Host API server side */
OI_MODULE_MSGQ, /**< 65 module that handles message queuing */
OI_MODULE_BHAPI_TRANSPORT, /**< 66 module that handles message queuing */
OI_MODULE_BLST_SRV, /**< 67 module that provides server side BHAPI Lightweight Serial Transport */
OI_MODULE_BLST_CLI, /**< 68 module that provides client side BHAPI Lightweight Serial Transport */
// OEM files --> Updates to oi_debug.c
OI_MODULE_OEM, /**< 69 Application Memory allocation */
// Application glue --> Updates to oi_debug.c
OI_MODULE_APP, /**< 70 Application Memory allocation */
/* various pieces of code depend on these last 2 elements occuring in a specific order:
OI_MODULE_ALL must be the 2nd to last element
OI_MODULE_UNKNOWN must be the last element
*/
OI_MODULE_ALL, /**< 71 special value identifying all modules - used for control of debug print statements */
OI_MODULE_UNKNOWN /**< 72 special value - used for debug print statements */
} OI_MODULE;
/**
* This constant is the number of actual modules in the list. ALL and UNKNOWN are
* special values that are not actually modules.
* Used for debug print and memmgr profiling
*/
#define OI_NUM_MODULES OI_MODULE_ALL
/**
* This constant is the number of profile and core components. It is used to size
* the initialization and configuration tables.
*/
#define OI_NUM_STACK_MODULES OI_MODULE_BHAPI
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_MODULES_H */
@@ -0,0 +1,197 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_OSINTERFACE_H
#define _OI_OSINTERFACE_H
/**
@file
* This file provides the platform-independent interface for functions for which
* implementation is platform-specific.
*
* The functions in this header file define the operating system or hardware
* services needed by the BLUEmagic 3.0 protocol stack. The
* actual implementation of these services is platform-dependent.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_stddefs.h"
#include "oi_time.h"
#include "oi_status.h"
#include "oi_modules.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Terminates execution.
*
* @param reason Reason for termination
*/
void OI_FatalError(OI_STATUS reason);
/**
* This function logs an error.
*
* When built for release mode, BLUEmagic 3 errors are logged to
* this function. (in debug mode, errors are logged via
* OI_Print()).
*
* @param module Module in which the error was detected (see
* oi_modules.h)
* @param lineno Line number of the C file OI_SLOG_ERROR called
* @param status Status code associated with the error event
*/
void OI_LogError(OI_MODULE module, OI_INT lineno, OI_STATUS status);
/**
* This function initializes the debug code handling.
*
* When built for debug mode, this function performs platform
* dependent initialization to handle message codes passed in
* via OI_SetMsgCode().
*/
void OI_InitDebugCodeHandler(void);
/**
* This function reads the time from the real time clock.
*
* All timing in BM3 is relative, typically a granularity
* of 5 or 10 msecs is adequate.
*
* @param[out] now Pointer to the buffer to which the current
* time will be returned
*/
void OI_Time_Now(OI_TIME *now);
/**
* This function causes the current thread to sleep for the
* specified amount of time. This function must be called
* without the stack access token.
*
* @note BM3 corestack and profiles never suspend and never call
* OI_Sleep. The use of OI_Sleep is limited to applications and
* platform-specific code.
*
* If your port and applications never use OI_Sleep, this function can be left unimplemented.
*
* @param milliseconds Number of milliseconds to sleep
*/
void OI_Sleep(OI_UINT32 milliseconds);
/**
* Defines for message type codes.
*/
#define OI_MSG_CODE_APPLICATION 0 /**< Application output */
#define OI_MSG_CODE_ERROR 1 /**< Error message output */
#define OI_MSG_CODE_WARNING 2 /**< Warning message output */
#define OI_MSG_CODE_TRACE 3 /**< User API function trace output */
#define OI_MSG_CODE_PRINT1 4 /**< Catagory 1 debug print output */
#define OI_MSG_CODE_PRINT2 5 /**< Catagory 2 debug print output */
#define OI_MSG_CODE_HEADER 6 /**< Error/Debug output header */
/**
* This function is used to indicate the type of text being output with
* OI_Print(). For the Linux and Win32 platforms, it will set
* the color of the text. Other possible uses could be to insert
* HTML style tags, add some other message type indication, or
* be completely ignored altogether.
*
* @param code OI_MSG_CODE_* indicating setting the message type.
*/
void OI_SetMsgCode(OI_UINT8 code);
/**
* All output from OI_Printf() and all debug output is sent to OI_Print.
* Typically, if the platform has a console, OI_Print() is sent to stdout.
* Embedded platforms typically send OI_Print() output to a serial port.
*
* @param str String to print
*/
void OI_Print(OI_CHAR const *str);
/**
* In cases where OI_Print() is sending output to a logfile in addition to console,
* it is desirable to also put console input into the logfile.
* This function can be called by the console input process.
*
* @note This is an optional API which is strictly
* between the platform-specific stack_console and osinterface
* modules. This API need only be implemented on those
* platforms where is serves a useful purpose, e.g., win32.
*
* @param str Console input string
*/
void OI_Print_ConsoleInput(OI_CHAR const *str);
/**
* This function computes the CRC16 of the program image.
*/
OI_UINT16 OI_ProgramImageCRC16(void);
/**
* Writes an integer to stdout in hex. This macro is intended
* for selective use when debugging in small memory
* configurations or other times when it is not possible to use
* OI_DBGPRINT.
*
* @param n the integer to print
*/
#define OI_Print_Int(n) \
{ \
static const OI_CHAR _digits[] = "0123456789ABCDEF"; \
OI_CHAR _buf[9]; \
OI_CHAR *_str = &_buf[8]; \
OI_UINT32 _i = n; \
*_str = 0; \
do { *(--_str) = _digits[(_i & 0xF)]; _i >>= 4; } while (_i); \
OI_Print(_str); \
}
/**
* Application Dynamic Memory allocation.
*
* These APIs are provided for application use on those
* platforms which have no dynamic memory support. Memory is
* allocated from the pool-based heap managed by the stack's
* internal memory manager.
*/
void *OI_APP_Malloc(OI_INT32 size);
void OI_APP_Free(void *ptr);
/*****************************************************************************/
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_OSINTERFACE_H */
+579
View File
@@ -0,0 +1,579 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_STATUS_H
#define _OI_STATUS_H
/**
* @file
* This file contains status codes for BLUEmagic 3.0 software.
*/
#include "oi_stddefs.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/** test it **/
/**
* OI_STATUS must fit in 16 bits, so status codes can range from 0 to 66535, inclusive.
*/
typedef enum {
OI_STATUS_SUCCESS = 0, /**< function call succeeded alias for #OI_OK */
OI_OK = 0, /**< function call succeeded alias for #OI_STATUS_SUCCESS */
OI_STATUS_INVALID_PARAMETERS = 101, /**< invalid function input parameters */
OI_STATUS_NOT_IMPLEMENTED = 102, /**< attempt to use an unimplemented function */
OI_STATUS_NOT_INITIALIZED = 103, /**< data not initialized */
OI_STATUS_NO_RESOURCES = 104, /**< generic resource allocation failure status */
OI_STATUS_INTERNAL_ERROR = 105, /**< internal inconsistency */
OI_STATUS_OUT_OF_MEMORY = 106, /**< generally, OI_Malloc failed */
OI_ILLEGAL_REENTRANT_CALL = 107, /**< violation of non-reentrant module policy */
OI_STATUS_INITIALIZATION_FAILED = 108, /**< module initialization failed */
OI_STATUS_INITIALIZATION_PENDING = 109, /**< inititialization not yet complete */
OI_STATUS_NO_SCO_SUPPORT = 110, /**< SCO operation rejected; system not configured for SCO */
OI_STATUS_OUT_OF_STATIC_MEMORY = 111, /**< static malloc failed */
OI_TIMEOUT = 112, /**< generic timeout */
OI_OS_ERROR = 113, /**< some operating system error */
OI_FAIL = 114, /**< generic failure */
OI_STRING_FORMAT_ERROR = 115, /**< error in VarString formatting string */
OI_STATUS_PENDING = 116, /**< The operation is pending. */
OI_STATUS_INVALID_COMMAND = 117, /**< The command was invalid. */
OI_BUSY_FAIL = 118, /**< command rejected due to busy */
OI_STATUS_ALREADY_REGISTERED = 119, /**< The registration has already been performed. */
OI_STATUS_NOT_FOUND = 120, /**< The referenced resource was not found. */
OI_STATUS_NOT_REGISTERED = 121, /**< not registered */
OI_STATUS_NOT_CONNECTED = 122, /**< not connected */
OI_CALLBACK_FUNCTION_REQUIRED = 123, /**< A callback function parameter was required. */
OI_STATUS_MBUF_OVERFLOW = 124, /**< There is no room to add another buffer to an mbuf. */
OI_STATUS_MBUF_UNDERFLOW = 125, /**< There was an attempt to pull too many bytes from an mbuf. */
OI_STATUS_CONNECTION_EXISTS = 126, /**< connection exists */
OI_STATUS_NOT_CONFIGURED = 127, /**< module not configured */
OI_LOWER_STACK_ERROR = 128, /**< An error was reported by lower stack API. This is used for embedded platforms. */
OI_STATUS_RESET_IN_PROGRESS = 129, /**< Request failed/rejected because we're busy resetting. */
OI_STATUS_ACCESS_DENIED = 130, /**< Generic access denied error. */
OI_STATUS_DATA_ERROR = 131, /**< Generic data error. */
OI_STATUS_INVALID_ROLE = 132, /**< The requested role was invalid. */
OI_STATUS_ALREADY_CONNECTED = 133, /**< The requested connection is already established. */
OI_STATUS_PARSE_ERROR = 134, /**< Parse error */
OI_STATUS_END_OF_FILE = 135, /**< End of file */
OI_STATUS_READ_ERROR = 136, /**< Generic read error */
OI_STATUS_WRITE_ERROR = 137, /**< Generic write error */
OI_STATUS_NEGOTIATION_FAILURE = 138, /**< Error in negotiation */
OI_STATUS_READ_IN_PROGRESS = 139, /**< A read is already in progress */
OI_STATUS_ALREADY_INITIALIZED = 140, /**< Initialization has already been done */
OI_STATUS_STILL_CONNECTED = 141, /**< The service cannot be shutdown because there are still active connections. */
OI_STATUS_MTU_EXCEEDED = 142, /**< The packet is too big */
OI_STATUS_LINK_TERMINATED = 143, /**< The link was terminated */
OI_STATUS_PIN_CODE_TOO_LONG = 144, /**< Application gave us a pin code that is too long */
OI_STATUS_STILL_REGISTERED = 145, /**< The service cannot be shutdown because there are still active registrations. */
OI_STATUS_SPEC_VIOLATION = 146, /**< Some application behavior contrary to BT specifications */
OI_STATUS_PSM_ALREADY_REGISTERED = 402, /**< L2CAP: The specified PSM has already been registered. */
OI_STATUS_INVALID_CID = 403, /**< L2CAP: CID is invalid or no longer valid (connection terminated) */
OI_STATUS_CID_NOT_FOUND = 404, /**< L2CAP: CID does not represent a current connection */
OI_STATUS_CHANNEL_NOT_FOUND = 406, /**< L2CAP: CID does not represent a current connection */
OI_STATUS_PSM_NOT_FOUND = 407, /**< L2CAP: PSM not found */
OI_STATUS_INVALID_STATE = 408, /**< L2CAP: invalid state */
OI_STATUS_WRITE_IN_PROGRESS = 410, /**< L2CAP: write in progress */
OI_STATUS_INVALID_PACKET = 411, /**< L2CAP: invalid packet */
OI_STATUS_SEND_COMPLETE = 412, /**< L2CAP: send is complete */
OI_STATUS_INVALID_HANDLE = 414, /**< L2CAP: handle is invalid */
OI_STATUS_GROUP_FULL = 418, /**< L2CAP: No more members can be added to the specified group. */
OI_STATUS_DEVICE_ALREADY_IN_GROUP = 423, /**< L2CAP: The device already exists in the group. */
OI_STATUS_DUPLICATE_GROUP = 425, /**< L2CAP: attempt to add more than one group */
OI_STATUS_EMPTY_GROUP = 426, /**< L2CAP: group is empty */
OI_STATUS_PACKET_NOT_FOUND = 427, /**< L2CAP: packet not found */
OI_STATUS_BUFFER_TOO_SMALL = 428, /**< L2CAP: The buffer size is too small. */
OI_STATUS_IDENTIFIER_NOT_FOUND = 429, /**< L2CAP: identifier not found */
OI_L2CAP_DISCONNECT_LOWER_LAYER = 430, /**< L2CAP: The lower level forced a disconnect. */
OI_L2CAP_DISCONNECT_REMOTE_REQUEST = 431, /**< L2CAP: The remote device requested a disconnect. */
OI_L2CAP_GROUP_ADD_CONNECT_FAIL = 433, /**< L2CAP: Group add connect faiL */
OI_L2CAP_GROUP_REMOVE_FAILURE = 434, /**< L2CAP: Group remove failure */
OI_L2CAP_DATA_WRITE_ERROR_LINK_TERM = 435, /**< L2CAP: Data write error LINK_TERM */
OI_L2CAP_DISCONNECT_LOCAL_REQUEST = 436, /**< L2CAP: Disconnect local request */
OI_L2CAP_CONNECT_TIMEOUT = 437, /**< L2CAP: Connect timeout */
OI_L2CAP_DISCONNECT_TIMEOUT = 439, /**< L2CAP: Disconnect timeout */
OI_L2CAP_PING_TIMEOUT = 440, /**< L2CAP: Ping timeout */
OI_L2CAP_GET_INFO_TIMEOUT = 441, /**< L2CAP: Get info timeout */
OI_L2CAP_INVALID_ADDRESS = 444, /**< L2CAP: Invalid address */
OI_L2CAP_CMD_REJECT_RCVD = 445, /**< L2CAP: remote sent us 'command reject' response */
OI_L2CAP_CONNECT_BASE = 450, /**< L2CAP: Connect base */
OI_L2CAP_CONNECT_PENDING = 451, /**< L2CAP: Connect pending */
OI_L2CAP_CONNECT_REFUSED_INVALID_PSM = 452, /**< L2CAP: Connect refused invalid PSM */
OI_L2CAP_CONNECT_REFUSED_SECURITY = 453, /**< L2CAP: Connect refused security */
OI_L2CAP_CONNECT_REFUSED_NO_RESOURCES = 454, /**< L2CAP: Connect refused no resources */
OI_L2CAP_CONFIG_BASE = 460, /**< L2CAP: Config base */
OI_L2CAP_CONFIG_FAIL_INVALID_PARAMETERS= 461, /**< L2CAP: Config fail invalid parameters */
OI_L2CAP_CONFIG_FAIL_NO_REASON = 462, /**< L2CAP: Config fail no reason */
OI_L2CAP_CONFIG_FAIL_UNKNOWN_OPTIONS = 463, /**< L2CAP: Config fail unknown options */
OI_L2CAP_GET_INFO_BASE = 470, /**< L2CAP: Get info base */
OI_L2CAP_GET_INFO_NOT_SUPPORTED = 471, /**< L2CAP: Get info not supported */
OI_L2CAP_MTU_EXCEEDED = 472, /**< L2CAP: The MTU of the channel was exceeded */
OI_L2CAP_INVALID_PSM = 482, /**< L2CAP: Invalid PSM */
OI_L2CAP_INVALID_MTU = 483, /**< L2CAP: Invalid MTU */
OI_L2CAP_INVALID_FLUSHTO = 484, /**< L2CAP: Invalid flush timeout */
OI_HCI_NO_SUCH_CONNECTION = 601, /**< HCI: caller specified a non-existent connection handle */
OI_HCI_CB_LIST_FULL = 603, /**< HCI: callback list is full, cannot attempt to send command */
OI_HCI_EVENT_UNDERRUN = 605, /**< HCI: parsing event packet, premature end-of-parameters */
OI_HCI_UNKNOWN_EVENT_CODE = 607, /**< HCI: event received - event code is unknown */
OI_HCI_BAD_EVENT_PARM_LEN = 608, /**< HCI: event - parameter length is incorrect */
OI_HCI_CMD_QUEUE_FULL = 611, /**< HCI: command queue is full */
OI_HCI_SHORT_EVENT = 612, /**< HCI: event received, missing event code and/or parm len */
OI_HCI_TRANSMIT_NOT_READY = 613, /**< HCI: ACL/SCO transmit request failed - busy or no buffers available */
OI_HCI_ORPHAN_SENT_EVENT = 614, /**< HCI: got spurious 'sent' event from transport layer */
OI_HCI_CMD_TABLE_ERROR = 615, /**< HCI: inconsistency in the internal command table */
OI_HCI_UNKNOWN_CMD_ID = 616, /**< HCI: HciApi Command - unknown command id */
OI_HCI_UNEXPECTED_EVENT = 619, /**< HCI: event received which only occurs in response to our cmd */
OI_HCI_EVENT_TABLE_ERROR = 620, /**< HCI: inconsistency in the internal event table */
OI_HCI_EXPECTED_EVENT_TIMOUT = 621, /**< HCI: timed out waiting for an expected event */
OI_HCI_NO_CMD_DESC_FOR_OPCODE = 622, /**< HCI: event opcode is not known */
OI_HCI_INVALID_OPCODE_ERROR = 623, /**< HCI: command opcode is invalid */
OI_HCI_FLOW_CONTROL_DISABLED = 624, /**< HCI: can not use host flow control APIs if disabled in configuration */
OI_HCI_TX_COMPLETE = 625, /**< HCI: packet delivery to Host Controler complete */
OI_HCI_TX_ERROR = 626, /**< HCI: failed to deliver packet to Host Controler */
OI_HCI_DEVICE_NOT_INITIALIZED = 627, /**< HCI: commands from upper layers disallowed until device is up and running */
OI_HCI_UNSUPPORTED_COMMAND = 628, /**< HCI: command requested is not supported by local device */
OI_HCI_PASSTHROUGH_ERROR = 629, /**< HCI: Error processing passthrough command */
OI_HCI_PASSTHROUGH_ALREADY_SET = 630, /**< HCI: Passthrough mode already enabled */
OI_HCI_RESET_FAILURE = 631, /**< HCI: failed to reset the device/baseband */
OI_HCI_TRANSPORT_RESET = 632, /**< HCI: some operation failed because of a reset in the transport */
OI_HCIERR_HCIIFC_INIT_FAILURE = 633, /**< HCI: failed to initialize transport layer interface */
OI_HCIERR_FIRST_ERROR_VALUE = 701, /**< marker for first HCI protocol error */
OI_HCIERR_UNKNOWN_HCI_COMMAND = 701, /**< HCI: protocol error 0x01 */
OI_HCIERR_NO_CONNECTION = 702, /**< HCI: protocol error 0x02 */
OI_HCIERR_HARDWARE_FAILURE = 703, /**< HCI: protocol error 0x03 */
OI_HCIERR_PAGE_TIMEOUT = 704, /**< HCI: protocol error 0x04 */
OI_HCIERR_AUTHENTICATION_FAILURE = 705, /**< HCI: protocol error 0x05 */
OI_HCIERR_KEY_MISSING = 706, /**< HCI: protocol error 0x06 */
OI_HCIERR_MEMORY_FULL = 707, /**< HCI: protocol error 0x07 */
OI_HCIERR_CONNECTION_TIMEOUT = 708, /**< HCI: protocol error 0x08 */
OI_HCIERR_MAX_NUM_OF_CONNECTIONS = 709, /**< HCI: protocol error 0x09 */
OI_HCIERR_MAX_NUM_OF_SCO_CONNECTIONS = 710, /**< HCI: protocol error 0x0A */
OI_HCIERR_ACL_CONNECTION_ALREADY_EXISTS = 711, /**< HCI: protocol error 0x0B */
OI_HCIERR_COMMAND_DISALLOWED = 712, /**< HCI: protocol error 0x0C */
OI_HCIERR_HOST_REJECTED_RESOURCES = 713, /**< HCI: protocol error 0x0D */
OI_HCIERR_HOST_REJECTED_SECURITY = 714, /**< HCI: protocol error 0x0E */
OI_HCIERR_HOST_REJECTED_PERSONAL_DEVICE = 715, /**< HCI: protocol error 0x0F */
OI_HCIERR_HOST_TIMEOUT = 716, /**< HCI: protocol error 0x10 */
OI_HCIERR_UNSUPPORTED = 717, /**< HCI: protocol error 0x11 */
OI_HCIERR_INVALID_PARAMETERS = 718, /**< HCI: protocol error 0x12 */
OI_HCIERR_OTHER_END_USER_DISCONNECT = 719, /**< HCI: protocol error 0x13 */
OI_HCIERR_OTHER_END_LOW_RESOURCES = 720, /**< HCI: protocol error 0x14 */
OI_HCIERR_OTHER_END_POWERING_OFF = 721, /**< HCI: protocol error 0x15 */
OI_HCIERR_CONNECTION_TERMINATED_LOCALLY = 722, /**< HCI: protocol error 0x16 */
OI_HCIERR_REPEATED_ATTEMPTS = 723, /**< HCI: protocol error 0x17 */
OI_HCIERR_PAIRING_NOT_ALLOWED = 724, /**< HCI: protocol error 0x18 */
OI_HCIERR_UNKNOWN_LMP_PDU = 725, /**< HCI: protocol error 0x19 */
OI_HCIERR_UNSUPPORTED_REMOTE_FEATURE = 726, /**< HCI: protocol error 0x1A */
OI_HCIERR_SCO_OFFSET_REJECTED = 727, /**< HCI: protocol error 0x1B */
OI_HCIERR_SCO_INTERVAL_REJECTED = 728, /**< HCI: protocol error 0x1C */
OI_HCIERR_SCO_AIR_MODE_REJECTED = 729, /**< HCI: protocol error 0x1D */
OI_HCIERR_INVALID_LMP_PARMS = 730, /**< HCI: protocol error 0x1E */
OI_HCIERR_UNSPECIFIED_ERROR = 731, /**< HCI: protocol error 0x1F */
OI_HCIERR_UNSUPPORTED_LMP_PARAMETERS = 732, /**< HCI: protocol error 0x20 */
OI_HCIERR_ROLE_CHANGE_NOT_ALLOWED = 733, /**< HCI: protocol error 0x21 */
OI_HCIERR_LMP_RESPONSE_TIMEOUT = 734, /**< HCI: protocol error 0x22 */
OI_HCIERR_LMP_ERROR_TRANS_COLLISION = 735, /**< HCI: protocol error 0x23 */
OI_HCIERR_LMP_PDU_NOT_ALLOWED = 736, /**< HCI: protocol error 0x24 */
OI_HCIERR_ENCRYPTION_MODE_NOT_ACCEPTABLE = 737, /**< HCI: protocol error 0x25 */
OI_HCIERR_UNIT_KEY_USED = 738, /**< HCI: protocol error 0x26 */
OI_HCIERR_QOS_NOT_SUPPORTED = 739, /**< HCI: protocol error 0x27 */
OI_HCIERR_INSTANT_PASSED = 740, /**< HCI: protocol error 0x28 */
OI_HCIERR_UNIT_KEY_PAIRING_UNSUPPORTED = 741, /**< HCI: protocol error 0x29 */
OI_HCIERR_DIFFERENT_TRANS_COLLISION = 742, /**< HCI: protocol error 0x2A */
OI_HCIERR_RESERVED_2B = 743, /**< HCI: protocol error 0x2B */
OI_HCIERR_QOS_UNACCEPTABLE_PARAMETER = 744, /**< HCI: protocol error 0x2C */
OI_HCIERR_QOS_REJECTED = 745, /**< HCI: protocol error 0x2D */
OI_HCIERR_CHANNEL_CLASSIFICATION_NS = 746, /**< HCI: protocol error 0x2E */
OI_HCIERR_INSUFFICIENT_SECURITY = 747, /**< HCI: protocol error 0x2F */
OI_HCIERR_PARM_OUT_OF_MANDATORY_RANGE = 748, /**< HCI: protocol error 0x30 */
OI_HCIERR_RESERVED_31 = 749, /**< HCI: protocol error 0x31 */
OI_HCIERR_ROLE_SWITCH_PENDING = 750, /**< HCI: protocol error 0x32 */
OI_HCIERR_RESERVED_33 = 751, /**< HCI: protocol error 0x33 */
OI_HCIERR_RESERVED_SLOT_VIOLATION = 752, /**< HCI: protocol error 0x34 */
OI_HCIERR_ROLE_SWITCH_FAILED = 753, /**< HCI: protocol error 0x35 */
OI_HCIERR_EIR_TOO_LARGE = 754, /**< HCI: protocol error 0x36 */
OI_HCIERR_SSP_NOT_SUPPORTED_BY_HOST = 755, /**< HCI: protocol error 0x37 */
OI_HCIERR_HOST_BUSY_PAIRING = 756, /**< HCI: protocol error 0x38 */
OI_HCIERR_UNKNOWN_ERROR = 757, /**< HCI: unknown error code */
OI_HCIERR_LAST_ERROR_VALUE = 757, /**< marker for last HCI protocol error */
OI_SDP_SPEC_ERROR = 800, /**< SDP: Base error status for mapping OI_STATUS codes to SDP errors */
OI_SDP_INVALID_SERVICE_RECORD_HANDLE = (OI_SDP_SPEC_ERROR + 2), /**< SDP: protocol error Invalid Service Record Handle */
OI_SDP_INVALID_REQUEST_SYNTAX = (OI_SDP_SPEC_ERROR + 3), /**< SDP: protocol error Invalid Request Syntax */
OI_SDP_INVALID_PDU_SIZE = (OI_SDP_SPEC_ERROR + 4), /**< SDP: protocol error Invalid PDU Size */
OI_SDP_INVALID_CONTINUATION_STATE = (OI_SDP_SPEC_ERROR + 5), /**< SDP: protocol error Invalid Continuation State */
OI_SDP_INSUFFICIENT_RESOURCES = (OI_SDP_SPEC_ERROR + 6), /**< SDP: protocol error Insufficient Resources */
OI_SDP_ERROR = 807, /**< SDP: server returned an error code */
OI_SDP_CORRUPT_DATA_ELEMENT = 808, /**< SDP: Invalid or corrupt data element representation */
OI_SDP_SERVER_NOT_CONNECTED = 810, /**< SDP: Attempt to disconnect from an unconnected server */
OI_SDP_ACCESS_DENIED = 811, /**< SDP: Server denied access to server */
OI_SDP_ATTRIBUTES_OUT_OF_ORDER = 812, /**< SDP: Attributes in attribute list not in ascending order */
OI_SDP_DEVICE_DOES_NOT_SUPPORT_SDP = 813, /**< SDP: Tried to connect to a device that does not support SDP */
OI_SDP_NO_MORE_DATA = 815, /**< SDP: Server does not have more continuation data */
OI_SDP_REQUEST_PARAMS_TOO_LONG = 816, /**< SDP: Parameters for a request exceed the L2CAP buffer size */
OI_SDP_REQUEST_PENDING = 817, /**< SDP: Cannot make a request when another request is being processed */
OI_SDP_SERVER_CONNECT_FAILED = 819, /**< SDP: Failed attempt to connect to an SDP server */
OI_SDP_SERVER_TOO_MANY_CONNECTIONS = 821, /**< SDP: Exceeded maximum number of simultaneous server connections */
OI_SDP_NO_MATCHING_SERVICE_RECORD = 823, /**< SDP: No service record matched the UUID list */
OI_SDP_PARTIAL_RESPONSE = 824, /**< SDP: Internal use only */
OI_SDP_ILLEGAL_ARGUMENT = 825, /**< SDP: Illegal argument passed to an SDP function */
OI_SDP_ATTRIBUTE_NOT_FOUND = 826, /**< SDP: A requested attribute was not found in a service record */
OI_SDP_DATABASE_OUT_OF_RESOURCES = 827, /**< SDP: server database is out of memory */
OI_SDP_SHORT_PDU = 829, /**< SDP: Not enough bytes in the packet */
OI_SDP_TRANSACTION_ID_MISMATCH = 830, /**< SDP: Transaction Id was not as expected */
OI_SDP_UNEXPECTED_RESPONSE_PDU_ID = 831, /**< SDP: Did not expect this response PDU */
OI_SDP_REQUEST_TIMEOUT = 832, /**< SDP: Did not get a response within the timeout period */
OI_SDP_INVALID_RESPONSE_SYNTAX = 833, /**< SDP: Response is not correctly formatted */
OI_SDP_CONNECTION_TIMEOUT = 834, /**< SDP: Connection attempt timed out at a lower layer */
OI_SDP_RESPONSE_DATA_ERROR = 835, /**< SDP: Response to a service request appears to be corrupt */
OI_SDP_TOO_MANY_ATTRIBUTE_BYTES = 836, /**< SDP: Response contained more bytes than requested. */
OI_SDP_TOO_MANY_SERVICE_RECORDS = 837, /**< SDP: Response contained more service records than requested. */
OI_SDP_INVALID_CONNECTION_ID = 838, /**< SDP: Invalid connection ID in an SDP request */
OI_SDP_CANNOT_SET_ATTRIBUTE = 839, /**< SDP: Attempt to set a dynamic attribute value failed */
OI_SDP_BADLY_FORMED_ATTRIBUTE_VALUE = 840, /**< SDP: An attribute value has the wrong type or structure */
OI_SDP_NO_ATTRIBUTE_LIST_TO_REMOVE = 841, /**< SDP: Attempt to remove a non-existent attribute list from a service record */
OI_SDP_ATTRIBUTE_LIST_ALREADY_ADDED = 842, /**< SDP: An attribute list has already been added to the service record */
OI_SDP_DATA_ELEMENT_TRUNCATED = 843, /**< SDP: Data element truncated (too few bytes) */
OI_RFCOMM_WRITE_IN_PROGRESS = 901, /**< RFCOMM: Write in progress */
OI_RFCOMM_INVALID_BAUDRATE = 903, /**< RFCOMM: Invalid baudrate */
OI_RFCOMM_INVALID_DATABIT = 904, /**< RFCOMM: Invalid databit */
OI_RFCOMM_INVALID_STOPBIT = 905, /**< RFCOMM: Invalid stopbit */
OI_RFCOMM_INVALID_PARITY = 906, /**< RFCOMM: Invalid parity */
OI_RFCOMM_INVALID_PARITYTYPE = 907, /**< RFCOMM: Invalid paritytype */
OI_RFCOMM_INVALID_FLOWCONTROL = 908, /**< RFCOMM: Invalid flowcontrol */
OI_RFCOMM_SESSION_EXISTS = 909, /**< RFCOMM: Session exists */
OI_RFCOMM_INVALID_CHANNEL = 910, /**< RFCOMM: Invalid channel */
OI_RFCOMM_DLCI_EXISTS = 911, /**< RFCOMM: DLCI exists */
OI_RFCOMM_LINK_NOT_FOUND = 912, /**< RFCOMM: Link not found */
OI_RFCOMM_REMOTE_REJECT = 913, /**< RFCOMM: Remote reject */
OI_RFCOMM_TEST_IN_PROGRESS = 915, /**< RFCOMM: Test in progress */
OI_RFCOMM_SESSION_NOT_FOUND = 916, /**< RFCOMM: Session not found */
OI_RFCOMM_INVALID_PACKET = 917, /**< RFCOMM: Invalid packet */
OI_RFCOMM_FRAMESIZE_EXCEEDED = 918, /**< RFCOMM: Framesize exceeded */
OI_RFCOMM_INVALID_DLCI = 920, /**< RFCOMM: Invalid dlci */
OI_RFCOMM_SERVER_NOT_REGISTERED = 921, /**< RFCOMM: Server not registered */
OI_RFCOMM_CREDIT_ERROR = 922, /**< RFCOMM: Credit error */
OI_RFCOMM_NO_CHANNEL_NUMBER = 923, /**< RFCOMM: No channel number */
OI_RFCOMM_QUERY_IN_PROGRESS = 924, /**< RFCOMM: Query in progress */
OI_RFCOMM_SESSION_SHUTDOWN = 925, /**< RFCOMM: Session shutdown */
OI_RFCOMM_LOCAL_DEVICE_DISCONNECTED = 926, /**< RFCOMM: Local device disconnected */
OI_RFCOMM_REMOTE_DEVICE_DISCONNECTED = 927, /**< RFCOMM: Remote device disconnected */
OI_RFCOMM_OUT_OF_SERVER_CHANNELS = 928, /**< RFCOMM: Out of server channels */
OI_DISPATCH_INVALID_CB_HANDLE = 1001, /**< Dispatcher was handed an invalid callback handle */
OI_DISPATCH_TABLE_OVERFLOW = 1002, /**< Dispatcher table is full */
OI_TEST_UNKNOWN_TEST = 1101, /**< TEST: Unknown test */
OI_TEST_FAIL = 1102, /**< TEST: Fail */
OI_HCITRANS_CANNOT_CONNECT_TO_DEVICE = 1201, /**< TRANSPORT: Cannot connect to device */
OI_HCITRANS_BUFFER_TOO_SMALL = 1203, /**< TRANSPORT: Buffer too small */
OI_HCITRANS_NULL_DEVICE_HANDLE = 1204, /**< TRANSPORT: Null device handle */
OI_HCITRANS_IO_ERROR = 1205, /**< TRANSPORT: IO error */
OI_HCITRANS_DEVICE_NOT_READY = 1206, /**< TRANSPORT: Device not ready */
OI_HCITRANS_FUNCTION_NOT_SUPPORTED = 1207, /**< TRANSPORT: Function not supporteD */
OI_HCITRANS_ACCESS_DENIED = 1209, /**< TRANSPORT: win32 */
OI_HCITRANS_ACL_DATA_ERROR = 1210, /**< TRANSPORT: ACL data error */
OI_HCITRANS_SCO_DATA_ERROR = 1211, /**< TRANSPORT: SCO data error */
OI_HCITRANS_EVENT_DATA_ERROR = 1212, /**< TRANSPORT: HCI event data error */
OI_HCITRANS_INTERNAL_ERROR = 1214, /**< TRANSPORT: Internal error in the transport */
OI_HCITRANS_LINK_NOT_ACTIVE = 1215, /**< TRANSPORT: Link to the device is not currently active */
OI_HCITRANS_INITIALIZING = 1216, /**< TRANSPORT: Transport is initializing */
OI_DEVMGR_NO_CONNECTION = 1301, /**< DEVMGR: No connection */
OI_DEVMGR_HARDWARE_ERROR = 1305, /**< DEVMGR: error reported by HCI */
OI_DEVMGR_PENDING_CONNECT_LIST_FULL = 1307, /**< DEVMGR: Pending connect list full */
OI_DEVMGR_CONNECTION_LIST_FULL = 1309, /**< DEVMGR: Connection list full */
OI_DEVMGR_NO_SUCH_CONNECTION = 1310, /**< DEVMGR: No such connection */
OI_DEVMGR_INQUIRY_IN_PROGRESS = 1311, /**< DEVMGR: Inquiry in progress */
OI_DEVMGR_PERIODIC_INQUIRY_ACTIVE = 1312, /**< DEVMGR: Periodic inquiry active */
OI_DEVMGR_NO_INQUIRIES_ACTIVE = 1313, /**< DEVMGR: can not cancel/exit if not active */
OI_DEVMGR_DUPLICATE_CONNECTION = 1314, /**< DEVMGR: internal error */
OI_DEVMGR_DUPLICATE_EVENT_CALLBACK = 1316, /**< DEVMGR: attempt to register same callback twice */
OI_DEVMGR_EVENT_CALLBACK_LIST_FULL = 1317, /**< DEVMGR: can not register event callback, list is full */
OI_DEVMGR_EVENT_CALLBACK_NOT_FOUND = 1318, /**< DEVMGR: attempt to unregister callback failed */
OI_DEVMGR_BUSY = 1319, /**< DEVMGR: some operations can only execute one at a time */
OI_DEVMGR_ENUM_UNEXPECTED_INQ_COMPLETE = 1320, /**< DEVMGR: inquiry complete event in inappropriate enumeration state */
OI_DEVMGR_ENUM_UNEXPECTED_INQ_RESULT = 1321, /**< DEVMGR: inquiry result event in inappropriate enumeration state */
OI_DEVMGR_ENUM_DATABASE_FULL = 1322, /**< DEVMGR: device enumeration, database is full, couldn't add a new device */
OI_DEVMGR_ENUM_INQUIRIES_OVERLAP = 1323, /**< DEVMGR: device enumeration, periodic inquiries occurring too close together */
OI_DEVMGR_UNKNOWN_LINK_TYPE = 1324, /**< DEVMGR: HCI connect request with unkown link type */
OI_DEVMGR_PARAM_IO_ACTIVE = 1325, /**< DEVMGR: request for parameter read/write while param read/write active */
OI_DEVMGR_UNKNOWN_IAC_LAP = 1326, /**< DEVMGR: unrecognized IAC LAP */
OI_DEVMGR_SCO_ALREADY_REGISTERED = 1327, /**< DEVMGR: only one application can use SCO */
OI_DEVMGR_SCO_NOT_REGISTERED = 1328, /**< DEVMGR: SCO applications must register before using the API */
OI_DEVMGR_SCO_WITHOUT_ACL = 1329, /**< DEVMGR: Got SCO connection but there is no underlying ACL connection */
OI_DEVMGR_NO_SUPPORT = 1330, /**< DEVMGR: Request is not supported by the device */
OI_DEVMGR_WRITE_POLICY_FAILED = 1331, /**< DEVMGR: connection attempt failed - unable to write link policy */
OI_DEVMGR_NOT_IN_MASTER_MODE = 1332, /**< DEVMGR: OI_DEVMGR EndMasterMode without prior OI_DEVMGR_BeginMasterMode */
OI_DEVMGR_POLICY_VIOLATION = 1333, /**< DEVMGR: low-power request is rejected - link policy does not allow it */
OI_DEVMGR_BUSY_TIMEOUT = 1334, /**< DEVMGR: queued operation timed out while in the queue; \n
timeout configurable via @ref OI_CONFIG_DEVMGR::connectQueueTimeoutSecs "connectQueueTimeoutSecs" */
OI_DEVMGR_REENCRYPT_FAILED = 1335, /**< DEVMGR: failed to re-encrypt link after role switch */
OI_DEVMGR_ROLE_POLICY_CONFLICT = 1336, /**< DEVMGR: requested role conflicts with current policy */
OI_DEVMGR_BAD_INTERVAL = 1337, /**< DEVMGR: current linkTO outside range of requested min/max interval */
OI_DEVMGR_INVALID_SCO_HANDLE = 1338, /**< DEVMGR: HCI SCO event, invalid handle */
OI_DEVMGR_CONNECTION_OVERLAP = 1339, /**< DEVMGR: Connection failed due to race condition with remote side */
OI_DEVMGR_ORPHAN_SUBRATE_COMPLETE = 1340, /**< DEVMGR: sniff subrate complete, but no callback */
OI_DEVMGR_EIR_RESPONSE_2_LARGE = 1341, /**< DEVMGR: eir builder, response length would exceed spec max */
OI_SECMGR_NO_POLICY = 1401, /**< SECMGR: no security policy has been established */
OI_SECMGR_INTERNAL_ERROR = 1402, /**< SECMGR: internal inconsistency */
OI_SECMGR_ORPHANED_CALLBACK = 1403, /**< SECMGR: we've been called back, but CB context is gone */
OI_SECMGR_BUSY = 1404, /**< SECMGR: configure and access request cannot be concurrent */
OI_SECMGR_DEVICE_NOT_TRUSTED = 1405, /**< SECMGR: l2cap access denied - device is not trusted */
OI_SECMGR_DEVICE_ENCRYPT_FAIL = 1407, /**< SECMGR: l2cap access denied - failed to start encryption */
OI_SECMGR_DISCONNECTED_FAIL = 1408, /**< SECMGR: l2cap access denied - disconnected */
OI_SECMGR_ACCESS_PENDING = 1409, /**< SECMGR: l2cap access request is still pending */
OI_SECMGR_PIN_CODE_TOO_SHORT = 1410, /**< SECMGR: Higher-layer process gave us a pin code that is too short */
OI_SECMGR_UNKNOWN_ENCRYPT_VALUE = 1411, /**< SECMGR: got EncryptionChange event, unknown encryption enable value */
OI_SECMGR_INVALID_POLICY = 1412, /**< SECMGR: the specified security policy is not valid for security mode */
OI_SECMGR_AUTHORIZATION_FAILED = 1413, /**< SECMGR: device authorization failed */
OI_SECMGR_ENCRYPTION_FAILED = 1414, /**< SECMGR: device encryption failed */
OI_SECMGR_UNIT_KEY_UNSUPPORTED = 1415, /**< SECMGR: authentication failed due to non-support of unit keys */
OI_SECMGR_NOT_REGISTERED = 1416, /**< SECMGR: required registrations have not yet occurred */
OI_SECMGR_ILLEGAL_WRITE_SSP_MODE = 1417, /**< SECMGR: 2.1 HCI spec does not allow SSP mode to be disabled */
OI_SECMGR_INVALID_SEC_LEVEL = 1418, /**< SECMGR: security level for a service is not a valid value */
OI_SECMGR_INSUFFICIENT_LINK_KEY = 1419, /**< SECMGR: link key type is not sufficient to meet service requirements */
OI_SECMGR_INVALID_KEY_TYPE = 1420, /**< SECMGR: link key type is not a valid value */
OI_SECMGR_SSP_NOT_ENCRYPTED = 1421, /**< SECMGR: ssp required encryption on incoming link */
OI_SECMGR_ORPHAN_EVENT = 1422, /**< SECMGR: some HCI security event unrelated to current processes */
OI_SECMGR_NOT_BONDABLE = 1423, /**< SECMGR: not in bondable mode */
OI_TCS_INVALID_ELEMENT_TYPE = 1602, /**< TCS: element type is invalid */
OI_TCS_INVALID_PACKET = 1603, /**< TCS: packet is invalide */
OI_TCS_CALL_IN_PROGRESS = 1604, /**< TCS: call is in progress */
OI_TCS_NO_CALL_IN_PROGRESS = 1605, /**< TCS: no call in progress */
OI_OBEX_CONTINUE = 1701, /**< OBEX: Continue processing OBEX request */
OI_OBEX_COMMAND_ERROR = 1702, /**< OBEX: An unrecognized OBEX command opcode */
OI_OBEX_CONNECTION_TIMEOUT = 1703, /**< OBEX: Timeout waiting for a response to a request */
OI_OBEX_CONNECT_FAILED = 1704, /**< OBEX: An OBEX connection request did not succeed */
OI_OBEX_DISCONNECT_FAILED = 1705, /**< OBEX: A disconnect failed probably because the connection did not exist */
OI_OBEX_ERROR = 1706, /**< OBEX: Unspecified OBEX error */
OI_OBEX_INCOMPLETE_PACKET = 1707, /**< OBEX: Packet too short or corrupt */
OI_OBEX_LENGTH_REQUIRED = 1708, /**< OBEX: Length header required in OBEX command */
OI_OBEX_NOT_CONNECTED = 1709, /**< OBEX: No connection to OBEX server */
OI_OBEX_NO_MORE_CONNECTIONS = 1710, /**< OBEX: Reached max connections limit */
OI_OBEX_OPERATION_IN_PROGRESS = 1711, /**< OBEX: Another operation is still in progress on a connection */
OI_OBEX_PUT_RESPONSE_ERROR = 1712, /**< OBEX: An error in the response to a PUT command */
OI_OBEX_GET_RESPONSE_ERROR = 1713, /**< OBEX: An error in the response to a GET command */
OI_OBEX_REQUIRED_HEADER_NOT_FOUND = 1714, /**< OBEX: packet was missing a required header */
OI_OBEX_SERVICE_UNAVAILABLE = 1715, /**< OBEX: Unown OBEX target or required service */
OI_OBEX_TOO_MANY_HEADER_BYTES = 1716, /**< OBEX: Headers will not fit in single OBEX packet */
OI_OBEX_UNKNOWN_COMMAND = 1717, /**< OBEX: Unrecognized OBEX command */
OI_OBEX_UNSUPPORTED_VERSION = 1718, /**< OBEX: Version mismatch */
OI_OBEX_CLIENT_ABORTED_COMMAND = 1719, /**< OBEX: server received abort command */
OI_OBEX_BAD_PACKET = 1720, /**< OBEX: Any malformed OBEX packet */
OI_OBEX_BAD_REQUEST = 1721, /**< OBEX: Maps to OBEX response of the same name */
OI_OBEX_OBJECT_OVERFLOW = 1723, /**< OBEX: Too many bytes received. */
OI_OBEX_NOT_FOUND = 1724, /**< OBEX: Maps to obex response of same name */
OI_OBEX_ACCESS_DENIED = 1735, /**< OBEX: Object could not be read or written. */
OI_OBEX_VALUE_NOT_ACCEPTABLE = 1736, /**< OBEX: Value in a command was not in the acceptable range. */
OI_OBEX_PACKET_OVERFLOW = 1737, /**< OBEX: Buffer will not fit in a single OBEX packet. */
OI_OBEX_NO_SUCH_FOLDER = 1738, /**< OBEX: Error returned by a setpath operation. */
OI_OBEX_NAME_REQUIRED = 1739, /**< OBEX: Name must be non-null and non-empty. */
OI_OBEX_PASSWORD_TOO_LONG = 1740, /**< OBEX: Password exceeds implementation imposed length limit. */
OI_OBEX_PRECONDITION_FAILED = 1741, /**< OBEX: response Precondition Failed */
OI_OBEX_UNAUTHORIZED = 1742, /**< OBEX: authentication was not successful. */
OI_OBEX_NOT_IMPLEMENTED = 1743, /**< OBEX: Unimplemented feature. */
OI_OBEX_INVALID_AUTH_DIGEST = 1744, /**< OBEX: An authentication digest was bad. */
OI_OBEX_INVALID_OPERATION = 1745, /**< OBEX: Operation not allowed at this time. */
OI_OBEX_DATABASE_FULL = 1746, /**< OBEX: Sync database full. */
OI_OBEX_DATABASE_LOCKED = 1747, /**< OBEX: Sync database locked. */
OI_OBEX_INTERNAL_SERVER_ERROR = 1748, /**< OBEX: response Internal Server Error */
OI_OBEX_UNSUPPORTED_MEDIA_TYPE = 1749, /**< OBEX: response Unsupported Media Type */
OI_OBEX_PARTIAL_CONTENT = 1750, /**< OBEX: response Partial Content */
OI_OBEX_METHOD_NOT_ALLOWED = 1751, /**< OBEX: response Method Not Allowed */
OI_OBEXSRV_INCOMPLETE_GET = 1752, /**< OBEX: Indicates to a GET handler that the request phase is still in progress */
OI_OBEX_FOLDER_BROWSING_NOT_ALLOWED = 1753, /**< OBEX: Indicates that an FTP server does not allow folder browsing */
OI_OBEX_SERVER_FORCED_DISCONNECT = 1754, /**< OBEX: connection was forcibly terminated by the server */
OI_OBEX_OFS_ERROR = 1755, /**< OBEX: OPP object file system error occurred */
OI_OBEX_FILEOP_ERROR = 1756, /**< OBEX: FTP/PBAP file operation system error occurred */
OI_OBEX_USERID_TOO_LONG = 1757, /**< OBEX: User Id exceeds spec limited length limit. */
OI_HANDSFREE_EVENT_REPORTING_DISABLED = 1801, /**< HANDSFREE: Event reporting disabled */
OI_HANDSFREE_NOT_CONNECTED = 1802, /**< HANDSFREE: Not connected */
OI_HANDSFREE_SERVICE_NOT_STARTED = 1803, /**< HANDSFREE: Cannot connect to handsfree AG if handsfree service not started */
OI_HANDSFREE_AG_SERVICE_NOT_STARTED = 1804, /**< HANDSFREE: Cannot connect to handsfree device if handsfree AG service not started */
OI_HANDSFREE_COMMAND_IN_PROGRESS = 1805, /**< HANDSFREE: Cannot accept a command at this time */
OI_HANDSFREE_AUDIO_ALREADY_CONNECTED = 1806, /**< HANDSFREE: Audio is already connected */
OI_HANDSFREE_AUDIO_NOT_CONNECTED = 1807, /**< HANDSFREE: Audio is not connected */
OI_HANDSFREE_FEATURE_NOT_SUPPORTED = 1808, /**< HANDSFREE: Local or remote feature not supported for requested command */
OI_HEADSET_SERVICE_NOT_STARTED = 1901, /**< HEADSET: Cannot connect to headset AG if headset service not started */
OI_HEADSET_AG_SERVICE_NOT_STARTED = 1902, /**< HEADSET: Cannot connect to headset device if headset AG service not started */
OI_HEADSET_COMMAND_IN_PROGRESS = 1903, /**< HEADSET: Cannot accept a command at this time */
OI_BNEP_INVALID_MTU = 2001, /**< BNEP: The remote device cannot support the minimum BNEP MTU */
OI_BNEP_SETUP_TIMEOUT = 2002, /**< BNEP: The setup request timed out. */
OI_BNEP_SERVICE_NOT_REGISTERED = 2003, /**< BNEP: The requested service was not found. */
OI_BNEP_INVALID_HANDLE = 2004, /**< BNEP: The specified connection handle is not valid. */
OI_BNEP_RESPONSE_TIMEOUT = 2005, /**< BNEP: The timer for receiving a response has expired. */
OI_BNEP_INVALID_CONNECTION = 2006, /**< BNEP: Invalid connection */
OI_BNEP_INVALID_FILTER = 2007, /**< BNEP: The supplied filter was invalid. */
OI_BNEP_CONNECTION_EXISTS = 2008, /**< BNEP: An attempt was made to create a duplicate connection. */
OI_BNEP_NOT_INITIALIZED = 2009, /**< BNEP: Init has not been called */
OI_BNEP_CONNECT_BASE = 2010, /**< BNEP: connection response codes */
OI_BNEP_CONNECT_FAILED_INVALID_DEST_UUID = 2011, /**< BNEP: connect response code Invalid Dest UUID */
OI_BNEP_CONNECT_FAILED_INVALID_SOURCE_UUID = 2012, /**< BNEP: connect response code Invalid Source UUID */
OI_BNEP_CONNECT_FAILED_INVALID_UUID_SIZE = 2013, /**< BNEP: connect response code Invalid UUID Size */
OI_BNEP_CONNECT_FAILED_NOT_ALLOWED = 2014, /**< BNEP: connect response code Not Allowed */
OI_BNEP_FILTER_NET_BASE = 2020, /**< BNEP: filter response codes */
OI_BNEP_FILTER_NET_UNSUPPORTED_REQUEST = 2021, /**< BNEP: filter response code Unsupported Request */
OI_BNEP_FILTER_NET_FAILED_INVALID_PROTOCOL_TYPE = 2022, /**< BNEP: filter response code Invalid Protocol Type */
OI_BNEP_FILTER_NET_FAILED_MAX_LIMIT_REACHED = 2023, /**< BNEP: filter response code Max Limit Reached */
OI_BNEP_FILTER_NET_FAILED_SECURITY = 2024, /**< BNEP: filter response code Security */
OI_BNEP_FILTER_MULTI_BASE = 2030, /**< BNEP: multicast response codes */
OI_BNEP_FILTER_MULTI_UNSUPPORTED_REQUEST = 2031, /**< BNEP: multicast response code Unsupported Request */
OI_BNEP_FILTER_MULTI_FAILED_INVALID_ADDRESS = 2032, /**< BNEP: multicast response code Invalid Address */
OI_BNEP_FILTER_MULTI_FAILED_MAX_LIMIT_REACHED = 2033, /**< BNEP: multicast response code Max Limit Reached */
OI_BNEP_FILTER_MULTI_FAILED_SECURITY = 2034, /**< BNEP: multicast response code Security */
OI_BNEP_LOCAL_DEVICE_MUST_BE_MASTER = 2040, /**< BNEP: Device must be master of the piconet for this function */
OI_BNEP_PACKET_FILTERED_OUT = 2041, /**< BNEP: Packet did not pass current filters */
OI_NETIFC_UP_FAILED = 2101, /**< NETIFC: Could not bring up network interface */
OI_NETIFC_COULD_NOT_CREATE_THREAD = 2102, /**< NETIFC: Network interface could not create a read thread */
OI_NETIFC_INITIALIZATION_FAILED = 2103, /**< NETIFC: Error in network interface initialization */
OI_NETIFC_INTERFACE_ALREADY_UP = 2104, /**< NETIFC: Network interface is already up */
OI_NETIFC_INTERFACE_NOT_UP = 2105, /**< NETIFC: Network interface is not up */
OI_NETIFC_PACKET_TOO_BIG = 2106, /**< NETIFC: The packet is too big */
OI_PAN_ROLE_ALREADY_REGISTERED = 2201, /**< PAN: This PAN role was already registered */
OI_PAN_ROLE_NOT_ALLOWED = 2202, /**< PAN: The PAN role is not currently allowed */
OI_PAN_INCOMPATIBLE_ROLES = 2203, /**< PAN: Only certain local and remote role combinations are permitted */
OI_PAN_INVALID_ROLE = 2204, /**< PAN: Role specified is not one the defined PAN roles */
OI_PAN_CONNECTION_IN_PROGRESS = 2205, /**< PAN: A PAN connection is currently being established */
OI_PAN_USER_ALREADY_CONNECTED = 2206, /**< PAN: PAN user role only allows a single connection */
OI_PAN_DEVICE_CONNECTED = 2207, /**< PAN: A PAN connection already exists to specified device */
OI_CODEC_SBC_NO_SYNCWORD = 2301, /**< CODEC: Couldn't find an SBC SYNCWORD */
OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA = 2302, /**< CODEC: Not enough data provided to decode an SBC header */
OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA = 2303, /**< CODEC: Decoded the header, but not enough data to contain the rest of the frame */
OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA = 2304, /**< CODEC: Not enough audio data for this frame */
OI_CODEC_SBC_CHECKSUM_MISMATCH = 2305, /**< CODEC: The frame header didn't match the checksum */
OI_CODEC_SBC_PARTIAL_DECODE = 2306, /**< CODEC: Decoding was successful, but frame data still remains. Next call will provide audio without consuming input data. */
OI_FIFOQ_QUEUE_NOT_ALIGNED = 2401, /**< FIFOQ: queue must be 32-bit aligned */
OI_FIFOQ_INVALID_Q = 2402, /**< FIFOQ: queue parameter is not a valid queue */
OI_FIFOQ_BUF_TOO_LARGE = 2403, /**< FIFOQ: attempt to queue a buffer which is too large */
OI_FIFOQ_FULL = 2404, /**< FIFOQ: enqueue() failed, queue is full */
OI_FIFOQ_NOT_ALLOCATED = 2405, /**< FIFOQ: Enqueue QBuf() failed, buffer not allocated */
OI_FIFOQ_INVALID_DATA_PTR = 2406, /**< FIFOQ: Enqueue QBuf() failed, data pointer does not match */
OI_HID_HOST_SERVICE_NOT_STARTED = 2601, /**< HID: Cannot connect to a HID device unless HID host is started */
OI_HID_DEVICE_SERVICE_NOT_STARTED = 2602, /**< HID: Cannot connect to a HID host unless HID device is started */
OI_AT_ERROR = 2701, /**< AT: ERROR response */
OI_AT_NO_CARRIER = 2702, /**< AT: NO CARRIER response */
OI_AT_BUSY = 2703, /**< AT: BUSY response */
OI_AT_NO_ANSWER = 2704, /**< AT: NO ANSWER response */
OI_AT_DELAYED = 2705, /**< AT: DELAYED response */
OI_AT_BLACKLISTED = 2706, /**< AT: BLACKLISTED response */
OI_AT_CME_ERROR = 2707, /**< AT: +CME ERROR response */
OI_AT_CMS_ERROR = 2708, /**< AT: +CMS ERROR response */
OI_BLST_CHARACTER_TIMEOUT = 2801, /**< BLST: Timeout expired while waiting for a character from the client. */
OI_BLST_ACKNOWLDGE_TIMEOUT = 2802, /**< BLST: Timeout expired while waiting for event acknowledgment from the client */
OI_BLST_TX_NOT_READY = 2803, /**< BLST: BLST is not ready to send a BHAPI message to the client. */
OI_BLST_TX_BUSY = 2804, /**< BLST: BLST transmit buffer is in use. */
OI_AVDTP_CONNECTION_SEQ_ERROR = 2901, /**< AVDTP: sequencing of signalling/media channel connections broken. */
OI_AVDTP_OUT_OF_RESOURCES = 2902, /**< AVDTP: Tried to allocate too many endpoints or signalling channels. */
OI_PBAP_REPOSITORY_NOT_SET = 3001, /**< PBAP: Phonebook repository must be set for operation to complete. */
OI_PBAP_PHONEBOOK_NOT_SET = 3002, /**< PBAP: Phonebook be set for operation to complete. */
OI_AADP_BAD_ENDPOINT = 3101, /**< AADP: Invalid local endpoint specified */
OI_AADP_BAD_STATE = 3102, /**< AADP: AADP State is not correct for this operation. */
OI_UNICODE_INVALID_SOURCE = 3200, /**< Unicode Conversion: Source string has invalid character encoding. */
OI_UNICODE_SOURCE_EXHAUSTED = 3201, /**< Unicode Conversion: Incomplete Unicode character at end of source buffer. */
OI_UNICODE_DESTINATION_EXHAUSTED = 3202, /**< Unicode Conversion: Destination buffer not large enough to hold resulting Unicode string. */
OI_AVRCP_TOO_MANY_CONNECTIONS = 3300, /**< AVRCP: Exceeded maximum number of simultaneous AVCTP connections. */
OI_AVRCP_NOT_IMPLEMENTED = 3301, /**< AVRCP: The target does not implement the command specified by the opcode and operand. */
OI_AVRCP_REJECTED = 3302, /**< AVRCP: The target cannot respond because of invalid operands in command packet. */
OI_AVRCP_INVALID_RESPONSE = 3303, /**< AVRCP: The controller received the response with invalid parameters */
OI_AVRCP_RESPONSE_PACKET_OVERFLOW = 3304, /**< AVRCP: The response message does not fir in one AVRCP packet (512 bytes), has to be fragmented. */
OI_AVRCP_RESPONSE_INVALID_PDU = 3305, /**< AVRCP: Command rejected: target received a PDU that it did not understand. */
OI_AVRCP_RESPONSE_INVALID_PARAMETER = 3306, /**< AVRCP: Command rejected: target received a PDU with a parameter ID that it did not understand. */
OI_AVRCP_RESPONSE_PARAMETER_NOT_FOUND = 3307, /**< AVRCP: Command rejected: specified parameter not found, sent if the parameter ID is understood, but content is wrong or corrupted.*/
OI_AVRCP_RESPONSE_INTERNAL_ERROR = 3308, /**< AVRCP: Command rejected: target detected other error conditions. */
OI_MAX_BM3_STATUS_VAL, /* Maximum BM3 status code */
/* Status code values reserved for BM3 SDK platform-specific implementations */
OI_STATUS_RESERVED_FOR_BCOT = 9000,
/* Status code values reserved for BHAPI products */
OI_STATUS_RESERVED_FOR_BHAPI = 9200,
/* Status code values reserved for Soundabout products */
OI_STATUS_RESERVED_FOR_SOUNDABOUT= 9400,
/*
* Status code values greater than or equal to this value are reserved for use by applications.
* However, because of differences between compilers, and differences between 16-bit and 32-bit
* platforms custom status codes should be in the 16-bit range, so status codes can range from 0
* to 65534, inclusive (65535 is reserved)
*/
OI_STATUS_RESERVED_FOR_APPS = 10000,
OI_STATUS_NONE = 0xffff /**< Special status code to indicate that there is no status. (Only to be used for special cases involving OI_SLOG_ERROR() and OI_SLOG_WARNING().) */
} OI_STATUS;
/* Remeber to update the #define below when new reserved blocks are added to
* the list above. */
#define OI_NUM_RESERVED_STATUS_BLOCKS 4 /**< Number of status code blocks reserved, including user apps */
/**
* Test for success
*/
#define OI_SUCCESS(x) ((x) == OI_OK)
/*****************************************************************************/
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_STATUS_H */
+232
View File
@@ -0,0 +1,232 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef OI_STDDEFS_H
#define OI_STDDEFS_H
/**
* @file
* This file contains BM3 standard type definitions.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_cpu_dep.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef FALSE
#define FALSE 0 /**< This define statement sets FALSE as a preprocessor alias for 0. */
#endif
#ifndef TRUE
#define TRUE (!FALSE) /**< This define statement sets TRUE as a preprocessor alias for !FALSE. */
#endif
#ifdef HEW_TOOLCHAIN
#ifdef NULL
#undef NULL /**< Override HEW toolchain NULL definition */
#endif
#define NULL 0 /**< HEW toolchain does not allow us to compare (void*) type to function pointer */
#else
#ifndef NULL
#define NULL ((void*)0) /**< This define statement sets NULL as a preprocessor alias for (void*)0 */
#endif
#endif
/**
* @name Maximum and minimum values for basic types
* @{
*/
#define OI_INT8_MIN ((OI_INT8)0x80) /**< decimal value: -128 */
#define OI_INT8_MAX ((OI_INT8)0x7F) /**< decimal value: 127 */
#define OI_INT16_MIN ((OI_INT16)0x8000) /**< decimal value: -32768 */
#define OI_INT16_MAX ((OI_INT16)0x7FFF) /**< decimal value: 32767 */
#define OI_INT32_MIN ((OI_INT32)0x80000000) /**< decimal value: -2,147,483,648 */
#define OI_INT32_MAX ((OI_INT32)0x7FFFFFFF) /**< decimal value: 2,147,483,647 */
#define OI_UINT8_MIN ((OI_UINT8)0) /**< decimal value: 0 */
#define OI_UINT8_MAX ((OI_UINT8)0xFF) /**< decimal value: 255 */
#define OI_UINT16_MIN ((OI_UINT16)0) /**< decimal value: 0 */
#define OI_UINT16_MAX ((OI_UINT16)0xFFFF) /**< decimal value: 65535 */
#define OI_UINT32_MIN ((OI_UINT32)0) /**< decimal value: 0 */
#define OI_UINT32_MAX ((OI_UINT32)0xFFFFFFFF) /**< decimal value: 4,294,967,295 */
/**
* @}
*/
/**
* @name Integer types required by the Service Discovery Protocol
* @{
*/
/** unsigned 64-bit integer as a structure of two unsigned 32-bit integers */
typedef struct {
OI_UINT32 I1; /**< most significant 32 bits */
OI_UINT32 I2; /**< least significant 32 bits */
} OI_UINT64;
#define OI_UINT64_MIN { (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 }
#define OI_UINT64_MAX { (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF }
/** signed 64-bit integer as a structure of one unsigned 32-bit integer and one signed 32-bit integer */
typedef struct {
OI_INT32 I1; /**< most significant 32 bits as a signed integer */
OI_UINT32 I2; /**< least significant 32 bits as an unsigned integer */
} OI_INT64;
#define OI_INT64_MIN { (OI_INT32)0x80000000, (OI_UINT32)0x00000000 }
#define OI_INT64_MAX { (OI_INT32)0X7FFFFFFF, (OI_UINT32)0XFFFFFFFF }
/** unsigned 128-bit integer as a structure of four unsigned 32-bit integers */
typedef struct {
OI_UINT32 I1; /**< most significant 32 bits */
OI_UINT32 I2; /**< second-most significant 32 bits */
OI_UINT32 I3; /**< third-most significant 32 bits */
OI_UINT32 I4; /**< least significant 32 bits */
} OI_UINT128;
#define OI_UINT128_MIN { (OI_UINT32)0x00000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 }
#define OI_UINT128_MAX { (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF }
/** signed 128-bit integer as a structure of three unsigned 32-bit integers and one signed 32-bit integer */
typedef struct {
OI_INT32 I1; /**< most significant 32 bits as a signed integer */
OI_UINT32 I2; /**< second-most significant 32 bits as an unsigned integer */
OI_UINT32 I3; /**< third-most significant 32 bits as an unsigned integer */
OI_UINT32 I4; /**< least significant 32 bits as an unsigned integer */
} OI_INT128;
#define OI_INT128_MIN { (OI_UINT32)0x80000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 }
#define OI_INT128_MAX { (OI_UINT32)0X7FFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF }
/**
* @}
*/
/**
* type for ASCII character data items
*/
typedef char OI_CHAR;
/**
* type for double-byte character data items
*/
typedef OI_UINT16 OI_CHAR16;
/**
* types for UTF encoded strings.
*/
typedef OI_UINT8 OI_UTF8;
typedef OI_UINT16 OI_UTF16;
typedef OI_UINT32 OI_UTF32;
/**
* @name Single-bit operation macros
* @{
* In these macros, x is the data item for which a bit is to be tested or set and y specifies which bit
* is to be tested or set.
*/
/** This macro's value is TRUE if the bit specified by y is set in data item x. */
#define OI_BIT_TEST(x,y) ((x) & (y))
/** This macro's value is TRUE if the bit specified by y is not set in data item x. */
#define OI_BIT_CLEAR_TEST(x,y) (((x) & (y)) == 0)
/** This macro sets the bit specified by y in data item x. */
#define OI_BIT_SET(x,y) ((x) |= (y))
/** This macro clears the bit specified by y in data item x. */
#define OI_BIT_CLEAR(x,y) ((x) &= ~(y))
/** @} */
/**
* The OI_ARRAYSIZE macro is set to the number of elements in an array
* (instead of the number of bytes, which is returned by sizeof()).
*/
#ifndef OI_ARRAYSIZE
#define OI_ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#endif
/**
* @name Preprocessor aliases for individual bit positions
* Bits are defined here only if they are not already defined.
* @{
*/
#ifndef BIT0
#define BIT0 0x00000001 /**< preprocessor alias for 32-bit value with bit 0 set, used to specify this single bit */
#define BIT1 0x00000002 /**< preprocessor alias for 32-bit value with bit 1 set, used to specify this single bit */
#define BIT2 0x00000004 /**< preprocessor alias for 32-bit value with bit 2 set, used to specify this single bit */
#define BIT3 0x00000008 /**< preprocessor alias for 32-bit value with bit 3 set, used to specify this single bit */
#define BIT4 0x00000010 /**< preprocessor alias for 32-bit value with bit 4 set, used to specify this single bit */
#define BIT5 0x00000020 /**< preprocessor alias for 32-bit value with bit 5 set, used to specify this single bit */
#define BIT6 0x00000040 /**< preprocessor alias for 32-bit value with bit 6 set, used to specify this single bit */
#define BIT7 0x00000080 /**< preprocessor alias for 32-bit value with bit 7 set, used to specify this single bit */
#define BIT8 0x00000100 /**< preprocessor alias for 32-bit value with bit 8 set, used to specify this single bit */
#define BIT9 0x00000200 /**< preprocessor alias for 32-bit value with bit 9 set, used to specify this single bit */
#define BIT10 0x00000400 /**< preprocessor alias for 32-bit value with bit 10 set, used to specify this single bit */
#define BIT11 0x00000800 /**< preprocessor alias for 32-bit value with bit 11 set, used to specify this single bit */
#define BIT12 0x00001000 /**< preprocessor alias for 32-bit value with bit 12 set, used to specify this single bit */
#define BIT13 0x00002000 /**< preprocessor alias for 32-bit value with bit 13 set, used to specify this single bit */
#define BIT14 0x00004000 /**< preprocessor alias for 32-bit value with bit 14 set, used to specify this single bit */
#define BIT15 0x00008000 /**< preprocessor alias for 32-bit value with bit 15 set, used to specify this single bit */
#define BIT16 0x00010000 /**< preprocessor alias for 32-bit value with bit 16 set, used to specify this single bit */
#define BIT17 0x00020000 /**< preprocessor alias for 32-bit value with bit 17 set, used to specify this single bit */
#define BIT18 0x00040000 /**< preprocessor alias for 32-bit value with bit 18 set, used to specify this single bit */
#define BIT19 0x00080000 /**< preprocessor alias for 32-bit value with bit 19 set, used to specify this single bit */
#define BIT20 0x00100000 /**< preprocessor alias for 32-bit value with bit 20 set, used to specify this single bit */
#define BIT21 0x00200000 /**< preprocessor alias for 32-bit value with bit 21 set, used to specify this single bit */
#define BIT22 0x00400000 /**< preprocessor alias for 32-bit value with bit 22 set, used to specify this single bit */
#define BIT23 0x00800000 /**< preprocessor alias for 32-bit value with bit 23 set, used to specify this single bit */
#define BIT24 0x01000000 /**< preprocessor alias for 32-bit value with bit 24 set, used to specify this single bit */
#define BIT25 0x02000000 /**< preprocessor alias for 32-bit value with bit 25 set, used to specify this single bit */
#define BIT26 0x04000000 /**< preprocessor alias for 32-bit value with bit 26 set, used to specify this single bit */
#define BIT27 0x08000000 /**< preprocessor alias for 32-bit value with bit 27 set, used to specify this single bit */
#define BIT28 0x10000000 /**< preprocessor alias for 32-bit value with bit 28 set, used to specify this single bit */
#define BIT29 0x20000000 /**< preprocessor alias for 32-bit value with bit 29 set, used to specify this single bit */
#define BIT30 0x40000000 /**< preprocessor alias for 32-bit value with bit 30 set, used to specify this single bit */
#define BIT31 0x80000000 /**< preprocessor alias for 32-bit value with bit 31 set, used to specify this single bit */
#endif /* BIT0 et al */
/** @} */
#ifdef __cplusplus
}
#endif
/**@}*/
/*****************************************************************************/
#endif /* OI_STDDEFS_H */
+208
View File
@@ -0,0 +1,208 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef OI_STRING_H
#define OI_STRING_H
/**
* @file
* This file contains BM3 supplied portable string.h functions
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_cpu_dep.h"
#include "oi_stddefs.h"
#if defined(USE_NATIVE_MEMCPY) || defined(USE_NATIVE_MALLOC)
#include <string.h>
#endif
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* If we are using Native malloc(), we must also use
* native Ansi string.h functions for memory manipulation.
*/
#ifdef USE_NATIVE_MALLOC
#ifndef USE_NATIVE_MEMCPY
#define USE_NATIVE_MEMCPY
#endif
#endif
#ifdef USE_NATIVE_MEMCPY
#define OI_MemCopy(to, from, size) memcpy((to), (from), (size))
#define OI_MemSet(block, val, size) memset((block), (val), (size))
#define OI_MemZero(block, size) memset((block), 0, (size))
#define OI_MemCmp(s1, s2, n) memcmp((s1), (s2), (n))
#define OI_Strcpy(dest, src) strcpy((dest),(src))
#define OI_Strcat(dest, src) strcat((dest),(src))
#define OI_StrLen(str) strlen((str))
#define OI_Strcmp(s1, s2) strcmp((s1), (s2))
#define OI_Strncmp(s1, s2, n) strncmp((s1), (s2), (n))
#else
/*
* OI_MemCopy
*
* Copy an arbitrary number of bytes from one memory address to another.
* The underlying implementation is the ANSI memmove() or equivalant, so
* overlapping memory copies will work correctly.
*/
void OI_MemCopy(void *To, void const *From, OI_UINT32 Size);
/*
* OI_MemSet
*
* Sets all bytes in a block of memory to the same value
*/
void OI_MemSet(void *Block, OI_UINT8 Val, OI_UINT32 Size);
/*
* OI_MemZero
*
* Sets all bytes in a block of memory to zero
*/
void OI_MemZero(void *Block, OI_UINT32 Size);
/*
* OI_MemCmp
*
* Compare two blocks of memory
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_MemCmp(void const *s1, void const *s2, OI_UINT32 n);
/*
* OI_Strcpy
*
* Copies the Null terminated string from pStr to pDest, and
* returns pDest.
*/
OI_CHAR* OI_Strcpy(OI_CHAR *pDest,
OI_CHAR const *pStr);
/*
* OI_Strcat
*
* Concatonates the pStr string to the end of pDest, and
* returns pDest.
*/
OI_CHAR* OI_Strcat(OI_CHAR *pDest,
OI_CHAR const *pStr) ;
/*
* OI_StrLen
*
* Calculates the number of OI_CHARs in pStr (not including
* the Null terminator) and returns the value.
*/
OI_UINT OI_StrLen(OI_CHAR const *pStr) ;
/*
* OI_Strcmp
*
* Compares two Null terminated strings
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_Strcmp(OI_CHAR const *s1,
OI_CHAR const *s2);
/*
* OI_Strncmp
*
* Compares the first "len" OI_CHARs of strings s1 and s2.
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_Strncmp(OI_CHAR const *s1,
OI_CHAR const *s2,
OI_UINT32 len);
#endif /* USE_NATIVE_MEMCPY */
/*
* OI_StrcmpInsensitive
*
* Compares two Null terminated strings, treating
* the Upper and Lower case of 'A' through 'Z' as
* equivilent.
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_StrcmpInsensitive(OI_CHAR const *s1,
OI_CHAR const *s2);
/*
* OI_StrncmpInsensitive
*
* Compares the first "len" OI_CHARs of strings s1 and s2,
* treating the Upper and Lower case of 'A' through 'Z' as
* equivilent.
*
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_StrncmpInsensitive(OI_CHAR const *s1,
OI_CHAR const *s2,
OI_UINT len);
#ifdef __cplusplus
}
#endif
/** @} */
/*****************************************************************************/
#endif /* OI_STRING_H */
+200
View File
@@ -0,0 +1,200 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_TIME_H
#define _OI_TIME_H
/** @file
*
* This file provides time type definitions and interfaces to time-related functions.
*
* The stack maintains a 64-bit real-time millisecond clock. The choice of
* milliseconds is for convenience, not accuracy.
*
* Timeouts are specified as tenths of seconds in a 32-bit value. Timeout values
* specified by the Bluetooth specification are usually muliple seconds, so
* accuracy to a tenth of a second is more than adequate.
*
* This file also contains macros to convert between seconds and the Link
* Manager's 1.28-second units.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_stddefs.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Within the core stack timeouts are specified in intervals of tenths of seconds
*/
typedef OI_UINT16 OI_INTERVAL;
#define OI_INTERVALS_PER_SECOND 10
#define MSECS_PER_OI_INTERVAL (1000 / OI_INTERVALS_PER_SECOND)
/** maximum interval (54 min 36.7 sec) */
#define OI_MAX_INTERVAL 0x7fff
/**
* Macro to convert seconds to OI_INTERVAL time units
*/
#define OI_SECONDS(n) ((OI_INTERVAL) ((n) * OI_INTERVALS_PER_SECOND))
/**
* Macro to convert milliseconds to OI_INTERVAL time units (Rounded Up)
*/
#define OI_MSECONDS(n) ((OI_INTERVAL) ((n + MSECS_PER_OI_INTERVAL - 1) / MSECS_PER_OI_INTERVAL))
/**
* Macro to convert minutes to OI_INTERVAL time units
*/
#define OI_MINUTES(n) ((OI_INTERVAL) ((n) * OI_SECONDS(60)))
/** Convert an OI_INTERVAL to milliseconds. */
#define OI_INTERVAL_TO_MILLISECONDS(i) ((i) * MSECS_PER_OI_INTERVAL)
/**
* The stack depends on relative not absolute time. Any mapping between the
* stack's real-time clock and absolute time and date is implementation-dependent.
*/
typedef struct {
OI_INT32 seconds;
OI_INT16 mseconds;
} OI_TIME;
/**
* Convert an OI_TIME to milliseconds.
*
* @param t the time to convert
*
* @return the time in milliseconds
*/
OI_UINT32 OI_Time_ToMS(OI_TIME *t);
/**
* This function compares two time values.
*
* @param T1 first time to compare.
*
* @param T2 second time to compare.
*
* @return
@verbatim
-1 if t1 < t2
0 if t1 = t2
+1 if t1 > t2
@endverbatim
*/
OI_INT16 OI_Time_Compare(OI_TIME *T1,
OI_TIME *T2);
/**
* This function returns the interval between two times to a granularity of 0.1 seconds.
*
* @param Sooner a time value more recent that Later
*
* @param Later a time value later than Sooner
*
* @note The result is an OI_INTERVAL value so this function only works for time intervals
* that are less than about 71 minutes.
*
* @return the time interval between the two times = (Later - Sooner)
*/
OI_INTERVAL OI_Time_Interval(OI_TIME *Sooner,
OI_TIME *Later);
/**
* This function returns the interval between two times to a granularity of milliseconds.
*
* @param Sooner a time value more recent that Later
*
* @param Later a time value later than Sooner
*
* @note The result is an OI_UINT32 value so this function only works for time intervals
* that are less than about 50 days.
*
* @return the time interval between the two times = (Later - Sooner)
*/
OI_UINT32 OI_Time_IntervalMsecs(OI_TIME *Sooner,
OI_TIME *Later);
/**
* This function answers the question, Have we reached or gone past the target time?
*
* @param pTargetTime target time
*
* @return TRUE means time now is at or past target time
* FALSE means target time is still some time in the future
*/
OI_BOOL OI_Time_NowReachedTime(OI_TIME *pTargetTime);
/**
* Convert seconds to the Link Manager 1.28-second units
* Approximate by using 1.25 conversion factor.
*/
#define OI_SECONDS_TO_LM_TIME_UNITS(lmUnits) ((lmUnits)<4?(lmUnits):(lmUnits)-((lmUnits)>>2))
/**
* Convert Link Manager 1.28-second units to seconds.
* Approximate by using 1.25 conversion factor.
*/
#define OI_LM_TIME_UNITS_TO_SECONDS(lmUnits) ((lmUnits) + ((lmUnits)>>2))
#ifdef __cplusplus
}
#endif
/**@}*/
/* Include for OI_Time_Now() prototype
* Must be included at end to obtain OI_TIME typedef
*/
#include "oi_osinterface.h"
/*****************************************************************************/
#endif /* _OI_TIME_H */
+377
View File
@@ -0,0 +1,377 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _OI_UTILS_H
#define _OI_UTILS_H
/**
* @file
*
* This file provides the interface for utility functions.
* Among the utilities are strlen (string length), strcmp (string compare), and
* other string manipulation functions. These are provided for those plaforms
* where this functionality is not available in stdlib.
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include <stdarg.h>
#include "oi_common.h"
#include "oi_string.h"
#include "oi_bt_spec.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Opaque type for a callback function handle. See OI_ScheduleCallbackFunction()
*/
typedef OI_UINT32 OI_CALLBACK_HANDLE;
/**
* Function prototype for a timed procedure callback.
*
* @param arg Value that was passed into the OI_ScheduleCallback() function
*
*/
typedef void (*OI_SCHEDULED_CALLBACK)(void *arg);
/**
* Registers a function to be called when a timeout expires. This API uses BLUEmagic's internal
* function dispatch mechanism, so applications that make extensive use of this facility may need to
* increase the value of DispatchTableSize in the configuration block for the dispatcher (see
* oi_bt_stack_config.h).
*
* @param callbackFunction The function that will be called when the timeout expires
*
* @param arg Value that will be returned as the parameter to the callback function.
*
* @param timeout A timeout expressed in OI_INTERVALs (tenths of seconds). This can be
* zero in which case the callback function will be called as soon as
* possible.
*
* @param handle NULL or a pointer receive the callback handle.
*
* @return OI_OK if the function was reqistered, or an error status.
*/
OI_STATUS OI_ScheduleCallbackFunction(OI_SCHEDULED_CALLBACK callbackFunction,
void *arg,
OI_INTERVAL timeout,
OI_CALLBACK_HANDLE *handle);
/**
* Cancels a function registered with OI_ScheduleCallbackFunction() before its timer expires.
*
* @param handle handle returned by OI_ScheduleCallbackFunction().
*
* @return OI_OK if the function was cancelled, or an error status.
*/
OI_STATUS OI_CancelCallbackFunction(OI_CALLBACK_HANDLE handle);
/**
* Registers a function to be called when a timeout expires. This version does not return a handle
* so can only be canceled by calling OI_CancelCallback().
*
* @param callbackFunction The function that will be called when the timeout expires
*
* @param arg Value that will be returned as the parameter to the callback function.
*
* @param timeout A timeout expressed in OI_INTERVALs (tenths of seconds). This can be
* zero in which case the callback function will be called as soon as
* possible.
*
* @return OI_OK if the function was reqistered, or an error status.
*/
#define OI_ScheduleCallback(f, a, t) OI_ScheduleCallbackFunction(f, a, t, NULL);
/**
* Cancels a function registered with OI_ScheduleCallback() before its timer expires. This
* function will cancel the first entry matches the indicated callback function pointer.
*
* @param callbackFunction The function that was originally registered
*
* @return OI_OK if the function was cancelled, or an error status.
*/
OI_STATUS OI_CancelCallback(OI_SCHEDULED_CALLBACK callbackFunction);
/**
* Parse a Bluetooth device address from the specified string.
*
* @param str the string to parse
* @param addr the parsed address, if successful
*
* @return TRUE if an address was successfully parsed, FALSE otherwise
*/
OI_BOOL OI_ParseBdAddr(const OI_CHAR *str,
OI_BD_ADDR *addr) ;
/**
* Printf function for platforms which have no stdio or printf available.
* OI_Printf supports the basic formatting types, with the exception of
* floating point types. Additionally, OI_Printf supports several formats
* specific to BLUEmagic 3.0 software:
*
* \%! prints the string for an #OI_STATUS value.
* @code OI_Printf("There was an error %!", status); @endcode
*
* \%@ prints a hex dump of a buffer.
* Requires a pointer to the buffer and a signed integer length
* (0 for default length). If the buffer is large, only an excerpt will
* be printed.
* @code OI_Printf("Contents of buffer %@", buffer, sizeof(buffer)); @endcode
*
* \%: prints a Bluetooth address in the form "HH:HH:HH:HH:HH:HH".
* Requires a pointer to an #OI_BD_ADDR.
* @code OI_Printf("Bluetooth address %:", &bdaddr); @endcode
*
* \%^ decodes and prints a data element as formatted XML.
* Requires a pointer to an #OI_DATAELEM.
* @code OI_Printf("Service attribute list is:\n%^", &attributes); @endcode
*
* \%/ prints the base file name of a path, that is, the final substring
* following a '/' or '\\' character. Requires a pointer to a null
* terminated string.
* @code OI_Printf("File %/", "c:\\dir1\\dir2\\file.txt"); @endcode
*
* \%~ prints a string, escaping characters as needed to display it in
* ASCII. Requires a pointer to an #OI_PSTR and an #OI_UNICODE_ENCODING
* parameter.
* @code OI_Printf("Identifier %~", &id, OI_UNICODE_UTF16_BE); @endcode
*
* \%[ inserts an ANSI color escape sequence. Requires a single character
* identifying the color to select. Colors are red (r/R), green (g/G),
* blue (b/B), yellow (y/Y), cyan (c/C), magenta (m/M), white (W),
* light-gray (l/L), dark-gray (d/D), and black (0). The lower case is
* dim, the upper case is bright (except in the case of light-gray and
* dark-gray, where bright and dim are identical). Any other value will
* select the default color.
* @code OI_Printf("%[red text %[black %[normal\n", 'r', '0', 0); @endcode
*
* \%a same as \%s, except '\\r' and '\\n' are output as "<cr>" and "<lf>".
* \%?a is valid, but \%la is not.
*
* \%b prints an integer in base 2.
* @code OI_Printf("Bits are %b", I); @endcode
*
* \%lb prints a long integer in base 2.
*
* \%?b prints the least significant N bits of an integer (or long integer)
* in base 2. Requires the integer and a length N.
* @code OI_Printf("Bottom 4 bits are: %?b", I, 4); @endcode
*
* \%B prints an integer as boolean text, "TRUE" or "FALSE".
* @code OI_Printf("The value 0 is %B, the value 1 is %B", 0, 1); @endcode
*
* \%?s prints a substring up to a specified maximum length.
* Requires a pointer to a string and a length parameter.
* @code OI_Printf("String prefix is %?s", str, 3); @endcode
*
* \%ls same as \%S.
*
* \%S prints a UTF16 string as UTF8 (plain ASCII, plus 8-bit char sequences
* where needed). Requires a pointer to #OI_CHAR16. \%?S is valid. The
* length parameter is in OI_CHAR16 characters.
*
* \%T prints time, formatted as "secs.msecs".
* Requires pointer to #OI_TIME struct, NULL pointer prints current time.
* @code OI_Printf("The time now is %T", NULL); @endcode
*
* @param format The format string
*
*/
void OI_Printf(const OI_CHAR *format, ...);
/**
* Var-args version OI_Printf
*
* @param format Same as for OI_Printf.
*
* @param argp Var-args list.
*/
void OI_VPrintf(const OI_CHAR *format, va_list argp);
/**
* Writes a formatted string to a buffer. This function supports the same format specifiers as
* OI_Printf().
*
* @param buffer Destination buffer for the formatted string.
*
* @param bufLen The length of the destination buffer.
*
* @param format The format string
*
* @return Number of characters written or -1 in the case of an error.
*/
OI_INT32 OI_SNPrintf(OI_CHAR *buffer,
OI_UINT16 bufLen,
const OI_CHAR* format, ...);
/**
* Var-args version OI_SNPrintf
*
* @param buffer Destination buffer for the formatted string.
*
* @param bufLen The length of the destination buffer.
*
* @param format The format string
*
* @param argp Var-args list.
*
* @return Number of characters written or -1 in the case of an error.
*/
OI_INT32 OI_VSNPrintf(OI_CHAR *buffer,
OI_UINT16 bufLen,
const OI_CHAR *format, va_list argp);
/**
* Convert a string to an integer.
*
* @param str the string to parse
*
* @return the integer value of the string or 0 if the string could not be parsed
*/
OI_INT OI_atoi(const OI_CHAR *str);
/**
* Parse a signed integer in a string.
*
* Skips leading whitespace (space and tabs only) and parses a decimal or hex string. Hex string
* must be prefixed by "0x". Returns pointer to first character following the integer. Returns the
* pointer passed in if the string does not describe an integer.
*
* @param str String to parse.
*
* @param val Pointer to receive the parsed integer value.
*
* @return A pointer to the first character following the integer or the pointer passed in.
*/
const OI_CHAR* OI_ScanInt(const OI_CHAR *str,
OI_INT32 *val);
/**
* Parse an unsigned integer in a string.
*
* Skips leading whitespace (space and tabs only) and parses a decimal or hex string. Hex string
* must be prefixed by "0x". Returns pointer to first character following the integer. Returns the
* pointer passed in if the string does not describe an integer.
*
* @param str String to parse.
*
* @param val Pointer to receive the parsed unsigned integer value.
*
* @return A pointer to the first character following the unsigned integer or the pointer passed in.
*/
const OI_CHAR* OI_ScanUInt(const OI_CHAR *str,
OI_UINT32 *val);
/**
* Parse a whitespace delimited substring out of a string.
*
* @param str Input string to parse.
* @param outStr Buffer to return the substring
* @param len Length of outStr
*
*
* @return A pointer to the first character following the substring or the pointer passed in.
*/
const OI_CHAR* OI_ScanStr(const OI_CHAR *str,
OI_CHAR *outStr,
OI_UINT16 len);
/**
* Parse a string for one of a set of alternative value. Skips leading whitespace (space and tabs
* only) and parses text matching one of the alternative strings. Returns pointer to first character
* following the matched text.
*
* @param str String to parse.
*
* @param alts Alternative matching strings separated by '|'
*
* @param index Pointer to receive the index of the matching alternative, return value is -1 if
* there is no match.
*
* @return A pointer to the first character following the matched value or the pointer passed in
* if there was no matching text.
*/
const OI_CHAR* OI_ScanAlt(const OI_CHAR *str,
const OI_CHAR *alts,
OI_INT *index);
/**
* Parse a string for a BD Addr. Skips leading whitespace (space and tabs only) and parses a
* Bluetooth device address with nibbles optionally separated by colons. Return pointet to first
* character following the BD Addr.
*
* @param str String to parse.
*
* @param addr Pointer to receive the Bluetooth device address
*
* @return A pointer to the first character following the BD Addr or the pointer passed in.
*/
const OI_CHAR* OI_ScanBdAddr(const OI_CHAR *str,
OI_BD_ADDR *addr);
/** Get a character from a digit integer value (0 - 9). */
#define OI_DigitToChar(d) ((d) + '0')
/**
* Determine Maximum and Minimum between two arguments.
*
* @param a 1st value
* @param b 2nd value
*
* @return the max or min value between a & b
*/
#define OI_MAX(a, b) (((a) < (b)) ? (b) : (a) )
#define OI_MIN(a, b) (((a) > (b)) ? (b) : (a) )
/**
* Compare two BD_ADDRs
* SAME_BD_ADDR - Boolean: TRUE if they are the same address
*/
#define SAME_BD_ADDR(x, y) (0 == OI_MemCmp((x),(y),OI_BD_ADDR_BYTE_SIZE) )
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_UTILS_H */
+310
View File
@@ -0,0 +1,310 @@
#include "msbc_decoder_port.h"
static struct sbc_decoder_state sbc_internal_decoder_state = {0};
static void msbc_append_received_data(struct sbc_decoder_state * state, uint8_t * buffer, int size)
{
int numFreeBytes = sizeof(state->frame_buffer) - state->bytes_in_frame_buffer;
if (size > numFreeBytes) {
printf("SBC data: more bytes read %u than free bytes in buffer %u", size, numFreeBytes);
}
(void)memcpy(state->frame_buffer + state->bytes_in_frame_buffer, buffer,
size);
state->bytes_in_frame_buffer += size;
}
// returns position of mSBC sync word
static int msbc_find_h2_sync(const uint8_t *frame_data, OI_UINT32 frame_bytes, int * sync_word_nr)
{
int syncword = mSBC_SYNCWORD;
uint8_t h2_first_byte = 0;
uint8_t h2_second_byte = 0;
unsigned int i;
for (i=0; i<frame_bytes; i++) {
if (frame_data[i] == syncword) {
// check: first byte == 1
if (h2_first_byte == 1) {
// check lower nibble of second byte == 0x08
uint8_t ln = h2_second_byte & 0x0F;
if (ln == 8) {
// check if bits 0+2 == bits 1+3
uint8_t hn = h2_second_byte >> 4;
if ( ((hn>>1) & 0x05) == (hn & 0x05) ) {
*sync_word_nr = ((hn & 0x04) >> 1) | (hn & 0x01);
return i;
}
}
}
}
h2_first_byte = h2_second_byte;
h2_second_byte = frame_data[i];
}
return -1;
}
static int msbc_find_sequence_of_zeros(const uint8_t *frame_data, OI_UINT32 frame_bytes,
int seq_length)
{
int zero_seq_count = 0;
unsigned int i;
for (i=0; i<frame_bytes; i++) {
if (frame_data[i] == 0) {
zero_seq_count++;
if (zero_seq_count >= seq_length)
return zero_seq_count;
} else {
zero_seq_count = 0;
}
}
return 0;
}
static void msbc_decoder_drop_processed_bytes(struct sbc_decoder_state * decoder_state, uint16_t bytes_processed)
{
memmove(decoder_state->frame_buffer, decoder_state->frame_buffer + bytes_processed,
decoder_state->bytes_in_frame_buffer-bytes_processed);
decoder_state->bytes_in_frame_buffer -= bytes_processed;
}
static int16_t msbc_crop_sample(float val){
float croped_val = val;
if (croped_val > 32767.0) croped_val= 32767.0;
if (croped_val < -32768.0) croped_val=-32768.0;
return (int16_t) croped_val;
}
void msbc_plc_good_frame(struct sbc_plc_state *plc_state, int16_t *in, int16_t *out){
float val;
int i = 0;
plc_state->good_frames_nr++;
plc_state->frame_count++;
#ifdef OCTAVE_OUTPUT
FILE * oct_file = NULL;
if (plc_state->nbf>0){
oct_file = open_octave_file(plc_state, OCTAVE_FRAME_TYPE_GOOD);
if (oct_file){
octave_fprintf_plot_history_frame(plc_state, oct_file, plc_state->frame_count);
}
}
#endif
if (plc_state->nbf>0) {
for (i=0;i<SBC_RT;i++) {
out[i] = plc_state->hist[SBC_LHIST+i];
}
for (i = SBC_RT;i<(SBC_RT+SBC_OLAL);i++) {
float left = plc_state->hist[SBC_LHIST+i];
float right = in[i];
val = (left*rcos[i-SBC_RT]) + (right*rcos[SBC_OLAL+SBC_RT-1-i]);
out[i] = msbc_crop_sample(val);
}
}
for (;i<SBC_FS;i++) {
out[i] = in[i];
}
// Copy the output to the history buffer
for (i=0;i<SBC_FS;i++) {
plc_state->hist[SBC_LHIST+i] = out[i];
}
// shift the history buffer
for (i=0;i<SBC_LHIST;i++) {
plc_state->hist[i] = plc_state->hist[i+SBC_FS];
}
#ifdef OCTAVE_OUTPUT
if (oct_file){
octave_fprintf_plot_output(plc_state, oct_file);
fclose(oct_file);
}
#endif
plc_state->nbf=0;
}
static int msbc_decoder_get_num_samples_per_frame(struct sbc_decoder_state * state)
{
return state->decoder_context.common.frameInfo.nrof_blocks * state->decoder_context.common.frameInfo.nrof_subbands;
}
static int msbc_decoder_get_num_channels(struct sbc_decoder_state * state)
{
return state->decoder_context.common.frameInfo.nrof_channels;
}
static int msbc_decoder_get_sample_rate(struct sbc_decoder_state * state)
{
return state->decoder_context.common.frameInfo.frequency;
}
void msbc_decoder_process_msbc_data(int packet_status_flag, uint8_t * buffer, int size)
{
int h2_syncword = 0,h2_sync_pos = 0,zero_seq_found = 0,bytes_missing = 0,bytes_to_append = 0;
int input_bytes = size;
int bad_frame = 0;
uint16_t undecoding_bytes = 0,bytes_processed = 0;
const uint8_t *frame_data;
const unsigned int MSBC_FRAME_SIZE = 60;
struct sbc_decoder_state * decoder_state = &sbc_internal_decoder_state;
while (input_bytes > 0) {
bytes_missing = MSBC_FRAME_SIZE - decoder_state->bytes_in_frame_buffer;
bytes_to_append = (input_bytes < bytes_missing ? input_bytes : bytes_missing);
if (bytes_to_append) {
msbc_append_received_data(decoder_state, buffer, bytes_to_append);
buffer += bytes_to_append;
input_bytes -= bytes_to_append;
}
if (decoder_state->bytes_in_frame_buffer < MSBC_FRAME_SIZE)
break;
undecoding_bytes = decoder_state->bytes_in_frame_buffer;
frame_data = decoder_state->frame_buffer;
// testing only - corrupt frame periodically
//btstack_sbc_decoder_bluedroid_simulate_error(frame_data);
// assert frame looks like this: 01 x8 AD [rest of frame 56 bytes] 00
h2_sync_pos = msbc_find_h2_sync(frame_data, decoder_state->bytes_in_frame_buffer, &h2_syncword);
if (h2_sync_pos < 0) {
// no sync found, discard all but last 2 bytes
bytes_processed = decoder_state->bytes_in_frame_buffer - 2;
msbc_decoder_drop_processed_bytes(decoder_state, bytes_processed);
// don't try PLC without at least a single good frame
if (decoder_state->first_good_frame_found){
decoder_state->msbc_bad_bytes += bytes_processed;
}
continue;
}
zero_seq_found = msbc_find_sequence_of_zeros(frame_data, decoder_state->bytes_in_frame_buffer, 20);
// after first valid frame, zero sequences count as bad frames
if (decoder_state->first_good_frame_found) {
bad_frame = zero_seq_found || packet_status_flag;
}
if (bad_frame) {
// stats
if (zero_seq_found) {
decoder_state->zero_frames_nr++;
} else {
decoder_state->bad_frames_nr++;
}
#ifdef LOG_FRAME_STATUS
if (zero_seq_found) {
printf("%d : ZERO FRAME\n", decoder_state->h2_sequence_nr);
} else {
printf("%d : BAD FRAME\n", decoder_state->h2_sequence_nr);
}
#endif
// retry after dropping 3 byte sync
bytes_processed = 3;
msbc_decoder_drop_processed_bytes(decoder_state, bytes_processed);
decoder_state->msbc_bad_bytes += bytes_processed;
// log_info("Trace bad frame");
continue;
}
//ready to decode frame
OI_STATUS status = OI_CODEC_SBC_DecodeFrame(&(decoder_state->decoder_context),
&frame_data,
&(decoder_state->bytes_in_frame_buffer),
decoder_state->pcm_plc_data,
&(decoder_state->pcm_bytes));
bytes_processed = undecoding_bytes - decoder_state->bytes_in_frame_buffer;
// log_info("Trace decode status %u, processed %u (bad bytes %u), bytes in buffer %u", (int) status, bytes_processed, decoder_state->msbc_bad_bytes, decoder_state->bytes_in_frame_buffer);
switch(status) {
case 0:
// synced
decoder_state->first_good_frame_found = 1;
// get rid of padding byte, not processed by SBC decoder
decoder_state->bytes_in_frame_buffer = 0;
// restart counting bad bytes
decoder_state->msbc_bad_bytes = 0;
// feed good frame into PLC history
msbc_plc_good_frame(&decoder_state->plc_state,
decoder_state->pcm_plc_data,
decoder_state->pcm_data);
// deliver PCM data
decoder_state->handle_pcm_data(decoder_state->pcm_data,
msbc_decoder_get_num_samples_per_frame(decoder_state),
msbc_decoder_get_num_channels(decoder_state),
msbc_decoder_get_sample_rate(decoder_state),
decoder_state->context);
// stats
decoder_state->good_frames_nr++;
continue;
case OI_CODEC_SBC_CHECKSUM_MISMATCH:
// The next frame is somehow corrupt.
printf("OI_CODEC_SBC_CHECKSUM_MISMATCH");
// Did the codec consume any bytes?
if (bytes_processed > 0){
// Good. Nothing to do.
} else {
// Skip the bogus frame by skipping the header.
bytes_processed = 1;
}
break;
case OI_STATUS_INVALID_PARAMETERS:
// This caused by corrupt frames.
// The codec apparently does not recover from this.
// Re-initialize the codec.
printf("SBC decode: invalid parameters: resetting codec");
if (OI_CODEC_mSBC_DecoderReset(&(decoder_state->decoder_context),
decoder_state->decoder_data,
sizeof(decoder_state->decoder_data)) != OI_STATUS_SUCCESS) {
printf("SBC decode: resetting codec failed");
}
break;
default:
printf("Frame decode error: %d", status);
break;
}
// on success, while loop was restarted, so all processed bytes have been "bad"
decoder_state->msbc_bad_bytes += bytes_processed;
// drop processed bytes from frame buffer
msbc_decoder_drop_processed_bytes(decoder_state, bytes_processed);
}
}
int msbc_decoder_init(msbc_decoder_data_cb cb)
{
struct sbc_decoder_state * decoder_state = &sbc_internal_decoder_state;
OI_STATUS status = OI_STATUS_SUCCESS;
status = OI_CODEC_mSBC_DecoderReset(&(decoder_state->decoder_context),
decoder_state->decoder_data,
sizeof(decoder_state->decoder_data));
decoder_state->bytes_in_frame_buffer = 0;
decoder_state->pcm_bytes = sizeof(decoder_state->pcm_data);
decoder_state->h2_sequence_nr = -1;
decoder_state->first_good_frame_found = 0;
decoder_state->handle_pcm_data = cb;
decoder_state->context = NULL;
decoder_state->plc_state.nbf = 0;
decoder_state->plc_state.bestlag = 0;
memset(decoder_state->plc_state.hist,0,sizeof(decoder_state->plc_state.hist));
return (int)status;
}
+70
View File
@@ -0,0 +1,70 @@
#ifndef __MSBC_DECODER_PORT_H_
#define __MSBC_DECODER_PORT_H_
#include "oi_codec_sbc.h"
#include <stdint.h>
#define DECODER_DATA_SIZE (SBC_MAX_CHANNELS*SBC_MAX_BLOCKS*SBC_MAX_BANDS * 4 + \
SBC_CODEC_MIN_FILTER_BUFFERS*SBC_MAX_BANDS*SBC_MAX_CHANNELS * 2)
#define SBC_FS 120 /* SBC Frame Size */
#define SBC_N 512 /* 32ms - Window Length for pattern matching */
#define SBC_M 64 /* 4ms - Template for matching */
#define SBC_LHIST (SBC_N+SBC_FS-1) /* Length of history buffer required */
#define SBC_RT 36 /* SBC Reconvergence Time (samples) */
#define SBC_OLAL 16 /* OverLap-Add Length (samples) */
#define mSBC_SYNCWORD 0xad
static float rcos[8] = {
0.99148655f,0.92510857f,
0.80131732f,0.63683150f,
0.45386582f,0.27713082f,
0.13049554f,0.03376389f,
};
/* PLC State Information */
struct sbc_plc_state {
int16_t hist[SBC_LHIST+SBC_FS+SBC_RT+SBC_OLAL];
int16_t bestlag;
int nbf;
// summary of processed good and bad frames
int good_frames_nr;
int bad_frames_nr;
int frame_count;
int max_consecutive_bad_frames_nr;
} __attribute__((packed));
struct sbc_decoder_state {
void *context;
struct sbc_plc_state plc_state;
void (*handle_pcm_data)(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context);
uint32_t bytes_in_frame_buffer;
OI_CODEC_SBC_DECODER_CONTEXT decoder_context;
uint8_t frame_buffer[SBC_MAX_FRAME_LEN];
int16_t pcm_plc_data[SBC_MAX_CHANNELS * SBC_MAX_BANDS * SBC_MAX_BLOCKS];
int16_t pcm_data[SBC_MAX_CHANNELS * SBC_MAX_BANDS * SBC_MAX_BLOCKS];
uint32_t pcm_bytes;
uint32_t decoder_data[(DECODER_DATA_SIZE+3)/4];
int first_good_frame_found;
int h2_sequence_nr;
uint16_t msbc_bad_bytes;
// summary of processed good, bad and zero frames
int good_frames_nr;
int bad_frames_nr;
int zero_frames_nr;
};
typedef void (*msbc_decoder_data_cb)(int16_t * data, int num_samples,int num_channels,
int sample_rate, void * context);
void msbc_decoder_process_msbc_data(int packet_status_flag, uint8_t * buffer, int size);
int msbc_decoder_init(msbc_decoder_data_cb cb);
#endif
+78
View File
@@ -0,0 +1,78 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#include <stdlib.h>
#include <oi_codec_sbc_private.h>
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
PRIVATE OI_STATUS OI_CODEC_SBC_Alloc(OI_CODEC_SBC_COMMON_CONTEXT *common,
OI_UINT32 *codecDataAligned,
OI_UINT32 codecDataBytes,
OI_UINT8 maxChannels,
OI_UINT8 pcmStride)
{
int i;
size_t filterBufferCount;
size_t subdataSize;
OI_BYTE *codecData = (OI_BYTE*)codecDataAligned;
if ((maxChannels < 1) || (maxChannels > 2)) {
return OI_STATUS_INVALID_PARAMETERS;
}
if ((pcmStride < 1) || (pcmStride > maxChannels)) {
return OI_STATUS_INVALID_PARAMETERS;
}
common->maxChannels = maxChannels;
common->pcmStride = pcmStride;
/* Compute sizes needed for the memory regions, and bail if we don't have
* enough memory for them. */
subdataSize = maxChannels * sizeof(common->subdata[0]) * SBC_MAX_BANDS * SBC_MAX_BLOCKS;
if (subdataSize > codecDataBytes) {
return OI_STATUS_OUT_OF_MEMORY;
}
filterBufferCount = (codecDataBytes - subdataSize) / (sizeof(common->filterBuffer[0][0]) * SBC_MAX_BANDS * maxChannels);
if (filterBufferCount < SBC_CODEC_MIN_FILTER_BUFFERS) {
return OI_STATUS_OUT_OF_MEMORY;
}
common->filterBufferLen = (uint32_t) filterBufferCount * SBC_MAX_BANDS;
/* Allocate memory for the subband data */
common->subdata = (OI_INT32*)codecData;
codecData += subdataSize;
OI_ASSERT(codecDataBytes >= subdataSize);
codecDataBytes -= (uint32_t) subdataSize;
/* Allocate memory for the synthesis buffers */
for (i = 0; i < maxChannels; ++i) {
size_t allocSize = common->filterBufferLen * sizeof(common->filterBuffer[0][0]);
common->filterBuffer[i] = (SBC_BUFFER_T*)codecData;
OI_ASSERT(codecDataBytes >= allocSize);
codecData += allocSize;
codecDataBytes -= (uint32_t) allocSize;
}
return OI_OK;
}
+165
View File
@@ -0,0 +1,165 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
@ingroup codec_internal
*/
/**@addgroup codec_internal*/
/**@{*/
#include <oi_codec_sbc_private.h>
static void dualBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
OI_UINT bitcountL;
OI_UINT bitcountR;
OI_UINT bitpoolPreferenceL = 0;
OI_UINT bitpoolPreferenceR = 0;
BITNEED_UNION1 bitneedsL;
BITNEED_UNION1 bitneedsR;
bitcountL = computeBitneed(common, bitneedsL.uint8, 0, &bitpoolPreferenceL);
bitcountR = computeBitneed(common, bitneedsR.uint8, 1, &bitpoolPreferenceR);
oneChannelBitAllocation(common, &bitneedsL, 0, bitcountL);
oneChannelBitAllocation(common, &bitneedsR, 1, bitcountR);
}
static void stereoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
BITNEED_UNION2 bitneeds;
OI_UINT excess;
OI_INT bitadjust;
OI_UINT bitcount;
OI_UINT sbL;
OI_UINT sbR;
OI_UINT bitpoolPreference = 0;
bitcount = computeBitneed(common, &bitneeds.uint8[0], 0, &bitpoolPreference);
bitcount += computeBitneed(common, &bitneeds.uint8[nrof_subbands], 1, &bitpoolPreference);
{
OI_UINT ex;
bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds.uint32, 2 * nrof_subbands, bitcount, &ex);
/* We want the compiler to put excess into a register */
excess = ex;
}
sbL = 0;
sbR = nrof_subbands;
while (sbL < nrof_subbands) {
excess = allocAdjustedBits(&common->bits.uint8[sbL], bitneeds.uint8[sbL] + bitadjust, excess);
++sbL;
excess = allocAdjustedBits(&common->bits.uint8[sbR], bitneeds.uint8[sbR] + bitadjust, excess);
++sbR;
}
sbL = 0;
sbR = nrof_subbands;
while (excess) {
excess = allocExcessBits(&common->bits.uint8[sbL], excess);
++sbL;
if (!excess) {
break;
}
excess = allocExcessBits(&common->bits.uint8[sbR], excess);
++sbR;
}
}
static const BIT_ALLOC balloc[] = {
monoBitAllocation, /* SBC_MONO */
dualBitAllocation, /* SBC_DUAL_CHANNEL */
stereoBitAllocation, /* SBC_STEREO */
stereoBitAllocation /* SBC_JOINT_STEREO */
};
PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
OI_ASSERT(common->frameInfo.bitpool <= OI_SBC_MaxBitpool(&common->frameInfo));
OI_ASSERT(common->frameInfo.mode < OI_ARRAYSIZE(balloc));
/*
* Using an array of function pointers prevents the compiler from creating a suboptimal
* monolithic inlined bit allocation function.
*/
balloc[common->frameInfo.mode](common);
}
OI_UINT32 OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame)
{
return internal_CalculateBitrate(frame);
}
/*
* Return the current maximum bitneed and clear it.
*/
#if 0
OI_UINT8 OI_CODEC_SBC_GetMaxBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
OI_UINT8 max = common->maxBitneed;
common->maxBitneed = 0;
return max;
}
#endif
/*
* Calculates the bitpool size for a given frame length
*/
OI_UINT16 OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO *frame,
OI_UINT16 frameLen)
{
OI_UINT16 nrof_subbands = frame->nrof_subbands;
OI_UINT16 nrof_blocks = frame->nrof_blocks;
OI_UINT16 hdr;
OI_UINT16 bits;
if (frame->mode == SBC_JOINT_STEREO) {
hdr = 9 * nrof_subbands;
} else {
if (frame->mode == SBC_MONO) {
hdr = 4 * nrof_subbands;
} else {
hdr = 8 * nrof_subbands;
}
if (frame->mode == SBC_DUAL_CHANNEL) {
nrof_blocks *= 2;
}
}
bits = (8 * (frameLen - SBC_HEADER_LEN)) - hdr;
return DIVIDE(bits, nrof_blocks);
}
OI_UINT16 OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
return sizeof(OI_INT16) * common->pcmStride * common->frameInfo.nrof_subbands * common->frameInfo.nrof_blocks;
}
OI_UINT16 OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame)
{
return internal_CalculateFramelen(frame);
}
/**@}*/
+394
View File
@@ -0,0 +1,394 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
The functions in this file relate to the allocation of available bits to
subbands within the SBC/eSBC frame, along with support functions for computing
frame length and bitrate.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "oi_utils.h"
#include <oi_codec_sbc_private.h>
OI_UINT32 OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO *frame)
{
switch (frame->mode) {
case SBC_MONO:
case SBC_DUAL_CHANNEL:
return 16 * frame->nrof_subbands;
case SBC_STEREO:
case SBC_JOINT_STEREO:
return 32 * frame->nrof_subbands;
default:
break;
}
ERROR(("Invalid frame mode %d", frame->mode));
OI_ASSERT(FALSE);
return 0; /* Should never be reached */
}
PRIVATE OI_UINT16 internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame)
{
OI_UINT16 nbits = frame->nrof_blocks * frame->bitpool;
OI_UINT16 nrof_subbands = frame->nrof_subbands;
OI_UINT16 result = nbits;
if (frame->mode == SBC_JOINT_STEREO) {
result += nrof_subbands + (8 * nrof_subbands);
} else {
if (frame->mode == SBC_DUAL_CHANNEL) { result += nbits; }
if (frame->mode == SBC_MONO) { result += 4*nrof_subbands; } else { result += 8*nrof_subbands; }
}
return SBC_HEADER_LEN + ((result + 7) / 8);
}
PRIVATE OI_UINT32 internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame)
{
OI_UINT blocksbands;
blocksbands = frame->nrof_subbands * frame->nrof_blocks;
return DIVIDE(8 * internal_CalculateFramelen(frame) * frame->frequency, blocksbands);
}
INLINE OI_UINT16 OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO *frame, OI_UINT *headerLen_)
{
OI_UINT headerLen = SBC_HEADER_LEN + (frame->nrof_subbands * frame->nrof_channels/2);
if (frame->mode == SBC_JOINT_STEREO) { headerLen++; }
*headerLen_ = headerLen;
return internal_CalculateFramelen(frame);
}
#define MIN(x, y) ((x) < (y) ? (x) : (y))
/*
* Computes the bit need for each sample and as also returns a counts of bit needs that are greater
* than one. This count is used in the first phase of bit allocation.
*
* We also compute a preferred bitpool value that this is the minimum bitpool needed to guarantee
* lossless representation of the audio data. The preferred bitpool may be larger than the bits
* actually required but the only input we have are the scale factors. For example, it takes 2 bits
* to represent values in the range -1 .. +1 but the scale factor is 0. To guarantee lossless
* representation we add 2 to each scale factor and sum them to come up with the preferred bitpool.
* This is not ideal because 0 requires 0 bits but we currently have no way of knowing this.
*
* @param bitneed Array to return bitneeds for each subband
*
* @param ch Channel 0 or 1
*
* @param preferredBitpool Returns the number of reserved bits
*
* @return The SBC bit need
*
*/
OI_UINT computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common,
OI_UINT8 *bitneeds,
OI_UINT ch,
OI_UINT *preferredBitpool)
{
static const OI_INT8 offset4[4][4] = {
{ -1, 0, 0, 0 },
{ -2, 0, 0, 1 },
{ -2, 0, 0, 1 },
{ -2, 0, 0, 1 }
};
static const OI_INT8 offset8[4][8] = {
{ -2, 0, 0, 0, 0, 0, 0, 1 },
{ -3, 0, 0, 0, 0, 0, 1, 2 },
{ -4, 0, 0, 0, 0, 0, 1, 2 },
{ -4, 0, 0, 0, 0, 0, 1, 2 }
};
const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
OI_UINT sb;
OI_INT8 *scale_factor = &common->scale_factor[ch ? nrof_subbands : 0];
OI_UINT bitcount = 0;
OI_UINT8 maxBits = 0;
OI_UINT8 prefBits = 0;
if (common->frameInfo.alloc == SBC_SNR) {
for (sb = 0; sb < nrof_subbands; sb++) {
OI_INT bits = scale_factor[sb];
if (bits > maxBits) {
maxBits = bits;
}
if ((bitneeds[sb] = bits) > 1) {
bitcount += bits;
}
prefBits += 2 + bits;
}
} else {
const OI_INT8 *offset;
if (nrof_subbands == 4) {
offset = offset4[common->frameInfo.freqIndex];
} else {
offset = offset8[common->frameInfo.freqIndex];
}
for (sb = 0; sb < nrof_subbands; sb++) {
OI_INT bits = scale_factor[sb];
if (bits > maxBits) {
maxBits = bits;
}
prefBits += 2 + bits;
if (bits) {
bits -= offset[sb];
if (bits > 0) {
bits /= 2;
}
bits += 5;
}
if ((bitneeds[sb] = bits) > 1) {
bitcount += bits;
}
}
}
common->maxBitneed = OI_MAX(maxBits, common->maxBitneed);
*preferredBitpool += prefBits;
return bitcount;
}
/*
* Explanation of the adjustToFitBitpool inner loop.
*
* The inner loop computes the effect of adjusting the bit allocation up or
* down. Allocations must be 0 or in the range 2..16. This is accomplished by
* the following code:
*
* for (s = bands - 1; s >= 0; --s) {
* OI_INT bits = bitadjust + bitneeds[s];
* bits = bits < 2 ? 0 : bits;
* bits = bits > 16 ? 16 : bits;
* count += bits;
* }
*
* This loop can be optimized to perform 4 operations at a time as follows:
*
* Adjustment is computed as a 7 bit signed value and added to the bitneed.
*
* Negative allocations are zeroed by masking. (n & 0x40) >> 6 puts the
* sign bit into bit 0, adding this to 0x7F give us a mask of 0x80
* for -ve values and 0x7F for +ve values.
*
* n &= 0x7F + (n & 0x40) >> 6)
*
* Allocations greater than 16 are truncated to 16. Adjusted allocations are in
* the range 0..31 so we know that bit 4 indicates values >= 16. We use this bit
* to create a mask that zeroes bits 0 .. 3 if bit 4 is set.
*
* n &= (15 + (n >> 4))
*
* Allocations of 1 are disallowed. Add and shift creates a mask that
* eliminates the illegal value
*
* n &= ((n + 14) >> 4) | 0x1E
*
* These operations can be performed in 8 bits without overflowing so we can
* operate on 4 values at once.
*/
/*
* Encoder/Decoder
*
* Computes adjustment +/- of bitneeds to fill bitpool and returns overall
* adjustment and excess bits.
*
* @param bitpool The bitpool we have to work within
*
* @param bitneeds An array of bit needs (more acturately allocation prioritities) for each
* subband across all blocks in the SBC frame
*
* @param subbands The number of subbands over which the adkustment is calculated. For mono and
* dual mode this is 4 or 8, for stereo or joint stereo this is 8 or 16.
*
* @param bitcount A starting point for the adjustment
*
* @param excess Returns the excess bits after the adjustment
*
* @return The adjustment.
*/
OI_INT adjustToFitBitpool(const OI_UINT bitpool,
OI_UINT32 *bitneeds,
const OI_UINT subbands,
OI_UINT bitcount,
OI_UINT *excess)
{
OI_INT maxBitadjust = 0;
OI_INT bitadjust = (bitcount > bitpool) ? -8 : 8;
OI_INT chop = 8;
/*
* This is essentially a binary search for the optimal adjustment value.
*/
while ((bitcount != bitpool) && chop) {
OI_UINT32 total = 0;
OI_UINT count;
OI_UINT32 adjust4;
OI_INT i;
adjust4 = bitadjust & 0x7F;
adjust4 |= (adjust4 << 8);
adjust4 |= (adjust4 << 16);
for (i = ((subbands / 4) - 1); i >= 0; --i) {
OI_UINT32 mask;
OI_UINT32 n = bitneeds[i] + adjust4;
mask = 0x7F7F7F7F + ((n & 0x40404040) >> 6);
n &= mask;
mask = 0x0F0F0F0F + ((n & 0x10101010) >> 4);
n &= mask;
mask = (((n + 0x0E0E0E0E) >> 4) | 0x1E1E1E1E);
n &= mask;
total += n;
}
count = (total & 0xFFFF) + (total >> 16);
count = (count & 0xFF) + (count >> 8);
chop >>= 1;
if (count > bitpool) {
bitadjust -= chop;
} else {
maxBitadjust = bitadjust;
bitcount = count;
bitadjust += chop;
}
}
*excess = bitpool - bitcount;
return maxBitadjust;
}
/*
* The bit allocator trys to avoid single bit allocations except as a last resort. So in the case
* where a bitneed of 1 was passed over during the adsjustment phase 2 bits are now allocated.
*/
INLINE OI_INT allocAdjustedBits(OI_UINT8 *dest,
OI_INT bits,
OI_INT excess)
{
if (bits < 16) {
if (bits > 1) {
if (excess) {
++bits;
--excess;
}
} else if ((bits == 1) && (excess > 1)) {
bits = 2;
excess -= 2;
} else {
bits = 0;
}
} else {
bits = 16;
}
*dest = (OI_UINT8)bits;
return excess;
}
/*
* Excess bits not allocated by allocaAdjustedBits are allocated round-robin.
*/
INLINE OI_INT allocExcessBits(OI_UINT8 *dest,
OI_INT excess)
{
if (*dest < 16) {
*dest += 1;
return excess - 1;
} else {
return excess;
}
}
void oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common,
BITNEED_UNION1 *bitneeds,
OI_UINT ch,
OI_UINT bitcount)
{
const OI_UINT8 nrof_subbands = common->frameInfo.nrof_subbands;
OI_UINT excess;
OI_UINT sb;
OI_INT bitadjust;
OI_UINT8 RESTRICT *allocBits;
{
OI_UINT ex;
bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds->uint32, nrof_subbands, bitcount, &ex);
/* We want the compiler to put excess into a register */
excess = ex;
}
/*
* Allocate adjusted bits
*/
allocBits = &common->bits.uint8[ch ? nrof_subbands : 0];
sb = 0;
while (sb < nrof_subbands) {
excess = allocAdjustedBits(&allocBits[sb], bitneeds->uint8[sb] + bitadjust, excess);
++sb;
}
sb = 0;
while (excess) {
excess = allocExcessBits(&allocBits[sb], excess);
++sb;
}
}
void monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
BITNEED_UNION1 bitneeds;
OI_UINT bitcount;
OI_UINT bitpoolPreference = 0;
bitcount = computeBitneed(common, bitneeds.uint8, 0, &bitpoolPreference);
oneChannelBitAllocation(common, &bitneeds, 0, bitcount);
}
/**
@}
*/
@@ -0,0 +1,92 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Functions for manipulating input bitstreams.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "oi_stddefs.h"
#include "oi_bitstream.h"
#include "oi_assert.h"
PRIVATE void OI_BITSTREAM_ReadInit(OI_BITSTREAM *bs,
const OI_BYTE *buffer)
{
bs->value = ((OI_INT32)buffer[0] << 16) | ((OI_INT32)buffer[1] << 8) | (buffer[2]);
bs->ptr.r = buffer + 3;
bs->bitPtr = 8;
}
PRIVATE OI_UINT32 OI_BITSTREAM_ReadUINT(OI_BITSTREAM *bs, OI_UINT bits)
{
OI_UINT32 result;
OI_BITSTREAM_READUINT(result, bits, bs->ptr.r, bs->value, bs->bitPtr);
return result;
}
PRIVATE OI_UINT8 OI_BITSTREAM_ReadUINT4Aligned(OI_BITSTREAM *bs)
{
OI_UINT32 result;
OI_ASSERT(bs->bitPtr < 16);
OI_ASSERT(bs->bitPtr % 4 == 0);
if (bs->bitPtr == 8) {
result = bs->value << 8;
bs->bitPtr = 12;
} else {
result = bs->value << 12;
bs->value = (bs->value << 8) | *bs->ptr.r++;
bs->bitPtr = 8;
}
result >>= 28;
OI_ASSERT(result < (1u << 4));
return (OI_UINT8)result;
}
PRIVATE OI_UINT8 OI_BITSTREAM_ReadUINT8Aligned(OI_BITSTREAM *bs)
{
OI_UINT32 result;
OI_ASSERT(bs->bitPtr == 8);
result = bs->value >> 16;
bs->value = (bs->value << 8) | *bs->ptr.r++;
return (OI_UINT8)result;
}
/**
@}
*/
+140
View File
@@ -0,0 +1,140 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2006 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
This file exposes OINA-specific interfaces to decoder functions.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include <oi_codec_sbc_private.h>
OI_STATUS OI_CODEC_SBC_DecoderConfigureRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_BOOL enhanced,
OI_UINT8 frequency,
OI_UINT8 mode,
OI_UINT8 subbands,
OI_UINT8 blocks,
OI_UINT8 alloc,
OI_UINT8 maxBitpool)
{
if (frequency > SBC_FREQ_48000) {
return OI_STATUS_INVALID_PARAMETERS;
}
if (enhanced) {
#ifdef SBC_ENHANCED
if (subbands != SBC_SUBBANDS_8) {
return OI_STATUS_INVALID_PARAMETERS;
}
#else
return OI_STATUS_INVALID_PARAMETERS;
#endif
}
if (mode > SBC_JOINT_STEREO) {
return OI_STATUS_INVALID_PARAMETERS;
}
if (subbands > SBC_SUBBANDS_8) {
return OI_STATUS_INVALID_PARAMETERS;
}
if (blocks > SBC_BLOCKS_16) {
return OI_STATUS_INVALID_PARAMETERS;
}
if (alloc > SBC_SNR) {
return OI_STATUS_INVALID_PARAMETERS;
}
#ifdef SBC_ENHANCED
context->common.frameInfo.enhanced = enhanced;
#else
context->common.frameInfo.enhanced = FALSE;
#endif
context->common.frameInfo.freqIndex = frequency;
context->common.frameInfo.mode = mode;
context->common.frameInfo.subbands = subbands;
context->common.frameInfo.blocks = blocks;
context->common.frameInfo.alloc = alloc;
context->common.frameInfo.bitpool = maxBitpool;
OI_SBC_ExpandFrameFields(&context->common.frameInfo);
if (context->common.frameInfo.nrof_channels >= context->common.pcmStride) {
return OI_STATUS_INVALID_PARAMETERS;
}
return OI_OK;
}
OI_STATUS OI_CODEC_SBC_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT8 bitpool,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes)
{
return internal_DecodeRaw(context,
bitpool,
frameData,
frameBytes,
pcmData,
pcmBytes);
}
OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_BOOL enhanced,
OI_UINT8 subbands)
{
if (enhanced)
{
#ifdef SBC_ENHANCED
context->enhancedEnabled = TRUE;
#else
context->enhancedEnabled = FALSE;
#endif
}
else
{
context->enhancedEnabled = FALSE;
}
context->restrictSubbands = subbands;
context->limitFrameFormat = TRUE;
return OI_OK;
}
/**
@}
*/
@@ -0,0 +1,272 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
This file drives SBC decoding.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "oi_codec_sbc_private.h"
#include "oi_bitstream.h"
#include <stdio.h>
const OI_CHAR * OI_Codec_Copyright = "Copyright 2002-2007 Open Interface North America, Inc. All rights reserved";
INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes,
OI_BYTE maxChannels,
OI_BYTE pcmStride,
OI_BOOL enhanced)
{
OI_UINT i;
OI_STATUS status;
for (i = 0; i < sizeof(*context); i++) {
((char *)context)[i] = 0;
}
#ifdef SBC_ENHANCED
context->enhancedEnabled = enhanced ? TRUE : FALSE;
#else
context->enhancedEnabled = FALSE;
if (enhanced){
return OI_STATUS_INVALID_PARAMETERS;
}
#endif
status = OI_CODEC_SBC_Alloc(&context->common, decoderData, decoderDataBytes, maxChannels, pcmStride);
if (!OI_SUCCESS(status)) {
return status;
}
context->common.codecInfo = OI_Codec_Copyright;
context->common.maxBitneed = 0;
context->limitFrameFormat = FALSE;
OI_SBC_ExpandFrameFields(&context->common.frameInfo);
/*PLATFORM_DECODER_RESET(context);*/
return OI_OK;
}
/**
* Read the SBC header up to but not including the joint stereo mask. The syncword has already been
* examined, and the enhanced mode flag set, by FindSyncword.
*/
/* BK4BTSTACK_CHANGE START */
INLINE void OI_SBC_ReadHeader_mSBC(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data){
OI_CODEC_SBC_FRAME_INFO *frame = &common->frameInfo;
OI_ASSERT(data[0] == OI_mSBC_SYNCWORD);
/* Avoid filling out all these strucutures if we already remember the values
* from last time. Just in case we get a stream corresponding to data[1] ==
* 0, DecoderReset is responsible for ensuring the lookup table entries have
* already been populated
*/
frame->reserved_for_future_use[0] = data[1];
frame->reserved_for_future_use[1] = data[2];
frame->freqIndex = 0;
frame->frequency = 16000;
frame->blocks = 4; // ?
frame->nrof_blocks = 15;
frame->mode = 0;
frame->nrof_channels = 1;
frame->alloc = SBC_LOUDNESS;
frame->subbands = 1;
frame->nrof_subbands = 8;
frame->bitpool = 26;
frame->crc = data[3];
frame->cachedInfo = 0;
}
/* BK4BTSTACK_CHANGE END */
INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data)
{
OI_CODEC_SBC_FRAME_INFO *frame = &common->frameInfo;
OI_UINT8 d1;
OI_ASSERT(data[0] == OI_SBC_SYNCWORD || data[0] == OI_SBC_ENHANCED_SYNCWORD);
/* Avoid filling out all these strucutures if we already remember the values
* from last time. Just in case we get a stream corresponding to data[1] ==
* 0, DecoderReset is responsible for ensuring the lookup table entries have
* already been populated
*/
d1 = data[1];
if (d1 != frame->cachedInfo) {
frame->freqIndex = (d1 & (BIT7 | BIT6)) >> 6;
frame->frequency = freq_values[frame->freqIndex];
frame->blocks = (d1 & (BIT5 | BIT4)) >> 4;
frame->nrof_blocks = block_values[frame->blocks];
frame->mode = (d1 & (BIT3 | BIT2)) >> 2;
frame->nrof_channels = channel_values[frame->mode];
frame->alloc = (d1 & BIT1) >> 1;
frame->subbands = (d1 & BIT0);
frame->nrof_subbands = band_values[frame->subbands];
frame->cachedInfo = d1;
}
/*
* For decode, the bit allocator needs to know the bitpool value
*/
frame->bitpool = data[2];
frame->crc = data[3];
}
#define LOW(x) ((x)& 0xf)
#define HIGH(x) ((x) >> 4)
/*
* Read scalefactor values and prepare the bitstream for OI_SBC_ReadSamples
*/
PRIVATE void OI_SBC_ReadScalefactors(OI_CODEC_SBC_COMMON_CONTEXT *common,
const OI_BYTE *b,
OI_BITSTREAM *bs)
{
OI_UINT i = common->frameInfo.nrof_subbands * common->frameInfo.nrof_channels;
OI_INT8 *scale_factor = common->scale_factor;
OI_UINT f;
if ((common->frameInfo.nrof_subbands == 8) || (common->frameInfo.mode != SBC_JOINT_STEREO)) {
if (common->frameInfo.mode == SBC_JOINT_STEREO) {
common->frameInfo.join = *b++;
} else {
common->frameInfo.join = 0;
}
i /= 2;
do {
*scale_factor++ = HIGH(f = *b++);
*scale_factor++ = LOW(f);
} while (--i);
/*
* In this case we know that the scale factors end on a byte boundary so all we need to do
* is initialize the bitstream.
*/
OI_BITSTREAM_ReadInit(bs, b);
} else {
OI_ASSERT(common->frameInfo.nrof_subbands == 4 && common->frameInfo.mode == SBC_JOINT_STEREO);
common->frameInfo.join = HIGH(f = *b++);
i = (i - 1) / 2;
do {
*scale_factor++ = LOW(f);
*scale_factor++ = HIGH(f = *b++);
} while (--i);
*scale_factor++ = LOW(f);
/*
* In 4-subband joint stereo mode, the joint stereo information ends on a half-byte
* boundary, so it's necessary to use the bitstream abstraction to read it, since
* OI_SBC_ReadSamples will need to pick up in mid-byte.
*/
OI_BITSTREAM_ReadInit(bs, b);
*scale_factor++ = OI_BITSTREAM_ReadUINT4Aligned(bs);
}
}
/** Read quantized subband samples from the input bitstream and expand them. */
PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
{
OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
OI_UINT nrof_blocks = common->frameInfo.nrof_blocks;
OI_INT32 * RESTRICT s = common->subdata;
OI_UINT8 *ptr = global_bs->ptr.w;
OI_UINT32 value = global_bs->value;
OI_UINT bitPtr = global_bs->bitPtr;
const OI_UINT iter_count = common->frameInfo.nrof_channels * common->frameInfo.nrof_subbands / 4;
do {
OI_UINT i;
for (i = 0; i < iter_count; ++i) {
OI_UINT32 sf_by4 = ((OI_UINT32*)common->scale_factor)[i];
OI_UINT32 bits_by4 = common->bits.uint32[i];
OI_UINT n;
for (n = 0; n < 4; ++n) {
OI_INT32 dequant;
OI_UINT bits;
OI_INT sf;
if (OI_CPU_BYTE_ORDER == OI_LITTLE_ENDIAN_BYTE_ORDER) {
bits = bits_by4 & 0xFF;
bits_by4 >>= 8;
sf = sf_by4 & 0xFF;
sf_by4 >>= 8;
} else {
bits = (bits_by4 >> 24) & 0xFF;
bits_by4 <<= 8;
sf = (sf_by4 >> 24) & 0xFF;
sf_by4 <<= 8;
}
if (bits) {
OI_UINT32 raw;
// return raw == audio sample (uint16)
// bits == number of bits to read from stream
// ptr == position in stream
// value == 32bit value
// bitPtr offset in 32bit value
OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
// dequant == sb_sample (int32)
dequant = OI_SBC_Dequant(raw, sf, bits);
} else {
dequant = 0;
}
*s++ = dequant;
}
}
} while (--nrof_blocks);
}
/**
@}
*/
+498
View File
@@ -0,0 +1,498 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2006 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
@ingroup codec_internal
*/
/**@addtogroup codec_internal */
/**@{*/
#include "oi_codec_sbc_private.h"
#include "oi_bitstream.h"
#define SPECIALIZE_READ_SAMPLES_JOINT
/**
* Scans through a buffer looking for a codec syncword. If the decoder has been
* set for enhanced operation using OI_CODEC_SBC_DecoderReset(), it will search
* for both a standard and an enhanced syncword.
*/
PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes);
PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes)
{
#ifdef SBC_ENHANCED
OI_BYTE search1 = OI_SBC_SYNCWORD;
OI_BYTE search2 = OI_SBC_ENHANCED_SYNCWORD;
#endif // SBC_ENHANCED
if (*frameBytes == 0) {
return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
}
#ifdef SBC_ENHANCED
if (context->limitFrameFormat && context->enhancedEnabled){
/* If the context is restricted, only search for specified SYNCWORD */
search1 = search2;
} else if (context->enhancedEnabled == FALSE) {
/* If enhanced is not enabled, only search for classic SBC SYNCWORD*/
search2 = search1;
}
while (*frameBytes && (**frameData != search1) && (**frameData != search2)) {
(*frameBytes)--;
(*frameData)++;
}
if (*frameBytes) {
/* Syncword found, *frameData points to it, and *frameBytes correctly
* reflects the number of bytes available to read, including the
* syncword. */
context->common.frameInfo.enhanced = (**frameData == OI_SBC_ENHANCED_SYNCWORD);
return OI_OK;
} else {
/* No syncword was found anywhere in the provided input data.
* *frameData points past the end of the original input, and
* *frameBytes is 0. */
return OI_CODEC_SBC_NO_SYNCWORD;
}
#else // SBC_ENHANCED
/* BK4BTSTACK_CHANGE START */
OI_UINT8 syncword = OI_SBC_SYNCWORD;
if (context->common.frameInfo.mSBCEnabled){
syncword = OI_mSBC_SYNCWORD;
}
/* BK4BTSTACK_CHANGE END */
while (*frameBytes && (**frameData != syncword)) {
(*frameBytes)--;
(*frameData)++;
}
if (*frameBytes) {
/* Syncword found, *frameData points to it, and *frameBytes correctly
* reflects the number of bytes available to read, including the
* syncword. */
context->common.frameInfo.enhanced = FALSE;
return OI_OK;
} else {
/* No syncword was found anywhere in the provided input data.
* *frameData points past the end of the original input, and
* *frameBytes is 0. */
return OI_CODEC_SBC_NO_SYNCWORD;
}
#endif // SBC_ENHANCED
}
static OI_STATUS DecodeBody(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE *bodyData,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes,
OI_BOOL allowPartial)
{
OI_BITSTREAM bs;
OI_UINT frameSamples = context->common.frameInfo.nrof_blocks * context->common.frameInfo.nrof_subbands;
OI_UINT decode_block_count;
/*
* Based on the header data, make sure that there is enough room to write the output samples.
*/
if ((*pcmBytes < (sizeof(OI_INT16) * frameSamples * context->common.pcmStride)) && !allowPartial) {
/* If we're not allowing partial decodes, we need room for the entire
* codec frame */
TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA"));
return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
} else if (*pcmBytes < (sizeof (OI_INT16) * context->common.frameInfo.nrof_subbands * context->common.pcmStride)) {
/* Even if we're allowing partials, we can still only decode on a frame
* boundary */
return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
}
if (context->bufferedBlocks == 0) {
TRACE(("Reading scalefactors"));
OI_SBC_ReadScalefactors(&context->common, bodyData, &bs);
TRACE(("Computing bit allocation"));
OI_SBC_ComputeBitAllocation(&context->common);
TRACE(("Reading samples"));
if (context->common.frameInfo.mode == SBC_JOINT_STEREO) {
OI_SBC_ReadSamplesJoint(context, &bs);
} else {
OI_SBC_ReadSamples(context, &bs);
}
context->bufferedBlocks = context->common.frameInfo.nrof_blocks;
}
if (allowPartial) {
decode_block_count = *pcmBytes / sizeof(OI_INT16) / context->common.pcmStride / context->common.frameInfo.nrof_subbands;
if (decode_block_count > context->bufferedBlocks) {
decode_block_count = context->bufferedBlocks;
}
} else {
decode_block_count = context->common.frameInfo.nrof_blocks;
}
TRACE(("Synthesizing frame"));
{
OI_UINT start_block = context->common.frameInfo.nrof_blocks - context->bufferedBlocks;
OI_SBC_SynthFrame(context, pcmData, start_block, decode_block_count);
}
OI_ASSERT(context->bufferedBlocks >= decode_block_count);
context->bufferedBlocks -= decode_block_count;
frameSamples = decode_block_count * context->common.frameInfo.nrof_subbands;
/*
* When decoding mono into a stride-2 array, copy pcm data to second channel
*/
if ((context->common.frameInfo.nrof_channels == 1) && (context->common.pcmStride == 2)) {
OI_UINT i;
for (i = 0; i < frameSamples; ++i) {
pcmData[(2*i)+1] = pcmData[2*i];
}
}
/*
* Return number of pcm bytes generated by the decode operation.
*/
*pcmBytes = frameSamples * sizeof(OI_INT16) * context->common.pcmStride;
if (context->bufferedBlocks > 0) {
return OI_CODEC_SBC_PARTIAL_DECODE;
} else {
return OI_OK;
}
}
PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT8 bitpool,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes)
{
OI_STATUS status;
OI_UINT bodyLen;
TRACE(("+OI_CODEC_SBC_DecodeRaw"));
if (context->bufferedBlocks == 0) {
/*
* The bitallocator needs to know the bitpool value.
*/
context->common.frameInfo.bitpool = bitpool;
/*
* Compute the frame length and check we have enough frame data to proceed
*/
bodyLen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo) - SBC_HEADER_LEN;
if (*frameBytes < bodyLen) {
TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
}
} else {
bodyLen = 0;
}
/*
* Decode the SBC data. Pass TRUE to DecodeBody to allow partial decoding of
* tones.
*/
status = DecodeBody(context, *frameData, pcmData, pcmBytes, TRUE);
if (OI_SUCCESS(status) || (status == OI_CODEC_SBC_PARTIAL_DECODE)) {
*frameData += bodyLen;
*frameBytes -= bodyLen;
}
TRACE(("-OI_CODEC_SBC_DecodeRaw: %d", status));
return status;
}
OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes,
OI_UINT8 maxChannels,
OI_UINT8 pcmStride,
OI_BOOL enhanced)
{
return internal_DecoderReset(context, decoderData, decoderDataBytes, maxChannels, pcmStride, enhanced);
}
/* BK4BTSTACK_CHANGE START */
OI_STATUS OI_CODEC_mSBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes)
{
OI_STATUS status = OI_CODEC_SBC_DecoderReset(context, decoderData, decoderDataBytes, 1, 1, FALSE);
context->common.frameInfo.mSBCEnabled = TRUE;
return status;
}
/* BK4BTSTACK_CHANGE END */
OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes)
{
OI_STATUS status;
OI_UINT framelen;
OI_UINT8 crc;
TRACE(("+OI_CODEC_SBC_DecodeFrame"));
TRACE(("Finding syncword"));
status = FindSyncword(context, frameData, frameBytes);
if (!OI_SUCCESS(status)) {
return status;
}
/* Make sure enough data remains to read the header. */
if (*frameBytes < SBC_HEADER_LEN) {
TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA"));
return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
}
TRACE(("Reading Header"));
if (context->common.frameInfo.mSBCEnabled){
OI_SBC_ReadHeader_mSBC(&context->common, *frameData);
} else {
OI_SBC_ReadHeader(&context->common, *frameData);
}
/*
* Some implementations load the decoder into RAM and use overlays for 4 vs 8 subbands. We need
* to ensure that the SBC parameters for this frame are compatible with the restrictions imposed
* by the loaded overlays.
*/
if (context->limitFrameFormat && (context->common.frameInfo.subbands != context->restrictSubbands)) {
ERROR(("SBC parameters incompatible with loaded overlay"));
return OI_STATUS_INVALID_PARAMETERS;
}
TRACE(("Frame: "));
if (context->common.frameInfo.nrof_channels > context->common.maxChannels) {
ERROR(("SBC parameters incompatible with number of channels specified during reset"));
return OI_STATUS_INVALID_PARAMETERS;
}
if ((context->common.pcmStride < 1) || (context->common.pcmStride > 2)) {
ERROR(("PCM stride not set correctly during reset"));
return OI_STATUS_INVALID_PARAMETERS;
}
/*
* At this point a header has been read. However, it's possible that we found a false syncword,
* so the header data might be invalid. Make sure we have enough bytes to read in the
* CRC-protected header, but don't require we have the whole frame. That way, if it turns out
* that we're acting on bogus header data, we don't stall the decoding process by waiting for
* data that we don't actually need.
*/
framelen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo);
if (*frameBytes < framelen) {
TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
}
TRACE(("Calculating checksum"));
if (context->common.frameInfo.mSBCEnabled){
crc = OI_SBC_CalculateChecksum_mSBC(&context->common.frameInfo, *frameData);
} else {
crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
}
if (crc != context->common.frameInfo.crc) {
TRACE(("CRC Mismatch: calc=%02x read=%02x\n", crc, context->common.frameInfo.crc));
TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_CHECKSUM_MISMATCH"));
return OI_CODEC_SBC_CHECKSUM_MISMATCH;
}
#ifdef OI_DEBUG
/*
* Make sure the bitpool values are sane.
*/
if ((context->common.frameInfo.bitpool < SBC_MIN_BITPOOL) && !context->common.frameInfo.enhanced) {
ERROR(("Bitpool too small: %d (must be >= 2)", context->common.frameInfo.bitpool));
return OI_STATUS_INVALID_PARAMETERS;
}
if (context->common.frameInfo.bitpool > OI_SBC_MaxBitpool(&context->common.frameInfo)) {
ERROR(("Bitpool too large: %d (must be <= %ld)", context->common.frameInfo.bitpool, OI_SBC_MaxBitpool(&context->common.frameInfo)));
return OI_STATUS_INVALID_PARAMETERS;
}
#endif
/*
* Now decode the SBC data. Partial decode is not yet implemented for an SBC
* stream, so pass FALSE to decode body to have it enforce the old rule that
* you have to decode a whole packet at a time.
*/
status = DecodeBody(context, *frameData + SBC_HEADER_LEN, pcmData, pcmBytes, FALSE);
if (OI_SUCCESS(status)) {
*frameData += framelen;
*frameBytes -= framelen;
}
TRACE(("-OI_CODEC_SBC_DecodeFrame: %d", status));
return status;
}
OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes)
{
OI_STATUS status;
OI_UINT framelen;
OI_UINT headerlen;
OI_UINT8 crc;
status = FindSyncword(context, frameData, frameBytes);
if (!OI_SUCCESS(status)) {
return status;
}
if (*frameBytes < SBC_HEADER_LEN) {
return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
}
OI_SBC_ReadHeader(&context->common, *frameData);
framelen = OI_SBC_CalculateFrameAndHeaderlen(&context->common.frameInfo, &headerlen);
if (*frameBytes < headerlen) {
return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
}
crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
if (crc != context->common.frameInfo.crc) {
return OI_CODEC_SBC_CHECKSUM_MISMATCH;
}
if (*frameBytes < framelen) {
return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
}
context->bufferedBlocks = 0;
*frameData += framelen;
*frameBytes -= framelen;
return OI_OK;
}
OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE *frameData,
OI_UINT32 frameBytes)
{
OI_UINT8 mode;
OI_UINT8 blocks;
OI_UINT8 subbands;
OI_UINT8 frameCount = 0;
OI_UINT frameLen;
while (frameBytes){
while (frameBytes && ((frameData[0] & 0xFE) != 0x9C)){
frameData++;
frameBytes--;
}
if (frameBytes < SBC_HEADER_LEN) {
return frameCount;
}
/* Extract and translate required fields from Header */
subbands = mode = blocks = frameData[1];;
mode = (mode & (BIT3 | BIT2)) >> 2;
blocks = block_values[(blocks & (BIT5 | BIT4)) >> 4];
subbands = band_values[(subbands & BIT0)];
/* Inline logic to avoid corrupting context */
frameLen = blocks * frameData[2];
switch (mode){
case SBC_JOINT_STEREO:
frameLen += subbands + (8 * subbands);
break;
case SBC_DUAL_CHANNEL:
frameLen *= 2;
/* fall through */
default:
if (mode == SBC_MONO){
frameLen += 4*subbands;
} else {
frameLen += 8*subbands;
}
}
frameCount++;
frameLen = SBC_HEADER_LEN + ((frameLen + 7) / 8);
if (frameBytes > frameLen){
frameBytes -= frameLen;
frameData += frameLen;
} else {
frameBytes = 0;
}
}
return frameCount;
}
/** Read quantized subband samples from the input bitstream and expand them. */
#ifdef SPECIALIZE_READ_SAMPLES_JOINT
PRIVATE void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs);
PRIVATE void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
{
#define NROF_SUBBANDS 4
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
PRIVATE void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs);
PRIVATE void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
{
#define NROF_SUBBANDS 8
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
typedef void (*READ_SAMPLES)(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs);
static const READ_SAMPLES SpecializedReadSamples[] = {
OI_SBC_ReadSamplesJoint4,
OI_SBC_ReadSamplesJoint8
};
#endif /* SPECIALIZE_READ_SAMPLES_JOINT */
PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
{
OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
#ifdef SPECIALIZE_READ_SAMPLES_JOINT
OI_ASSERT((nrof_subbands >> 3u) <= 1u);
SpecializedReadSamples[nrof_subbands >> 3](context, global_bs);
#else
#define NROF_SUBBANDS nrof_subbands
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
#endif /* SPECIALIZE_READ_SAMPLES_JOINT */
}
/**@}*/
+211
View File
@@ -0,0 +1,211 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Dequantizer for SBC decoder; reconstructs quantized representation of subband samples.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
/**
This function is a fixed-point approximation of a modification of the following
dequantization operation defined in the spec, as inferred from section 12.6.4:
@code
dequant = 2^(scale_factor+1) * ((raw * 2.0 + 1.0) / ((2^bits) - 1) - 1)
2 <= bits <= 16
0 <= raw < (2^bits)-1 (the -1 is because quantized values with all 1's are forbidden)
-65535 < dequant < 65535
@endcode
The code below computes the dequantized value divided by a scaling constant
equal to about 1.38. This constant is chosen to ensure that the entry in the
dequant_long_scaled table for 16 bits is as accurate as possible, since it has
the least relative precision available to it due to its small magnitude.
This routine outputs in Q16.15 format.
The helper array dequant_long is defined as follows:
@code
dequant_long_long[bits] = round(2^31 * 1/((2^bits - 1) / 1.38...) for 2 <= bits <= 16
@endcode
Additionally, the table entries have the following property:
@code
dequant_long_scaled[bits] <= 2^31 / ((2^bits - 1)) for 2 <= bits <= 16
@endcode
Therefore
@code
d = 2 * raw + 1 1 <= d <= 2^bits - 2
d' = d * dequant_long[bits]
d * dequant_long_scaled[bits] <= (2^bits - 2) * (2^31 / (2^bits - 1))
d * dequant_long_scaled[bits] <= 2^31 * (2^bits - 2)/(2^bits - 1) < 2^31
@endcode
Therefore, d' doesn't overflow a signed 32-bit value.
@code
d' =~ 2^31 * (raw * 2.0 + 1.0) / (2^bits - 1) / 1.38...
result = d' - 2^31/1.38... =~ 2^31 * ((raw * 2.0 + 1.0) / (2^bits - 1) - 1) / 1.38...
result is therefore a scaled approximation to dequant. It remains only to
turn 2^31 into 2^(scale_factor+1). Since we're aiming for Q16.15 format,
this is achieved by shifting right by (15-scale_factor):
(2^31 * x) >> (15-scale_factor) =~ 2^(31-15+scale_factor) * x = 2^15 * 2^(1+scale_factor) * x
@endcode
*/
#include <oi_codec_sbc_private.h>
#ifndef SBC_DEQUANT_LONG_SCALED_OFFSET
#define SBC_DEQUANT_LONG_SCALED_OFFSET 1555931970
#endif
#ifndef SBC_DEQUANT_LONG_UNSCALED_OFFSET
#define SBC_DEQUANT_LONG_UNSCALED_OFFSET 2147483648
#endif
#ifndef SBC_DEQUANT_SCALING_FACTOR
#define SBC_DEQUANT_SCALING_FACTOR 1.38019122262781f
#endif
extern const OI_UINT32 dequant_long_scaled[17];
extern const OI_UINT32 dequant_long_unscaled[17];
/** Scales x by y bits to the right, adding a rounding factor.
*/
#ifndef SCALE
#define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
#endif
#ifdef DEBUG_DEQUANTIZATION
#include <math.h>
INLINE float dequant_float(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
{
float result = (1 << (scale_factor+1)) * ((raw * 2.0f + 1.0f) / ((1 << bits) - 1.0f) - 1.0f);
result /= SBC_DEQUANT_SCALING_FACTOR;
/* Unless the encoder screwed up, all correct dequantized values should
* satisfy this inequality. Non-compliant encoders which generate quantized
* values with all 1-bits set can, theoretically, trigger this assert. This
* is unlikely, however, and only an issue in debug mode.
*/
OI_ASSERT(fabs(result) < 32768 * 1.6);
return result;
}
#endif
INLINE OI_INT32 OI_SBC_Dequant(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
{
OI_UINT32 d;
OI_INT32 result;
OI_ASSERT(scale_factor <= 15);
OI_ASSERT(bits <= 16);
if (bits <= 1) {
return 0;
}
d = (raw * 2) + 1;
d *= dequant_long_scaled[bits];
result = d - SBC_DEQUANT_LONG_SCALED_OFFSET;
#ifdef DEBUG_DEQUANTIZATION
{
OI_INT32 integerized_float_result;
float float_result;
float_result = dequant_float(raw, scale_factor, bits);
integerized_float_result = (OI_INT32)floor(0.5f+float_result * (1 << 15));
/* This detects overflow */
OI_ASSERT(((result >= 0) && (integerized_float_result >= 0)) ||
((result <= 0) && (integerized_float_result <= 0)));
}
#endif
return result >> (15 - scale_factor);
}
/* This version of Dequant does not incorporate the scaling factor of 1.38. It
* is intended for use with implementations of the filterbank which are
* hard-coded into a DSP. Output is Q16.4 format, so that after joint stereo
* processing (which leaves the most significant bit equal to the sign bit if
* the encoder is conformant) the result will fit a 24 bit fixed point signed
* value.*/
INLINE OI_INT32 OI_SBC_Dequant_Unscaled(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits);
INLINE OI_INT32 OI_SBC_Dequant_Unscaled(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
{
OI_UINT32 d;
OI_INT32 result;
OI_ASSERT(scale_factor <= 15);
OI_ASSERT(bits <= 16);
if (bits <= 1) {
return 0;
}
if (bits == 16) {
result = (raw << 16) + raw - 0x7fff7fff;
return SCALE(result, 24 - scale_factor);
}
d = (raw * 2) + 1;
d *= dequant_long_unscaled[bits];
result = d - 0x80000000;
return SCALE(result, 24 - scale_factor);
}
/**
@}
*/
+55
View File
@@ -0,0 +1,55 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
@ingroup codec_internal
*/
/**@addgroup codec_internal*/
/**@{*/
#include "oi_codec_sbc_private.h"
const OI_CHAR* const OI_CODEC_SBC_FreqText[] = { "SBC_FREQ_16000", "SBC_FREQ_32000", "SBC_FREQ_44100", "SBC_FREQ_48000" };
const OI_CHAR* const OI_CODEC_SBC_ModeText[] = { "SBC_MONO", "SBC_DUAL_CHANNEL", "SBC_STEREO", "SBC_JOINT_STEREO" };
const OI_CHAR* const OI_CODEC_SBC_SubbandsText[] = { "SBC_SUBBANDS_4", "SBC_SUBBANDS_8" };
const OI_CHAR* const OI_CODEC_SBC_BlocksText[] = { "SBC_BLOCKS_4", "SBC_BLOCKS_8", "SBC_BLOCKS_12", "SBC_BLOCKS_16" };
const OI_CHAR* const OI_CODEC_SBC_AllocText[] = { "SBC_LOUDNESS", "SBC_SNR" };
#ifdef OI_DEBUG
#include <stdio.h>
void OI_CODEC_SBC_DumpConfig(OI_CODEC_SBC_FRAME_INFO *frameInfo)
{
printf("SBC configuration\n");
printf(" enhanced: %s\n", frameInfo->enhanced ? "TRUE" : "FALSE");
printf(" frequency: %d\n", frameInfo->frequency);
printf(" subbands: %d\n", frameInfo->nrof_subbands);
printf(" blocks: %d\n", frameInfo->nrof_blocks);
printf(" channels: %d\n", frameInfo->nrof_channels);
printf(" mode: %s\n", OI_CODEC_SBC_ModeText[frameInfo->mode]);
printf(" alloc: %s\n", OI_CODEC_SBC_AllocText[frameInfo->alloc]);
printf(" bitpool: %d\n", frameInfo->bitpool);
}
#endif /* OI_DEBUG */
/**@}*/
+278
View File
@@ -0,0 +1,278 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Checksum and header-related functions.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "oi_codec_sbc_private.h"
#include "oi_assert.h"
/* asdasd */
#define USE_NIBBLEWISE_CRC
/* #define PRINT_SAMPLES */
/* #define PRINT_SCALEFACTORS */
/* #define DEBUG_CRC */
/*
* CRC-8 table for X^8 + X^4 + X^3 + X^2 + 1; byte-wise lookup
*/
#ifdef USE_WIDE_CRC
/* Save space if a char is 16 bits, such as on the C54x */
const OI_BYTE crc8_wide[128] = {
0x001d, 0x3a27, 0x7469, 0x4e53, 0xe8f5, 0xd2cf, 0x9c81, 0xa6bb, 0xcdd0, 0xf7ea, 0xb9a4, 0x839e, 0x2538, 0x1f02, 0x514c, 0x6b76, 0x879a, 0xbda0, 0xf3ee, 0xc9d4, 0x6f72, 0x5548, 0x1b06, 0x213c, 0x4a57, 0x706d, 0x3e23, 0x0419, 0xa2bf, 0x9885, 0xd6cb, 0xecf1, 0x130e, 0x2934, 0x677a, 0x5d40, 0xfbe6, 0xc1dc, 0x8f92, 0xb5a8, 0xdec3, 0xe4f9, 0xaab7, 0x908d, 0x362b, 0x0c11, 0x425f, 0x7865, 0x9489, 0xaeb3, 0xe0fd, 0xdac7, 0x7c61, 0x465b, 0x0815, 0x322f, 0x5944, 0x637e, 0x2d30, 0x170a, 0xb1ac, 0x8b96, 0xc5d8, 0xffe2, 0x263b, 0x1c01, 0x524f, 0x6875, 0xced3, 0xf4e9, 0xbaa7, 0x809d, 0xebf6, 0xd1cc, 0x9f82, 0xa5b8, 0x031e, 0x3924, 0x776a, 0x4d50, 0xa1bc, 0x9b86, 0xd5c8, 0xeff2, 0x4954, 0x736e, 0x3d20, 0x071a, 0x6c71, 0x564b, 0x1805, 0x223f, 0x8499, 0xbea3, 0xf0ed, 0xcad7, 0x3528, 0x0f12, 0x415c, 0x7b66, 0xddc0, 0xe7fa, 0xa9b4, 0x938e, 0xf8e5, 0xc2df, 0x8c91, 0xb6ab, 0x100d, 0x2a37, 0x6479, 0x5e43, 0xb2af, 0x8895, 0xc6db, 0xfce1, 0x5a47, 0x607d, 0x2e33, 0x1409, 0x7f62, 0x4558, 0x0b16, 0x312c, 0x978a, 0xadb0, 0xe3fe, 0xd9c4,
};
#elif defined(USE_NIBBLEWISE_CRC)
const OI_BYTE crc8_narrow[16] = {
0x00, 0x1d, 0x3a, 0x27, 0x74, 0x69, 0x4e, 0x53, 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb
};
#else
const OI_BYTE crc8_narrow[256] = {
0x00, 0x1d, 0x3a, 0x27, 0x74, 0x69, 0x4e, 0x53, 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb, 0xcd, 0xd0, 0xf7, 0xea, 0xb9, 0xa4, 0x83, 0x9e, 0x25, 0x38, 0x1f, 0x02, 0x51, 0x4c, 0x6b, 0x76, 0x87, 0x9a, 0xbd, 0xa0, 0xf3, 0xee, 0xc9, 0xd4, 0x6f, 0x72, 0x55, 0x48, 0x1b, 0x06, 0x21, 0x3c, 0x4a, 0x57, 0x70, 0x6d, 0x3e, 0x23, 0x04, 0x19, 0xa2, 0xbf, 0x98, 0x85, 0xd6, 0xcb, 0xec, 0xf1, 0x13, 0x0e, 0x29, 0x34, 0x67, 0x7a, 0x5d, 0x40, 0xfb, 0xe6, 0xc1, 0xdc, 0x8f, 0x92, 0xb5, 0xa8, 0xde, 0xc3, 0xe4, 0xf9, 0xaa, 0xb7, 0x90, 0x8d, 0x36, 0x2b, 0x0c, 0x11, 0x42, 0x5f, 0x78, 0x65, 0x94, 0x89, 0xae, 0xb3, 0xe0, 0xfd, 0xda, 0xc7, 0x7c, 0x61, 0x46, 0x5b, 0x08, 0x15, 0x32, 0x2f, 0x59, 0x44, 0x63, 0x7e, 0x2d, 0x30, 0x17, 0x0a, 0xb1, 0xac, 0x8b, 0x96, 0xc5, 0xd8, 0xff, 0xe2, 0x26, 0x3b, 0x1c, 0x01, 0x52, 0x4f, 0x68, 0x75, 0xce, 0xd3, 0xf4, 0xe9, 0xba, 0xa7, 0x80, 0x9d, 0xeb, 0xf6, 0xd1, 0xcc, 0x9f, 0x82, 0xa5, 0xb8, 0x03, 0x1e, 0x39, 0x24, 0x77, 0x6a, 0x4d, 0x50, 0xa1, 0xbc, 0x9b, 0x86, 0xd5, 0xc8, 0xef, 0xf2, 0x49, 0x54, 0x73, 0x6e, 0x3d, 0x20, 0x07, 0x1a, 0x6c, 0x71, 0x56, 0x4b, 0x18, 0x05, 0x22, 0x3f, 0x84, 0x99, 0xbe, 0xa3, 0xf0, 0xed, 0xca, 0xd7, 0x35, 0x28, 0x0f, 0x12, 0x41, 0x5c, 0x7b, 0x66, 0xdd, 0xc0, 0xe7, 0xfa, 0xa9, 0xb4, 0x93, 0x8e, 0xf8, 0xe5, 0xc2, 0xdf, 0x8c, 0x91, 0xb6, 0xab, 0x10, 0x0d, 0x2a, 0x37, 0x64, 0x79, 0x5e, 0x43, 0xb2, 0xaf, 0x88, 0x95, 0xc6, 0xdb, 0xfc, 0xe1, 0x5a, 0x47, 0x60, 0x7d, 0x2e, 0x33, 0x14, 0x09, 0x7f, 0x62, 0x45, 0x58, 0x0b, 0x16, 0x31, 0x2c, 0x97, 0x8a, 0xad, 0xb0, 0xe3, 0xfe, 0xd9, 0xc4
};
#endif
const OI_UINT32 dequant_long_scaled[17] = {
0,
0,
0x1ee9e116, /* bits=2 0.24151243 1/3 * (1/1.38019122262781) (0x00000008)*/
0x0d3fa99c, /* bits=3 0.10350533 1/7 * (1/1.38019122262781) (0x00000013)*/
0x062ec69e, /* bits=4 0.04830249 1/15 * (1/1.38019122262781) (0x00000029)*/
0x02fddbfa, /* bits=5 0.02337217 1/31 * (1/1.38019122262781) (0x00000055)*/
0x0178d9f5, /* bits=6 0.01150059 1/63 * (1/1.38019122262781) (0x000000ad)*/
0x00baf129, /* bits=7 0.00570502 1/127 * (1/1.38019122262781) (0x0000015e)*/
0x005d1abe, /* bits=8 0.00284132 1/255 * (1/1.38019122262781) (0x000002bf)*/
0x002e760d, /* bits=9 0.00141788 1/511 * (1/1.38019122262781) (0x00000582)*/
0x00173536, /* bits=10 0.00070825 1/1023 * (1/1.38019122262781) (0x00000b07)*/
0x000b9928, /* bits=11 0.00035395 1/2047 * (1/1.38019122262781) (0x00001612)*/
0x0005cc37, /* bits=12 0.00017693 1/4095 * (1/1.38019122262781) (0x00002c27)*/
0x0002e604, /* bits=13 0.00008846 1/8191 * (1/1.38019122262781) (0x00005852)*/
0x000172fc, /* bits=14 0.00004422 1/16383 * (1/1.38019122262781) (0x0000b0a7)*/
0x0000b97d, /* bits=15 0.00002211 1/32767 * (1/1.38019122262781) (0x00016150)*/
0x00005cbe, /* bits=16 0.00001106 1/65535 * (1/1.38019122262781) (0x0002c2a5)*/
};
const OI_UINT32 dequant_long_unscaled[17] = {
0,
0,
0x2aaaaaab, /* bits=2 0.33333333 1/3 (0x00000005)*/
0x12492492, /* bits=3 0.14285714 1/7 (0x0000000e)*/
0x08888889, /* bits=4 0.06666667 1/15 (0x0000001d)*/
0x04210842, /* bits=5 0.03225806 1/31 (0x0000003e)*/
0x02082082, /* bits=6 0.01587302 1/63 (0x0000007e)*/
0x01020408, /* bits=7 0.00787402 1/127 (0x000000fe)*/
0x00808081, /* bits=8 0.00392157 1/255 (0x000001fd)*/
0x00402010, /* bits=9 0.00195695 1/511 (0x000003fe)*/
0x00200802, /* bits=10 0.00097752 1/1023 (0x000007fe)*/
0x00100200, /* bits=11 0.00048852 1/2047 (0x00000ffe)*/
0x00080080, /* bits=12 0.00024420 1/4095 (0x00001ffe)*/
0x00040020, /* bits=13 0.00012209 1/8191 (0x00003ffe)*/
0x00020008, /* bits=14 0.00006104 1/16383 (0x00007ffe)*/
0x00010002, /* bits=15 0.00003052 1/32767 (0x0000fffe)*/
0x00008001, /* bits=16 0.00001526 1/65535 (0x0001fffc)*/
};
#if defined(OI_DEBUG) || defined(PRINT_SAMPLES) || defined(PRINT_SCALEFACTORS)
#include <stdio.h>
#endif
#ifdef USE_WIDE_CRC
INLINE OI_CHAR crc_iterate(OI_UINT8 oldcrc, OI_UINT8 next);
INLINE OI_CHAR crc_iterate(OI_UINT8 oldcrc, OI_UINT8 next)
{
OI_UINT crc;
OI_UINT idx;
idx = oldcrc^next;
crc = crc8_wide[idx >> 1];
if (idx%2) {
crc &= 0xff;
} else {
crc >>= 8;
}
return crc;
}
INLINE OI_CHAR crc_iterate_top4(OI_UINT8 oldcrc, OI_UINT8 next);
INLINE OI_CHAR crc_iterate_top4(OI_UINT8 oldcrc, OI_UINT8 next)
{
OI_UINT crc;
OI_UINT idx;
idx = (oldcrc ^ next) >> 4;
crc = crc8_wide[idx>>1];
if (idx%2) {
crc &= 0xff;
} else {
crc >>= 8;
}
return (oldcrc << 4) ^ crc;
}
#else // USE_WIDE_CRC
INLINE OI_UINT8 crc_iterate_top4(OI_UINT8 oldcrc, OI_UINT8 next);
INLINE OI_UINT8 crc_iterate_top4(OI_UINT8 oldcrc, OI_UINT8 next)
{
return (oldcrc << 4) ^ crc8_narrow[(oldcrc^next) >> 4];
}
#ifdef USE_NIBBLEWISE_CRC
INLINE OI_UINT8 crc_iterate(OI_UINT8 crc, OI_UINT8 next);
INLINE OI_UINT8 crc_iterate(OI_UINT8 crc, OI_UINT8 next)
{
crc = (crc << 4) ^ crc8_narrow[(crc^next) >> 4];
crc = (crc << 4) ^ crc8_narrow[((crc>>4)^next)&0xf];
return crc;
}
#else // USE_NIBBLEWISE_CRC
INLINE OI_UINT8 crc_iterate(OI_UINT8 crc, OI_UINT8 next);
INLINE OI_UINT8 crc_iterate(OI_UINT8 crc, OI_UINT8 next)
{
return crc8_narrow[crc^next];
}
#endif // USE_NIBBLEWISE_CRC
#endif // USE_WIDE_CRC
PRIVATE OI_UINT8 OI_SBC_CalculateChecksum_mSBC(OI_CODEC_SBC_FRAME_INFO *frame, OI_BYTE const *data)
{
OI_UINT i;
OI_UINT8 crc = 0x0f;
/* Count is the number of whole bytes subject to CRC. Actually, it's one
* more than this number, because data[3] is the CRC field itself, which is
* explicitly skipped. Since crc_iterate (should be) inlined, it's cheaper
* spacewise to include the check in the loop. This shouldn't be much of a
* bottleneck routine in the first place. */
// 0 - syncword (skip)
// 1 - reserved
crc = crc_iterate(crc,frame->reserved_for_future_use[0]);
// 2 - reserved
crc = crc_iterate(crc,frame->reserved_for_future_use[1]);
// 3 - crc (skip)
// 4..7 - scale factors (8 x 4 bit = 4 byte)
for (i = 0; i < 4; i++) {
crc = crc_iterate(crc,data[4+i]);
}
return crc;
}
PRIVATE OI_UINT8 OI_SBC_CalculateChecksum(OI_CODEC_SBC_FRAME_INFO *frame, OI_BYTE const *data)
{
OI_UINT i;
OI_UINT8 crc = 0x0f;
/* Count is the number of whole bytes subject to CRC. Actually, it's one
* more than this number, because data[3] is the CRC field itself, which is
* explicitly skipped. Since crc_iterate (should be) inlined, it's cheaper
* spacewise to include the check in the loop. This shouldn't be much of a
* bottleneck routine in the first place. */
OI_UINT count = (frame->nrof_subbands * frame->nrof_channels / 2u) + 4;
if ((frame->mode == SBC_JOINT_STEREO) && (frame->nrof_subbands == 8)) {
count++;
}
for (i = 1; i < count; i++) {
if (i != 3) {
crc = crc_iterate(crc,data[i]);
}
}
if ((frame->mode == SBC_JOINT_STEREO) && (frame->nrof_subbands == 4)) {
crc = crc_iterate_top4(crc, data[i]);
}
return crc;
}
void OI_SBC_ExpandFrameFields(OI_CODEC_SBC_FRAME_INFO *frame)
{
frame->nrof_blocks = block_values[frame->blocks];
frame->nrof_subbands = band_values[frame->subbands];
frame->frequency = freq_values[frame->freqIndex];
frame->nrof_channels = channel_values[frame->mode];
}
/**
* Unrolled macro to copy 4 32-bit aligned 32-bit values backward in memory
*/
#define COPY4WORDS_BACK(_dest, _src) \
do { \
OI_INT32 _a, _b, _c, _d; \
_a = *--_src; \
_b = *--_src; \
_c = *--_src; \
_d = *--_src; \
*--_dest = _a; \
*--_dest = _b; \
*--_dest = _c; \
*--_dest = _d; \
} while (0)
#if defined(USE_PLATFORM_MEMMOVE) || defined(USE_PLATFORM_MEMCPY)
#include <string.h>
#endif
PRIVATE void shift_buffer(SBC_BUFFER_T *dest, SBC_BUFFER_T *src, OI_UINT wordCount)
{
#ifdef USE_PLATFORM_MEMMOVE
memmove(dest, src, wordCount * sizeof(SBC_BUFFER_T));
#elif defined(USE_PLATFORM_MEMCPY)
OI_ASSERT(((OI_CHAR *)(dest) - (OI_CHAR *)(src)) >= wordCount*sizeof(*dest));
memcpy(dest, src, wordCount * sizeof(SBC_BUFFER_T));
#else
OI_UINT n;
OI_INT32 *d;
OI_INT32 *s;
n = wordCount / 4 / (sizeof(OI_INT32)/sizeof(*dest));
OI_ASSERT((n * 4 * (sizeof(OI_INT32)/sizeof(*dest))) == wordCount);
d = (OI_INT32*)(dest + wordCount);
s = (OI_INT32*)(src + wordCount);
do {
COPY4WORDS_BACK(d, s);
} while (--n);
#endif
}
/**
@}
*/
@@ -0,0 +1,57 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**
@file
This file contains a single function, which returns a string indicating the
version number of the eSBC codec
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_stddefs.h"
#include "oi_codec_sbc_private.h"
/** Version string for the BLUEmagic 3.0 protocol stack and profiles */
PRIVATE const OI_CHAR * codecVersion = "v1.5"
#ifdef OI_SBC_EVAL
" (Evaluation version)"
#endif
;
/** This function returns the version string for the BLUEmagic 3.0 protocol stack
and profiles */
const OI_CHAR *OI_CODEC_Version(void) {
return codecVersion;
}
/**********************************************************************************/
/**
@}
*/
@@ -0,0 +1,111 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/*******************************************************************************
* @file readsamplesjoint.inc
*
* This is the body of the generic version of OI_SBC_ReadSamplesJoint().
* It is designed to be \#included into a function as follows:
\code
void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_COMMON_CONTEXT *common, OI_BITSTREAM *global_bs)
{
#define NROF_SUBBANDS 4
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_COMMON_CONTEXT *common, OI_BITSTREAM *global_bs)
{
#define NROF_SUBBANDS 8
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
\endcode
* Or to make a generic version:
\code
void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_COMMON_CONTEXT *common, OI_BITSTREAM *global_bs)
{
OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
#define NROF_SUBBANDS nrof_subbands
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
\endcode
* @ingroup codec_internal
*******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
{
OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
OI_UINT bl = common->frameInfo.nrof_blocks;
OI_INT32 * RESTRICT s = common->subdata;
OI_UINT8 *ptr = global_bs->ptr.w;
OI_UINT32 value = global_bs->value;
OI_UINT bitPtr = global_bs->bitPtr;
OI_UINT8 jmask = common->frameInfo.join << (8 - NROF_SUBBANDS);
do {
OI_INT8 *sf_array = &common->scale_factor[0];
OI_UINT8 *bits_array = &common->bits.uint8[0];
OI_UINT8 joint = jmask;
OI_UINT sb;
/*
* Left channel
*/
sb = NROF_SUBBANDS;
do {
OI_UINT32 raw;
OI_INT32 dequant;
OI_UINT8 bits = *bits_array++;
OI_INT sf = *sf_array++;
OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
dequant = OI_SBC_Dequant(raw, sf, bits);
*s++ = dequant;
} while (--sb);
/*
* Right channel
*/
sb = NROF_SUBBANDS;
do {
OI_UINT32 raw;
OI_INT32 dequant;
OI_UINT8 bits = *bits_array++;
OI_INT sf = *sf_array++;
OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
dequant = OI_SBC_Dequant(raw, sf, bits);
/*
* Check if we need to do mid/side
*/
if (joint & 0x80) {
OI_INT32 mid = *(s - NROF_SUBBANDS);
OI_INT32 side = dequant;
*(s - NROF_SUBBANDS) = mid + side;
dequant = mid - side;
}
joint <<= 1;
*s++ = dequant;
} while (--sb);
} while (--bl);
}
@@ -0,0 +1,136 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**
@file
DO NOT EDIT THIS FILE DIRECTLY
This file is automatically generated by the "synthesis-gen.pl" script.
Any changes to this generated file will be lost when the script is re-run.
These functions are called by functions in synthesis.c to perform the synthesis
filterbank computations for the SBC decoder.
*/
#include <oi_codec_sbc_private.h>
#ifndef CLIP_INT16
#define CLIP_INT16(x) do { if (x > OI_INT16_MAX) { x = OI_INT16_MAX; } else if (x < OI_INT16_MIN) { x = OI_INT16_MIN; } } while (0)
#endif
#define MUL_16S_16S(_x, _y) ((_x) * (_y))
PRIVATE void SynthWindow80_generated(OI_INT16 *pcm, SBC_BUFFER_T const * RESTRICT buffer, OI_UINT strideShift);
PRIVATE void SynthWindow80_generated(OI_INT16 *pcm, SBC_BUFFER_T const * RESTRICT buffer, OI_UINT strideShift)
{
OI_INT32 pcm_a, pcm_b;
/* 1 - stage 0 */ pcm_b = 0;
/* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(8235, buffer[ 12]))>> 3;
/* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(-23167, buffer[ 20]))>> 3;
/* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(26479, buffer[ 28]))>> 2;
/* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(-17397, buffer[ 36]))<< 1;
/* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(9399, buffer[ 44]))<< 3;
/* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(17397, buffer[ 52]))<< 1;
/* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(26479, buffer[ 60]))>> 2;
/* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(23167, buffer[ 68]))>> 3;
/* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(8235, buffer[ 76]))>> 3;
/* 1 - stage 0 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[(uint32_t)(0<<strideShift)] = (OI_INT16)pcm_b;
/* 1 - stage 1 */ pcm_a = 0;
/* 1 - stage 1 */ pcm_b = 0;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(-3263, buffer[ 5]))>> 5;
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(9293, buffer[ 5]))>> 3;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(29293, buffer[ 11]))>> 5;
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(-6087, buffer[ 11]))>> 2;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(-5229, buffer[ 21]));
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(1247, buffer[ 21]))<< 3;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(30835, buffer[ 27]))>> 3;
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(-2893, buffer[ 27]))<< 3;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(-27021, buffer[ 37]))<< 1;
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(23671, buffer[ 37]))<< 2;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(31633, buffer[ 43]))<< 1;
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(18055, buffer[ 43]))<< 1;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(17319, buffer[ 53]))<< 1;
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(11537, buffer[ 53]))>> 1;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(26663, buffer[ 59]))>> 2;
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(1747, buffer[ 59]))<< 1;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(4555, buffer[ 69]))>> 1;
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(685, buffer[ 69]))<< 1;
/* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(12419, buffer[ 75]))>> 4;
/* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(8721, buffer[ 75]))>> 7;
/* 1 - stage 1 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[(uint32_t)(1<<strideShift)] = (OI_INT16)pcm_a;
/* 1 - stage 1 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[(uint32_t)(7<<strideShift)] = (OI_INT16)pcm_b;
/* 1 - stage 2 */ pcm_a = 0;
/* 1 - stage 2 */ pcm_b = 0;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(-10385, buffer[ 6]))>> 6;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(11167, buffer[ 6]))>> 4;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(24995, buffer[ 10]))>> 5;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(-10337, buffer[ 10]))>> 4;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(-309, buffer[ 22]))<< 4;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(1917, buffer[ 22]))<< 2;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(9161, buffer[ 26]))>> 3;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(-30605, buffer[ 26]))>> 1;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(-23063, buffer[ 38]))<< 1;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(8317, buffer[ 38]))<< 3;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(27561, buffer[ 42]))<< 1;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(9553, buffer[ 42]))<< 2;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(2309, buffer[ 54]))<< 3;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(22117, buffer[ 54]))>> 4;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(12705, buffer[ 58]))>> 1;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(16383, buffer[ 58]))>> 2;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(6239, buffer[ 70]))>> 3;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(7543, buffer[ 70]))>> 3;
/* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(9251, buffer[ 74]))>> 4;
/* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(8603, buffer[ 74]))>> 6;
/* 1 - stage 2 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[(uint32_t)(2<<strideShift)] = (OI_INT16)pcm_a;
/* 1 - stage 2 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[(uint32_t)(6<<strideShift)] = (OI_INT16)pcm_b;
/* 1 - stage 3 */ pcm_a = 0;
/* 1 - stage 3 */ pcm_b = 0;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(-16457, buffer[ 7]))>> 6;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(16913, buffer[ 7]))>> 5;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(19083, buffer[ 9]))>> 5;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(-8443, buffer[ 9]))>> 7;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(-23641, buffer[ 23]))>> 2;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(3687, buffer[ 23]))<< 1;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(-29015, buffer[ 25]))>> 4;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(-301, buffer[ 25]))<< 5;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(-12889, buffer[ 39]))<< 2;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(15447, buffer[ 39]))<< 2;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(6145, buffer[ 41]))<< 3;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(10255, buffer[ 41]))<< 2;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(24211, buffer[ 55]))>> 1;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(-18233, buffer[ 55]))>> 3;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(23469, buffer[ 57]))>> 2;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(9405, buffer[ 57]))>> 1;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(21223, buffer[ 71]))>> 8;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(1499, buffer[ 71]))>> 1;
/* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(26913, buffer[ 73]))>> 6;
/* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(26189, buffer[ 73]))>> 7;
/* 1 - stage 3 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[(uint32_t)(3<<strideShift)] = (OI_INT16)pcm_a;
/* 1 - stage 3 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[(uint32_t)(5<<strideShift)] = (OI_INT16)pcm_b;
/* 1 - stage 4 */ pcm_a = 0;
/* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(10445, buffer[ 8]))>> 4;
/* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(-5297, buffer[ 24]))<< 1;
/* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(22299, buffer[ 40]))<< 2;
/* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(10603, buffer[ 56]));
/* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(9539, buffer[ 72]))>> 4;
/* 1 - stage 4 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[(uint32_t)(4<<strideShift)] = (OI_INT16)pcm_a;
}
+307
View File
@@ -0,0 +1,307 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
@ingroup codec_internal
*/
/**@addgroup codec_internal*/
/**@{*/
/*
* Performs an 8-point Type-II scaled DCT using the Arai-Agui-Nakajima
* factorization. The scaling factors are folded into the windowing
* constants. 29 adds and 5 16x32 multiplies per 8 samples.
*/
#include "oi_codec_sbc_private.h"
#define AAN_C4_FIX (759250125)/* S1.30 759250125 0.707107*/
#define AAN_C6_FIX (410903207)/* S1.30 410903207 0.382683*/
#define AAN_Q0_FIX (581104888)/* S1.30 581104888 0.541196*/
#define AAN_Q1_FIX (1402911301)/* S1.30 1402911301 1.306563*/
/** Scales x by y bits to the right, adding a rounding factor.
*/
#ifndef SCALE
#define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
#endif
/**
* Default C language implementation of a 32x32->32 multiply. This function may
* be replaced by a platform-specific version for speed.
*
* @param u A signed 32-bit multiplicand
* @param v A signed 32-bit multiplier
* @return A signed 32-bit value corresponding to the 32 most significant bits
* of the 64-bit product of u and v.
*/
INLINE OI_INT32 default_mul_32s_32s_hi(OI_INT32 u, OI_INT32 v);
INLINE OI_INT32 default_mul_32s_32s_hi(OI_INT32 u, OI_INT32 v)
{
OI_UINT32 u0, v0;
OI_INT32 u1, v1, w1, w2, t;
u0 = u & 0xFFFF; u1 = u >> 16;
v0 = v & 0xFFFF; v1 = v >> 16;
t = u0*v0;
t = (u1*v0) + ((OI_UINT32)t >> 16);
w1 = t & 0xFFFF;
w2 = t >> 16;
w1 = (u0*v1) + w1;
return (u1*v1) + w2 + (w1 >> 16);
}
#define MUL_32S_32S_HI(_x, _y) default_mul_32s_32s_hi(_x, _y)
#ifdef DEBUG_DCT
PRIVATE void float_dct2_8(float * RESTRICT out, OI_INT32 const *RESTRICT in)
{
#define FIX(x,bits) (((int)floor(0.5f+((x)*((float)(1<<bits)))))/((float)(1<<bits)))
#define FLOAT_BUTTERFLY(x,y) x += y; y = x - (y*2); OI_ASSERT(VALID_INT32(x)); OI_ASSERT(VALID_INT32(y));
#define FLOAT_MULT_DCT(K, sample) (FIX(K,20) * sample)
#define FLOAT_SCALE(x, y) (((x) / (double)(1 << (y))))
double L00,L01,L02,L03,L04,L05,L06,L07;
double L25;
double in0,in1,in2,in3;
double in4,in5,in6,in7;
in0 = FLOAT_SCALE(in[0], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in0));
in1 = FLOAT_SCALE(in[1], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in1));
in2 = FLOAT_SCALE(in[2], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in2));
in3 = FLOAT_SCALE(in[3], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in3));
in4 = FLOAT_SCALE(in[4], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in4));
in5 = FLOAT_SCALE(in[5], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in5));
in6 = FLOAT_SCALE(in[6], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in6));
in7 = FLOAT_SCALE(in[7], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in7));
L00 = (in0 + in7); OI_ASSERT(VALID_INT32(L00));
L01 = (in1 + in6); OI_ASSERT(VALID_INT32(L01));
L02 = (in2 + in5); OI_ASSERT(VALID_INT32(L02));
L03 = (in3 + in4); OI_ASSERT(VALID_INT32(L03));
L04 = (in3 - in4); OI_ASSERT(VALID_INT32(L04));
L05 = (in2 - in5); OI_ASSERT(VALID_INT32(L05));
L06 = (in1 - in6); OI_ASSERT(VALID_INT32(L06));
L07 = (in0 - in7); OI_ASSERT(VALID_INT32(L07));
FLOAT_BUTTERFLY(L00, L03);
FLOAT_BUTTERFLY(L01, L02);
L02 += L03; OI_ASSERT(VALID_INT32(L02));
L02 = FLOAT_MULT_DCT(AAN_C4_FLOAT, L02); OI_ASSERT(VALID_INT32(L02));
FLOAT_BUTTERFLY(L00, L01);
out[0] = (float)FLOAT_SCALE(L00, DCTII_8_SHIFT_0); OI_ASSERT(VALID_INT16(out[0]));
out[4] = (float)FLOAT_SCALE(L01, DCTII_8_SHIFT_4); OI_ASSERT(VALID_INT16(out[4]));
FLOAT_BUTTERFLY(L03, L02);
out[6] = (float)FLOAT_SCALE(L02, DCTII_8_SHIFT_6); OI_ASSERT(VALID_INT16(out[6]));
out[2] = (float)FLOAT_SCALE(L03, DCTII_8_SHIFT_2); OI_ASSERT(VALID_INT16(out[2]));
L04 += L05; OI_ASSERT(VALID_INT32(L04));
L05 += L06; OI_ASSERT(VALID_INT32(L05));
L06 += L07; OI_ASSERT(VALID_INT32(L06));
L04/=2;
L05/=2;
L06/=2;
L07/=2;
L05 = FLOAT_MULT_DCT(AAN_C4_FLOAT, L05); OI_ASSERT(VALID_INT32(L05));
L25 = L06 - L04; OI_ASSERT(VALID_INT32(L25));
L25 = FLOAT_MULT_DCT(AAN_C6_FLOAT, L25); OI_ASSERT(VALID_INT32(L25));
L04 = FLOAT_MULT_DCT(AAN_Q0_FLOAT, L04); OI_ASSERT(VALID_INT32(L04));
L04 -= L25; OI_ASSERT(VALID_INT32(L04));
L06 = FLOAT_MULT_DCT(AAN_Q1_FLOAT, L06); OI_ASSERT(VALID_INT32(L06));
L06 -= L25; OI_ASSERT(VALID_INT32(L25));
FLOAT_BUTTERFLY(L07, L05);
FLOAT_BUTTERFLY(L05, L04);
out[3] = (float)(FLOAT_SCALE(L04, DCTII_8_SHIFT_3-1)); OI_ASSERT(VALID_INT16(out[3]));
out[5] = (float)(FLOAT_SCALE(L05, DCTII_8_SHIFT_5-1)); OI_ASSERT(VALID_INT16(out[5]));
FLOAT_BUTTERFLY(L07, L06);
out[7] = (float)(FLOAT_SCALE(L06, DCTII_8_SHIFT_7-1)); OI_ASSERT(VALID_INT16(out[7]));
out[1] = (float)(FLOAT_SCALE(L07, DCTII_8_SHIFT_1-1)); OI_ASSERT(VALID_INT16(out[1]));
}
#undef BUTTERFLY
#endif
/*
* This function calculates the AAN DCT. Its inputs are in S16.15 format, as
* returned by OI_SBC_Dequant. In practice, abs(in[x]) < 52429.0 / 1.38
* (1244918057 integer). The function it computes is an approximation to the array defined
* by:
*
* diag(aan_s) * AAN= C2
*
* or
*
* AAN = diag(1/aan_s) * C2
*
* where C2 is as it is defined in the comment at the head of this file, and
*
* aan_s[i] = aan_s = 1/(2*cos(i*pi/16)) with i = 1..7, aan_s[0] = 1;
*
* aan_s[i] = [ 1.000 0.510 0.541 0.601 0.707 0.900 1.307 2.563 ]
*
* The output ranges are shown as follows:
*
* Let Y[0..7] = AAN * X[0..7]
*
* Without loss of generality, assume the input vector X consists of elements
* between -1 and 1. The maximum possible value of a given output element occurs
* with some particular combination of input vector elements each of which is -1
* or 1. Consider the computation of Y[i]. Y[i] = sum t=0..7 of AAN[t,i]*X[i]. Y is
* maximized if the sign of X[i] matches the sign of AAN[t,i], ensuring a
* positive contribution to the sum. Equivalently, one may simply sum
* abs(AAN)[t,i] over t to get the maximum possible value of Y[i].
*
* This yields approximately [8.00 10.05 9.66 8.52 8.00 5.70 4.00 2.00]
*
* Given the maximum magnitude sensible input value of +/-37992, this yields the
* following vector of maximum output magnitudes:
*
* [ 303936 381820 367003 323692 303936 216555 151968 75984 ]
*
* Ultimately, these values must fit into 16 bit signed integers, so they must
* be scaled. A non-uniform scaling helps maximize the kept precision. The
* relative number of extra bits of precision maintainable with respect to the
* largest value is given here:
*
* [ 0 0 0 0 0 0 1 2 ]
*
*/
PRIVATE void dct2_8(SBC_BUFFER_T * RESTRICT out, OI_INT32 const *RESTRICT in);
PRIVATE void dct2_8(SBC_BUFFER_T * RESTRICT out, OI_INT32 const *RESTRICT in)
{
#define BUTTERFLY(x,y) x += y; y = x - (y<<1);
#define FIX_MULT_DCT(K, x) (MUL_32S_32S_HI(K,x)<<2)
OI_INT32 L00,L01,L02,L03,L04,L05,L06,L07;
OI_INT32 L25;
OI_INT32 in0,in1,in2,in3;
OI_INT32 in4,in5,in6,in7;
#if DCTII_8_SHIFT_IN != 0
in0 = SCALE(in[0], DCTII_8_SHIFT_IN);
in1 = SCALE(in[1], DCTII_8_SHIFT_IN);
in2 = SCALE(in[2], DCTII_8_SHIFT_IN);
in3 = SCALE(in[3], DCTII_8_SHIFT_IN);
in4 = SCALE(in[4], DCTII_8_SHIFT_IN);
in5 = SCALE(in[5], DCTII_8_SHIFT_IN);
in6 = SCALE(in[6], DCTII_8_SHIFT_IN);
in7 = SCALE(in[7], DCTII_8_SHIFT_IN);
#else
in0 = in[0];
in1 = in[1];
in2 = in[2];
in3 = in[3];
in4 = in[4];
in5 = in[5];
in6 = in[6];
in7 = in[7];
#endif
L00 = in0 + in7;
L01 = in1 + in6;
L02 = in2 + in5;
L03 = in3 + in4;
L04 = in3 - in4;
L05 = in2 - in5;
L06 = in1 - in6;
L07 = in0 - in7;
BUTTERFLY(L00, L03);
BUTTERFLY(L01, L02);
L02 += L03;
L02 = FIX_MULT_DCT(AAN_C4_FIX, L02);
BUTTERFLY(L00, L01);
out[0] = (OI_INT16)SCALE(L00, DCTII_8_SHIFT_0);
out[4] = (OI_INT16)SCALE(L01, DCTII_8_SHIFT_4);
BUTTERFLY(L03, L02);
out[6] = (OI_INT16)SCALE(L02, DCTII_8_SHIFT_6);
out[2] = (OI_INT16)SCALE(L03, DCTII_8_SHIFT_2);
L04 += L05;
L05 += L06;
L06 += L07;
L04/=2;
L05/=2;
L06/=2;
L07/=2;
L05 = FIX_MULT_DCT(AAN_C4_FIX, L05);
L25 = L06 - L04;
L25 = FIX_MULT_DCT(AAN_C6_FIX, L25);
L04 = FIX_MULT_DCT(AAN_Q0_FIX, L04);
L04 -= L25;
L06 = FIX_MULT_DCT(AAN_Q1_FIX, L06);
L06 -= L25;
BUTTERFLY(L07, L05);
BUTTERFLY(L05, L04);
out[3] = (OI_INT16)SCALE(L04, DCTII_8_SHIFT_3-1);
out[5] = (OI_INT16)SCALE(L05, DCTII_8_SHIFT_5-1);
BUTTERFLY(L07, L06);
out[7] = (OI_INT16)SCALE(L06, DCTII_8_SHIFT_7-1);
out[1] = (OI_INT16)SCALE(L07, DCTII_8_SHIFT_1-1);
#undef BUTTERFLY
#ifdef DEBUG_DCT
{
float float_out[8];
float_dct2_8(float_out, in);
}
#endif
}
/**@}*/
+513
View File
@@ -0,0 +1,513 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
This file, along with synthesis-generated.c, contains the synthesis
filterbank routines. The operations performed correspond to the
operations described in A2DP Appendix B, Figure 12.3. Several
mathematical optimizations are performed, particularly for the
8-subband case.
One important optimization is to note that the "matrixing" operation
can be decomposed into the product of a type II discrete cosine kernel
and another, sparse matrix.
According to Fig 12.3, in the 8-subband case,
@code
N[k][i] = cos((i+0.5)*(k+4)*pi/8), k = 0..15 and i = 0..7
@endcode
N can be factored as R * C2, where C2 is an 8-point type II discrete
cosine kernel given by
@code
C2[k][i] = cos((i+0.5)*k*pi/8)), k = 0..7 and i = 0..7
@endcode
R turns out to be a sparse 16x8 matrix with the following non-zero
entries:
@code
R[k][k+4] = 1, k = 0..3
R[k][abs(12-k)] = -1, k = 5..15
@endcode
The spec describes computing V[0..15] as N * R.
@code
V[0..15] = N * R = (R * C2) * R = R * (C2 * R)
@endcode
C2 * R corresponds to computing the discrete cosine transform of R, so
V[0..15] can be computed by taking the DCT of R followed by assignment
and selective negation of the DCT result into V.
Although this was derived empirically using GNU Octave, it is
formally demonstrated in, e.g., Liu, Chi-Min and Lee,
Wen-Chieh. "A Unified Fast Algorithm for Cosine Modulated
Filter Banks in Current Audio Coding Standards." Journal of
the AES 47 (December 1999): 1061.
Given the shift operation performed prior to computing V[0..15], it is
clear that V[0..159] represents a rolling history of the 10 most
recent groups of blocks input to the synthesis operation. Interpreting
the matrix N in light of its factorization into C2 and R, R's
sparseness has implications for interpreting the values in V. In
particular, there is considerable redundancy in the values stored in
V. Furthermore, since R[4][0..7] are all zeros, one out of every 16
values in V will be zero regardless of the input data. Within each
block of 16 values in V, fully half of them are redundant or
irrelevant:
@code
V[ 0] = DCT[4]
V[ 1] = DCT[5]
V[ 2] = DCT[6]
V[ 3] = DCT[7]
V[ 4] = 0
V[ 5] = -DCT[7] = -V[3] (redundant)
V[ 6] = -DCT[6] = -V[2] (redundant)
V[ 7] = -DCT[5] = -V[1] (redundant)
V[ 8] = -DCT[4] = -V[0] (redundant)
V[ 9] = -DCT[3]
V[10] = -DCT[2]
V[11] = -DCT[1]
V[12] = -DCT[0]
V[13] = -DCT[1] = V[11] (redundant)
V[14] = -DCT[2] = V[10] (redundant)
V[15] = -DCT[3] = V[ 9] (redundant)
@endcode
Since the elements of V beyond 15 were originally computed the same
way during a previous run, what holds true for V[x] also holds true
for V[x+16]. Thus, so long as care is taken to maintain the mapping,
we need only actually store the unique values, which correspond to the
output of the DCT, in some cases inverted. In fact, instead of storing
V[0..159], we could store DCT[0..79] which would contain a history of
DCT results. More on this in a bit.
Going back to figure 12.3 in the spec, it should be clear that the
vector U need not actually be explicitly constructed, but that with
suitable indexing into V during the window operation, the same end can
be accomplished. In the same spirit of the pseudocode shown in the
figure, the following is the construction of W without using U:
@code
for i=0 to 79 do
W[i] = D[i]*VSIGN(i)*V[remap_V(i)] where remap_V(i) = 32*(int(i/16)) + (i % 16) + (i % 16 >= 8 ? 16 : 0)
and VSIGN(i) maps i%16 into {1, 1, 1, 1, 0, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1 }
These values correspond to the
signs of the redundant values as
shown in the explanation three
paragraphs above.
@endcode
We saw above how V[4..8,13..15] (and by extension
V[(4..8,13..15)+16*n]) can be defined in terms of other elements
within the subblock of V. V[0..3,9..12] correspond to DCT elements.
@code
for i=0 to 79 do
W[i] = D[i]*DSIGN(i)*DCT[remap_DCT(i)]
@endcode
The DCT is calculated using the Arai-Agui-Nakajima factorization,
which saves some computation by producing output that needs to be
multiplied by scaling factors before being used.
@code
for i=0 to 79 do
W[i] = D[i]*SCALE[i%8]*AAN_DCT[remap_DCT(i)]
@endcode
D can be premultiplied with the DCT scaling factors to yield
@code
for i=0 to 79 do
W[i] = DSCALED[i]*AAN_DCT[remap_DCT(i)] where DSCALED[i] = D[i]*SCALE[i%8]
@endcode
The output samples X[0..7] are defined as sums of W:
@code
X[j] = sum{i=0..9}(W[j+8*i])
@endcode
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "oi_codec_sbc_private.h"
const OI_INT32 dec_window_4[21] = {
0, /* +0.00000000E+00 */
97, /* +5.36548976E-04 */
270, /* +1.49188357E-03 */
495, /* +2.73370904E-03 */
694, /* +3.83720193E-03 */
704, /* +3.89205149E-03 */
338, /* +1.86581691E-03 */
-554, /* -3.06012286E-03 */
1974, /* +1.09137620E-02 */
3697, /* +2.04385087E-02 */
5224, /* +2.88757392E-02 */
5824, /* +3.21939290E-02 */
4681, /* +2.58767811E-02 */
1109, /* +6.13245186E-03 */
-5214, /* -2.88217274E-02 */
-14047, /* -7.76463494E-02 */
24529, /* +1.35593274E-01 */
35274, /* +1.94987841E-01 */
44618, /* +2.46636662E-01 */
50984, /* +2.81828203E-01 */
53243, /* +2.94315332E-01 */
};
#define DCTII_4_K06_FIX ( 11585)/* S1.14 11585 0.707107*/
#define DCTII_4_K08_FIX ( 21407)/* S1.14 21407 1.306563*/
#define DCTII_4_K09_FIX (-15137)/* S1.14 -15137 -0.923880*/
#define DCTII_4_K10_FIX ( -8867)/* S1.14 -8867 -0.541196*/
/** Scales x by y bits to the right, adding a rounding factor.
*/
#ifndef SCALE
#define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
#endif
#ifndef CLIP_INT16
#define CLIP_INT16(x) do { if (x > OI_INT16_MAX) { x = OI_INT16_MAX; } else if (x < OI_INT16_MIN) { x = OI_INT16_MIN; } } while (0)
#endif
/**
* Default C language implementation of a 16x32->32 multiply. This function may
* be replaced by a platform-specific version for speed.
*
* @param u A signed 16-bit multiplicand
* @param v A signed 32-bit multiplier
* @return A signed 32-bit value corresponding to the 32 most significant bits
* of the 48-bit product of u and v.
*/
INLINE OI_INT32 default_mul_16s_32s_hi(OI_INT16 u, OI_INT32 v);
INLINE OI_INT32 default_mul_16s_32s_hi(OI_INT16 u, OI_INT32 v)
{
OI_UINT16 v0;
OI_INT16 v1;
OI_INT32 w,x;
v0 = (OI_UINT16)(v & 0xffff);
v1 = (OI_INT16) (v >> 16);
w = v1 * u;
x = u * v0;
return w + (x >> 16);
}
#define MUL_16S_32S_HI(_x, _y) default_mul_16s_32s_hi(_x, _y)
#define LONG_MULT_DCT(K, sample) (MUL_16S_32S_HI(K, sample)<<2)
PRIVATE void SynthWindow80_generated(OI_INT16 *pcm, SBC_BUFFER_T const * RESTRICT buffer, OI_UINT strideShift);
PRIVATE void SynthWindow112_generated(OI_INT16 *pcm, SBC_BUFFER_T const * RESTRICT buffer, OI_UINT strideShift);
PRIVATE void dct2_8(SBC_BUFFER_T * RESTRICT out, OI_INT32 const * RESTRICT x);
typedef void (*SYNTH_FRAME)(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount);
#ifndef COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS
#define COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(dest, src) do { shift_buffer(dest, src, 72); } while (0)
#endif
#ifndef DCT2_8
#define DCT2_8(dst, src) dct2_8(dst, src)
#endif
#ifndef SYNTH80
#define SYNTH80 SynthWindow80_generated
#endif
#ifndef SYNTH112
#define SYNTH112 SynthWindow112_generated
#endif
PRIVATE void OI_SBC_SynthFrame_80(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount);
PRIVATE void OI_SBC_SynthFrame_80(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount)
{
OI_UINT blk;
OI_UINT ch;
OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
OI_UINT pcmStrideShift = (context->common.pcmStride == 1) ? 0 : 1;
OI_UINT offset = context->common.filterBufferOffset;
OI_INT32 *s = context->common.subdata + (8 * nrof_channels * blkstart);
OI_UINT blkstop = blkstart + blkcount;
for (blk = blkstart; blk < blkstop; blk++) {
if (offset == 0) {
COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[0] + context->common.filterBufferLen - 72, context->common.filterBuffer[0]);
if (nrof_channels == 2) {
COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[1] + context->common.filterBufferLen - 72, context->common.filterBuffer[1]);
}
offset = context->common.filterBufferLen - 80;
} else {
offset -= 1*8;
}
for (ch = 0; ch < nrof_channels; ch++) {
DCT2_8(context->common.filterBuffer[ch] + offset, s);
SYNTH80(pcm + ch, context->common.filterBuffer[ch] + offset, pcmStrideShift);
s += 8;
}
pcm += (8 << pcmStrideShift);
}
context->common.filterBufferOffset = offset;
}
PRIVATE void OI_SBC_SynthFrame_4SB(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount);
PRIVATE void OI_SBC_SynthFrame_4SB(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount)
{
OI_UINT blk;
OI_UINT ch;
OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
OI_UINT pcmStrideShift = (context->common.pcmStride == 1) ? 0 : 1;
OI_UINT offset = context->common.filterBufferOffset;
OI_INT32 *s = context->common.subdata + (8 * nrof_channels * blkstart);
OI_UINT blkstop = blkstart + blkcount;
for (blk = blkstart; blk < blkstop; blk++) {
if (offset == 0) {
COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[0] + context->common.filterBufferLen - 72,context->common.filterBuffer[0]);
if (nrof_channels == 2) {
COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[1] + context->common.filterBufferLen - 72,context->common.filterBuffer[1]);
}
offset =context->common.filterBufferLen - 80;
} else {
offset -= 8;
}
for (ch = 0; ch < nrof_channels; ch++) {
cosineModulateSynth4(context->common.filterBuffer[ch] + offset, s);
SynthWindow40_int32_int32_symmetry_with_sum(pcm + ch,
context->common.filterBuffer[ch] + offset,
pcmStrideShift);
s += 4;
}
pcm += (4 << pcmStrideShift);
}
context->common.filterBufferOffset = offset;
}
#ifdef SBC_ENHANCED
PRIVATE void OI_SBC_SynthFrame_Enhanced(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount)
{
OI_UINT blk;
OI_UINT ch;
OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
OI_UINT pcmStrideShift = context->common.pcmStride == 1 ? 0 : 1;
OI_UINT offset = context->common.filterBufferOffset;
OI_INT32 *s = context->common.subdata + 8 * nrof_channels * blkstart;
OI_UINT blkstop = blkstart + blkcount;
for (blk = blkstart; blk < blkstop; blk++) {
if (offset == 0) {
COPY_BACKWARD_32BIT_ALIGNED_104_HALFWORDS(context->common.filterBuffer[0] +context->common.filterBufferLen - 104, context->common.filterBuffer[0]);
if (nrof_channels == 2) {
COPY_BACKWARD_32BIT_ALIGNED_104_HALFWORDS(context->common.filterBuffer[1] + context->common.filterBufferLen - 104, context->common.filterBuffer[1]);
}
offset = context->common.filterBufferLen - 112;
} else {
offset -= 8;
}
for (ch = 0; ch < nrof_channels; ++ch) {
DCT2_8(context->common.filterBuffer[ch] + offset, s);
SYNTH112(pcm + ch, context->common.filterBuffer[ch] + offset, pcmStrideShift);
s += 8;
}
pcm += (8 << pcmStrideShift);
}
context->common.filterBufferOffset = offset;
}
static const SYNTH_FRAME SynthFrameEnhanced[] = {
(SYNTH_FRAME) NULL, /* invalid */
OI_SBC_SynthFrame_Enhanced, /* mono */
OI_SBC_SynthFrame_Enhanced /* stereo */
};
#endif
static const SYNTH_FRAME SynthFrame8SB[] = {
(SYNTH_FRAME) NULL, /* invalid */
OI_SBC_SynthFrame_80, /* mono */
OI_SBC_SynthFrame_80 /* stereo */
};
static const SYNTH_FRAME SynthFrame4SB[] = {
(SYNTH_FRAME) NULL, /* invalid */
OI_SBC_SynthFrame_4SB, /* mono */
OI_SBC_SynthFrame_4SB /* stereo */
};
PRIVATE void OI_SBC_SynthFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT start_block, OI_UINT nrof_blocks)
{
OI_UINT nrof_subbands = context->common.frameInfo.nrof_subbands;
OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
OI_ASSERT(nrof_subbands == 4 || nrof_subbands == 8);
if (nrof_subbands == 4) {
SynthFrame4SB[nrof_channels](context, pcm, start_block, nrof_blocks);
#ifdef SBC_ENHANCED
} else if (context->common.frameInfo.enhanced) {
SynthFrameEnhanced[nrof_channels](context, pcm, start_block, nrof_blocks);
#endif /* SBC_ENHANCED */
} else {
SynthFrame8SB[nrof_channels](context, pcm, start_block, nrof_blocks);
}
}
void SynthWindow40_int32_int32_symmetry_with_sum(OI_INT16 *pcm, SBC_BUFFER_T buffer[80], OI_UINT strideShift)
{
OI_INT32 pa;
OI_INT32 pb;
/* These values should be zero, since out[2] of the 4-band cosine modulation
* is always zero. */
OI_ASSERT(buffer[ 2] == 0);
OI_ASSERT(buffer[10] == 0);
OI_ASSERT(buffer[18] == 0);
OI_ASSERT(buffer[26] == 0);
OI_ASSERT(buffer[34] == 0);
OI_ASSERT(buffer[42] == 0);
OI_ASSERT(buffer[50] == 0);
OI_ASSERT(buffer[58] == 0);
OI_ASSERT(buffer[66] == 0);
OI_ASSERT(buffer[74] == 0);
pa = dec_window_4[ 4] * (buffer[12] + buffer[76]);
pa += dec_window_4[ 8] * (buffer[16] - buffer[64]);
pa += dec_window_4[12] * (buffer[28] + buffer[60]);
pa += dec_window_4[16] * (buffer[32] - buffer[48]);
pa += dec_window_4[20] * buffer[44];
pa = SCALE(-pa, 15);
CLIP_INT16(pa);
pcm[(uint32_t)(0 << strideShift)] = (OI_INT16)pa;
pa = dec_window_4[ 1] * buffer[ 1]; pb = dec_window_4[ 1] * buffer[79];
pb += dec_window_4[ 3] * buffer[ 3]; pa += dec_window_4[ 3] * buffer[77];
pa += dec_window_4[ 5] * buffer[13]; pb += dec_window_4[ 5] * buffer[67];
pb += dec_window_4[ 7] * buffer[15]; pa += dec_window_4[ 7] * buffer[65];
pa += dec_window_4[ 9] * buffer[17]; pb += dec_window_4[ 9] * buffer[63];
pb += dec_window_4[11] * buffer[19]; pa += dec_window_4[11] * buffer[61];
pa += dec_window_4[13] * buffer[29]; pb += dec_window_4[13] * buffer[51];
pb += dec_window_4[15] * buffer[31]; pa += dec_window_4[15] * buffer[49];
pa += dec_window_4[17] * buffer[33]; pb += dec_window_4[17] * buffer[47];
pb += dec_window_4[19] * buffer[35]; pa += dec_window_4[19] * buffer[45];
pa = SCALE(-pa, 15);
CLIP_INT16(pa);
pcm[(uint32_t)(1 << strideShift)] = (OI_INT16)(pa);
pb = SCALE(-pb, 15);
CLIP_INT16(pb);
pcm[(uint32_t)(3 << strideShift)] = (OI_INT16)(pb);
pa = dec_window_4[2] * (/*buffer[ 2] + */ buffer[78]); /* buffer[ 2] is always zero */
pa += dec_window_4[6] * (buffer[14] /* + buffer[66]*/); /* buffer[66] is always zero */
pa += dec_window_4[10] * (/*buffer[18] + */ buffer[62]); /* buffer[18] is always zero */
pa += dec_window_4[14] * (buffer[30] /* + buffer[50]*/); /* buffer[50] is always zero */
pa += dec_window_4[18] * (/*buffer[34] + */ buffer[46]); /* buffer[34] is always zero */
pa = SCALE(-pa, 15);
CLIP_INT16(pa);
pcm[(uint32_t)(2 << strideShift)] = (OI_INT16)(pa);
}
/**
This routine implements the cosine modulation matrix for 4-subband
synthesis. This is called "matrixing" in the SBC specification. This
matrix, M4, can be factored into an 8-point Type II Discrete Cosine
Transform, DCTII_4 and a matrix S4, given here:
@code
__ __
| 0 0 1 0 |
| 0 0 0 1 |
| 0 0 0 0 |
| 0 0 0 -1 |
S4 = | 0 0 -1 0 |
| 0 -1 0 0 |
| -1 0 0 0 |
|__ 0 -1 0 0 __|
M4 * in = S4 * (DCTII_4 * in)
@endcode
(DCTII_4 * in) is computed using a Fast Cosine Transform. The algorithm
here is based on an implementation computed by the SPIRAL computer
algebra system, manually converted to fixed-point arithmetic. S4 can be
implemented using only assignment and negation.
*/
PRIVATE void cosineModulateSynth4(SBC_BUFFER_T * RESTRICT out, OI_INT32 const * RESTRICT in)
{
OI_INT32 f0, f1, f2, f3, f4, f7, f8, f9, f10;
OI_INT32 y0, y1, y2, y3;
f0 = (in[0] - in[3]);
f1 = (in[0] + in[3]);
f2 = (in[1] - in[2]);
f3 = (in[1] + in[2]);
f4 = f1 - f3;
y0 = -SCALE(f1 + f3, DCT_SHIFT);
y2 = -SCALE(LONG_MULT_DCT(DCTII_4_K06_FIX, f4), DCT_SHIFT);
f7 = f0 + f2;
f8 = LONG_MULT_DCT(DCTII_4_K08_FIX, f0);
f9 = LONG_MULT_DCT(DCTII_4_K09_FIX, f7);
f10 = LONG_MULT_DCT(DCTII_4_K10_FIX, f2);
y3 = -SCALE(f8 + f9, DCT_SHIFT);
y1 = -SCALE(f10 - f9, DCT_SHIFT);
out[0] = (OI_INT16)-y2;
out[1] = (OI_INT16)-y3;
out[2] = (OI_INT16)0;
out[3] = (OI_INT16)y3;
out[4] = (OI_INT16)y2;
out[5] = (OI_INT16)y1;
out[6] = (OI_INT16)y0;
out[7] = (OI_INT16)y1;
}
/**
@}
*/
+11
View File
@@ -0,0 +1,11 @@
# sbc encoder
SBC_ENCODER += \
sbc_analysis.c \
sbc_dct.c \
sbc_dct_coeffs.c \
sbc_enc_bit_alloc_mono.c \
sbc_enc_bit_alloc_ste.c \
sbc_enc_coeffs.c \
sbc_encoder.c \
sbc_packing.c \
+91
View File
@@ -0,0 +1,91 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* Definitions for the fast DCT.
*
******************************************************************************/
#ifndef SBC_DCT_H
#define SBC_DCT_H
#if (SBC_ARM_ASM_OPT==TRUE)
#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1, s32OutLow) \
{ \
__asm \
{ \
MUL s32OutLow,(SINT32)s16In2, (s32In1>>15) \
} \
}
#else
#if (SBC_DSP_OPT==TRUE)
#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow = SBC_Multiply_32_16_Simplified((SINT32)s16In2,s32In1);
#else
#if (SBC_IPAQ_OPT==TRUE)
/*#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow=(SINT32)((SINT32)(s16In2)*(SINT32)(s32In1>>15)); */
#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow=(SINT32)(((SINT64)s16In2*(SINT64)s32In1)>>15);
#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
#define SBC_MULT_32_32(s32In2, s32In1, s32OutLow) \
{ \
s64Temp = ((SINT64) s32In2) * ((SINT64) s32In1)>>31; \
s32OutLow = (SINT32) s64Temp; \
}
#endif
#else
#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) \
{ \
s32In1Temp = s32In1; \
s32In2Temp = (SINT32)s16In2; \
\
/* Multiply one +ve and the other -ve number */ \
if (s32In1Temp < 0) \
{ \
s32In1Temp ^= 0xFFFFFFFF; \
s32In1Temp++; \
s32OutLow = (s32In2Temp * (s32In1Temp >> 16)); \
s32OutLow += (( s32In2Temp * (s32In1Temp & 0xFFFF)) >> 16); \
s32OutLow ^= 0xFFFFFFFF; \
s32OutLow++; \
} \
else \
{ \
s32OutLow = (s32In2Temp * (s32In1Temp >> 16)); \
s32OutLow += (( s32In2Temp * (s32In1Temp & 0xFFFF)) >> 16); \
} \
s32OutLow <<= 1; \
}
#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
#define SBC_MULT_64(s32In1, s32In2, s32OutLow, s32OutHi) \
{\
s32OutLow=(SINT32)(((SINT64)s32In1*(SINT64)s32In2)& 0x00000000FFFFFFFF);\
s32OutHi=(SINT32)(((SINT64)s32In1*(SINT64)s32In2)>>32);\
}
#define SBC_MULT_32_32(s32In2, s32In1, s32OutLow) \
{ \
s32HiTemp = 0; \
SBC_MULT_64(s32In2,s32In1 , s32OutLow, s32HiTemp); \
s32OutLow = (((s32OutLow>>15)&0x1FFFF) | (s32HiTemp << 17)); \
}
#endif
#endif
#endif
#endif
#endif
@@ -0,0 +1,57 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* Function declarations.
*
******************************************************************************/
#ifndef SBC_FUNCDECLARE_H
#define SBC_FUNCDECLARE_H
/*#include "sbc_encoder.h"*/
/* Global data */
#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == FALSE)
extern const SINT16 gas32CoeffFor4SBs[];
extern const SINT16 gas32CoeffFor8SBs[];
#else
extern const SINT32 gas32CoeffFor4SBs[];
extern const SINT32 gas32CoeffFor8SBs[];
#endif
/* Global functions*/
extern void sbc_enc_bit_alloc_mono(SBC_ENC_PARAMS *CodecParams);
extern void sbc_enc_bit_alloc_ste(SBC_ENC_PARAMS *CodecParams);
extern void SbcAnalysisInit (SBC_ENC_PARAMS *CodecParams);
extern void SbcAnalysisFilter4(SBC_ENC_PARAMS *strEncParams);
extern void SbcAnalysisFilter8(SBC_ENC_PARAMS *strEncParams);
extern void SBC_FastIDCT8 (SINT32 *pInVect, SINT32 *pOutVect);
extern void SBC_FastIDCT4 (SINT32 *x0, SINT32 *pOutVect);
extern void EncPacking(SBC_ENC_PARAMS *strEncParams);
extern void EncQuantizer(SBC_ENC_PARAMS *);
#if (SBC_DSP_OPT==TRUE)
SINT32 SBC_Multiply_32_16_Simplified(SINT32 s32In2Temp,SINT32 s32In1Temp);
#endif
#endif
+218
View File
@@ -0,0 +1,218 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This file contains constants and structures used by Encoder.
*
******************************************************************************/
#ifndef SBC_ENCODER_H
#define SBC_ENCODER_H
#define ENCODER_VERSION "0025"
#ifdef BUILDCFG
#include "bt_target.h"
#endif
/*DEFINES*/
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
/* BK4BTSTACK_CHANGE START */
#define SBC_NO_PCM_CPY_OPTION TRUE
/* BK4BTSTACK_CHANGE END */
#define SBC_MAX_NUM_OF_SUBBANDS 8
#define SBC_MAX_NUM_OF_CHANNELS 2
#define SBC_MAX_NUM_OF_BLOCKS 16
#define SBC_LOUDNESS 0
#define SBC_SNR 1
#define SUB_BANDS_8 8
#define SUB_BANDS_4 4
#define SBC_sf16000 0
#define SBC_sf32000 1
#define SBC_sf44100 2
#define SBC_sf48000 3
#define SBC_MONO 0
#define SBC_DUAL 1
#define SBC_STEREO 2
#define SBC_JOINT_STEREO 3
#define SBC_BLOCK_0 4
#define SBC_BLOCK_1 8
#define SBC_BLOCK_2 12
#define SBC_BLOCK_3 16
#define SBC_NULL 0
#ifndef SBC_MAX_NUM_FRAME
#define SBC_MAX_NUM_FRAME 1
#endif
#ifndef SBC_DSP_OPT
#define SBC_DSP_OPT FALSE
#endif
/* Set SBC_USE_ARM_PRAGMA to TRUE to use "#pragma arm section zidata" */
#ifndef SBC_USE_ARM_PRAGMA
#define SBC_USE_ARM_PRAGMA FALSE
#endif
/* Set SBC_ARM_ASM_OPT to TRUE in case the target is an ARM */
/* this will replace all the 32 and 64 bit mult by in line assembly code */
#ifndef SBC_ARM_ASM_OPT
#define SBC_ARM_ASM_OPT FALSE
#endif
/* green hill compiler option -> Used to distinguish the syntax for inline assembly code*/
#ifndef SBC_GHS_COMPILER
#define SBC_GHS_COMPILER FALSE
#endif
/* ARM compiler option -> Used to distinguish the syntax for inline assembly code */
#ifndef SBC_ARM_COMPILER
#define SBC_ARM_COMPILER TRUE
#endif
/* Set SBC_IPAQ_OPT to TRUE in case the target is an ARM */
/* 32 and 64 bit mult will be performed using SINT64 ( usualy __int64 ) cast that usualy give optimal performance if supported */
#ifndef SBC_IPAQ_OPT
#define SBC_IPAQ_OPT TRUE
#endif
/* Debug only: set SBC_IS_64_MULT_IN_WINDOW_ACCU to TRUE to use 64 bit multiplication in the windowing */
/* -> not recomended, more MIPS for the same restitution. */
#ifndef SBC_IS_64_MULT_IN_WINDOW_ACCU
#define SBC_IS_64_MULT_IN_WINDOW_ACCU FALSE
#endif /*SBC_IS_64_MULT_IN_WINDOW_ACCU */
/* Set SBC_IS_64_MULT_IN_IDCT to TRUE to use 64 bits multiplication in the DCT of Matrixing */
/* -> more MIPS required for a better audio quality. comparasion with the SIG utilities shows a division by 10 of the RMS */
/* CAUTION: It only apply in the if SBC_FAST_DCT is set to TRUE */
#ifndef SBC_IS_64_MULT_IN_IDCT
#define SBC_IS_64_MULT_IN_IDCT FALSE
#endif /*SBC_IS_64_MULT_IN_IDCT */
/* set SBC_IS_64_MULT_IN_QUANTIZER to TRUE to use 64 bits multiplication in the quantizer */
/* setting this flag to FALSE add whistling noise at 5.5 and 11 KHz usualy not perceptible by human's hears. */
#ifndef SBC_IS_64_MULT_IN_QUANTIZER
#define SBC_IS_64_MULT_IN_QUANTIZER TRUE
#endif /*SBC_IS_64_MULT_IN_IDCT */
/* Debug only: set this flag to FALSE to disable fast DCT algorithm */
#ifndef SBC_FAST_DCT
#define SBC_FAST_DCT TRUE
#endif /*SBC_FAST_DCT */
/* In case we do not use joint stereo mode the flag save some RAM and ROM in case it is set to FALSE */
#ifndef SBC_JOINT_STE_INCLUDED
#define SBC_JOINT_STE_INCLUDED TRUE
#endif
/* TRUE -> application should provide PCM buffer, FALSE PCM buffer reside in SBC_ENC_PARAMS */
#ifndef SBC_NO_PCM_CPY_OPTION
#define SBC_NO_PCM_CPY_OPTION FALSE
#endif
#define MINIMUM_ENC_VX_BUFFER_SIZE (8*10*2)
#ifndef ENC_VX_BUFFER_SIZE
#define ENC_VX_BUFFER_SIZE (MINIMUM_ENC_VX_BUFFER_SIZE + 64)
/*#define ENC_VX_BUFFER_SIZE MINIMUM_ENC_VX_BUFFER_SIZE + 1024*/
#endif
#ifndef SBC_FOR_EMBEDDED_LINUX
#define SBC_FOR_EMBEDDED_LINUX FALSE
#endif
/*constants used for index calculation*/
#define SBC_BLK (SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS)
#include "sbc_types.h"
typedef struct SBC_ENC_PARAMS_TAG
{
SINT16 s16SamplingFreq; /* 16k, 32k, 44.1k or 48k*/
SINT16 s16ChannelMode; /* mono, dual, streo or joint streo*/
SINT16 s16NumOfSubBands; /* 4 or 8 */
SINT16 s16NumOfChannels;
SINT16 s16NumOfBlocks; /* SBC: 4, 8, 12 or 16; mSBC: 15*/
SINT16 s16AllocationMethod; /* loudness or SNR*/
SINT16 s16BitPool; /* 16*numOfSb for mono & dual;
32*numOfSb for stereo & joint stereo */
/* BK4BTSTACK_CHANGE START */
// UINT16 u16BitRate;
/* BK4BTSTACK_CHANGE END */
UINT8 u8NumPacketToEncode; /* number of sbc frame to encode. Default is 1 */
#if (SBC_JOINT_STE_INCLUDED == TRUE)
SINT16 as16Join[SBC_MAX_NUM_OF_SUBBANDS]; /*1 if JS, 0 otherwise*/
#endif
SINT16 s16MaxBitNeed;
SINT16 as16ScaleFactor[SBC_MAX_NUM_OF_CHANNELS*SBC_MAX_NUM_OF_SUBBANDS];
SINT16 *ps16NextPcmBuffer;
#if (SBC_NO_PCM_CPY_OPTION == TRUE)
SINT16 *ps16PcmBuffer;
#else
SINT16 as16PcmBuffer[SBC_MAX_NUM_FRAME*SBC_MAX_NUM_OF_BLOCKS * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
#endif
SINT16 s16ScartchMemForBitAlloc[16];
SINT32 s32SbBuffer[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * SBC_MAX_NUM_OF_BLOCKS];
SINT16 as16Bits[SBC_MAX_NUM_OF_CHANNELS*SBC_MAX_NUM_OF_SUBBANDS];
UINT8 *pu8Packet;
UINT8 *pu8NextPacket;
UINT16 FrameHeader;
UINT16 u16PacketLength;
/* BK4BTSTACK_CHANGE START */
UINT8 mSBCEnabled;
// from sbc_analysis
SINT32 s32DCTY[16];// = {0};
SINT32 s32X[ENC_VX_BUFFER_SIZE/2];
SINT16 *s16X;//=(SINT16*) s32X; /* s16X must be 32 bits aligned cf SHIFTUP_X8_2*/
SINT16 ShiftCounter;
// from sbc_encoder
SINT16 EncMaxShiftCounter;
/* BK4BTSTACK_CHANGE END */
}SBC_ENC_PARAMS;
#ifdef __cplusplus
extern "C"
{
#endif
SBC_API extern void SBC_Encoder(SBC_ENC_PARAMS *strEncParams);
SBC_API extern void SBC_Encoder_Init(SBC_ENC_PARAMS *strEncParams);
#ifdef __cplusplus
}
#endif
#endif
+75
View File
@@ -0,0 +1,75 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* Data type declarations.
*
******************************************************************************/
#ifndef SBC_TYPES_H
#define SBC_TYPES_H
#ifdef BUILDCFG
#include "bt_target.h"
#endif
/* BK4BTSTACK_CHANGE START */
#if 0
// #include "data_types.h"
typedef short SINT16;
typedef long SINT32;
#if (SBC_IPAQ_OPT == TRUE)
#if (SBC_FOR_EMBEDDED_LINUX == TRUE)
typedef long long SINT64;
#else
typedef __int64 SINT64;
#endif
#elif (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE) || (SBC_IS_64_MULT_IN_IDCT == TRUE)
#if (SBC_FOR_EMBEDDED_LINUX == TRUE)
typedef long long SINT64;
#else
typedef __int64 SINT64;
#endif
#endif
#else
#include <stdint.h>
typedef int8_t SINT8;
typedef int16_t SINT16;
typedef int32_t SINT32;
typedef int64_t SINT64;
typedef uint8_t UINT8;
typedef uint16_t UINT16;
typedef uint32_t UINT32;
typedef uint64_t UINT64;
#endif
/* BK4BTSTACK_CHANGE STOP */
#define SBC_API
#define abs32(x) ( (x >= 0) ? x : (-x) )
#endif
+72
View File
@@ -0,0 +1,72 @@
//#include "msbc_encoder_port.h"
#include "sbc_encoder.h"
#include "xc60xx.h"
#define mSBC_SYNCWORD 0xad
#define SBC_MAX_CHANNELS 2
struct msbc_encoder_state {
SBC_ENC_PARAMS *context;
int num_data_bytes;
uint8_t sbc_packet[512];
};
static struct msbc_encoder_state encoder_state = {0};
static uint8_t msbc_encode_inited = 0;
int msbc_encoder_init(void)
{
static SBC_ENC_PARAMS msbc_context = {
.s16NumOfBlocks = 15,
.s16NumOfSubBands = 8,
.s16AllocationMethod = SBC_LOUDNESS,
.s16BitPool = 26,
.s16ChannelMode = SBC_MONO,
.s16NumOfChannels = 1,
.mSBCEnabled = 1,
.s16SamplingFreq = SBC_sf16000,
};
// int status = 0;
encoder_state.context = &msbc_context;
encoder_state.context->pu8Packet = encoder_state.sbc_packet;
SBC_Encoder_Init(encoder_state.context);
msbc_encode_inited = 1;
return 0;
}
int msbc_encoder_num_audio_frames(void)
{
SBC_ENC_PARAMS * context = encoder_state.context;
return context->s16NumOfSubBands * context->s16NumOfBlocks;
}
uint8_t * msbc_encoder_sbc_buffer(void)
{
SBC_ENC_PARAMS * context = encoder_state.context;
return context->pu8Packet;
}
uint16_t msbc_encoder_sbc_buffer_length(void)
{
SBC_ENC_PARAMS * context = encoder_state.context;
return context->u16PacketLength;
}
void /*__attribute__((section("ram_em")))*/ msbc_encoder_process_data(int16_t * input_buffer)
{
if (!msbc_encode_inited) {
printf("SBC encoder: sbc state is NULL, call btstack_sbc_encoder_init to initialize it\r\n");
}
SBC_ENC_PARAMS * context = encoder_state.context;
context->ps16PcmBuffer = input_buffer;
if (context->mSBCEnabled) {
context->pu8Packet[0] = 0xad;
}
SBC_Encoder(context);
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef __MSBC_ENCODER_PORT_H_
#define __MSBC_ENCODER_PORT_H_
int msbc_encoder_num_audio_frames(void);
uint8_t * msbc_encoder_sbc_buffer(void);
uint16_t msbc_encoder_sbc_buffer_length(void);
int msbc_encoder_init(void);
void msbc_encoder_process_data(int16_t * input_buffer);
#endif
File diff suppressed because it is too large Load Diff
+241
View File
@@ -0,0 +1,241 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* source file for fast dct operations
*
******************************************************************************/
#include "sbc_encoder.h"
#include "sbc_enc_func_declare.h"
#include "sbc_dct.h"
#include "xc60xx.h"
/*******************************************************************************
**
** Function SBC_FastIDCT8
**
** Description implementation of fast DCT algorithm by Feig and Winograd
**
**
** Returns y = dct(pInVect)
**
**
*******************************************************************************/
#if (SBC_IS_64_MULT_IN_IDCT == FALSE)
#define SBC_COS_PI_SUR_4 (0x00005a82) /* ((0x8000) * 0.7071) = cos(pi/4) */
#define SBC_COS_PI_SUR_8 (0x00007641) /* ((0x8000) * 0.9239) = (cos(pi/8)) */
#define SBC_COS_3PI_SUR_8 (0x000030fb) /* ((0x8000) * 0.3827) = (cos(3*pi/8)) */
#define SBC_COS_PI_SUR_16 (0x00007d8a) /* ((0x8000) * 0.9808)) = (cos(pi/16)) */
#define SBC_COS_3PI_SUR_16 (0x00006a6d) /* ((0x8000) * 0.8315)) = (cos(3*pi/16)) */
#define SBC_COS_5PI_SUR_16 (0x0000471c) /* ((0x8000) * 0.5556)) = (cos(5*pi/16)) */
#define SBC_COS_7PI_SUR_16 (0x000018f8) /* ((0x8000) * 0.1951)) = (cos(7*pi/16)) */
#define SBC_IDCT_MULT(a,b,c) SBC_MULT_32_16_SIMPLIFIED(a,b,c)
#else
#define SBC_COS_PI_SUR_4 (0x5A827999) /* ((0x80000000) * 0.707106781) = (cos(pi/4) ) */
#define SBC_COS_PI_SUR_8 (0x7641AF3C) /* ((0x80000000) * 0.923879533) = (cos(pi/8) ) */
#define SBC_COS_3PI_SUR_8 (0x30FBC54D) /* ((0x80000000) * 0.382683432) = (cos(3*pi/8) ) */
#define SBC_COS_PI_SUR_16 (0x7D8A5F3F) /* ((0x80000000) * 0.98078528 )) = (cos(pi/16) ) */
#define SBC_COS_3PI_SUR_16 (0x6A6D98A4) /* ((0x80000000) * 0.831469612)) = (cos(3*pi/16)) */
#define SBC_COS_5PI_SUR_16 (0x471CECE6) /* ((0x80000000) * 0.555570233)) = (cos(5*pi/16)) */
#define SBC_COS_7PI_SUR_16 (0x18F8B83C) /* ((0x80000000) * 0.195090322)) = (cos(7*pi/16)) */
#define SBC_IDCT_MULT(a,b,c) SBC_MULT_32_32(a,b,c)
#endif /* SBC_IS_64_MULT_IN_IDCT */
#if (SBC_FAST_DCT == FALSE)
extern const SINT16 gas16AnalDCTcoeff8[];
extern const SINT16 gas16AnalDCTcoeff4[];
#endif
void __attribute__((section("ram_em"))) SBC_FastIDCT8(SINT32 *pInVect, SINT32 *pOutVect)
{
#if (SBC_FAST_DCT == TRUE)
#if (SBC_ARM_ASM_OPT==TRUE)
#else
#if (SBC_IPAQ_OPT==TRUE)
#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
SINT64 s64Temp;
#endif
#else
#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
SINT32 s32HiTemp;
#else
SINT32 s32In2Temp;
register SINT32 s32In1Temp;
#endif
#endif
#endif
register SINT32 x0, x1, x2, x3, x4, x5, x6, x7,temp;
SINT32 res_even[4], res_odd[4];
SBC_IDCT_MULT(SBC_COS_PI_SUR_4,pInVect[4], x0);
x1 = (pInVect[3] + pInVect[5]) >>1;
x2 = (pInVect[2] + pInVect[6]) >>1;
x3 = (pInVect[1] + pInVect[7]) >>1;
x4 = (pInVect[0] + pInVect[8]) >>1;
x5 = (pInVect[9] - pInVect[15]) >>1;
x6 = (pInVect[10] - pInVect[14])>>1;
x7 = (pInVect[11] - pInVect[13])>>1;
/* 2-point IDCT of x0 and x4 as in (11) */
temp = x0 ;
SBC_IDCT_MULT(SBC_COS_PI_SUR_4, ( x0 + x4 ), x0); /*x0 = ( x0 + x4 ) * cos(1*pi/4) ; */
SBC_IDCT_MULT(SBC_COS_PI_SUR_4, ( temp - x4 ), x4); /*x4 = ( temp - x4 ) * cos(1*pi/4) ; */
/* rearrangement of x2 and x6 as in (15) */
x2 -=x6;
x6 <<= 1 ;
/* 2-point IDCT of x2 and x6 and post-multiplication as in (15) */
SBC_IDCT_MULT(SBC_COS_PI_SUR_4,x6, x6); /*x6 = x6 * cos(1*pi/4) ; */
temp = x2 ;
SBC_IDCT_MULT(SBC_COS_PI_SUR_8,( x2 + x6 ), x2); /*x2 = ( x2 + x6 ) * cos(1*pi/8) ; */
SBC_IDCT_MULT(SBC_COS_3PI_SUR_8,( temp - x6 ), x6); /*x6 = ( temp - x6 ) * cos(3*pi/8) ;*/
/* 4-point IDCT of x0,x2,x4 and x6 as in (11) */
res_even[ 0 ] = x0 + x2 ;
res_even[ 1 ] = x4 + x6 ;
res_even[ 2 ] = x4 - x6 ;
res_even[ 3 ] = x0 - x2 ;
/* rearrangement of x1,x3,x5,x7 as in (15) */
x7 <<= 1 ;
x5 = ( x5 <<1 ) - x7 ;
x3 = ( x3 <<1 ) - x5 ;
x1 -= x3 >>1 ;
/* two-dimensional IDCT of x1 and x5 */
SBC_IDCT_MULT(SBC_COS_PI_SUR_4, x5, x5); /*x5 = x5 * cos(1*pi/4) ; */
temp = x1 ;
x1 = x1 + x5 ;
x5 = temp - x5 ;
/* rearrangement of x3 and x7 as in (15) */
x3 -= x7;
x7 <<= 1 ;
SBC_IDCT_MULT(SBC_COS_PI_SUR_4, x7, x7); /*x7 = x7 * cos(1*pi/4) ; */
/* 2-point IDCT of x3 and x7 and post-multiplication as in (15) */
temp = x3 ;
SBC_IDCT_MULT( SBC_COS_PI_SUR_8,( x3 + x7 ), x3); /*x3 = ( x3 + x7 ) * cos(1*pi/8) ; */
SBC_IDCT_MULT( SBC_COS_3PI_SUR_8,( temp - x7 ), x7); /*x7 = ( temp - x7 ) * cos(3*pi/8) ;*/
/* 4-point IDCT of x1,x3,x5 and x7 and post multiplication by diagonal matrix as in (14) */
SBC_IDCT_MULT((SBC_COS_PI_SUR_16), ( x1 + x3 ) , res_odd[0]); /*res_odd[ 0 ] = ( x1 + x3 ) * cos(1*pi/16) ; */
SBC_IDCT_MULT((SBC_COS_3PI_SUR_16), ( x5 + x7 ) , res_odd[1]); /*res_odd[ 1 ] = ( x5 + x7 ) * cos(3*pi/16) ; */
SBC_IDCT_MULT((SBC_COS_5PI_SUR_16), ( x5 - x7 ) , res_odd[2]); /*res_odd[ 2 ] = ( x5 - x7 ) * cos(5*pi/16) ; */
SBC_IDCT_MULT((SBC_COS_7PI_SUR_16), ( x1 - x3 ) , res_odd[3]); /*res_odd[ 3 ] = ( x1 - x3 ) * cos(7*pi/16) ; */
/* additions and subtractions as in (9) */
pOutVect[0] = (res_even[ 0 ] + res_odd[ 0 ]) ;
pOutVect[1] = (res_even[ 1 ] + res_odd[ 1 ]) ;
pOutVect[2] = (res_even[ 2 ] + res_odd[ 2 ]) ;
pOutVect[3] = (res_even[ 3 ] + res_odd[ 3 ]) ;
pOutVect[7] = (res_even[ 0 ] - res_odd[ 0 ]) ;
pOutVect[6] = (res_even[ 1 ] - res_odd[ 1 ]) ;
pOutVect[5] = (res_even[ 2 ] - res_odd[ 2 ]) ;
pOutVect[4] = (res_even[ 3 ] - res_odd[ 3 ]) ;
#else
UINT8 Index, k;
SINT32 temp;
/*Calculate 4 subband samples by matrixing*/
for(Index=0; Index<8; Index++)
{
temp = 0;
for(k=0; k<16; k++)
{
/*temp += (SINT32)(((SINT64)M[(Index*strEncParams->numOfSubBands*2)+k] * Y[k]) >> 16 );*/
temp += (gas16AnalDCTcoeff8[(Index*8*2)+k] * (pInVect[k] >> 16));
temp += ((gas16AnalDCTcoeff8[(Index*8*2)+k] * (pInVect[k] & 0xFFFF)) >> 16);
}
pOutVect[Index] = temp;
}
#endif
}
/*******************************************************************************
**
** Function SBC_FastIDCT4
**
** Description implementation of fast DCT algorithm by Feig and Winograd
**
**
** Returns y = dct(x0)
**
**
*******************************************************************************/
void __attribute__((section("ram_em"))) SBC_FastIDCT4(SINT32 *pInVect, SINT32 *pOutVect)
{
#if (SBC_FAST_DCT == TRUE)
#if (SBC_ARM_ASM_OPT==TRUE)
#else
#if (SBC_IPAQ_OPT==TRUE)
#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
SINT64 s64Temp;
#endif
#else
#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
SINT32 s32HiTemp;
#else
UINT16 s32In2Temp;
SINT32 s32In1Temp;
#endif
#endif
#endif
SINT32 temp,x2;
SINT32 tmp[8];
x2=pInVect[2]>>1;
temp=(pInVect[0]+pInVect[4]);
SBC_IDCT_MULT((SBC_COS_PI_SUR_4>>1), temp , tmp[0]);
tmp[1]=x2-tmp[0];
tmp[0]+=x2;
temp=(pInVect[1]+pInVect[3]);
SBC_IDCT_MULT((SBC_COS_3PI_SUR_8>>1), temp , tmp[3]);
SBC_IDCT_MULT((SBC_COS_PI_SUR_8>>1), temp , tmp[2]);
temp=(pInVect[5]-pInVect[7]);
SBC_IDCT_MULT((SBC_COS_3PI_SUR_8>>1), temp , tmp[5]);
SBC_IDCT_MULT((SBC_COS_PI_SUR_8>>1), temp , tmp[4]);
tmp[6]=tmp[2]+tmp[5];
tmp[7]=tmp[3]-tmp[4];
pOutVect[0] = (tmp[0]+tmp[6]);
pOutVect[1] = (tmp[1]+tmp[7]);
pOutVect[2] = (tmp[1]-tmp[7]);
pOutVect[3] = (tmp[0]-tmp[6]);
#else
UINT8 Index, k;
SINT32 temp;
/*Calculate 4 subband samples by matrixing*/
for(Index=0; Index<4; Index++)
{
temp = 0;
for(k=0; k<8; k++)
{
/*temp += (SINT32)(((SINT64)M[(Index*strEncParams->numOfSubBands*2)+k] * Y[k]) >> 16 ); */
temp += (gas16AnalDCTcoeff4[(Index*4*2)+k] * (pInVect[k] >> 16));
temp += ((gas16AnalDCTcoeff4[(Index*4*2)+k] * (pInVect[k] & 0xFFFF)) >> 16);
}
pOutVect[Index] = temp;
}
#endif
}
+200
View File
@@ -0,0 +1,200 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This file contains the coefficient table used for DCT computation in
* analysis.
*
******************************************************************************/
#include "sbc_encoder.h"
/*DCT coeff for 4 sub-band case.*/
#if (SBC_FAST_DCT == FALSE)
const SINT16 gas16AnalDCTcoeff4[] =
{
(SINT16)(0.7071*32768),
(SINT16)(0.9239*32768),
(SINT16)(1.0000*32767),
(SINT16)(0.9239*32768),
(SINT16)(0.7071*32768),
(SINT16)(0.3827*32768),
(SINT16)(0.0000*32768),
(SINT16)(-0.3827*32768),
(SINT16)(-0.7071*32768),
(SINT16)(0.3827*32768),
(SINT16)(1.0000*32767),
(SINT16)(0.3827*32768),
(SINT16)(-0.7071*32768),
(SINT16)(-0.9239*32768),
(SINT16)(-0.0000*32768),
(SINT16)(0.9239*32768),
(SINT16)(-0.7071*32768),
(SINT16)(-0.3827*32768),
(SINT16)(1.0000*32767),
(SINT16)(-0.3827*32768),
(SINT16)(-0.7071*32768),
(SINT16)(0.9239*32768),
(SINT16)(0.0000*32768),
(SINT16)(-0.9239*32768),
(SINT16)(0.7071*32768),
(SINT16)(-0.9239*32768),
(SINT16)(1.0000*32767),
(SINT16)(-0.9239*32768),
(SINT16)(0.7071*32768),
(SINT16)(-0.3827*32768),
(SINT16)(-0.0000*32768),
(SINT16)(0.3827*32768)
};
/*DCT coeff for 8 sub-band case.*/
const SINT16 gas16AnalDCTcoeff8[] =
{
(SINT16)(0.7071*32768),
(SINT16)(0.8315*32768),
(SINT16)(0.9239*32768),
(SINT16)(0.9808*32768),
(SINT16)(1.0000*32767),
(SINT16)(0.9808*32768),
(SINT16)(0.9239*32768),
(SINT16)(0.8315*32768),
(SINT16)(0.7071*32768),
(SINT16)(0.5556*32768),
(SINT16)(0.3827*32768),
(SINT16)(0.1951*32768),
(SINT16)(0.0000*32768),
(SINT16)(-0.1951*32768),
(SINT16)(-0.3827*32768),
(SINT16)(-0.5556*32768),
(SINT16)(-0.7071*32768),
(SINT16)(-0.1951*32768),
(SINT16)(0.3827*32768),
(SINT16)(0.8315*32768),
(SINT16)(1.0000*32767),
(SINT16)(0.8315*32768),
(SINT16)(0.3827*32768),
(SINT16)(-0.1951*32768),
(SINT16)(-0.7071*32768),
(SINT16)(-0.9808*32768),
(SINT16)(-0.9239*32768),
(SINT16)(-0.5556*32768),
(SINT16)(-0.0000*32768),
(SINT16)(0.5556*32768),
(SINT16)(0.9239*32768),
(SINT16)(0.9808*32768),
(SINT16)(-0.7071*32768),
(SINT16)(-0.9808*32768),
(SINT16)(-0.3827*32768),
(SINT16)(0.5556*32768),
(SINT16)(1.0000*32767),
(SINT16)(0.5556*32768),
(SINT16)(-0.3827*32768),
(SINT16)(-0.9808*32768),
(SINT16)(-0.7071*32768),
(SINT16)(0.1951*32768),
(SINT16)(0.9239*32768),
(SINT16)(0.8315*32768),
(SINT16)(0.0000*32768),
(SINT16)(-0.8315*32768),
(SINT16)(-0.9239*32768),
(SINT16)(-0.1951*32768),
(SINT16)(0.7071*32768),
(SINT16)(-0.5556*32768),
(SINT16)(-0.9239*32768),
(SINT16)(0.1951*32768),
(SINT16)(1.0000*32767),
(SINT16)(0.1951*32768),
(SINT16)(-0.9239*32768),
(SINT16)(-0.5556*32768),
(SINT16)(0.7071*32768),
(SINT16)(0.8315*32768),
(SINT16)(-0.3827*32768),
(SINT16)(-0.9808*32768),
(SINT16)(-0.0000*32768),
(SINT16)(0.9808*32768),
(SINT16)(0.3827*32768),
(SINT16)(-0.8315*32768),
(SINT16)(0.7071*32768),
(SINT16)(0.5556*32768),
(SINT16)(-0.9239*32768),
(SINT16)(-0.1951*32768),
(SINT16)(1.0000*32767),
(SINT16)(-0.1951*32768),
(SINT16)(-0.9239*32768),
(SINT16)(0.5556*32768),
(SINT16)(0.7071*32768),
(SINT16)(-0.8315*32768),
(SINT16)(-0.3827*32768),
(SINT16)(0.9808*32768),
(SINT16)(0.0000*32768),
(SINT16)(-0.9808*32768),
(SINT16)(0.3827*32768),
(SINT16)(0.8315*32768),
(SINT16)(-0.7071*32768),
(SINT16)(0.9808*32768),
(SINT16)(-0.3827*32768),
(SINT16)(-0.5556*32768),
(SINT16)(1.0000*32767),
(SINT16)(-0.5556*32768),
(SINT16)(-0.3827*32768),
(SINT16)(0.9808*32768),
(SINT16)(-0.7071*32768),
(SINT16)(-0.1951*32768),
(SINT16)(0.9239*32768),
(SINT16)(-0.8315*32768),
(SINT16)(-0.0000*32768),
(SINT16)(0.8315*32768),
(SINT16)(-0.9239*32768),
(SINT16)(0.1951*32768),
(SINT16)(-0.7071*32768),
(SINT16)(0.1951*32768),
(SINT16)(0.3827*32768),
(SINT16)(-0.8315*32768),
(SINT16)(1.0000*32767),
(SINT16)(-0.8315*32768),
(SINT16)(0.3827*32768),
(SINT16)(0.1951*32768),
(SINT16)(-0.7071*32768),
(SINT16)(0.9808*32768),
(SINT16)(-0.9239*32768),
(SINT16)(0.5556*32768),
(SINT16)(-0.0000*32768),
(SINT16)(-0.5556*32768),
(SINT16)(0.9239*32768),
(SINT16)(-0.9808*32768),
(SINT16)(0.7071*32768),
(SINT16)(-0.8315*32768),
(SINT16)(0.9239*32768),
(SINT16)(-0.9808*32768),
(SINT16)(1.0000*32767),
(SINT16)(-0.9808*32768),
(SINT16)(0.9239*32768),
(SINT16)(-0.8315*32768),
(SINT16)(0.7071*32768),
(SINT16)(-0.5556*32768),
(SINT16)(0.3827*32768),
(SINT16)(-0.1951*32768),
(SINT16)(-0.0000*32768),
(SINT16)(0.1951*32768),
(SINT16)(-0.3827*32768),
(SINT16)(0.5556*32768)
};
#endif
@@ -0,0 +1,200 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This file contains the code for bit allocation algorithm. It calculates
* the number of bits required for the encoded stream of data.
*
******************************************************************************/
/*Includes*/
#include "sbc_encoder.h"
#include "sbc_enc_func_declare.h"
#include "xc60xx.h"
/*global arrays*/
const SINT16 sbc_enc_as16Offset4[4][4] = { {-1, 0, 0, 0}, {-2, 0, 0, 1},
{-2, 0, 0, 1}, {-2, 0, 0, 1} };
const SINT16 sbc_enc_as16Offset8[4][8] = { {-2, 0, 0, 0, 0, 0, 0, 1},
{-3, 0, 0, 0, 0, 0, 1, 2},
{-4, 0, 0, 0, 0, 0, 1, 2},
{-4, 0, 0, 0, 0, 0, 1, 2} };
/****************************************************************************
* BitAlloc - Calculates the required number of bits for the given scale factor
* and the number of subbands.
*
* RETURNS : N/A
*/
void __attribute__((section("ram_em"))) sbc_enc_bit_alloc_mono(SBC_ENC_PARAMS *pstrCodecParams)
{
SINT32 s32MaxBitNeed; /*to store the max bits needed per sb*/
SINT32 s32BitCount; /*the used number of bits*/
SINT32 s32SliceCount; /*to store hwo many slices can be put in bitpool*/
SINT32 s32BitSlice; /*number of bitslices in bitpool*/
SINT32 s32Sb; /*counter for sub-band*/
SINT32 s32Ch; /*counter for channel*/
SINT16 *ps16BitNeed; /*temp memory to store required number of bits*/
SINT32 s32Loudness; /*used in Loudness calculation*/
SINT16 *ps16GenBufPtr;
SINT16 *ps16GenArrPtr;
SINT16 *ps16GenTabPtr;
SINT32 s32NumOfSubBands = pstrCodecParams->s16NumOfSubBands;
ps16BitNeed = pstrCodecParams->s16ScartchMemForBitAlloc;
for (s32Ch = 0; s32Ch < pstrCodecParams->s16NumOfChannels; s32Ch++)
{
ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
ps16GenArrPtr = pstrCodecParams->as16Bits+(s32Ch*SBC_MAX_NUM_OF_SUBBANDS);
/* bitneed values are derived from scale factor */
if (pstrCodecParams->s16AllocationMethod == SBC_SNR)
{
ps16BitNeed = pstrCodecParams->as16ScaleFactor;
ps16GenBufPtr = ps16BitNeed + (s32Ch * s32NumOfSubBands);
}
else
{
ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
if(s32NumOfSubBands == 4)
{
ps16GenTabPtr = (SINT16 *)
sbc_enc_as16Offset4[pstrCodecParams->s16SamplingFreq];
}
else
{
ps16GenTabPtr = (SINT16 *)
sbc_enc_as16Offset8[pstrCodecParams->s16SamplingFreq];
}
for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
{
if(pstrCodecParams->as16ScaleFactor[(s32Ch*s32NumOfSubBands)+s32Sb] == 0)
*(ps16GenBufPtr) = -5;
else
{
s32Loudness =
(SINT32)(pstrCodecParams->as16ScaleFactor[(s32Ch*s32NumOfSubBands)+s32Sb]
- *ps16GenTabPtr);
if(s32Loudness > 0)
*(ps16GenBufPtr) = (SINT16)(s32Loudness >>1);
else
*(ps16GenBufPtr) = (SINT16)s32Loudness;
}
ps16GenBufPtr++;
ps16GenTabPtr++;
}
}
/* max bitneed index is searched*/
s32MaxBitNeed = 0;
ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
{
if( *(ps16GenBufPtr) > s32MaxBitNeed)
s32MaxBitNeed = *(ps16GenBufPtr);
ps16GenBufPtr++;
}
ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
/*iterative process to find hwo many bitslices fit into the bitpool*/
s32BitSlice = s32MaxBitNeed + 1;
s32BitCount = pstrCodecParams->s16BitPool;
s32SliceCount = 0;
do
{
s32BitSlice --;
s32BitCount -= s32SliceCount;
s32SliceCount = 0;
for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
{
if( (((*ps16GenBufPtr-s32BitSlice)< 16) && ((*ps16GenBufPtr-s32BitSlice) >= 1)))
{
if((*ps16GenBufPtr-s32BitSlice) == 1)
s32SliceCount+=2;
else
s32SliceCount++;
}
ps16GenBufPtr++;
}/*end of for*/
ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
}while((s32BitCount-s32SliceCount)>0);
if(s32BitCount == 0)
{
s32BitCount -= s32SliceCount;
s32BitSlice --;
}
/*Bits are distributed until the last bitslice is reached*/
ps16GenArrPtr = pstrCodecParams->as16Bits+(s32Ch*s32NumOfSubBands);
ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
{
if(*(ps16GenBufPtr) < (s32BitSlice+2))
*(ps16GenArrPtr) = 0;
else
*(ps16GenArrPtr) = ((*(ps16GenBufPtr)-s32BitSlice)<16) ?
(SINT16)(*(ps16GenBufPtr)-s32BitSlice) : 16;
ps16GenBufPtr++;
ps16GenArrPtr++;
}
ps16GenArrPtr = pstrCodecParams->as16Bits+(s32Ch*s32NumOfSubBands);
ps16GenBufPtr = ps16BitNeed + (s32Ch*s32NumOfSubBands);
/*the remaining bits are allocated starting at subband 0*/
s32Sb=0;
while( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) )
{
if( (*(ps16GenArrPtr) >= 2) && (*(ps16GenArrPtr) < 16) )
{
(*(ps16GenArrPtr))++;
s32BitCount--;
}
else if( (*(ps16GenBufPtr) == (s32BitSlice+1)) &&
(s32BitCount > 1) )
{
*(ps16GenArrPtr) = 2;
s32BitCount -= 2;
}
s32Sb++;
ps16GenArrPtr++;
ps16GenBufPtr++;
}
ps16GenArrPtr = pstrCodecParams->as16Bits+(s32Ch*s32NumOfSubBands);
s32Sb=0;
while( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) )
{
if( *(ps16GenArrPtr) < 16)
{
(*(ps16GenArrPtr))++;
s32BitCount--;
}
s32Sb++;
ps16GenArrPtr++;
}
}
}
/*End of BitAlloc() function*/
@@ -0,0 +1,213 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This file contains the code for bit allocation algorithm. It calculates
* the number of bits required for the encoded stream of data.
*
******************************************************************************/
/*Includes*/
#include "sbc_encoder.h"
#include "sbc_enc_func_declare.h"
#include "xc60xx.h"
/*global arrays*/
extern const SINT16 sbc_enc_as16Offset4[4][4];
extern const SINT16 sbc_enc_as16Offset8[4][8];
/****************************************************************************
* BitAlloc - Calculates the required number of bits for the given scale factor
* and the number of subbands.
*
* RETURNS : N/A
*/
void /*__attribute__((section("ram_em")))*/ sbc_enc_bit_alloc_ste(SBC_ENC_PARAMS *pstrCodecParams)
{
/* CAUTIOM -> mips optim for arm 32 require to use SINT32 instead of SINT16 */
/* Do not change variable type or name */
SINT32 s32MaxBitNeed; /*to store the max bits needed per sb*/
SINT32 s32BitCount; /*the used number of bits*/
SINT32 s32SliceCount; /*to store hwo many slices can be put in bitpool*/
SINT32 s32BitSlice; /*number of bitslices in bitpool*/
SINT32 s32Sb; /*counter for sub-band*/
SINT32 s32Ch; /*counter for channel*/
SINT16 *ps16BitNeed; /*temp memory to store required number of bits*/
SINT32 s32Loudness; /*used in Loudness calculation*/
SINT16 *ps16GenBufPtr,*pas16ScaleFactor;
SINT16 *ps16GenArrPtr;
SINT16 *ps16GenTabPtr;
SINT32 s32NumOfSubBands = pstrCodecParams->s16NumOfSubBands;
SINT32 s32BitPool = pstrCodecParams->s16BitPool;
/* bitneed values are derived from scale factor */
if (pstrCodecParams->s16AllocationMethod == SBC_SNR)
{
ps16BitNeed = pstrCodecParams->as16ScaleFactor;
s32MaxBitNeed = pstrCodecParams->s16MaxBitNeed;
}
else
{
ps16BitNeed = pstrCodecParams->s16ScartchMemForBitAlloc;
pas16ScaleFactor=pstrCodecParams->as16ScaleFactor;
s32MaxBitNeed = 0;
ps16GenBufPtr = ps16BitNeed;
for (s32Ch = 0; s32Ch < 2; s32Ch++)
{
if (s32NumOfSubBands == 4)
{
ps16GenTabPtr = (SINT16 *)sbc_enc_as16Offset4[pstrCodecParams->s16SamplingFreq];
}
else
{
ps16GenTabPtr = (SINT16 *)sbc_enc_as16Offset8[pstrCodecParams->s16SamplingFreq];
}
for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++)
{
if (*pas16ScaleFactor == 0)
*ps16GenBufPtr = -5;
else
{
s32Loudness = (SINT32)(*pas16ScaleFactor - *ps16GenTabPtr);
if (s32Loudness > 0)
*ps16GenBufPtr = (SINT16)(s32Loudness >> 1);
else
*ps16GenBufPtr = (SINT16)s32Loudness;
}
if (*ps16GenBufPtr > s32MaxBitNeed)
s32MaxBitNeed = *ps16GenBufPtr;
pas16ScaleFactor++;
ps16GenBufPtr++;
ps16GenTabPtr++;
}
}
}
/* iterative process to find out hwo many bitslices fit into the bitpool */
s32BitSlice = s32MaxBitNeed + 1;
s32BitCount = s32BitPool;
s32SliceCount = 0;
do
{
s32BitSlice --;
s32BitCount -= s32SliceCount;
s32SliceCount = 0;
ps16GenBufPtr = ps16BitNeed;
for (s32Sb = 0; s32Sb < (2*s32NumOfSubBands); s32Sb++)
{
if ( (*ps16GenBufPtr >= (s32BitSlice + 1)) && (*ps16GenBufPtr < (s32BitSlice + 16)) )
{
if (*(ps16GenBufPtr) == (s32BitSlice+1))
s32SliceCount += 2;
else
s32SliceCount++;
}
ps16GenBufPtr++;
}
} while ((s32BitCount-s32SliceCount)>0);
if ((s32BitCount-s32SliceCount) == 0)
{
s32BitCount -= s32SliceCount;
s32BitSlice --;
}
/* Bits are distributed until the last bitslice is reached */
ps16GenBufPtr = ps16BitNeed;
ps16GenArrPtr = pstrCodecParams->as16Bits;
for (s32Ch = 0; s32Ch < 2; s32Ch++)
{
for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++)
{
if (*ps16GenBufPtr < (s32BitSlice+2))
*ps16GenArrPtr = 0;
else
*ps16GenArrPtr = ((*(ps16GenBufPtr)-s32BitSlice) < 16) ?
(SINT16)(*(ps16GenBufPtr)-s32BitSlice):16;
ps16GenBufPtr++;
ps16GenArrPtr++;
}
}
/* the remaining bits are allocated starting at subband 0 */
s32Ch=0;
s32Sb=0;
ps16GenBufPtr = ps16BitNeed;
ps16GenArrPtr -= 2*s32NumOfSubBands;
while ( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) )
{
if ( (*(ps16GenArrPtr) >= 2) && (*(ps16GenArrPtr) < 16) )
{
(*(ps16GenArrPtr))++;
s32BitCount--;
}
else if ((*ps16GenBufPtr == (s32BitSlice+1)) && (s32BitCount > 1))
{
*(ps16GenArrPtr) = 2;
s32BitCount -= 2;
}
if(s32Ch == 1)
{
s32Ch = 0;
s32Sb++;
ps16GenBufPtr = ps16BitNeed+s32Sb;
ps16GenArrPtr = pstrCodecParams->as16Bits+s32Sb;
}
else
{
s32Ch =1;
ps16GenBufPtr = ps16BitNeed+s32NumOfSubBands+s32Sb;
ps16GenArrPtr = pstrCodecParams->as16Bits+s32NumOfSubBands+s32Sb;
}
}
s32Ch=0;
s32Sb=0;
ps16GenArrPtr = pstrCodecParams->as16Bits;
while ((s32BitCount >0) && (s32Sb < s32NumOfSubBands))
{
if(*(ps16GenArrPtr) < 16)
{
(*(ps16GenArrPtr))++;
s32BitCount--;
}
if (s32Ch == 1)
{
s32Ch = 0;
s32Sb++;
ps16GenArrPtr = pstrCodecParams->as16Bits+s32Sb;
}
else
{
s32Ch = 1;
ps16GenArrPtr = pstrCodecParams->as16Bits+s32NumOfSubBands+s32Sb;
}
}
}
/*End of BitAlloc() function*/
+319
View File
@@ -0,0 +1,319 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This file contains the Windowing coeffs for synthesis filter
*
******************************************************************************/
#include "sbc_encoder.h"
#if (SBC_ARM_ASM_OPT==FALSE && SBC_IPAQ_OPT==FALSE)
#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == FALSE)
/*Window coeff for 4 sub band case*/
const SINT16 gas32CoeffFor4SBs[] =
{
(SINT16)((SINT32)0x00000000 >> 16), (SINT16)0x00000000,
(SINT16)((SINT32)0x001194E6 >> 16), (SINT16)0x001194E6,
(SINT16)((SINT32)0x0030E2D3 >> 16), (SINT16)0x0030E2D3,
(SINT16)((SINT32)0x00599403 >> 16), (SINT16)0x00599403,
(SINT16)((SINT32)0x007DBCC8 >> 16), (SINT16)0x007DBCC8,
(SINT16)((SINT32)0x007F88E4 >> 16), (SINT16)0x007F88E4,
(SINT16)((SINT32)0x003D239B >> 16), (SINT16)0x003D239B,
(SINT16)((SINT32)0xFF9BB9D5 >> 16), (SINT16)0xFF9BB9D5,
(SINT16)((SINT32)0x01659F45 >> 16), (SINT16)0x01659F45,
(SINT16)((SINT32)0x029DBAA3 >> 16), (SINT16)0x029DBAA3,
(SINT16)((SINT32)0x03B23341 >> 16), (SINT16)0x03B23341,
(SINT16)((SINT32)0x041EEE40 >> 16), (SINT16)0x041EEE40,
(SINT16)((SINT32)0x034FEE2C >> 16), (SINT16)0x034FEE2C,
(SINT16)((SINT32)0x00C8F2BC >> 16), (SINT16)0x00C8F2BC,
(SINT16)((SINT32)0xFC4F91D4 >> 16), (SINT16)0xFC4F91D4,
(SINT16)((SINT32)0xF60FAF37 >> 16), (SINT16)0xF60FAF37,
(SINT16)((SINT32)0x115B1ED2 >> 16), (SINT16)0x115B1ED2,
(SINT16)((SINT32)0x18F55C90 >> 16), (SINT16)0x18F55C90,
(SINT16)((SINT32)0x1F91CA46 >> 16), (SINT16)0x1F91CA46,
(SINT16)((SINT32)0x2412F251 >> 16), (SINT16)0x2412F251,
(SINT16)((SINT32)0x25AC1FF2 >> 16), (SINT16)0x25AC1FF2,
(SINT16)((SINT32)0x2412F251 >> 16), (SINT16)0x2412F251,
(SINT16)((SINT32)0x1F91CA46 >> 16), (SINT16)0x1F91CA46,
(SINT16)((SINT32)0x18F55C90 >> 16), (SINT16)0x18F55C90,
(SINT16)((SINT32)0xEEA4E12E >> 16), (SINT16)0xEEA4E12E,
(SINT16)((SINT32)0xF60FAF37 >> 16), (SINT16)0xF60FAF37,
(SINT16)((SINT32)0xFC4F91D4 >> 16), (SINT16)0xFC4F91D4,
(SINT16)((SINT32)0x00C8F2BC >> 16), (SINT16)0x00C8F2BC,
(SINT16)((SINT32)0x034FEE2C >> 16), (SINT16)0x034FEE2C,
(SINT16)((SINT32)0x041EEE40 >> 16), (SINT16)0x041EEE40,
(SINT16)((SINT32)0x03B23341 >> 16), (SINT16)0x03B23341,
(SINT16)((SINT32)0x029DBAA3 >> 16), (SINT16)0x029DBAA3,
(SINT16)((SINT32)0xFE9A60BB >> 16), (SINT16)0xFE9A60BB,
(SINT16)((SINT32)0xFF9BB9D5 >> 16), (SINT16)0xFF9BB9D5,
(SINT16)((SINT32)0x003D239B >> 16), (SINT16)0x003D239B,
(SINT16)((SINT32)0x007F88E4 >> 16), (SINT16)0x007F88E4,
(SINT16)((SINT32)0x007DBCC8 >> 16), (SINT16)0x007DBCC8,
(SINT16)((SINT32)0x00599403 >> 16), (SINT16)0x00599403,
(SINT16)((SINT32)0x0030E2D3 >> 16), (SINT16)0x0030E2D3,
(SINT16)((SINT32)0x001194E6 >> 16), (SINT16)0x001194E6
};
/*Window coeff for 8 sub band case*/
const SINT16 gas32CoeffFor8SBs[] =
{
(SINT16)((SINT32)0x00000000 >>16), (SINT16)0x00000000,
(SINT16)((SINT32)0x00052173 >>16), (SINT16)0x00052173,
(SINT16)((SINT32)0x000B3F71 >>16), (SINT16)0x000B3F71,
(SINT16)((SINT32)0x00122C7D >>16), (SINT16)0x00122C7D,
(SINT16)((SINT32)0x001AFF89 >>16), (SINT16)0x001AFF89,
(SINT16)((SINT32)0x00255A62 >>16), (SINT16)0x00255A62,
(SINT16)((SINT32)0x003060F4 >>16), (SINT16)0x003060F4,
(SINT16)((SINT32)0x003A72E7 >>16), (SINT16)0x003A72E7,
(SINT16)((SINT32)0x0041EC6A >>16), (SINT16)0x0041EC6A, /* 8 */
(SINT16)((SINT32)0x0044EF48 >>16), (SINT16)0x0044EF48,
(SINT16)((SINT32)0x00415B75 >>16), (SINT16)0x00415B75,
(SINT16)((SINT32)0x0034F8B6 >>16), (SINT16)0x0034F8B6,
(SINT16)((SINT32)0x001D8FD2 >>16), (SINT16)0x001D8FD2,
(SINT16)((SINT32)0xFFFA2413 >>16), (SINT16)0xFFFA2413,
(SINT16)((SINT32)0xFFC9F10E >>16), (SINT16)0xFFC9F10E,
(SINT16)((SINT32)0xFF8D6793 >>16), (SINT16)0xFF8D6793,
(SINT16)((SINT32)0x00B97348 >>16), (SINT16)0x00B97348, /* 16 */
(SINT16)((SINT32)0x01071B96 >>16), (SINT16)0x01071B96,
(SINT16)((SINT32)0x0156B3CA >>16), (SINT16)0x0156B3CA,
(SINT16)((SINT32)0x01A1B38B >>16), (SINT16)0x01A1B38B,
(SINT16)((SINT32)0x01E0224C >>16), (SINT16)0x01E0224C,
(SINT16)((SINT32)0x0209291F >>16), (SINT16)0x0209291F,
(SINT16)((SINT32)0x02138653 >>16), (SINT16)0x02138653,
(SINT16)((SINT32)0x01F5F424 >>16), (SINT16)0x01F5F424,
(SINT16)((SINT32)0x01A7ECEF >>16), (SINT16)0x01A7ECEF, /* 24 */
(SINT16)((SINT32)0x01223EBA >>16), (SINT16)0x01223EBA,
(SINT16)((SINT32)0x005FD0FF >>16), (SINT16)0x005FD0FF,
(SINT16)((SINT32)0xFF5EEB73 >>16), (SINT16)0xFF5EEB73,
(SINT16)((SINT32)0xFE20435D >>16), (SINT16)0xFE20435D,
(SINT16)((SINT32)0xFCA86E7E >>16), (SINT16)0xFCA86E7E,
(SINT16)((SINT32)0xFAFF95FC >>16), (SINT16)0xFAFF95FC,
(SINT16)((SINT32)0xF9312891 >>16), (SINT16)0xF9312891,
(SINT16)((SINT32)0x08B4307A >>16), (SINT16)0x08B4307A, /* 32 */
(SINT16)((SINT32)0x0A9F3E9A >>16), (SINT16)0x0A9F3E9A,
(SINT16)((SINT32)0x0C7D59B6 >>16), (SINT16)0x0C7D59B6,
(SINT16)((SINT32)0x0E3BB16F >>16), (SINT16)0x0E3BB16F,
(SINT16)((SINT32)0x0FC721F9 >>16), (SINT16)0x0FC721F9,
(SINT16)((SINT32)0x110ECEF0 >>16), (SINT16)0x110ECEF0,
(SINT16)((SINT32)0x120435FA >>16), (SINT16)0x120435FA,
(SINT16)((SINT32)0x129C226F >>16), (SINT16)0x129C226F,
(SINT16)((SINT32)0x12CF6C75 >>16), (SINT16)0x12CF6C75, /* 40 */
(SINT16)((SINT32)0x129C226F >>16), (SINT16)0x129C226F,
(SINT16)((SINT32)0x120435FA >>16), (SINT16)0x120435FA,
(SINT16)((SINT32)0x110ECEF0 >>16), (SINT16)0x110ECEF0,
(SINT16)((SINT32)0x0FC721F9 >>16), (SINT16)0x0FC721F9,
(SINT16)((SINT32)0x0E3BB16F >>16), (SINT16)0x0E3BB16F,
(SINT16)((SINT32)0x0C7D59B6 >>16), (SINT16)0x0C7D59B6,
(SINT16)((SINT32)0x0A9F3E9A >>16), (SINT16)0x0A9F3E9A,
(SINT16)((SINT32)0xF74BCF86 >>16), (SINT16)0xF74BCF86, /* 48 */
(SINT16)((SINT32)0xF9312891 >>16), (SINT16)0xF9312891,
(SINT16)((SINT32)0xFAFF95FC >>16), (SINT16)0xFAFF95FC,
(SINT16)((SINT32)0xFCA86E7E >>16), (SINT16)0xFCA86E7E,
(SINT16)((SINT32)0xFE20435D >>16), (SINT16)0xFE20435D,
(SINT16)((SINT32)0xFF5EEB73 >>16), (SINT16)0xFF5EEB73,
(SINT16)((SINT32)0x005FD0FF >>16), (SINT16)0x005FD0FF,
(SINT16)((SINT32)0x01223EBA >>16), (SINT16)0x01223EBA,
(SINT16)((SINT32)0x01A7ECEF >>16), (SINT16)0x01A7ECEF, /* 56 */
(SINT16)((SINT32)0x01F5F424 >>16), (SINT16)0x01F5F424,
(SINT16)((SINT32)0x02138653 >>16), (SINT16)0x02138653,
(SINT16)((SINT32)0x0209291F >>16), (SINT16)0x0209291F,
(SINT16)((SINT32)0x01E0224C >>16), (SINT16)0x01E0224C,
(SINT16)((SINT32)0x01A1B38B >>16), (SINT16)0x01A1B38B,
(SINT16)((SINT32)0x0156B3CA >>16), (SINT16)0x0156B3CA,
(SINT16)((SINT32)0x01071B96 >>16), (SINT16)0x01071B96,
(SINT16)((SINT32)0xFF468CB8 >>16), (SINT16)0xFF468CB8, /* 64 */
(SINT16)((SINT32)0xFF8D6793 >>16), (SINT16)0xFF8D6793,
(SINT16)((SINT32)0xFFC9F10E >>16), (SINT16)0xFFC9F10E,
(SINT16)((SINT32)0xFFFA2413 >>16), (SINT16)0xFFFA2413,
(SINT16)((SINT32)0x001D8FD2 >>16), (SINT16)0x001D8FD2,
(SINT16)((SINT32)0x0034F8B6 >>16), (SINT16)0x0034F8B6,
(SINT16)((SINT32)0x00415B75 >>16), (SINT16)0x00415B75,
(SINT16)((SINT32)0x0044EF48 >>16), (SINT16)0x0044EF48,
(SINT16)((SINT32)0x0041EC6A >>16), (SINT16)0x0041EC6A, /* 72 */
(SINT16)((SINT32)0x003A72E7 >>16), (SINT16)0x003A72E7,
(SINT16)((SINT32)0x003060F4 >>16), (SINT16)0x003060F4,
(SINT16)((SINT32)0x00255A62 >>16), (SINT16)0x00255A62,
(SINT16)((SINT32)0x001AFF89 >>16), (SINT16)0x001AFF89,
(SINT16)((SINT32)0x00122C7D >>16), (SINT16)0x00122C7D,
(SINT16)((SINT32)0x000B3F71 >>16), (SINT16)0x000B3F71,
(SINT16)((SINT32)0x00052173 >>16), (SINT16)0x00052173
};
#else
/*Window coeff for 4 sub band case*/
const SINT32 gas32CoeffFor4SBs[] =
{
(SINT32)0x00000000,
(SINT32)0x001194E6,
(SINT32)0x0030E2D3,
(SINT32)0x00599403,
(SINT32)0x007DBCC8,
(SINT32)0x007F88E4,
(SINT32)0x003D239B,
(SINT32)0xFF9BB9D5,
(SINT32)0x01659F45,
(SINT32)0x029DBAA3,
(SINT32)0x03B23341,
(SINT32)0x041EEE40,
(SINT32)0x034FEE2C,
(SINT32)0x00C8F2BC,
(SINT32)0xFC4F91D4,
(SINT32)0xF60FAF37,
(SINT32)0x115B1ED2,
(SINT32)0x18F55C90,
(SINT32)0x1F91CA46,
(SINT32)0x2412F251,
(SINT32)0x25AC1FF2,
(SINT32)0x2412F251,
(SINT32)0x1F91CA46,
(SINT32)0x18F55C90,
(SINT32)0xEEA4E12E,
(SINT32)0xF60FAF37,
(SINT32)0xFC4F91D4,
(SINT32)0x00C8F2BC,
(SINT32)0x034FEE2C,
(SINT32)0x041EEE40,
(SINT32)0x03B23341,
(SINT32)0x029DBAA3,
(SINT32)0xFE9A60BB,
(SINT32)0xFF9BB9D5,
(SINT32)0x003D239B,
(SINT32)0x007F88E4,
(SINT32)0x007DBCC8,
(SINT32)0x00599403,
(SINT32)0x0030E2D3,
(SINT32)0x001194E6
};
/*Window coeff for 8 sub band case*/
const SINT32 gas32CoeffFor8SBs[] =
{
(SINT32)0x00000000,
(SINT32)0x00052173,
(SINT32)0x000B3F71,
(SINT32)0x00122C7D,
(SINT32)0x001AFF89,
(SINT32)0x00255A62,
(SINT32)0x003060F4,
(SINT32)0x003A72E7,
(SINT32)0x0041EC6A, /* 8 */
(SINT32)0x0044EF48,
(SINT32)0x00415B75,
(SINT32)0x0034F8B6,
(SINT32)0x001D8FD2,
(SINT32)0xFFFA2413,
(SINT32)0xFFC9F10E,
(SINT32)0xFF8D6793,
(SINT32)0x00B97348, /* 16 */
(SINT32)0x01071B96,
(SINT32)0x0156B3CA,
(SINT32)0x01A1B38B,
(SINT32)0x01E0224C,
(SINT32)0x0209291F,
(SINT32)0x02138653,
(SINT32)0x01F5F424,
(SINT32)0x01A7ECEF, /* 24 */
(SINT32)0x01223EBA,
(SINT32)0x005FD0FF,
(SINT32)0xFF5EEB73,
(SINT32)0xFE20435D,
(SINT32)0xFCA86E7E,
(SINT32)0xFAFF95FC,
(SINT32)0xF9312891,
(SINT32)0x08B4307A, /* 32 */
(SINT32)0x0A9F3E9A,
(SINT32)0x0C7D59B6,
(SINT32)0x0E3BB16F,
(SINT32)0x0FC721F9,
(SINT32)0x110ECEF0,
(SINT32)0x120435FA,
(SINT32)0x129C226F,
(SINT32)0x12CF6C75, /* 40 */
(SINT32)0x129C226F,
(SINT32)0x120435FA,
(SINT32)0x110ECEF0,
(SINT32)0x0FC721F9,
(SINT32)0x0E3BB16F,
(SINT32)0x0C7D59B6,
(SINT32)0x0A9F3E9A,
(SINT32)0xF74BCF86, /* 48 */
(SINT32)0xF9312891,
(SINT32)0xFAFF95FC,
(SINT32)0xFCA86E7E,
(SINT32)0xFE20435D,
(SINT32)0xFF5EEB73,
(SINT32)0x005FD0FF,
(SINT32)0x01223EBA,
(SINT32)0x01A7ECEF, /* 56 */
(SINT32)0x01F5F424,
(SINT32)0x02138653,
(SINT32)0x0209291F,
(SINT32)0x01E0224C,
(SINT32)0x01A1B38B,
(SINT32)0x0156B3CA,
(SINT32)0x01071B96,
(SINT32)0xFF468CB8, /* 64 */
(SINT32)0xFF8D6793,
(SINT32)0xFFC9F10E,
(SINT32)0xFFFA2413,
(SINT32)0x001D8FD2,
(SINT32)0x0034F8B6,
(SINT32)0x00415B75,
(SINT32)0x0044EF48,
(SINT32)0x0041EC6A, /* 72 */
(SINT32)0x003A72E7,
(SINT32)0x003060F4,
(SINT32)0x00255A62,
(SINT32)0x001AFF89,
(SINT32)0x00122C7D,
(SINT32)0x000B3F71,
(SINT32)0x00052173
};
#endif
#endif
+314
View File
@@ -0,0 +1,314 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* contains code for encoder flow and initalization of encoder
*
******************************************************************************/
#include <string.h>
#include "sbc_encoder.h"
#include "sbc_enc_func_declare.h"
#include "xc60xx.h"
SINT16 EncMaxShiftCounter;
#if (SBC_JOINT_STE_INCLUDED == TRUE)
SINT32 s32LRDiff[SBC_MAX_NUM_OF_BLOCKS] = {0};
SINT32 s32LRSum[SBC_MAX_NUM_OF_BLOCKS] = {0};
#endif
void /*__attribute__((section("ram_em")))*/ SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams)
{
SINT32 s32Ch; /* counter for ch*/
SINT32 s32Sb; /* counter for sub-band*/
UINT32 u32Count, maxBit = 0; /* loop count*/
SINT32 s32MaxValue; /* temp variable to store max value */
SINT16 *ps16ScfL;
SINT32 *SbBuffer;
SINT32 s32Blk; /* counter for block*/
SINT32 s32NumOfBlocks = pstrEncParams->s16NumOfBlocks;
#if (SBC_JOINT_STE_INCLUDED == TRUE)
SINT32 s32MaxValue2;
UINT32 u32CountSum,u32CountDiff;
SINT32 *pSum, *pDiff;
#endif
register SINT32 s32NumOfSubBands = pstrEncParams->s16NumOfSubBands;
pstrEncParams->pu8NextPacket = pstrEncParams->pu8Packet;
#if (SBC_NO_PCM_CPY_OPTION == TRUE)
pstrEncParams->ps16NextPcmBuffer = pstrEncParams->ps16PcmBuffer;
#else
pstrEncParams->ps16NextPcmBuffer = pstrEncParams->as16PcmBuffer;
#endif
do
{
/* SBC ananlysis filter*/
if (s32NumOfSubBands == 4)
SbcAnalysisFilter4(pstrEncParams);
else
SbcAnalysisFilter8(pstrEncParams);
/* compute the scale factor, and save the max */
ps16ScfL = pstrEncParams->as16ScaleFactor;
s32Ch=pstrEncParams->s16NumOfChannels*s32NumOfSubBands;
pstrEncParams->ps16NextPcmBuffer+=s32Ch*s32NumOfBlocks; /* in case of multible sbc frame to encode update the pcm pointer */
for (s32Sb=0; s32Sb<s32Ch; s32Sb++)
{
SbBuffer=pstrEncParams->s32SbBuffer+s32Sb;
s32MaxValue=0;
for (s32Blk=s32NumOfBlocks;s32Blk>0;s32Blk--)
{
if (s32MaxValue<abs32(*SbBuffer))
s32MaxValue=abs32(*SbBuffer);
SbBuffer+=s32Ch;
}
u32Count = (s32MaxValue > 0x800000) ? 9 : 0;
for ( ; u32Count < 15; u32Count++)
{
if (s32MaxValue <= (SINT32)(0x8000 << u32Count))
break;
}
*ps16ScfL++ = (SINT16)u32Count;
if (u32Count > maxBit)
maxBit = u32Count;
}
/* In case of JS processing,check whether to use JS */
#if (SBC_JOINT_STE_INCLUDED == TRUE)
if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
{
/* Calculate sum and differance scale factors for making JS decision */
ps16ScfL = pstrEncParams->as16ScaleFactor ;
/* calculate the scale factor of Joint stereo max sum and diff */
for (s32Sb = 0; s32Sb < (s32NumOfSubBands-1); s32Sb++)
{
SbBuffer=pstrEncParams->s32SbBuffer+s32Sb;
s32MaxValue2=0;
s32MaxValue=0;
pSum = s32LRSum;
pDiff = s32LRDiff;
for (s32Blk=0;s32Blk<s32NumOfBlocks;s32Blk++)
{
*pSum=(*SbBuffer+*(SbBuffer+s32NumOfSubBands))>>1;
if (abs32(*pSum)>s32MaxValue)
s32MaxValue=abs32(*pSum);
pSum++;
*pDiff=(*SbBuffer-*(SbBuffer+s32NumOfSubBands))>>1;
if (abs32(*pDiff)>s32MaxValue2)
s32MaxValue2=abs32(*pDiff);
pDiff++;
SbBuffer+=s32Ch;
}
u32Count = (s32MaxValue > 0x800000) ? 9 : 0;
for ( ; u32Count < 15; u32Count++)
{
if (s32MaxValue <= (SINT32)(0x8000 << u32Count))
break;
}
u32CountSum=u32Count;
u32Count = (s32MaxValue2 > 0x800000) ? 9 : 0;
for ( ; u32Count < 15; u32Count++)
{
if (s32MaxValue2 <= (SINT32)(0x8000 << u32Count))
break;
}
u32CountDiff=u32Count;
if ( (*ps16ScfL + *(ps16ScfL+s32NumOfSubBands)) > (SINT16)(u32CountSum + u32CountDiff) )
{
if (u32CountSum > maxBit)
maxBit = u32CountSum;
if (u32CountDiff > maxBit)
maxBit = u32CountDiff;
*ps16ScfL = (SINT16)u32CountSum;
*(ps16ScfL+s32NumOfSubBands) = (SINT16)u32CountDiff;
SbBuffer=pstrEncParams->s32SbBuffer+s32Sb;
pSum = s32LRSum;
pDiff = s32LRDiff;
for (s32Blk = 0; s32Blk < s32NumOfBlocks; s32Blk++)
{
*SbBuffer = *pSum;
*(SbBuffer+s32NumOfSubBands) = *pDiff;
SbBuffer += s32NumOfSubBands<<1;
pSum++;
pDiff++;
}
pstrEncParams->as16Join[s32Sb] = 1;
}
else
{
pstrEncParams->as16Join[s32Sb] = 0;
}
ps16ScfL++;
}
pstrEncParams->as16Join[s32Sb] = 0;
}
#endif
pstrEncParams->s16MaxBitNeed = (SINT16)maxBit;
/* bit allocation */
if ((pstrEncParams->s16ChannelMode == SBC_STEREO) || (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO))
sbc_enc_bit_alloc_ste(pstrEncParams);
else
sbc_enc_bit_alloc_mono(pstrEncParams);
/* save the beginning of the frame. pu8NextPacket is modified in EncPacking() */
// pu8 = pstrEncParams->pu8NextPacket;
/* Quantize the encoded audio */
EncPacking(pstrEncParams);
}
while(--(pstrEncParams->u8NumPacketToEncode));
pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */
}
/****************************************************************************
* InitSbcAnalysisFilt - Initalizes the input data to 0
*
* RETURNS : N/A
*/
void SBC_Encoder_Init(SBC_ENC_PARAMS *pstrEncParams)
{
// UINT16 s16SamplingFreq; /*temp variable to store smpling freq*/
SINT16 s16Bitpool; /*to store bit pool value*/
// SINT16 s16BitRate; /*to store bitrate*/
// SINT16 s16FrameLen; /*to store frame length*/
UINT16 HeaderParams;
pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */
/* Required number of channels */
if (pstrEncParams->s16ChannelMode == SBC_MONO)
pstrEncParams->s16NumOfChannels = 1;
else
pstrEncParams->s16NumOfChannels = 2;
/* BK4BTSTACK_CHANGE START */
/* Bit pool calculation */
// if (pstrEncParams->s16SamplingFreq == SBC_sf16000)
// s16SamplingFreq = 16000;
// else if (pstrEncParams->s16SamplingFreq == SBC_sf32000)
// s16SamplingFreq = 32000;
// else if (pstrEncParams->s16SamplingFreq == SBC_sf44100)
// s16SamplingFreq = 44100;
// else
// s16SamplingFreq = 48000;
/* BK4BTSTACK_CHANGE END */
if ( (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
|| (pstrEncParams->s16ChannelMode == SBC_STEREO) )
{
/* BK4BTSTACK_CHANGE START */
// s16Bitpool = (SINT16)( (pstrEncParams->u16BitRate *
// pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq)
// -( (32 + (4 * pstrEncParams->s16NumOfSubBands *
// pstrEncParams->s16NumOfChannels)
// + ( (pstrEncParams->s16ChannelMode - 2) *
// pstrEncParams->s16NumOfSubBands ) )
// / pstrEncParams->s16NumOfBlocks) );
s16Bitpool = pstrEncParams->s16BitPool;
// s16FrameLen = 4 + (4*pstrEncParams->s16NumOfSubBands*
// pstrEncParams->s16NumOfChannels)/8
// + ( ((pstrEncParams->s16ChannelMode - 2) *
// pstrEncParams->s16NumOfSubBands)
// + (pstrEncParams->s16NumOfBlocks * s16Bitpool) ) / 8;
// s16BitRate = (8 * s16FrameLen * s16SamplingFreq)
// / (pstrEncParams->s16NumOfSubBands *
// pstrEncParams->s16NumOfBlocks * 1000);
// if (s16BitRate > pstrEncParams->u16BitRate)
// s16Bitpool--;
/* BK4BTSTACK_CHANGE END */
if(pstrEncParams->s16NumOfSubBands == 8)
pstrEncParams->s16BitPool = (s16Bitpool > 255) ? 255 : s16Bitpool;
else
pstrEncParams->s16BitPool = (s16Bitpool > 128) ? 128 : s16Bitpool;
}
else
{
if (!pstrEncParams->mSBCEnabled){
/* BK4BTSTACK_CHANGE START */
// s16Bitpool = (SINT16)( ((pstrEncParams->s16NumOfSubBands *
// pstrEncParams->u16BitRate * 1000)
// / (s16SamplingFreq * pstrEncParams->s16NumOfChannels))
// -( ( (32 / pstrEncParams->s16NumOfChannels) +
// (4 * pstrEncParams->s16NumOfSubBands) )
// / pstrEncParams->s16NumOfBlocks ) );
s16Bitpool = pstrEncParams->s16BitPool;
/* BK4BTSTACK_CHANGE END */
pstrEncParams->s16BitPool = (s16Bitpool >
(16 * pstrEncParams->s16NumOfSubBands))
? (16*pstrEncParams->s16NumOfSubBands) : s16Bitpool;
}
}
if (pstrEncParams->s16BitPool < 0)
pstrEncParams->s16BitPool = 0;
/* sampling freq */
HeaderParams = ((pstrEncParams->s16SamplingFreq & 3)<< 6);
/* number of blocks*/
HeaderParams |= (((pstrEncParams->s16NumOfBlocks -4) & 12) << 2);
/* channel mode: mono, dual...*/
HeaderParams |= ((pstrEncParams->s16ChannelMode & 3)<< 2);
/* Loudness or SNR */
HeaderParams |= ((pstrEncParams->s16AllocationMethod & 1)<< 1);
HeaderParams |= ((pstrEncParams->s16NumOfSubBands >> 3) & 1); /*4 or 8*/
pstrEncParams->FrameHeader=HeaderParams;
if (pstrEncParams->s16NumOfSubBands==4)
{
if (pstrEncParams->s16NumOfChannels==1)
pstrEncParams->EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(4*10))>>2)<<2;
else
pstrEncParams->EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(4*10*2))>>3)<<2;
}
else
{
if (pstrEncParams->s16NumOfChannels==1)
pstrEncParams->EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(8*10))>>3)<<3;
else
pstrEncParams->EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-(8*10*2))>>4)<<3;
}
// APPL_TRACE_EVENT("SBC_Encoder_Init : bitrate %d, bitpool %d",
// pstrEncParams->u16BitRate, pstrEncParams->s16BitPool);
SbcAnalysisInit(pstrEncParams);
}
+294
View File
@@ -0,0 +1,294 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This file contains code for packing the Encoded data into bit streams.
*
******************************************************************************/
#include "sbc_encoder.h"
#include "sbc_enc_func_declare.h"
#include <stddef.h>
#include "xc60xx.h"
#if (SBC_ARM_ASM_OPT==TRUE)
#define Mult32(s32In1,s32In2,s32OutLow) \
{ \
__asm \
{ \
MUL s32OutLow,s32In1,s32In2; \
} \
}
#define Mult64(s32In1, s32In2, s32OutLow, s32OutHi) \
{ \
__asm \
{ \
SMULL s32OutLow,s32OutHi,s32In1,s32In2 \
} \
}
#else
#define Mult32(s32In1,s32In2,s32OutLow) s32OutLow=(SINT32)s32In1*(SINT32)s32In2;
#define Mult64(s32In1, s32In2, s32OutLow, s32OutHi) \
{ \
s32OutLow = ((SINT32)(UINT16)s32In1 * (UINT16)s32In2); \
s32TempVal2 = (SINT32)((s32In1 >> 16) * (UINT16)s32In2); \
s32Carry = ( (((UINT32)(s32OutLow)>>16)&0xFFFF) + \
+ (s32TempVal2 & 0xFFFF) ) >> 16; \
s32OutLow += (s32TempVal2 << 16); \
s32OutHi = (s32TempVal2 >> 16) + s32Carry; \
}
#endif
void /*__attribute__((section("ram_em")))*/ EncPacking(SBC_ENC_PARAMS *pstrEncParams)
{
UINT8 *pu8PacketPtr; /* packet ptr*/
UINT8 Temp;
SINT32 s32Blk; /* counter for block*/
SINT32 s32Ch; /* counter for channel*/
SINT32 s32Sb; /* counter for sub-band*/
SINT32 s32PresentBit; /* represents bit to be stored*/
/*SINT32 s32LoopCountI; loop counter*/
SINT32 s32LoopCountJ; /* loop counter*/
UINT32 u32QuantizedSbValue,u32QuantizedSbValue0; /* temp variable to store quantized sb val*/
SINT32 s32LoopCount; /* loop counter*/
UINT8 u8XoredVal; /* to store XORed value in CRC calculation*/
UINT8 u8CRC; /* to store CRC value*/
SINT16 *ps16GenPtr;
SINT32 s32NumOfBlocks;
SINT32 s32NumOfSubBands = pstrEncParams->s16NumOfSubBands;
SINT32 s32NumOfChannels = pstrEncParams->s16NumOfChannels;
UINT32 u32SfRaisedToPow2; /*scale factor raised to power 2*/
SINT16 *ps16ScfPtr;
SINT32 *ps32SbPtr;
UINT16 u16Levels; /*to store levels*/
SINT32 s32Temp1; /*used in 64-bit multiplication*/
SINT32 s32Low; /*used in 64-bit multiplication*/
#if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE)
SINT32 s32Hi1,s32Low1,s32Carry,s32TempVal2,s32Hi, s32Temp2;
#endif
pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/
/* BK4BTSTACK_CHANGE START */
uint8_t * reserved_ptr = NULL;
if (pstrEncParams->mSBCEnabled){
*pu8PacketPtr++ = (UINT8)0xAD; /*Sync word*/
reserved_ptr = pu8PacketPtr;
} else {
*pu8PacketPtr++ = (UINT8)0x9C; /*Sync word*/
}
/* BK4BTSTACK_CHANGE END */
*pu8PacketPtr++=(UINT8)(pstrEncParams->FrameHeader);
*pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF);
pu8PacketPtr += 2; /*skip for CRC*/
/*here it indicate if it is byte boundary or nibble boundary*/
s32PresentBit = 8;
Temp=0;
#if (SBC_JOINT_STE_INCLUDED == TRUE)
if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
{
/* pack join stero parameters */
for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++)
{
Temp <<= 1;
Temp |= pstrEncParams->as16Join[s32Sb];
}
/* pack RFA */
if (s32NumOfSubBands == SUB_BANDS_4)
{
s32PresentBit = 4;
}
else
{
*(pu8PacketPtr++)=Temp;
Temp = 0;
}
}
#endif
/* Pack Scale factor */
ps16GenPtr = pstrEncParams->as16ScaleFactor;
s32Sb=s32NumOfChannels*s32NumOfSubBands;
/*Temp=*pu8PacketPtr;*/
for (s32Ch = s32Sb; s32Ch >0; s32Ch--)
{
Temp<<= 4;
Temp |= *ps16GenPtr++;
if(s32PresentBit == 4)
{
s32PresentBit = 8;
*(pu8PacketPtr++)=Temp;
Temp = 0;
}
else
{
s32PresentBit = 4;
}
}
/* Pack samples */
ps32SbPtr = pstrEncParams->s32SbBuffer;
/*Temp=*pu8PacketPtr;*/
s32NumOfBlocks= pstrEncParams->s16NumOfBlocks;
for (s32Blk = s32NumOfBlocks-1; s32Blk >=0; s32Blk--)
{
ps16GenPtr = pstrEncParams->as16Bits;
ps16ScfPtr = pstrEncParams->as16ScaleFactor;
for (s32Ch = s32Sb-1; s32Ch >= 0; s32Ch--)
{
s32LoopCount = *ps16GenPtr++;
if (s32LoopCount != 0)
{
#if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE)
/* finding level from reconstruction part of decoder */
u32SfRaisedToPow2 = ((UINT32)1 << ((*ps16ScfPtr)+1));
u16Levels = (UINT16)(((UINT32)1 << s32LoopCount) - 1);
/* quantizer */
s32Temp1 = (*ps32SbPtr >> 2) + (u32SfRaisedToPow2 << 12);
s32Temp2 = u16Levels;
Mult64 (s32Temp1, s32Temp2, s32Low, s32Hi);
s32Low1 = s32Low >> ((*ps16ScfPtr)+2);
s32Low1 &= ((UINT32)1 << (32 - ((*ps16ScfPtr)+2))) - 1;
s32Hi1 = s32Hi << (32 - ((*ps16ScfPtr) +2));
u32QuantizedSbValue0 = (UINT16)((s32Low1 | s32Hi1) >> 12);
#else
/* finding level from reconstruction part of decoder */
u32SfRaisedToPow2 = ((UINT32)1 << *ps16ScfPtr);
u16Levels = (UINT16)(((UINT32)1 << s32LoopCount)-1);
/* quantizer */
s32Temp1 = (*ps32SbPtr >> 15) + u32SfRaisedToPow2;
Mult32(s32Temp1,u16Levels,s32Low);
s32Low>>= (*ps16ScfPtr+1);
u32QuantizedSbValue0 = (UINT16)s32Low;
#endif
/*store the number of bits required and the quantized s32Sb
sample to ease the coding*/
u32QuantizedSbValue = u32QuantizedSbValue0;
if(s32PresentBit >= s32LoopCount)
{
Temp <<= s32LoopCount;
Temp |= u32QuantizedSbValue;
s32PresentBit -= s32LoopCount;
}
else
{
while (s32PresentBit < s32LoopCount)
{
s32LoopCount -= s32PresentBit;
u32QuantizedSbValue >>= s32LoopCount;
/*remove the unwanted msbs*/
/*u32QuantizedSbValue <<= 16 - s32PresentBit;
u32QuantizedSbValue >>= 16 - s32PresentBit;*/
Temp <<= s32PresentBit;
Temp |= u32QuantizedSbValue ;
/*restore the original*/
u32QuantizedSbValue=u32QuantizedSbValue0;
*(pu8PacketPtr++)=Temp;
Temp = 0;
s32PresentBit = 8;
}
Temp <<= s32LoopCount;
/* remove the unwanted msbs */
/*u32QuantizedSbValue <<= 16 - s32LoopCount;
u32QuantizedSbValue >>= 16 - s32LoopCount;*/
Temp |= u32QuantizedSbValue;
s32PresentBit -= s32LoopCount;
}
}
ps16ScfPtr++;
ps32SbPtr++;
}
}
Temp <<= s32PresentBit;
*pu8PacketPtr=Temp;
pstrEncParams->u16PacketLength= (uint16_t)(pu8PacketPtr-pstrEncParams->pu8NextPacket)+1;
/*find CRC*/
pu8PacketPtr = pstrEncParams->pu8NextPacket+1; /*Initialize the ptr*/
u8CRC = 0x0F;
s32LoopCount = s32Sb >> 1;
/* BK4BTSTACK_CHANGE START */
if (reserved_ptr){
// overwrite fixed values for mSBC before CRC calculation
*reserved_ptr++ = 0;
*reserved_ptr++ = 0;
}
/* BK4BTSTACK_CHANGE END */
/*
The loops is run from the start of the packet till the scale factor
parameters. In case of JS, 'join' parameter is included in the packet
so that many more bytes are included in CRC calculation.
*/
Temp=*pu8PacketPtr;
for (s32Ch=1; s32Ch < (s32LoopCount+4); s32Ch++)
{
/* skip sync word and CRC bytes */
if (s32Ch != 3)
{
for (s32LoopCountJ=7; s32LoopCountJ>=0; s32LoopCountJ--)
{
u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01);
u8CRC <<= 1;
u8CRC ^= (u8XoredVal * 0x1D);
u8CRC &= 0xFF;
}
}
Temp=*(++pu8PacketPtr);
}
if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
{
for (s32LoopCountJ = 7; s32LoopCountJ >= (8 - s32NumOfSubBands); s32LoopCountJ--)
{
u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01);
u8CRC <<= 1;
u8CRC ^= (u8XoredVal * 0x1D);
u8CRC &= 0xFF;
}
}
/* CRC calculation ends here */
/* store CRC in packet */
pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/
pu8PacketPtr += 3;
*pu8PacketPtr = u8CRC;
pstrEncParams->pu8NextPacket+=pstrEncParams->u16PacketLength; /* move the pointer to the end in case there is more than one frame to encode */
}
+39
View File
@@ -0,0 +1,39 @@
#ifndef __PLATFORM_H
#define __PLATFORM_H
/*
*********************************************************************************************************
* HARDWARE PLATFORM
*********************************************************************************************************
*/
#include "stdio.h"
/*
*********************************************************************************************************
* PLATFORM DEFINES
*********************************************************************************************************
*/
#define CORE_CLK 32000000ul /* Set Processor frequency */
#define TICKS_PER_SEC 100ul /* Set the number of ticks in one second */
/*
*********************************************************************************************************
* GLOBAL FUNCTION
*********************************************************************************************************
*/
#define AT_USE_UART 1
#define AT_BUFF_LEN 100
#define PIN_32_16
#define __ASSERT(a) while(!(a))
void delay_us(uint32_t nus);
void delay_ms(uint32_t nms);
#endif
+133
View File
@@ -0,0 +1,133 @@
/**
****************************************************************************************
*
* @file ahi.h
*
* @brief This file contains definitions related to the Application Host Interface
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#ifndef AHI_H_
#define AHI_H_
/**
****************************************************************************************
* @addtogroup AHI Application Host Interface
* @ingroup AHI
* @brief Application Host Interface, based on AHI functionality.
*
*@{
*
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "rwip_config.h" // SW configuration
#if (AHI_TL_SUPPORT)
#include <stdint.h>
/*
* Defines
****************************************************************************************
*/
/// Kernel message type
#define AHI_KE_MSG_TYPE 0x10
/// Kernel message header length for transport through interface between App and SW stack.
#define AHI_KE_MSG_HDR_LEN 8
/// Maximum number of advertising reports that can be queued
#define AHI_MAX_ADV_REPORT 10
/// GAPM Reset size (LC + KE_HEADER + Reset_operation code)
#define AHI_RESET_MSG_LEN (1+AHI_KE_MSG_HDR_LEN+1)
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/*
* GLOBAL VARIABLE DECLARATIONS
****************************************************************************************
*/
extern const uint8_t ahi_reset_msg[AHI_RESET_MSG_LEN];
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief AHI initialization function: initializes states and transport.
*****************************************************************************************
*/
void ahi_init(void);
/**
****************************************************************************************
* @brief Handle received AHI header through transport layer
*
* @param[in] p_hdr_data Pointer to received header
* @param[out] p_rem_length Pointer to returned remaining length to receive.
*
* @return Pointer to data buffer where remaining data can be pushed.
****************************************************************************************
*/
uint8_t* ahi_rx_hdr_handle(uint8_t* p_hdr_data, uint16_t* p_rem_length);
/**
****************************************************************************************
* @brief Inform AHI that payload data has been received
*
* @param[in] p_data Pointer to received payload
****************************************************************************************
*/
void ahi_rx_done(uint8_t* p_data);
/**
****************************************************************************************
* @brief Reset pattern received, handle it at AHI level
****************************************************************************************
*/
void ahi_reset(void);
/**
****************************************************************************************
* @brief Retrieve Task Identifier from Task number
* (automatically update index of task in returned task id)
*
* @param task Task number
* @return Task Identifier
****************************************************************************************
*/
uint16_t ahi_get_id_from_task(uint16_t task);
/**
****************************************************************************************
* @brief Retrieve Task Number from Task Identifier
* (automatically update index of task in returned task id)
*
* @param id Task Identifier
* @return Task Number
****************************************************************************************
*/
uint16_t ahi_get_task_from_id(uint16_t id);
#endif //AHI_TL_SUPPORT
/// @} AHI
#endif // AHI_H_
+470
View File
@@ -0,0 +1,470 @@
/**
****************************************************************************************
* @file xc_gap_api.c
* @brief GAP APIs source code
* Copyright (c) 2022 - 2025, XinChip
* All rights reserved.
****************************************************************************************
*/
#include "rwip_config.h"
#if BLE_APP_PRESENT
#include "xc_gap_api.h"
void xc_ble_gapm_reset(void)
{
// Reset the stack
struct gapm_reset_cmd *p_cmd =
KE_MSG_ALLOC(GAPM_RESET_CMD, TASK_GAPM, TASK_APP, gapm_reset_cmd);
p_cmd->operation = GAPM_RESET;
ke_msg_send(p_cmd);
}
void xc_ble_set_dev_config(struct gapm_set_dev_config_cmd *cfg_param)
{
struct gapm_set_dev_config_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_SET_DEV_CONFIG_CMD, TASK_GAPM, TASK_APP, gapm_set_dev_config_cmd);
memcpy(p_cmd, cfg_param, sizeof(struct gapm_set_dev_config_cmd));
p_cmd->operation = GAPM_SET_DEV_CONFIG;
ke_msg_send(p_cmd);
}
void xc_ble_get_dev_info(struct gapm_get_dev_info_cmd *cmd)
{
struct gapm_get_dev_info_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_GET_DEV_INFO_CMD, TASK_GAPM, TASK_APP, gapm_get_dev_info_cmd);
p_cmd->operation = cmd->operation;
ke_msg_send(p_cmd);
}
void xc_ble_resolve_addr(uint8_t nb_key, gap_addr_t *addr, uint8_t *irk)
{
struct gapm_resolv_addr_cmd *p_cmd = KE_MSG_ALLOC_DYN(
GAPM_RESOLV_ADDR_CMD, TASK_GAPM, TASK_APP, gapm_resolv_addr_cmd,
(nb_key * sizeof(struct gap_sec_key)));
memcpy(&p_cmd->addr.addr[0], &addr->addr[0], GAP_BD_ADDR_LEN);
memcpy(&p_cmd->irk[0].key[0], &irk[0], GAP_KEY_LEN * nb_key);
p_cmd->nb_key = nb_key;
p_cmd->operation = GAPM_RESOLV_ADDR;
ke_msg_send(p_cmd);
}
void xc_ble_gen_random_addr(struct gapm_gen_rand_addr_cmd *p_param)
{
struct gapm_gen_rand_addr_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_GEN_RAND_ADDR_CMD, TASK_GAPM, TASK_APP, gapm_gen_rand_addr_cmd);
memcpy(p_cmd, p_param, sizeof(struct gapm_gen_rand_addr_cmd));
p_cmd->operation = GAPM_GEN_RAND_ADDR;
ke_msg_send(p_cmd);
}
void xc_ble_get_pub_key(void)
{
struct gapm_get_pub_key_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_GET_PUB_KEY_CMD, TASK_GAPM, TASK_APP, gapm_get_pub_key_cmd);
p_cmd->operation = GAPM_GET_PUB_KEY;
ke_msg_send(p_cmd);
}
void xc_ble_gen_random_nb(void)
{
struct gapm_gen_rand_nb_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_GEN_RAND_NB_CMD, TASK_GAPM, TASK_APP, gapm_gen_rand_nb_cmd);
p_cmd->operation = GAPM_GEN_RAND_NB;
ke_msg_send(p_cmd);
}
void xc_ble_set_irk(gap_sec_key_t *irk)
{
struct gapm_set_irk_cmd *p_cmd =
KE_MSG_ALLOC(GAPM_SET_IRK_CMD, TASK_GAPM, TASK_APP, gapm_set_irk_cmd);
p_cmd->operation = GAPM_SET_IRK;
memcpy(p_cmd->irk.key, irk->key, GAP_KEY_LEN);
ke_msg_send(p_cmd);
}
void xc_ble_get_ral_addr(struct gapm_get_ral_addr_cmd *p_param)
{
struct gapm_get_ral_addr_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_GET_RAL_ADDR_CMD, TASK_GAPM, TASK_APP, gapm_get_ral_addr_cmd);
memcpy(p_cmd, p_param, sizeof(struct gapm_get_ral_addr_cmd));
p_cmd->operation = p_param->operation;
ke_msg_send(p_cmd);
}
void xc_ble_set_ral_list(uint8_t size, struct gap_ral_dev_info *ral_info)
{
struct gapm_list_set_ral_cmd *p_cmd = KE_MSG_ALLOC_DYN(
GAPM_LIST_SET_CMD, TASK_GAPM, TASK_APP, gapm_list_set_ral_cmd,
(size * sizeof(struct gap_ral_dev_info)));
p_cmd->size = size;
memcpy(&p_cmd->ral_info, ral_info, sizeof(struct gap_ral_dev_info) * size);
p_cmd->operation = GAPM_SET_RAL;
ke_msg_send(p_cmd);
}
void xc_ble_set_white_list(uint8_t size, gap_bdaddr_t *wl_info)
{
struct gapm_list_set_wl_cmd *p_cmd = KE_MSG_ALLOC_DYN(
GAPM_LIST_SET_CMD, TASK_GAPM, TASK_APP, gapm_list_set_wl_cmd,
(size * sizeof(struct gap_bdaddr)));
p_cmd->size = size;
memcpy(&p_cmd->wl_info, wl_info, sizeof(struct gap_bdaddr) * size);
p_cmd->operation = GAPM_SET_WL;
ke_msg_send(p_cmd);
}
void xc_ble_advertise_create(
struct gapm_activity_create_adv_cmd *adv_creat_param)
{
struct gapm_activity_create_adv_cmd *p_cmd =
KE_MSG_ALLOC(GAPM_ACTIVITY_CREATE_CMD, TASK_GAPM, TASK_APP,
gapm_activity_create_adv_cmd);
memcpy(p_cmd, adv_creat_param, sizeof(struct gapm_activity_create_adv_cmd));
p_cmd->operation = GAPM_CREATE_ADV_ACTIVITY;
ke_msg_send(p_cmd);
}
void xc_ble_set_adv_data(uint8_t actv_idx, uint16_t adv_data_length,
uint8_t *p_adv_data)
{
struct gapm_set_adv_data_cmd *p_cmd =
KE_MSG_ALLOC_DYN(GAPM_SET_ADV_DATA_CMD, TASK_GAPM, TASK_APP,
gapm_set_adv_data_cmd, adv_data_length);
p_cmd->operation = GAPM_SET_ADV_DATA;
p_cmd->actv_idx = actv_idx;
p_cmd->length = adv_data_length;
memcpy(&p_cmd->data[0], p_adv_data, adv_data_length);
ke_msg_send(p_cmd);
}
void xc_ble_set_scan_rsp_data(uint8_t actv_idx, uint16_t scan_rsp_data_length,
uint8_t *p_scan_rsp_data)
{
struct gapm_set_adv_data_cmd *p_cmd =
KE_MSG_ALLOC_DYN(GAPM_SET_ADV_DATA_CMD, TASK_GAPM, TASK_APP,
gapm_set_adv_data_cmd, scan_rsp_data_length);
p_cmd->operation = GAPM_SET_SCAN_RSP_DATA;
p_cmd->actv_idx = actv_idx;
p_cmd->length = scan_rsp_data_length;
memcpy(&p_cmd->data[0], p_scan_rsp_data, scan_rsp_data_length);
ke_msg_send(p_cmd);
}
void xc_ble_advertise_start(struct gapm_activity_start_cmd *adv_start_param)
{
struct gapm_activity_start_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_ACTIVITY_START_CMD, TASK_GAPM, TASK_APP, gapm_activity_start_cmd);
memcpy(p_cmd, adv_start_param, sizeof(struct gapm_activity_start_cmd));
p_cmd->operation = GAPM_START_ACTIVITY;
ke_msg_send(p_cmd);
}
void xc_ble_scan_create(struct gapm_activity_create_cmd *scan_creat_param)
{
struct gapm_activity_create_cmd *p_cmd =
KE_MSG_ALLOC(GAPM_ACTIVITY_CREATE_CMD, TASK_GAPM, TASK_APP,
gapm_activity_create_cmd);
memcpy(p_cmd, scan_creat_param, sizeof(struct gapm_activity_create_cmd));
p_cmd->operation = GAPM_CREATE_SCAN_ACTIVITY;
ke_msg_send(p_cmd);
}
void xc_ble_scan_start(struct gapm_activity_start_cmd *scan_start_param)
{
struct gapm_activity_start_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_ACTIVITY_START_CMD, TASK_GAPM, TASK_APP, gapm_activity_start_cmd);
memcpy(p_cmd, scan_start_param, sizeof(struct gapm_activity_start_cmd));
p_cmd->operation = GAPM_START_ACTIVITY;
ke_msg_send(p_cmd);
}
void xc_ble_init_create(struct gapm_activity_create_cmd *init_creat_param)
{
struct gapm_activity_create_cmd *p_cmd =
KE_MSG_ALLOC(GAPM_ACTIVITY_CREATE_CMD, TASK_GAPM, TASK_APP,
gapm_activity_create_cmd);
memcpy(p_cmd, init_creat_param, sizeof(struct gapm_activity_create_cmd));
p_cmd->operation = GAPM_CREATE_INIT_ACTIVITY;
ke_msg_send(p_cmd);
}
void xc_ble_init_start(struct gapm_activity_start_cmd *init_start_param)
{
struct gapm_activity_start_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_ACTIVITY_START_CMD, TASK_GAPM, TASK_APP, gapm_activity_start_cmd);
memcpy(p_cmd, init_start_param, sizeof(struct gapm_activity_start_cmd));
p_cmd->operation = GAPM_START_ACTIVITY;
p_cmd->u_param.init_param.conn_param_1m.ce_len_min = CE_LEN_MIN;
p_cmd->u_param.init_param.conn_param_1m.ce_len_max = CE_LEN_MAX;
p_cmd->u_param.init_param.conn_param_2m.ce_len_min = CE_LEN_MIN;
p_cmd->u_param.init_param.conn_param_2m.ce_len_max = CE_LEN_MAX;
p_cmd->u_param.init_param.conn_param_coded.ce_len_min = CE_LEN_MIN;
p_cmd->u_param.init_param.conn_param_coded.ce_len_max = CE_LEN_MAX;
ke_msg_send(p_cmd);
}
void xc_ble_activity_stop(int actv_idx)
{
struct gapm_activity_stop_cmd *p_cmd = KE_MSG_ALLOC(
GAPM_ACTIVITY_STOP_CMD, TASK_GAPM, TASK_APP, gapm_activity_stop_cmd);
if (actv_idx >= 0) {
p_cmd->operation = GAPM_STOP_ACTIVITY;
} else {
p_cmd->operation = GAPM_STOP_ALL_ACTIVITIES;
}
p_cmd->actv_idx = actv_idx;
ke_msg_send(p_cmd);
}
void xc_ble_activity_delete(int actv_idx)
{
struct gapm_activity_delete_cmd *p_cmd =
KE_MSG_ALLOC(GAPM_ACTIVITY_DELETE_CMD, TASK_GAPM, TASK_APP,
gapm_activity_delete_cmd);
if (actv_idx >= 0) {
p_cmd->operation = GAPM_DELETE_ACTIVITY;
} else {
p_cmd->operation = GAPM_DELETE_ALL_ACTIVITIES;
}
p_cmd->actv_idx = actv_idx;
ke_msg_send(p_cmd);
}
void xc_ble_disconnect(int conidx, uint32_t reason)
{
struct gapc_disconnect_cmd *p_cmd =
KE_MSG_ALLOC(GAPC_DISCONNECT_CMD, KE_BUILD_ID(TASK_GAPC, conidx),
TASK_APP, gapc_disconnect_cmd);
p_cmd->operation = GAPC_DISCONNECT;
p_cmd->reason = reason;
ke_msg_send(p_cmd);
}
void xc_ble_update_param(int conidx, uint16_t intv_min, uint16_t intv_max,
uint16_t latency, uint16_t time_out)
{
struct gapc_param_update_cmd *p_cmd =
KE_MSG_ALLOC(GAPC_PARAM_UPDATE_CMD, KE_BUILD_ID(TASK_GAPC, conidx),
TASK_APP, gapc_param_update_cmd);
p_cmd->operation = GAPC_UPDATE_PARAMS;
p_cmd->intv_min = intv_min;
p_cmd->intv_max = intv_max;
p_cmd->latency = latency;
p_cmd->time_out = time_out;
// not used by a slave device
p_cmd->ce_len_min = CE_LEN_MIN;
// p_cmd->ce_len_min = 0xFFFF;
p_cmd->ce_len_max = CE_LEN_MAX;
ke_msg_send(p_cmd);
}
void xc_ble_conn_cfm(int conidx, struct gapc_connection_cfm *p_cfm)
{
struct gapc_connection_cfm *p_cmd =
KE_MSG_ALLOC(GAPC_CONNECTION_CFM, KE_BUILD_ID(TASK_GAPC, conidx),
TASK_APP, gapc_connection_cfm);
memcpy(p_cmd, p_cfm, sizeof(struct gapc_connection_cfm));
ke_msg_send(p_cmd);
}
void xc_ble_get_peer_info(int conidx, struct gapc_get_info_cmd *get_info)
{
struct gapc_get_info_cmd *p_cmd =
KE_MSG_ALLOC(GAPC_GET_INFO_CMD, KE_BUILD_ID(TASK_GAPC, conidx),
TASK_APP, gapc_get_info_cmd);
p_cmd->operation = get_info->operation;
ke_msg_send(p_cmd);
}
void xc_ble_param_update_cfm(int conidx,
struct gapc_param_update_cfm *update_cfm)
{
struct gapc_param_update_cfm *p_cmd =
KE_MSG_ALLOC(GAPC_PARAM_UPDATE_CFM, KE_BUILD_ID(TASK_GAPC, conidx),
TASK_APP, gapc_param_update_cfm);
memcpy(p_cmd, update_cfm, sizeof(struct gapc_param_update_cfm));
p_cmd->ce_len_min = CE_LEN_MIN;
p_cmd->ce_len_max = CE_LEN_MAX;
ke_msg_send(p_cmd);
}
void xc_ble_bond(int conidx, struct gapc_bond_cmd *p_param)
{
struct gapc_bond_cmd *p_cmd = KE_MSG_ALLOC(
GAPC_BOND_CMD, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP, gapc_bond_cmd);
memcpy(p_cmd, p_param, sizeof(struct gapc_bond_cmd));
p_cmd->operation = GAPC_BOND;
ke_msg_send(p_cmd);
}
void xc_ble_bond_cfm(int conidx, struct gapc_bond_cfm *p_param)
{
struct gapc_bond_cfm *p_cmd = KE_MSG_ALLOC(
GAPC_BOND_CFM, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP, gapc_bond_cfm);
memcpy(p_cmd, p_param, sizeof(struct gapc_bond_cfm));
ke_msg_send(p_cmd);
}
void xc_ble_get_dev_info_cfm(int conidx, struct gapc_get_dev_info_cfm *p_param)
{
if ((p_param->req == GAPC_DEV_NAME) ||
(p_param->req == GAPC_DEV_APPEARANCE) ||
(p_param->req == GAPC_DEV_SLV_PREF_PARAMS)) {
struct gapc_get_dev_info_cfm *p_cmd = KE_MSG_ALLOC_DYN(
GAPC_GET_DEV_INFO_CFM, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
gapc_get_dev_info_cfm, DEVICE_NAME_MAX_LEN);
memcpy(p_cmd, p_param, sizeof(struct gapc_get_dev_info_cfm));
ke_msg_send(p_cmd);
} else {
// do nothing;
}
}
void xc_ble_set_dev_info_cfm(int conidx, struct gapc_set_dev_info_cfm *p_param)
{
struct gapc_set_dev_info_cfm *p_cmd =
KE_MSG_ALLOC(GAPC_SET_DEV_INFO_CFM, KE_BUILD_ID(TASK_GAPC, conidx),
TASK_APP, gapc_set_dev_info_cfm);
memcpy(p_cmd, p_param, sizeof(struct gapc_set_dev_info_cfm));
ke_msg_send(p_cmd);
}
void xc_ble_encrypt(int conidx, struct gapc_encrypt_cmd *p_param)
{
struct gapc_encrypt_cmd *p_cmd =
KE_MSG_ALLOC(GAPC_ENCRYPT_CMD, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
gapc_encrypt_cmd);
memcpy(p_cmd, p_param, sizeof(struct gapc_encrypt_cmd));
p_cmd->operation = GAPC_ENCRYPT;
ke_msg_send(p_cmd);
}
/// issue from master
void xc_ble_encrypt_cfm(int conidx, struct gapc_encrypt_cfm *p_param)
{
struct gapc_encrypt_cfm *p_cmd =
KE_MSG_ALLOC(GAPC_ENCRYPT_CFM, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
gapc_encrypt_cfm);
memcpy(p_cmd, p_param, sizeof(struct gapc_encrypt_cfm));
ke_msg_send(p_cmd);
}
/// issue from slave
void xc_ble_req_security(int conidx, uint8_t sec_auth)
{
struct gapc_security_cmd *p_cmd =
KE_MSG_ALLOC(GAPC_SECURITY_CMD, KE_BUILD_ID(TASK_GAPC, conidx),
TASK_APP, gapc_security_cmd);
p_cmd->operation = GAPC_SECURITY_REQ;
p_cmd->auth = sec_auth;
ke_msg_send(p_cmd);
}
void xc_ble_set_pkt_size(int conidx, uint16_t tx_octets, uint16_t tx_time)
{
struct gapc_set_le_pkt_size_cmd *p_cmd =
KE_MSG_ALLOC(GAPC_SET_LE_PKT_SIZE_CMD, KE_BUILD_ID(TASK_GAPC, conidx),
TASK_APP, gapc_set_le_pkt_size_cmd);
p_cmd->operation = GAPC_SET_LE_PKT_SIZE;
p_cmd->tx_octets = tx_octets;
p_cmd->tx_time = tx_time;
// Send the message
ke_msg_send(p_cmd);
}
void xc_ble_set_rx_pkt_size(int conidx, uint16_t rx_octets, uint16_t rx_time)
{
struct gapc_set_max_rx_size_and_time_cmd *p_cmd = KE_MSG_ALLOC(
GAPC_SET_MAX_RX_SIZE_AND_TIME_CMD, KE_BUILD_ID(TASK_GAPC, conidx),
TASK_APP, gapc_set_max_rx_size_and_time_cmd);
p_cmd->operation = GAPC_SET_MAX_RX_SIZE_AND_TIME;
p_cmd->rx_octets = rx_octets;
p_cmd->rx_time = rx_time;
// Send the message
ke_msg_send(p_cmd);
}
void xc_ble_set_channel_map(struct gapm_set_channel_map_cmd *p_param)
{
struct gapm_set_channel_map_cmd *p_cmd =
KE_MSG_ALLOC(GAPM_SET_CHANNEL_MAP_CMD, TASK_GAPM, TASK_APP,
gapm_set_channel_map_cmd);
memcpy(p_cmd, p_param, sizeof(struct gapm_set_channel_map_cmd));
p_cmd->operation = GAPM_SET_CHANNEL_MAP;
ke_msg_send(p_cmd);
}
#endif // (BLE_APP_PRESENT)
+630
View File
@@ -0,0 +1,630 @@
/**
****************************************************************************************
* @file xc_gap_api.h
* @brief GAP API.
* Copyright (c) 2022 - 2025, XinChip
* All rights reserved.
****************************************************************************************
*/
#ifndef __XC_GAP_API_H__
#define __XC_GAP_API_H__
#include "gapc_msg.h"
#include "gapm_msg.h"
#include "ke_msg.h"
/*
* DEFINES
****************************************************************************************
*/
#define CE_LEN_MIN 2
#define CE_LEN_MAX 4
#define DEVICE_NAME_MAX_LEN 18
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Called only in the app_init(). It's used to reset the device but setting\n
* device configuration is still required to use host stack.\n
* Software reset: This will initialize the RW-BLE Host stack rearrange to default settings the ATT, GAP, GATT,\n
* L2CAP and SMP blocks. Furthermore, this will cause the host to send a reset command down to the link\n
* layer part.
* Platform reset: Use platform mechanism to reset hardware.
* @note Trigger GAPM_CMP_EVT, operation is GAPM_RESET
*****************************************************************************************
*/
void xc_ble_gapm_reset(void);
/**
****************************************************************************************
* @brief Set the device configuration such as:\n
* Device role\n
* Manage device address type: Public, Private static or Generated for Privacy\n
* Internal IRK used to generate resolvable random address.\n
* Set Internal GAP / GATT service start.\n
* Set specific write permissions on the appearance and name attributes in internal GAP database.\n
* Manage presence of some attribute.\n
* Configure Data Length Extension features.\n
* The set device configuration first resets the device to close all active link and configured profiles.\n
* This command must be sent before adding profiles and start air activities.
* @note
* Trigger GAPM_CMP_EVT, operation is GAPM_SET_DEV_CONFIG.
*
* @param[in] cfg_param Pointer to the device configurtion
* structure.
*
****************************************************************************************
*/
void xc_ble_set_dev_config(struct gapm_set_dev_config_cmd *cfg_param);
/**
****************************************************************************************
* @brief Get information about local device such as:\n
* Local Device Name\n
* Local Device Version\n
* Local Device Public BD Address\n
* Data Length Extension parameters\n
* Antenna information
*
* @note
* operation is:\n
* GAPM_DEV_VERSION_IND: If local device version is requested.\n
* GAPM_DEV_BDADDR_IND: if local device public BD Address is requested.\n
* GAPM_DEV_ADV_TX_POWER_IND: If advertising TX power level is requested.\n
* GAPM_DBG_MEM_INFO_IND: if memory information are requested (DEBUG ONLY).\n
* GAPM_SUGG_DFLT_DATA_LEN_IND: if suggested Default Data Length is requested.\n
* GAPM_MAX_DATA_LEN_IND: if Maximum Data Length is requested.\n
* GAPM_NB_ADV_SETS_IND: if number of advertising sets is requested.\n
* GAPM_MAX_ADV_DATA_LEN_IND: if maximum advertising data length is requested.\n
* GAPM_ANTENNA_INF_IND: if antenna information requested.\n
* GAPM_CMP_EVT: When operation completed.\n
*
* @param[in] cmd Command for information
*
****************************************************************************************
*/
void xc_ble_get_dev_info(struct gapm_get_dev_info_cmd *cmd);
/**
****************************************************************************************
* @brief Resolve provided random address using array of Identity Resolution Key (IRK) exchanged and bonded with\n
* devices during pairing operations.\n
* Operation will complete successfully if address has been correctly resolved and GAPM_ADDR_SOLVED_IND\n
* message will be triggered to inform which key has been used to perform resolution.\n
* Else operation complete with GAP_ERR_NOT_FOUND error status code.
*
* @note
* GAPM_ADDR_SOLVED_IND: triggered if address correctly resolved.\n
* GAPM_CMP_EVT: When operation completed, operation is GAPM_RESOLV_ADDR.
*
* @param[in] nb_key Number of provided IRK (sahlle be > 0).
* @param[in] addr Pointer to resolvable random address to solve.
* @param[in] irk Pointer to array of IRK used for address resolution (MSB -> LSB).
*
****************************************************************************************
*/
void xc_ble_resolve_addr(uint8_t nb_key,gap_addr_t *addr,uint8_t *irk);
/**
****************************************************************************************
* @brief Generate a random device address without starting any air operation. This can be useful for privacy in order\n
* to generate the reconnection address on demand.
*
* @note
* GAPM_DEV_BDADDR_IND: triggered when address generated.\n
* GAPM_CMP_EVT: When operation completed, operation is GAPM_GEN_RAND_ADDR.
*
* @param[in] p_param random address type. @see enum random_addr_type
****************************************************************************************
*/
void xc_ble_gen_random_addr(struct gapm_gen_rand_addr_cmd *p_param);
/**
****************************************************************************************
* @brief Read the local P-256 Public Key. This key is renewed each time this command is called by\n
* requester and so each pairing using secure connection.
*
* @note
* GAPM_PUB_KEY_IND: triggered when P-256 Public Key properly read\n
* GAPM_CMP_EVT: When operation completed, operation is GAPM_GET_PUB_KEY.
*
****************************************************************************************
*/
void xc_ble_get_pub_key(void);
/**
****************************************************************************************
* @brief Used to generate an 8-byte random number. This can be useful to generate LTK\n
* random number before distributing it.
*
* @note
* GAPM_GEN_RAND_NB_IND: triggered when random number is generated.\n
* GAPM_CMP_EVT: When operation completed, operation is GAPM_GEN_RAND_NB.
*
****************************************************************************************
*/
void xc_ble_gen_random_nb(void);
/**
****************************************************************************************
* @brief Command to change the current IRK for a renewed one, it can be used every time\n
* no air operation is being performed.
* @note
* GAPM_CMP_EVT: When operation completed,
*
* @note This can only be called during no air operation, operation is GAPM_SET_IRK.
*
* @param[out] p_param Pointer to a security key data structure.
*
****************************************************************************************
*/
void xc_ble_set_irk(gap_sec_key_t *irk);
/**
****************************************************************************************
* @brief Get local or peer resolvable private address
*
* @note operation is:\n
* GAPM_GET_RAL_LOC_ADDR: Get resolving local address\n
* GAPM_GET_RAL_PEER_ADDR: Get resolving peer address\n
*
* @note
* GAPM_RAL_ADDR_IND: Return requested address.\n
* GAPM_CMP_EVT: When operation has been completed.
*
* @param[in] p_param Pointer Read local or peer address cmd ptr.
*
****************************************************************************************
*/
void xc_ble_get_ral_addr(struct gapm_get_ral_addr_cmd *p_param);
/**
****************************************************************************************
* @brief Request to set the content of the Resolving List. The current content of the indicated list will be cleared\n
* and replaced by the indicated content.\n
* If number of addresses to be added in the list is greater than list size, a GAP_ERR_INSUFF_RESOURCES status\n
* is returned in the GAPM_CMP_EVT message.\n
* A device can be present only once in the list. If not the case a GAP_ERR_INVALID_PARAM status is returned.
*
* @note
* GAPM_CMP_EVT: When operation has been completed, operation is GAPM_SET_RAL.
*
* @note This will overwrite the current resolving list.
*
* @param[in] size Number of entries to be added in the list. 0 means that list content has to be cleared.
* @param[in] ral_info Pointer to list of entries to be added in the list.
*
****************************************************************************************
*/
void xc_ble_set_ral_list(uint8_t size, struct gap_ral_dev_info *ral_info);
/**
****************************************************************************************
* @brief Request to set the content of the White List. The current content of the indicated list will be cleared\n
* and replaced by the indicated content.\n
* If number of addresses to be added in the list is greater than list size, a GAP_ERR_INSUFF_RESOURCES status\n
* is returned in the GAPM_CMP_EVT message.\n
* A device can be present only once in the list. If not the case a GAP_ERR_INVALID_PARAM status is returned.
*
* @note
* GAPM_CMP_EVT: When operation has been completed, operation is GAPM_SET_WL.
*
* @note This will overwrite the current white list.
*
* @param[in] size Number of entries to be added in the list. 0 means that list content has to be cleared.
* @param[in] wl_info Pointer to list of entries to be added in the list.
*
****************************************************************************************
*/
void xc_ble_set_white_list(uint8_t size, gap_bdaddr_t *wl_info);
/**
****************************************************************************************
* @brief Create an advertising activity.
* @note The number of activities that can be created in parallel is limited. If the limit has been reached and a new\n
* activity cannot be created, a GAP_ERR_INSUFF_RESOURCES status will be returned in the GAPM_CMT_EVT message.
* @note
* GAPM_ACTIVITY_CREATED_IND: Once the requested activity has been successfully created.\n
* GAPM_CMP_EVT: When operation has been completed, operation is GAPM_CREATE_ADV_ACTIVITY.
*
* @param[in] adv_creat_param Pointer to activity create
*structure.
*
****************************************************************************************
*/
void xc_ble_advertise_create(struct gapm_activity_create_adv_cmd *adv_creat_param);
/**
****************************************************************************************
* @brief Set advertising data for a given previously created advertising activity identified by its\n
* activity identifier.
* @note If the provided identifier appears not to identify an existing advertising activity, GAPM_CMP_EVT message\n
* will be returned with a GAP_ERR_INVALID_PARAM status.
*
* @note
* GAPM_CMP_EVT: When operation completed, operation is GAPM_SET_ADV_DATA.
*
* @param[in] actv_idx Activity identifier
* @param[in] adv_data_length ADV data length
* @param[in] p_adv_data Pointer to adv data
*
****************************************************************************************
*/
void xc_ble_set_adv_data(uint8_t actv_idx, uint16_t adv_data_length, uint8_t *p_adv_data);
/**
****************************************************************************************
* @brief Set Scan response data for a given previously created advertising activity identified by its\n
* activity identifier.
* @note If the provided identifier appears not to identify an existing advertising activity, GAPM_CMP_EVT message\n
* will be returned with a GAP_ERR_INVALID_PARAM status.
*
* @note
* GAPM_CMP_EVT: When operation completed, operation is GAPM_SET_SCAN_RSP_DATA.
*
* @param[in] actv_idx Activity identifier
* @param[in] scan_rsp_data_length Scan response data length
* @param[in] p_scan_rsp_data Pointer to scan response data.
*
*
****************************************************************************************
*/
void xc_ble_set_scan_rsp_data(uint8_t actv_idx, uint16_t scan_rsp_data_length, uint8_t *p_scan_rsp_data);
/**
****************************************************************************************
* @brief Start an advertising activity.
* @note Several advertising activities can be started in parallel.
*
* @note
* GAPM_CMP_EVT: When operation has well been started or if an error has been detected, operation is GAPM_START_ACTIVITY.
* @param[in] adv_start_param Pointer to activity start structure.
*
****************************************************************************************
*/
void xc_ble_advertise_start(struct gapm_activity_start_cmd *adv_start_param);
/**
****************************************************************************************
* @brief Create a scanning activity.
* @note
* The number of activities that can be created in parallel is limited. If the limit has been reached and a new\n
* activity cannot be created, a GAP_ERR_INSUFF_RESOURCES status will be returned in the GAPM_CMT_EVT message.
* @note
* GAPM_ACTIVITY_CREATED_IND: Once the requested activity has been successfully created.\n
* GAPM_CMP_EVT: When operation has been completed, operation is GAPM_CREATE_SCAN_ACTIVITY.
*
* @param[in] scan_creat_param Pointer to activity create
*structure.
*
****************************************************************************************
*/
void xc_ble_scan_create(struct gapm_activity_create_cmd *scan_creat_param);
/**
****************************************************************************************
* @brief Start a scanning activity.
*
* @note it is not possible to start several scanning or several initiating activities as controller only\n
* supports one scanning and one initiating procedure to be run in parallel.\n
* It is then application responsibility to decide which scanning/initiating activity can be started.\n
* If this rule is not respected, GAPM_CMP_EVT message will be returned with a\n
* GAP_ERR_COMMAND_DISALLOWED status.
*
* @note
* GAPM_CMP_EVT: When operation has well been started or if an error has been detected, operation is GAPM_START_ACTIVITY.
* @param[in] scan_start_param Pointer to activity start structure.
*
****************************************************************************************
*/
void xc_ble_scan_start(struct gapm_activity_start_cmd *scan_start_param);
/**
****************************************************************************************
* @brief Create a initiating activity.
*
* @note
* GAPM_ACTIVITY_CREATED_IND: Once the requested activity has been successfully created.\n
* GAPM_CMP_EVT: When operation has been completed, operation is GAPM_CREATE_INIT_ACTIVITY.\n
* The number of activities that can be created in parallel is limited. If the limit has been reached and a new\n
* activity cannot be created, a GAP_ERR_INSUFF_RESOURCES status will be returned in the GAPM_CMT_EVT message.
* @param[in] init_creat_param Pointer to activity create
*structure.
*
****************************************************************************************
*/
void xc_ble_init_create(struct gapm_activity_create_cmd *init_create_param);
/**
****************************************************************************************
* @brief Start a initiating activity.
*
* @note
* GAPM_CMP_EVT: When operation has well been started or if an error has been detected, operation is GAPM_ACTIVITY_START_CMD.\n
* it is not possible to start several scanning or\n
* several initiating activities as controller only supports one scanning and one initiating procedure to be run in parallel.\n
* It is then application responsibility to decide which scanning/initiating activity can be started.\n
* If this rule is not respected, GAPM_CMP_EVT message will be returned with a\n
* GAP_ERR_COMMAND_DISALLOWED status.
* @param[in] init_start_param Pointer to activity start structure.
*
****************************************************************************************
*/
void xc_ble_init_start(struct gapm_activity_start_cmd *init_start_param);
/**
****************************************************************************************
* @brief Stop an activity or all activities.
*
* @note Request the host to stop a started activity identified by its activity identifier.\n
* If the requested activity does not exist, GAPM_CMP_EVT message is returned with a\n
* GAP_ERR_INVALID_PARAM status. If the activity exists but was not started, error GAP_ERR_COMMAND_DISALLOWED\n
* is and no GAPM_ACTIVITY_STOPPED_IND message is sent.
*
* @note
* GAPM_ACTIVITY_STOPPED_IND: Once the requested activity has been successfully stopped.\n
* GAPM_CMP_EVT: When operation has been completed, operation is GAPM_ACTIVITY_START_CMD or GAPM_STOP_ALL_ACTIVITIES.
*
* @param[in] actv_idx Activity index ,If less than 0, stop all
*activities
*
****************************************************************************************
*/
void xc_ble_activity_stop(int actv_idx);
/**
****************************************************************************************
* @brief Delete an activity or all activities
*
* @note Request the host to delete either an activity identified by its activity identifier or all currently existing\n
* activities.\n
* If selected activity is not stopped (GAPM_DELETE_ACTIVITY operation) or if at least one activity is still\n
* running (GAPM_DELETE_ALL_ACTIVITIES), a GAP_ERR_COMMAND_DISALLOWED status will be returned in the\n
* GAPM_CMP_EVT message.
*
* @note
* GAPM_CMP_EVT: When operation has been completed, operation is GAPM_DELETE_ACTIVITY or GAPM_DELETE_ALL_ACTIVITIES.
*
* @param[in] actv_idx Activity index , If less than 0, stop all activities.
*activities
*
****************************************************************************************
*/
void xc_ble_activity_delete(int actv_idx);
/**
****************************************************************************************
* @brief Request for disconnection of the link. This can be requested by master or slave of the connection.
* @note
* Reason of disconnection shall be a valid disconnection reason @see enum co_error
* @note
* Either master or slave can call this function.
*
* @param[in] conidx Connection index.
* @param[in] reason Reason of disconnection, 0x13:User on the remote device terminated the connnection
*
****************************************************************************************
*/
void xc_ble_disconnect(int conidx, uint32_t reason);
/**
****************************************************************************************
* @brief Update connection paramters
*
* @note
* GAPC_PARAM_UPDATED_IND: event triggered if connection parameters are updated.\n
* GAPC_CMP_EVT: When operation completed, operation is GAPC_UPDATE_PARAMS.
*
* @note: Can be used by both master and slave
*
* @param[in] conidx Connection index
* @param[in] p_conn_param Pointer to update parameters structure.
*
****************************************************************************************
*/
void xc_ble_update_param(int conidx, uint16_t intv_min, uint16_t intv_max,
uint16_t latency, uint16_t time_out);
/**
****************************************************************************************
* @brief Confirm connection request\n
* Set specific link security configuration and bonding data,\n
* Set connection bond data,\n
* Authentication and authorization link configuration.\n
* This confirmation message shall be sent by application after receiving a GAPC_CONNECTION_REQ_IND in\n
* order to enables local attribute tasks and security manager for the connection.\n
* It can be resent later if peer device information is retrieved later (for instance when a master initiates an\n
* encryption, information of the LTK can be used to identify peer device). In fact, when encryption is initiated\n
* by master device, it uses a couple of encryption diversifier (ediv) and random number (rand_nb) that can be\n
* used to retrieve corresponding encryption Long Term Key (LTK) that has been exchanged during a previous\n
* connection. By retrieving the LTK, we retrieve a known device and in that case before terminating encryption\n
* procedure, application shall update connection parameters.
* @note This is to response to the event "GAP_EVT_CONN_REQ". Application can\n
* call this API in the call back.\n
* If authentication parameter is marked has “Not Bonded”, other parameters are ignored and peer\n
* device is considered as an unknown device.
*
* @param[in] conidx Connection index
* @param[in] p_cfm Pointer to comfirm parameters structure.
*
****************************************************************************************
*/
void xc_ble_conn_cfm(int conidx, struct gapc_connection_cfm *p_cfm);
/**
****************************************************************************************
* @brief Retrieve information about peer device or about the current active link.
*
* @note
* Getting rssi information about peer device:\n
* operation is :
* GAPC_PEER_ATT_INFO_IND: Event triggered when peer device attribute DB info such as device name,\n
* appearance, slave preferred parameters or address resolution supported is requested.\n
* GAPC_PEER_VERSION_IND: Event triggered when peer device version is requested\n
* GAPC_PEER_FEATURES_IND: Event triggered when peer device features are requested\n
* GAPC_CON_RSSI_IND: Event triggered when connection RSSI is requested\n
* GAPC_CON_CHANNEL_MAP_IND: Event triggered when connection channel map is requested\n
* GAPC_LE_PING_TO_VAL_IND: Event triggered when LE Ping timeout value is requested\n
* GAPC_LE_PHY_IND: Event triggered when RX/TX PHYs are requested\n
* GAPC_CHAN_SEL_ALGO_IND: Event triggered when current channel selection algorithm is requested.\n
* GAPC_LOC_TX_PWR_IND: Event trigger when reading local TX power value\n
* GAPC_PEER_TX_PWR_IND: Event trigger when reading peer TX power value\n
* GAPC_CMP_EVT: When operation completed.
*
* @param[in] conidx Connection index
* @param[in] get_info Pointer to parameters structure operation
*
****************************************************************************************
*/
void xc_ble_get_peer_info(int conidx, struct gapc_get_info_cmd *get_info);
/**
****************************************************************************************
* @brief Used by to accept or refuse connection parameters proposed by peer device.
*
* @param[in] conidx Connection index
* @param[in] update_cfm Pointer to parameters structure.
*
****************************************************************************************
*/
void xc_ble_param_update_cfm(int conidx, struct gapc_param_update_cfm *update_cfm);
/**
****************************************************************************************
* @brief Requested by master of the link in order to initiate the bond procedure. It\n
* contains pairing requirement of initiator.
*
* @note
* GAPC_BOND_REQ_IND: Triggered if some information should be provided by device during the pairing.\n
* GAPC_BOND_IND: Triggered in order to receive key exchanged by peer device and get pairing status.\n
* GAPC_CMP_EVT: When operation completed, operation is GAPC_BOND.
*
* @param[in] conidx Connection index
* @param[in] p_bond Pointer to pairing requirement of initiator.
*
****************************************************************************************
*/
void xc_ble_bond(int conidx, struct gapc_bond_cmd *p_param);
/**
****************************************************************************************
* @brief Confirm bond request.
* @note
* Confirmation message to send after receiving a GAPC_BOND_REQ_IND message\n
* This message can contain:\n
* Slave pairing information\n
* Pairing temporary key (TK)\n
* Key to provide to the peer device during key exchange.
*
* @param[in] conidx Connection index
* @param[in] p_cfm Pointer to bond confirm data structure.
*
****************************************************************************************
*/
void xc_ble_bond_cfm(int conidx, struct gapc_bond_cfm *p_param);
/**
****************************************************************************************
* @brief Called when the peer device obtains information about the local device.\n
* Device Name,\n
* Device Appearance,\n
* Icon Device Slave preferred parameters,\n
* Device Central address resolution,\n
* Device database hash value,\n
* Resolvable Private address only after bond.\n
*
* @param[in] conidx Connection index
* @param[in] p_param Pointer to data structure.
****************************************************************************************
*/
void xc_ble_get_dev_info_cfm(int conidx, struct gapc_get_dev_info_cfm *p_param);
/**
****************************************************************************************
* @brief Send the write confirmation to the stack.
*
* @param[in] conidx Connection index
* @param[in] p_param Pointer to data structure.
****************************************************************************************
*/
void xc_ble_set_dev_info_cfm(int conidx, struct gapc_set_dev_info_cfm *p_param);
/**
****************************************************************************************
* @brief This operation can be requested only by master of the link in order to initiate encryption procedure. It\n
* contains Long Term Key that should be used during the encryption.
*
* @note
* GAPC_ENCRYPT_IND: Triggered if encryption operation succeed.\n
* GAPC_CMP_EVT: When operation completed. operation is GAPC_ENCRYPT.
*
* @param[in] conidx Connection index
* @param[in] p_param Pointer to data structure.
****************************************************************************************
*/
void xc_ble_encrypt(int conidx, struct gapc_encrypt_cmd *p_param);
/**
****************************************************************************************
* @brief Confirmation message to send after receiving a GAPC_ENCRYPT_REQ_IND message\n
* This message can is used to inform if encryption key has been found, if yes found Long Term Key and its size\n
* shall be provided.
*
* @param[in] conidx Connection index
* @param[in] p_param Pointer to data structure
****************************************************************************************
*/
void xc_ble_encrypt_cfm(int conidx, struct gapc_encrypt_cfm *p_param);
/**
****************************************************************************************
* @brief This operation can be requested only by slave of the link in order to initiate security request procedure. It\n
* contains authentication level requested by current device.
*
* @note
* GAPC_CMP_EVT: When operation completed. operation is GAPC_SECURITY_REQ.
*
* @param[in] conidx Connection index
* @param[in] p_param Pointer to data structure.
****************************************************************************************
*/
void xc_ble_req_security(int conidx, uint8_t sec_auth);
/**
****************************************************************************************
* @brief This operation to define the preferred packet length to be used by the controller\n
*
* @note
* GAPC_CMP_EVT: When operation completed. operation is GAPC_SECURITY_REQ.
* GAPC_LE_PKT_SIZE_IND: Event triggered with the new values
*
* @param[in] conidx Connection index
* @param[in] tx_octets Preferred maximum number of payload octets that the local Controller should include in\n
* a single Link Layer Data Channel PDU.
* @param[in] tx_time Preferred maximum number of microseconds that the local Controller should use to transmit\n
* a single Link Layer Data Channel PDU
****************************************************************************************
*/
void xc_ble_set_pkt_size(int conidx, uint16_t tx_octets, uint16_t tx_time);
/**
****************************************************************************************
* @brief This operation can be requested only by master of the link in order to set the channel map of the device.\n
*
* @note
* GAPC_CMP_EVT: When operation completed. operation is GAPC_SECURITY_REQ.
*
* @param[in] p_param Pointer to data structure.
****************************************************************************************
*/
void xc_ble_set_channel_map(struct gapm_set_channel_map_cmd *p_param);
#endif // __XC_GAP_API_H__
@@ -0,0 +1,122 @@
/**
****************************************************************************************
* @file xc_gatt_client_api.c
* @brief GATT client APIs source code
* Copyright (c) 2022 - 2025, XinChip
* All rights reserved.
****************************************************************************************
*/
#include "rwip_config.h"
#include "stdint.h"
#if (BLE_GATT_CLI)
#include "xc_gatt_client_api.h"
uint16_t xc_ble_gatt_user_cli_register(uint16_t pref_mtu, uint8_t prio_level,
const gatt_cli_cb_t *p_cb,
uint8_t *p_user_lid)
{
return gatt_user_cli_register(pref_mtu, prio_level, p_cb, p_user_lid);
}
uint16_t xc_ble_gatt_user_unregister(uint8_t user_lid)
{
return gatt_user_unregister(user_lid);
}
uint16_t xc_ble_gatt_cli_discover_svc(uint8_t conidx, uint8_t user_lid,
uint16_t dummy, uint8_t disc_type, bool full,
uint16_t start_hdl, uint16_t end_hdl,
uint8_t uuid_type, const uint8_t *p_uuid)
{
return gatt_cli_discover_svc(conidx, user_lid, dummy, disc_type, full,
start_hdl, end_hdl, uuid_type, p_uuid);
}
uint16_t xc_ble_gatt_cli_discover_inc_svc(uint8_t conidx, uint8_t user_lid,
uint16_t dummy, uint16_t start_hdl,
uint16_t end_hdl)
{
return gatt_cli_discover_inc_svc(conidx, user_lid, dummy, start_hdl,
end_hdl);
}
uint16_t xc_ble_gatt_cli_discover_char(uint8_t conidx, uint8_t user_lid,
uint16_t dummy, uint8_t disc_type,
uint16_t start_hdl, uint16_t end_hdl,
uint8_t uuid_type, const uint8_t *p_uuid)
{
return gatt_cli_discover_char(conidx, user_lid, dummy, disc_type, start_hdl,
end_hdl, uuid_type, p_uuid);
}
uint16_t xc_ble_gatt_cli_discover_desc(uint8_t conidx, uint8_t user_lid,
uint16_t dummy, uint16_t start_hdl,
uint16_t end_hdl)
{
return gatt_cli_discover_desc(conidx, user_lid, dummy, start_hdl, end_hdl);
}
uint16_t xc_ble_gatt_cli_discover_cancel(uint8_t conidx, uint8_t user_lid,
uint16_t dummy)
{
return gatt_cli_discover_cancel(conidx, user_lid, dummy);
}
uint16_t xc_ble_gatt_cli_read(uint8_t conidx, uint8_t user_lid, uint16_t dummy,
uint16_t hdl, uint16_t offset, uint16_t length)
{
return gatt_cli_read(conidx, user_lid, dummy, hdl, offset, length);
}
uint16_t xc_ble_gatt_cli_read_by_uuid(uint8_t conidx, uint8_t user_lid,
uint16_t dummy, uint16_t start_hdl,
uint16_t end_hdl, uint8_t uuid_type,
const uint8_t *p_uuid)
{
return gatt_cli_read_by_uuid(conidx, user_lid, dummy, start_hdl, end_hdl,
uuid_type, p_uuid);
}
uint16_t xc_ble_gatt_cli_write(uint8_t conidx, uint8_t user_lid, uint16_t dummy,
uint8_t write_type, uint16_t hdl, uint16_t length,
const uint8_t* p_data)
{
co_buf_t* p_buf = NULL;
uint16_t status;
if(co_buf_alloc(&p_buf, GATT_BUFFER_HEADER_LEN, length, GATT_BUFFER_TAIL_LEN) == CO_BUF_ERR_NO_ERROR)
{
co_buf_copy_data_from_mem(p_buf, p_data, length);
status = gatt_cli_write(conidx, user_lid, dummy, write_type, hdl, 0, p_buf);
co_buf_release(p_buf);
}
else
{
status = GAP_ERR_INSUFF_RESOURCES;
}
return (status);
}
uint16_t xc_ble_gatt_cli_event_register(uint8_t conidx, uint8_t user_lid,
uint16_t start_hdl, uint16_t end_hdl)
{
return gatt_cli_event_register(conidx, user_lid, start_hdl, end_hdl);
}
uint16_t xc_ble_gatt_cli_event_unregister(uint8_t conidx, uint8_t user_lid,
uint16_t start_hdl, uint16_t end_hdl)
{
return gatt_cli_event_unregister(conidx, user_lid, start_hdl, end_hdl);
}
uint16_t xc_ble_gatt_cli_indicate_cfm(uint8_t conidx, uint8_t user_lid,
uint16_t token)
{
return gatt_cli_att_event_cfm(conidx, user_lid, token);
}
#endif // (BLE_GATT_CLI)
uint16_t xc_ble_gatt_cli_mtu_exch(uint8_t conidx, uint8_t user_lid)
{
return gatt_cli_mtu_exch(conidx, user_lid);
}
@@ -0,0 +1,320 @@
/**
****************************************************************************************
* @file xc_gatt_client_api.h
* @brief GATT client API.
* Copyright (c) 2022 - 2025, XinChip
* All rights reserved.
****************************************************************************************
*/
#ifndef __XC_GATT_CLIENT_API_H__
#define __XC_GATT_CLIENT_API_H__
#include "gatt_db.h" // GATT Database access
#include "gatt.h"
#include "co_buf.h"
#include "rwble_hl_error.h"
/**
****************************************************************************************
* @brief Command used to register a GATT user. This must be done prior to any GATT
* procedure execution.
*
* A GATT client user can initiate any client procedure, and shall be able to
* handle all client initiated message events
*
* Same module can register multiple GATT users.
*
* @param[in] pref_mtu Preferred MTU for attribute exchange.
* @param[in] prio_level User attribute priority level
* @param[in] p_cb Pointer to set of callback functions to be used for communication
* with the GATT server user
* @param[out] p_user_lid Pointer where GATT user local identifier will be set
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_user_cli_register(uint16_t pref_mtu, uint8_t prio_level, const gatt_cli_cb_t* p_cb, uint8_t* p_user_lid);
/**
****************************************************************************************
* @brief Command used to unregister a GATT user (client or server).
*
* @param[in] user_lid GATT User Local identifier
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_user_unregister(uint8_t user_lid);
/**
****************************************************************************************
* @brief Command used by a GATT client user to discover primary or secondary services,
* exposed by peer device in its attribute database.
*
* All services can be discovered or filtering services having a specific UUID.
* The discovery is done between start handle and end handle range.
* For a complete discovery start handle must be set to 0x0001 and end handle to
* 0xFFFF.
*
* Wait for @see cb_discover_cmp execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
* @param[in] disc_type GATT Service discovery type (@see enum gatt_svc_discovery_type)
* @param[in] full Perform discovery of all information present in the service
* (True: enable, False: disable)
* @param[in] start_hdl Search start handle
* @param[in] end_hdl Search end handle
* @param[in] uuid_type UUID Type (@see enum gatt_uuid_type)
* @param[in] p_uuid Pointer to searched Service UUID (meaningful only for
* discovery by UUID)
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_discover_svc(uint8_t conidx, uint8_t user_lid, uint16_t dummy, uint8_t disc_type, bool full,
uint16_t start_hdl, uint16_t end_hdl, uint8_t uuid_type, const uint8_t* p_uuid);
/**
****************************************************************************************
* @brief Command used by a GATT client user to discover included services, exposed
* by peer device in its attribute database.
*
* The discovery is done between start handle and end handle range.
* For a complete discovery start handle must be set to 0x0001 and end handle to
* 0xFFFF.
*
* Wait for @see cb_discover_cmp execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
* @param[in] start_hdl Search start handle
* @param[in] end_hdl Search end handle
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_discover_inc_svc(uint8_t conidx, uint8_t user_lid, uint16_t dummy,
uint16_t start_hdl, uint16_t end_hdl);
/**
****************************************************************************************
* @brief Command used by a GATT client user to discover all or according to a specific
* UUID characteristics exposed by peer device in its attribute database.
*
* The discovery is done between start handle and end handle range.
* For a complete discovery start handle must be set to 0x0001 and end handle to
* 0xFFFF.
*
* Wait for @see cb_discover_cmp execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
* @param[in] disc_type GATT characteristic discovery type (@see enum gatt_char_discovery_type)
* @param[in] start_hdl Search start handle
* @param[in] end_hdl Search end handle
* @param[in] uuid_type UUID Type (@see enum gatt_uuid_type)
* @param[in] p_uuid Pointer to searched Attribute Value UUID (meaningful only
* for discovery by UUID)
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_discover_char(uint8_t conidx, uint8_t user_lid, uint16_t dummy, uint8_t disc_type,
uint16_t start_hdl, uint16_t end_hdl, uint8_t uuid_type, const uint8_t* p_uuid);
/**
****************************************************************************************
* @brief Command used by a GATT client user to discover characteristic descriptor
* exposed by peer device in its attribute database.
*
* The discovery is done between start handle and end handle range.
* For a complete discovery start handle must be set to 0x0001 and end handle to
* 0xFFFF.
*
* Wait for @see cb_discover_cmp execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
* @param[in] start_hdl Search start handle
* @param[in] end_hdl Search end handle
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_discover_desc(uint8_t conidx, uint8_t user_lid, uint16_t dummy, uint16_t start_hdl, uint16_t end_hdl);
/**
****************************************************************************************
* @brief Command used by a GATT client user to cancel an on-going discovery procedure.
* The dummy parameter in the request must be equals to dummy parameter used for
* service discovery command.
*
* The discovery is aborted as soon as on-going discovery attribute transaction
* is over.
*
* Wait for @see cb_discover_cmp execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_discover_cancel(uint8_t conidx, uint8_t user_lid, uint16_t dummy);
/**
****************************************************************************************
* @brief Command used by a GATT client user to read value of an attribute (identified
* by its handle) present in peer database.
*
* Wait for @see cb_read_cmp execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
* @param[in] hdl Attribute handle
* @param[in] offset Value offset
* @param[in] length Value length to read (0 = read all)
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_read(uint8_t conidx, uint8_t user_lid, uint16_t dummy,
uint16_t hdl, uint16_t offset, uint16_t length);
/**
****************************************************************************************
* @brief Command used by a GATT client user to read value of an attribute with a given
* UUID in peer database.
*
* Wait for @see cb_read_cmp execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
* @param[in] start_hdl Search start handle
* @param[in] end_hdl Search end handle
* @param[in] uuid_type UUID Type (@see enum gatt_uuid_type)
* @param[in] p_uuid Pointer to searched attribute UUID (LSB First)
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_read_by_uuid(uint8_t conidx, uint8_t user_lid, uint16_t dummy,
uint16_t start_hdl, uint16_t end_hdl, uint8_t uuid_type, const uint8_t* p_uuid);
/**
****************************************************************************************
* @brief Command used by a GATT client user to request to write value of an attribute
* in peer database.
*
* Since user is not aware of MTU size of the bearer used for attribute
* transmission it cannot be considered reliable.
*
* For a GATT_WRITE_NO_RESP if attribute bearer max transmission size isn't sufficient,
* a GATT_WRITE (with response) procedure will be used.
*
* For a GATT_WRITE_SIGNED, if attribute bearer max transmission size isn't sufficient,
* the procedure is aborted with L2CAP_ERR_INVALID_MTU error code.
*
* Wait for @see cb_write_cmp execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
* @param[in] write_type GATT write type (@see enum gatt_write_type)
* @param[in] hdl Attribute handle
* @param[in] length Value length
* @param[in] p_data Pointer to data value
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_write(uint8_t conidx, uint8_t user_lid, uint16_t dummy, uint8_t write_type,
uint16_t hdl, uint16_t length, const uint8_t* p_data);
/**
****************************************************************************************
* @brief Command used by a GATT client user to register for reception of events
* (notification / indication) for a given handle range.
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] start_hdl Attribute start handle
* @param[in] end_hdl Attribute end handle
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_event_register(uint8_t conidx, uint8_t user_lid, uint16_t start_hdl, uint16_t end_hdl);
/**
****************************************************************************************
* @brief Command used by a GATT client user to stop reception of events (notification /
* indication) onto a specific handle range.
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] start_hdl Attribute start handle
* @param[in] end_hdl Attribute end handle
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_event_unregister(uint8_t conidx, uint8_t user_lid, uint16_t start_hdl, uint16_t end_hdl);
/**
****************************************************************************************
* @brief Request a MTU exchange on legacy attribute bearer.
* There is no callback executed when the procedure is over.
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_mtu_exch(uint8_t conidx, uint8_t user_lid);
/**
****************************************************************************************
* @brief Upper layer provide status of attribute event handled by GATT client user.
* confirmation of indicate by GATT client.
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] token Procedure token provided in corresponding callback
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_cli_indicate_cfm(uint8_t conidx, uint8_t user_lid, uint16_t token);
#endif // __XC_GATT_CLIENT_API_H__
@@ -0,0 +1,130 @@
/**
****************************************************************************************
* @file xc_gatt_server_api.c
* @brief GATT server APIs source code
* Copyright (c) 2022 - 2025, XinChip
* All rights reserved.
****************************************************************************************
*/
#include "rwip_config.h"
#if (BLE_APP_PRESENT)
#include "xc_gatt_server_api.h"
uint16_t xc_ble_gatt_user_srv_register(uint16_t pref_mtu, uint8_t prio_level,
const gatt_srv_cb_t *p_cb,
uint8_t *p_user_lid)
{
return gatt_user_srv_register(pref_mtu, prio_level, p_cb, p_user_lid);
}
uint16_t xc_ble_gatt_service_add(uint8_t user_lid, uint8_t info,
const uint8_t *p_uuid, uint8_t nb_att,
const uint8_t *p_att_mask,
const gatt_att_desc_t *p_atts,
uint8_t nb_att_rsvd, uint16_t *p_start_hdl)
{
return gatt_db_svc_add(user_lid, info, p_uuid, nb_att, p_att_mask, p_atts,
nb_att_rsvd, p_start_hdl);
}
uint16_t xc_ble_gatt_service16_add(uint8_t user_lid, uint8_t info,
uint16_t uuid16, uint8_t nb_att,
const uint8_t *p_att_mask,
const gatt_att16_desc_t *p_atts,
uint8_t nb_att_rsvd, uint16_t *p_start_hdl)
{
return gatt_db_svc16_add(user_lid, info, uuid16, nb_att, p_att_mask, p_atts,
nb_att_rsvd, p_start_hdl);
}
#if (MIN_STACK)
uint16_t xc_ble_gatt_service_remove(uint8_t user_lid, uint16_t start_hdl)
{
return gatt_db_svc_remove(user_lid, start_hdl);
}
#endif // (MIN_STACK)
uint16_t xc_ble_gatt_srv_notify(uint8_t conidx, uint8_t user_lid,
uint16_t dummy, uint16_t hdl, uint16_t length,
const uint8_t *p_value)
{
co_buf_t *p_data;
uint16_t status;
// allocate a buffer for event transmission
if (co_buf_alloc(&p_data, GATT_BUFFER_HEADER_LEN, length,
GATT_BUFFER_TAIL_LEN) != CO_BUF_ERR_NO_ERROR) {
status = ATT_ERR_INSUFF_RESOURCE;
} else {
// copy data into buffer
co_buf_copy_data_from_mem(p_data, p_value, length);
// request event to be sent
status = gatt_srv_event_send(conidx, user_lid, dummy, GATT_NOTIFY, hdl,
p_data);
co_buf_release(p_data);
}
return status;
}
uint16_t xc_ble_gatt_srv_indicate(uint8_t conidx, uint8_t user_lid,
uint16_t dummy, uint16_t hdl, uint16_t length,
const uint8_t *p_value)
{
co_buf_t *p_data;
uint16_t status;
// allocate a buffer for event transmission
if (co_buf_alloc(&p_data, GATT_BUFFER_HEADER_LEN, length,
GATT_BUFFER_TAIL_LEN) != CO_BUF_ERR_NO_ERROR) {
status = ATT_ERR_INSUFF_RESOURCE;
} else {
// copy data into buffer
co_buf_copy_data_from_mem(p_data, p_value, length);
// request event to be sent
status = gatt_srv_event_send(conidx, user_lid, dummy, GATT_INDICATE,
hdl, p_data);
co_buf_release(p_data);
}
return status;
}
uint16_t xc_ble_gatt_srv_read_cfm(uint8_t conidx, uint8_t user_lid,
uint16_t token, uint16_t status,
uint16_t att_length, uint16_t length,
const uint8_t *p_value)
{
co_buf_t *p_data = NULL;
uint8_t state;
if (status == GAP_ERR_NO_ERROR) {
// allocate a buffer for event transmission
if (co_buf_alloc(&p_data, GATT_BUFFER_HEADER_LEN, length,
GATT_BUFFER_TAIL_LEN) != CO_BUF_ERR_NO_ERROR) {
status = ATT_ERR_INSUFF_RESOURCE;
} else {
// copy data into buffer
co_buf_copy_data_from_mem(p_data, p_value, length);
}
}
// execute confirmation native function
state = gatt_srv_att_read_get_cfm(conidx, user_lid, token, status,
att_length, p_data);
// release buffer
if (p_data != NULL) {
co_buf_release(p_data);
}
return state;
}
uint16_t xc_ble_gatt_srv_write_cfm(uint8_t conidx, uint8_t user_lid,
uint16_t token, uint16_t status)
{
return gatt_srv_att_val_set_cfm(conidx, user_lid, token, status);
}
#endif // (BLE_APP_PRESENT)
@@ -0,0 +1,225 @@
/**
****************************************************************************************
* @file xc_gatt_server_api.h
* @brief GATT server API.
* Copyright (c) 2022 - 2025, XinChip
* All rights reserved.
****************************************************************************************
*/
#ifndef __XC_GATT_SERVER_API_H__
#define __XC_GATT_SERVER_API_H__
#include "gatt_db.h" // GATT Database access
#include "gatt.h"
#include "co_buf.h"
#include "rwble_hl_error.h"
enum gatt_err
{
/// No error
GATT_NO_ERROR = 0x00,
};
enum gatt_switch
{
GATT_DISABLE = 0,
GATT_ENABLE = 1
};
/**
****************************************************************************************
* @brief Command used to register a GATT user. This must be done prior to any GATT
* procedure execution.
*
* A GATT server can manipulate local attribute database and initiate server
* procedures. It shall be able to handle all server initiated events
*
* Same module can register multiple GATT users.
*
* @param[in] pref_mtu Preferred MTU for attribute exchange.
* @param[in] prio_level User attribute priority level
* @param[in] p_cb Pointer to set of callback functions to be used for communication
* with the GATT server user
* @param[out] p_user_lid Pointer where GATT user local identifier will be set
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_user_srv_register(uint16_t pref_mtu, uint8_t prio_level, const gatt_srv_cb_t* p_cb, uint8_t* p_user_lid);
/**
****************************************************************************************
* @brief Command used to add a service into local attribute database.
*
* If start handle is set to zero (invalid attribute handle), GATT looks for a
* free handle block matching with number of attributes to reserve.
* Else, according to start handle, GATT checks if attributes to reserve are
* not overlapping part of existing database.
*
* An added service is automatically visible for peer device.
*
* @note First attribute in attribute array must be a Primary or a Secondary service
*
* @param[in] user_lid GATT User Local identifier
* @param[in] info Service Information bit field (@see enum gatt_svc_info_bf)
* @param[in] p_uuid Pointer to service UUID (LSB first)
* @param[in] nb_att Number of attribute(s) in service
* @param[in] p_att_mask Pointer to mask of attribute to insert in database:
* - If NULL insert all attributes
* - If bit set to 1: attribute inserted
* - If bit set to 0: attribute not inserted
* @param[in] p_atts Pointer to List of attribute description present in service.
* @param[in] nb_att_rsvd Number of attribute(s) reserved for the service (shall be equals or greater nb_att)
* Prevent any services to be inserted between start_hdl and (start_hdl + nb_att_rsvd -1)
* @param[in|out] p_start_hdl Pointer to Service Start Handle (0 = chosen by GATT module)
* Pointer updated with service start handle associated to
* created service.
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_service_add(uint8_t user_lid, uint8_t info, const uint8_t* p_uuid, uint8_t nb_att, const uint8_t* p_att_mask,
const gatt_att_desc_t* p_atts, uint8_t nb_att_rsvd, uint16_t* p_start_hdl);
/**
****************************************************************************************
* @brief Command used to add a service into local attribute database.
*
* Service and attributes UUIDs in service must be 16-bit
*
* If start handle is set to zero (invalid attribute handle), GATT looks for a
* free handle block matching with number of attributes to reserve.
* Else, according to start handle, GATT checks if attributes to reserve are
* not overlapping part of existing database.
*
* An added service is automatically visible for peer device.
*
* @note First attribute in attribute array must be a Primary or a Secondary service
*
* @param[in] user_lid GATT User Local identifier
* @param[in] info Service Information bit field (@see enum gatt_svc_info_bf)
* @param[in] uuid16 Service UUID (16-bit UUID - LSB First)
* @param[in] nb_att Number of attribute(s) in service
* @param[in] p_att_mask Pointer to mask of attribute to insert in database:
* - If NULL insert all attributes
* - If bit set to 1: attribute inserted
* - If bit set to 0: attribute not inserted
* @param[in] p_atts Pointer to List of attribute (with 16-bit uuid) description present in service.
* @param[in] nb_att_rsvd Number of attribute(s) reserved for the service (shall be equals or greater nb_att)
* Prevent any services to be inserted between start_hdl and (start_hdl + nb_att_rsvd - 1)
* @param[in|out] p_start_hdl Pointer to Service Start Handle (0 = chosen by GATT module)
* Pointer updated with service start handle associated to
* created service.
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_service16_add(uint8_t user_lid, uint8_t info, uint16_t uuid16, uint8_t nb_att, const uint8_t* p_att_mask,
const gatt_att16_desc_t* p_atts, uint8_t nb_att_rsvd, uint16_t* p_start_hdl);
/**
****************************************************************************************
* @brief Command used to remove a service from local attribute database.
*
* Only GATT user responsible of service can remove it.
*
* @param[in] user_lid GATT User Local identifier
* @param[in] start_hdl Service Start Handle
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_service_remove(uint8_t user_lid, uint16_t start_hdl);
/**
****************************************************************************************
* @brief Command used by a GATT server user to send notifications
*
* Since user is not aware of MTU size of the bearer used for attribute
* transmission it cannot be considered reliable. If size of the data buffer is too
* big, data is truncated to max supported length.
*
* Wait for @see cb_event_sent execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
* @param[in] hdl Attribute handle
* @param[in] length Value length
* @param[in] p_value Pointer to Value to transmit
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_srv_notify(uint8_t conidx, uint8_t user_lid, uint16_t dummy, uint16_t hdl,
uint16_t length, const uint8_t *p_value);
/**
****************************************************************************************
* @brief Command used by a GATT server user to send indication
*
* Since user is not aware of MTU size of the bearer used for attribute
* transmission it cannot be considered reliable. If size of the data buffer is too
* big, data is truncated to max supported length.
*
* Wait for @see cb_event_sent execution before starting a new procedure
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] dummy Dummy parameter whose meaning is upper layer dependent and
* which is returned in command complete.
* @param[in] hdl Attribute handle
* @param[in] length Value length
* @param[in] p_value Pointer to Value to transmit
*
* @return Status of the function execution (@see enum hl_err)
* Consider status only if an error occurs; else wait for execution completion
****************************************************************************************
*/
uint16_t xc_ble_gatt_srv_indicate(uint8_t conidx, uint8_t user_lid, uint16_t dummy, uint16_t hdl,
uint16_t length, const uint8_t *p_value);
/**
****************************************************************************************
* @brief Upper layer provide attribute value requested by GATT Layer for a read procedure
* If rejected, value is not used.
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] token Procedure token provided in corresponding callback
* @param[in] status Status of attribute value get (@see enum hl_err)
* @param[in] att_length Complete Length of the attribute value
* @param[in] length Value length
* @param[in] p_value Pointer to buffer attribute data
*
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_srv_read_cfm(uint8_t conidx, uint8_t user_lid, uint16_t token, uint16_t status,
uint16_t att_length, uint16_t length, const uint8_t *p_value);
/**
****************************************************************************************
* @brief Upper layer provide status of attribute value modification by GATT server user.
* Confirmation server user when an attribute value has been written by a
* peer device.
*
* @param[in] conidx Connection index
* @param[in] user_lid GATT User Local identifier
* @param[in] token Procedure token provided in corresponding callback
* @param[in] status Status of attribute value set (@see enum hl_err)
*
* @return Status of the function execution (@see enum hl_err)
****************************************************************************************
*/
uint16_t xc_ble_gatt_srv_write_cfm(uint8_t conidx, uint8_t user_lid, uint16_t token, uint16_t status);
#endif // __XC_GATT_SERVER_API_H__
+72
View File
@@ -0,0 +1,72 @@
/**
****************************************************************************************
*
* @file acc.h
*
* @brief Audio Content Control - Header file
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_H_
#define ACC_H_
/**
****************************************************************************************
* @addtogroup ACC Audio Content Control
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf_cfg.h" // GAF Configuration
#include "gaf.h" // GAF API
/*
* MACROS
****************************************************************************************
*/
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Module type values
enum acc_module_type
{
/// Common
ACC_MODULE_COMMON = 0,
/// Telephone Bearer Server
ACC_MODULE_TBS = 1,
/// Telephone Bearer Client
ACC_MODULE_TBC = 2,
/// Media Control Server
ACC_MODULE_MCS = 3,
/// Media Control Client
ACC_MODULE_MCC = 4,
/// Object Transfer Server
ACC_MODULE_OTS = 5,
/// Object Transfer Client
ACC_MODULE_OTC = 6,
ACC_MODULE_MAX,
};
/// List of GAF_REQ request codes
enum acc_msg_req_codes
{
ACC_GET_FEATURES = GAF_CODE(ACC, COMMON, 0),
};
/// @}
#endif // ACC_H_
@@ -0,0 +1,95 @@
/**
****************************************************************************************
*
* @file acc_msg.h
*
* @brief Audio Content Control - Definition of Kernel Messages
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_MSG_H_
#define ACC_MSG_H_
/**
****************************************************************************************
* @addtogroup ACC Audio Content Control - Definition of Kernel Messages
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc.h" // ACC Definitions
#if (GAF_ACC)
#include "gaf_msg.h" // Generic Audio Framework API Message Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Features bit field meaning
enum acc_msg_feat_bf
{
/// Telephone Bearer Service Server supported
ACC_FEAT_TBS_SUPP_POS = 0,
ACC_FEAT_TBS_SUPP_BIT = CO_BIT(ACC_FEAT_TBS_SUPP_POS),
/// Telephone Bearer Service Client supported
ACC_FEAT_TBC_SUPP_POS = 1,
ACC_FEAT_TBC_SUPP_BIT = CO_BIT(ACC_FEAT_TBC_SUPP_POS),
/// Media Control Service Server supported
ACC_FEAT_MCS_SUPP_POS = 2,
ACC_FEAT_MCS_SUPP_BIT = CO_BIT(ACC_FEAT_MCS_SUPP_POS),
/// Media Control Service Client supported
ACC_FEAT_MCC_SUPP_POS = 3,
ACC_FEAT_MCC_SUPP_BIT = CO_BIT(ACC_FEAT_MCC_SUPP_POS),
/// Object Transfer Service Server supported
ACC_FEAT_OTS_SUPP_POS = 4,
ACC_FEAT_OTS_SUPP_BIT = CO_BIT(ACC_FEAT_OTS_SUPP_POS),
/// Object Transfer Service Client supported
ACC_FEAT_OTC_SUPP_POS = 5,
ACC_FEAT_OTC_SUPP_BIT = CO_BIT(ACC_FEAT_OTC_SUPP_POS),
};
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ACC_GET_FEATURES request message
typedef struct acc_get_features_req
{
/// Request code (@see enum acc_msg_req_codes)
uint16_t req_code;
} acc_get_features_req_t;
/// Structure for ACC_GET_FEATURES response message
typedef struct acc_get_features_rsp
{
/// Request code (@see enum acc_msg_req_codes)
uint16_t req_code;
/// Status
uint16_t status;
/// Features bit field
uint32_t feat_bf;
} acc_get_features_rsp_t;
#endif //(GAF_ACC)
/// @}
#endif // ACC_MSG_H_
@@ -0,0 +1,378 @@
/**
****************************************************************************************
*
* @file acc_mc.h
*
* @brief Audio Content Control - Media Control - Header file
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_MC_H_
#define ACC_MC_H_
/**
****************************************************************************************
* @addtogroup ACC_MC Audio Content Control - Media Control
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc.h" // Audio Content Control Defintiions
/*
* DEFINES
****************************************************************************************
*/
/// Length of Object ID
#define ACC_MC_OBJ_ID_LEN (6)
/// Length of Track Changed characteristic value
#define ACC_MC_TRACK_CHANGED_LEN (0)
/// Length of Media State characteristic value
#define ACC_MC_MEDIA_STATE_LEN (1)
/// Length of Track Duration characteristic value
#define ACC_MC_TRACK_DURATION_LEN (4)
/// Length of Track Position characteristic value
#define ACC_MC_TRACK_POSITION_LEN (4)
/// Length of Playback Speed characteristic value
#define ACC_MC_PLAYBACK_SPEED_LEN (1)
/// Length of Seeking Speed characteristic value
#define ACC_MC_SEEKING_SPEED_LEN (1)
/// Length of Playing Order characteristic value
#define ACC_MC_PLAYING_ORDER_LEN (1)
/// Length of Playing Order Supported characteristic value
#define ACC_MC_PLAYING_ORDER_SUPP_LEN (2)
/// Length of Media Control Point Opcodes Supported characteristic value
#define ACC_MC_MEDIA_CP_OPCODES_SUPP_LEN (4)
/// Length of Search Control Point Result Code value
#define ACC_MC_SEARCH_CP_RESULT_LEN (1)
/// Indicate that Track Duration is unknown
#define ACC_MC_TRACK_DUR_UNKNOWN (0xFFFFFFFF)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Characteristic type values
/// Values are ordered so that the notification-capable characteristic type values are equal
/// to the characteristic type values
enum acc_mc_char_type
{
/// Media Player Name characteristic
ACC_MC_CHAR_TYPE_PLAYER_NAME = 0,
/// Track Changed characteristic
ACC_MC_CHAR_TYPE_TRACK_CHANGED,
/// Track Title characteristic
ACC_MC_CHAR_TYPE_TRACK_TITLE,
/// Track Duration characteristic
ACC_MC_CHAR_TYPE_TRACK_DURATION,
/// Track Position characteristic
ACC_MC_CHAR_TYPE_TRACK_POSITION,
/// Playback Speed characteristic
ACC_MC_CHAR_TYPE_PLAYBACK_SPEED,
/// Seeking Speed characteristic
ACC_MC_CHAR_TYPE_SEEKING_SPEED,
/// Current Track Object ID characteristic
ACC_MC_CHAR_TYPE_CUR_TRACK_OBJ_ID,
/// Next Track Object ID characteristic
ACC_MC_CHAR_TYPE_NEXT_TRACK_OBJ_ID,
/// Current Group Object ID characteristic
ACC_MC_CHAR_TYPE_CUR_GROUP_OBJ_ID,
/// Parent Group Object ID characteristic
ACC_MC_CHAR_TYPE_PARENT_GROUP_OBJ_ID,
/// Playing Order characteristic
ACC_MC_CHAR_TYPE_PLAYING_ORDER,
/// Media State characteristic
ACC_MC_CHAR_TYPE_MEDIA_STATE,
/// Media Control Point
ACC_MC_CHAR_TYPE_MEDIA_CP,
/// Media Control Point Opcodes Supported
ACC_MC_CHAR_TYPE_MEDIA_CP_OPCODES_SUPP,
/// Search Results Object ID
ACC_MC_CHAR_TYPE_SEARCH_RESULTS_OBJ_ID,
/// Search Control Point
ACC_MC_CHAR_TYPE_SEARCH_CP,
/// All characteristics above are notification-capable
ACC_MC_NTF_CHAR_TYPE_MAX,
/// Current Track Segments Object ID characteristic
ACC_MC_CHAR_TYPE_CUR_TRACK_SEG_OBJ_ID = ACC_MC_NTF_CHAR_TYPE_MAX,
/// Media Player Icon Object ID characteristic
ACC_MC_CHAR_TYPE_PLAYER_ICON_OBJ_ID,
/// Media Player Icon URL characteristic
ACC_MC_CHAR_TYPE_PLAYER_ICON_URL,
/// Playing Order Supported characteristic
ACC_MC_CHAR_TYPE_PLAYING_ORDER_SUPP,
/// Content Control ID
ACC_MC_CHAR_TYPE_CCID,
ACC_MC_CHAR_TYPE_MAX,
};
/// Descriptor type values
enum acc_mc_desc_type
{
/// Client Characteristic Configuration descriptor for Media Player Name characteristic
ACC_MC_DESC_TYPE_CCC_PLAYER_NAME = 0,
/// Client Characteristic Configuration descriptor for Track Changed characteristic
ACC_MC_DESC_TYPE_CCC_TRACK_CHANGED,
/// Client Characteristic Configuration descriptor for Track Title characteristic
ACC_MC_DESC_TYPE_CCC_TRACK_TITLE,
/// Client Characteristic Configuration descriptor for Track Duration characteristic
ACC_MC_DESC_TYPE_CCC_TRACK_DURATION,
/// Client Characteristic Configuration descriptor for Track Position characteristic
ACC_MC_DESC_TYPE_CCC_TRACK_POSITION,
/// Client Characteristic Configuration descriptor for Playback Speed characteristic
ACC_MC_DESC_TYPE_CCC_PLAYBACK_SPEED,
/// Client Characteristic Configuration descriptor for Seeking Speed characteristic
ACC_MC_DESC_TYPE_CCC_SEEKING_SPEED,
/// Client Characteristic Configuration descriptor for Current Track Object ID characteristic
ACC_MC_DESC_TYPE_CCC_CUR_TRACK_OBJ_ID,
/// Client Characteristic Configuration descriptor for Next Track Object ID characteristic
ACC_MC_DESC_TYPE_CCC_NEXT_TRACK_OBJ_ID,
/// Client Characteristic Configuration descriptor for Current Group Object ID characteristic
ACC_MC_DESC_TYPE_CCC_CUR_GROUP_OBJ_ID,
/// Client Characteristic Configuration descriptor for Parent Group Object ID characteristic
ACC_MC_DESC_TYPE_CCC_PARENT_GROUP_OBJ_ID,
/// Client Characteristic Configuration descriptor for Playing Order characteristic
ACC_MC_DESC_TYPE_CCC_PLAYING_ORDER,
/// Client Characteristic Configuration descriptor for Media State characteristic
ACC_MC_DESC_TYPE_CCC_MEDIA_STATE,
/// Client Characteristic Configuration descriptor for Media Control Point
ACC_MC_DESC_TYPE_CCC_MEDIA_CP,
/// Client Characteristic Configuration descriptor for Media Control Point Opcodes Supported
ACC_MC_DESC_TYPE_CCC_MEDIA_CP_OPCODES_SUPP,
/// Client Characteristic Configuration descriptor for Search Results Object ID
ACC_MC_DESC_TYPE_CCC_SEARCH_RESULTS_OBJ_ID,
/// Client Characteristic Configuration descriptor for Search Control Point
ACC_MC_DESC_TYPE_CCC_SEARCH_CP,
ACC_MC_DESC_TYPE_MAX,
};
/// Operation code values
enum acc_mc_opcode
{
/// Start playing the current track
ACC_MC_OPCODE_PLAY = 1,
/// Pause playing the current track
ACC_MC_OPCODE_PAUSE,
/// Fast forward the current track
ACC_MC_OPCODE_FAST_FW,
/// Fast rewind the current track
ACC_MC_OPCODE_FAST_RW,
/// Stop current activity and return to inactive state
ACC_MC_OPCODE_STOP,
/// Set the current position relative to the current position
ACC_MC_OPCODE_MOVE_RELATIVE = 16,
/// Set the current position to the previous segment of the current track
ACC_MC_OPCODE_PREV_SEG = 32,
/// Set the current position to the next segment of the current track
ACC_MC_OPCODE_NEXT_SEG,
/// Set the current position to the first segment of the current track
ACC_MC_OPCODE_FIRST_SEG,
/// Set the current position to the last segment of the current track
ACC_MC_OPCODE_LAST_SEG,
/// Set the current position to the nth segment of the current track
ACC_MC_OPCODE_GOTO_SEG,
/// Set the current track to the previous track in the current group playing order
ACC_MC_OPCODE_PREV_TRACK = 48,
/// Set the current track to the next track in the current group playing order
ACC_MC_OPCODE_NEXT_TRACK,
/// Set the current track to the first track in the current group playing order
ACC_MC_OPCODE_FIRST_TRACK,
/// Set the current track to the last track in the current group playing order
ACC_MC_OPCODE_LAST_TRACK,
/// Set the current track to the nth track in the current group playing order
ACC_MC_OPCODE_GOTO_TRACK,
/// Set the current group to the previous group in the sequence of groups
ACC_MC_OPCODE_PREV_GROUP = 64,
/// Set the current group to the next group in the sequence of groups
ACC_MC_OPCODE_NEXT_GROUP,
/// Set the current group to the first group in the sequence of groups
ACC_MC_OPCODE_FIRST_GROUP,
/// Set the current group to the next group in the sequence of groups
ACC_MC_OPCODE_LAST_GROUP,
/// Set the current group to the nth group in the sequence of groups
ACC_MC_OPCODE_GOTO_GROUP,
ACC_MC_MEDIA_CP_OPCODES_SUPP_MASK = 0x001FFFFF,
};
/// Search type values
enum acc_mc_search_type
{
ACC_MC_SEARCH_TYPE_MIN = 1,
/// Track Name
ACC_MC_SEARCH_TRACK_NAME = ACC_MC_SEARCH_TYPE_MIN,
/// Artist Name
ACC_MC_SEARCH_ARTIST_NAME,
/// Album Name
ACC_MC_SEARCH_ALBUM_NAME,
/// Group Name
ACC_MC_SEARCH_GROUP_NAME,
/// Earliest Year
ACC_MC_SEARCH_EARLIEST_YEAR,
/// Latest Year
ACC_MC_SEARCH_LATEST_YEAR,
/// Genre
ACC_MC_SEARCH_GENRE,
/// Only Tracks
ACC_MC_SEARCH_ONLY_TRACKS,
/// Only Groups
ACC_MC_SEARCH_ONLY_GROUPS,
ACC_MC_SEARCH_TYPE_MAX,
};
/// Media State values
enum acc_mc_media_state
{
/// Inactive
ACC_MC_MEDIA_STATE_INACTIVE = 0,
/// Playing
ACC_MC_MEDIA_STATE_PLAYING,
/// Paused
ACC_MC_MEDIA_STATE_PAUSED,
/// Seeking
ACC_MC_MEDIA_STATE_SEEKING,
ACC_MC_MEDIA_STATE_MAX,
};
/// Playing Order values
enum acc_mc_play_order
{
ACC_MC_PLAY_ORDER_MIN = 1,
/// A single track is played once there is no next track
ACC_MC_PLAY_ORDER_SINGLE_ONCE = ACC_MC_PLAY_ORDER_MIN,
/// A single track is played repeatedly; the next track is the current track
ACC_MC_PLAY_ORDER_SINGLE_REPEAT,
/// The tracks within a group are played once in track order
ACC_MC_PLAY_ORDER_ORDER_ONCE,
/// The tracks within a group are played in track order repeatedly
ACC_MC_PLAY_ORDER_ORDER_REPEAT,
/// The tracks within a group are played once only from the oldest first
ACC_MC_PLAY_ORDER_OLDEST_ONCE,
/// The tracks within a group are played from the oldest first repeatedly
ACC_MC_PLAY_ORDER_OLDEST_REPEAT,
/// The tracks within a group are played once only from the newest first
ACC_MC_PLAY_ORDER_NEWEST_ONCE,
/// The tracks within a group are played from the newest first repeatedly
ACC_MC_PLAY_ORDER_NEWEST_REPEAT,
/// The tracks within a group are played in random order once
ACC_MC_PLAY_ORDER_SHUFFLE_ONCE,
/// The tracks within a group are played in random order repeatedly
ACC_MC_PLAY_ORDER_SHUFFLE_REPEAT,
ACC_MC_PLAY_ORDER_MAX,
/// Mask for Playing Order Supported characteristic value
ACC_MC_PLAY_ORDER_SUPP_MASK = 0x03FF,
};
/// Result code values of Media Control Point Notificaiton
enum acc_mc_media_cp_result
{
ACC_MC_MEDIA_CP_RESULT_MIN = 1,
/// Success
ACC_MC_MEDIA_CP_RESULT_SUCCESS = ACC_MC_MEDIA_CP_RESULT_MIN,
/// Operation code not supported
ACC_MC_MEDIA_CP_RESULT_NOT_SUPPORTED,
/// Operation code action unsuccessful
ACC_MC_MEDIA_CP_RESULT_ACTION_UNSUCCESSFUL,
/// Media player inactive
ACC_MC_MEDIA_CP_RESULT_PLAYER_INACTIVE,
/// Command cannot be completed
ACC_MC_MEDIA_CP_RESULT_CANNOT_COMPLETE,
ACC_MC_MEDIA_CP_RESULT_MAX,
};
/// Result code values of Search Control Point Notification
enum acc_mc_search_cp_result
{
ACC_MC_SEARCH_CP_RESULT_MIN = 1,
/// Success
ACC_MC_SEARCH_CP_RESULT_SUCCESS = ACC_MC_SEARCH_CP_RESULT_MIN,
/// Failure
ACC_MC_SEARCH_CP_RESULT_FAILURE,
ACC_MC_SEARCH_CP_RESULT_MAX,
};
/// Media Control Point characteristic value position when written
enum acc_mc_cp_pos_wr
{
/// Operation code
ACC_MC_CP_POS_WR_OPCODE_POS = 0,
/// Parameter
ACC_MC_CP_POS_WR_PARAM_POS,
/// Minimum length
ACC_MC_CP_POS_WR_LEN_MIN = 1,
/// Maximum length
ACC_MC_CP_POS_WR_LEN_MAX = 5,
};
/// Media Control Point characteristic value position when notified
enum acc_mc_cp_pos_ntf
{
/// Operation code
ACC_MC_CP_POS_NTF_OPCODE_POS = 0,
/// Result code
ACC_MC_CP_POS_NTF_RESULT_POS,
/// Length
ACC_MC_CP_POS_NTF_LEN,
};
/// Search Control Point characteristic value position
enum acc_mc_search_cp_pos
{
/// Item length
ACC_MC_SEARCH_CP_ITEM_LEN_POS = 0,
/// Type
ACC_MC_SEARCH_CP_TYPE_POS,
/// Minimum length
ACC_MC_SEARCH_CP_LEN_MIN,
/// Minimum item length
ACC_MC_SEARCH_CP_ITEM_LEN_MIN = 1,
/// Parameter
ACC_MC_SEARCH_CP_PARAM_POS = ACC_MC_SEARCH_CP_LEN_MIN,
/// Maximum length
ACC_MC_SEARCH_CP_LEN_MAX = 64,
};
/*
* TYPES DEFINITION
****************************************************************************************
*/
/// Object ID
typedef struct acc_mc_object_id
{
/// Object ID
uint8_t obj_id[ACC_MC_OBJ_ID_LEN];
} acc_mc_object_id_t;
/// @}
#endif // ACC_MC_H_
@@ -0,0 +1,556 @@
/**
****************************************************************************************
*
* @file acc_mcc.h
*
* @brief Audio Content Control - Media Control Client - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_MCC_H_
#define ACC_MCC_H_
/**
****************************************************************************************
* @addtogroup ACC_MCC Audio Content Control - Media Control Client
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc_mc.h" // Audio Content Control - Media Control Definition
#if (GAF_ACC_MCC)
#include "gaf.h" // Generic Audio Framework Definitions
/*
* DEFINES
****************************************************************************************
*/
/// Maximum number of Media Control Service (Generic Media COntrol Service excluded)
/// that can be handled (limited by Media local index set in dummy value provided to GATT)
#define ACC_MCC_NB_MCS_MAX (126)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_CMD command codes
enum acc_mcc_cmd_codes
{
ACC_MCC_DISCOVER = GAF_CODE(ACC, MCC, 0),
ACC_MCC_GET = GAF_CODE(ACC, MCC, 1),
ACC_MCC_GET_CFG = GAF_CODE(ACC, MCC, 2),
ACC_MCC_SET_CFG = GAF_CODE(ACC, MCC, 3),
ACC_MCC_SET = GAF_CODE(ACC, MCC, 4),
ACC_MCC_SET_OBJECT_ID = GAF_CODE(ACC, MCC, 5),
ACC_MCC_CONTROL = GAF_CODE(ACC, MCC, 6),
ACC_MCC_SEARCH = GAF_CODE(ACC, MCC, 7),
};
/// List of GAF_REQ request codes
enum acc_mcc_msg_req_codes
{
ACC_MCC_CONFIGURE = GAF_CODE(ACC, MCC, 0),
ACC_MCC_RESTORE_BOND_DATA = GAF_CODE(ACC, MCC, 1),
};
/// List of GAF_IND indication codes
enum acc_mcc_msg_ind_codes
{
ACC_MCC_BOND_DATA = GAF_CODE(ACC, MCC, 0),
ACC_MCC_CFG = GAF_CODE(ACC, MCC, 1),
ACC_MCC_VALUE_LONG = GAF_CODE(ACC, MCC, 2),
ACC_MCC_VALUE = GAF_CODE(ACC, MCC, 3),
ACC_MCC_OBJECT_ID = GAF_CODE(ACC, MCC, 4),
ACC_MCC_TRACK_CHANGED = GAF_CODE(ACC, MCC, 5),
ACC_MCC_INCLUDED_SVC = GAF_CODE(ACC, MCC, 6),
ACC_MCC_SVC_CHANGED = GAF_CODE(ACC, MCC, 7),
};
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// Content description structure for Media Control Service
typedef struct acc_mcc_mcs_info
{
/// Service description
prf_svc_t svc_info;
/// UUID
uint16_t uuid;
/// Characteristics description
prf_char_t char_info[ACC_MC_CHAR_TYPE_MAX];
/// Descriptors description
prf_desc_t desc_info[ACC_MC_DESC_TYPE_MAX];
} acc_mcc_mcs_info_t;
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called when handling of a command has been completed
*
* @param[in] cmd_code Command code
* @param[in] status Status
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] param Additional parameter
* - Characteristic type
* - Characteristic type
* - Operation code
* @param[in] result Result code
****************************************************************************************
*/
typedef void (*acc_mcc_cb_cmp_evt)(uint16_t cmd_code, uint16_t status,
uint8_t con_lid, uint8_t media_lid, uint8_t param,
uint8_t result);
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration of a notification-capable
* characteristic has been received
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] char_type Characteristic type
* @param[in] enabled Indicate if sending of notifications is enabled or not
****************************************************************************************
*/
typedef void (*acc_mcc_cb_cfg)(uint8_t con_lid, uint8_t media_lid, uint8_t char_type,
uint8_t enabled);
/**
****************************************************************************************
* @brief Callback function called when value of one of the following characteristic is
* received:
* - Media Player Icon Object ID characteristic
* - Current Track Segments Object ID characteristic
* - Current Track Object ID characteristic
* - Next Track Object ID characteristic
* - Current Group Object ID characteristic
* - Parent Group Object ID characteristic
* - Search Results Object ID characteristic
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] char_type Characteristic type
* @param[in] p_obj_id Pointer to Object Id
****************************************************************************************
*/
typedef void (*acc_mcc_cb_object_id)(uint8_t con_lid, uint8_t media_lid, uint8_t char_type,
acc_mc_object_id_t* p_obj_id);
/**
****************************************************************************************
* @brief Callback function called when a notification indicating that current track has
* changed has been received
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
****************************************************************************************
*/
typedef void (*acc_mcc_cb_track_changed)(uint8_t con_lid, uint8_t media_lid);
/**
****************************************************************************************
* @brief Callback function called when value of one of the following characteristic is
* received:
* - Media Player Name characteristic
* - Media Player Icon URL characteristic
* - Track Title characteristic
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Bearer local index
* @param[in] char_type Characteristic type
* @param[in] val_len Length of value
* @param[in] p_val Pointer to value
****************************************************************************************
*/
typedef void (*acc_mcc_cb_value_long)(uint8_t con_lid, uint8_t media_lid, uint8_t char_type,
uint16_t val_len, uint8_t* p_val);
/**
****************************************************************************************
* @brief Callback function called when value of one of the following characteristic is
* received:
* - Track Duration characteristic
* - Track Position characteristic
* - Playback Speed characteristic
* - Seeking Speed characteristic
* - Playing Order characteristic
* - Playing Order Supported characteristic
* - Media State characteristic
* - Media Control Point Opcodes Supported characteristic
* - Content Control ID characteristic
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] char_type Characteristic type
* @param[in] val Value to be casted as follow:
* - Playback speed (uint8_t)
* - Seeking speed (int8_t)
* - State (uint8_t)
* - Supported operation codes bit field (uint32_t)
* - Playing order (uint8_t)
* - Supported playing orders bit field (uint32_t)
* - Track duration (uint32_t)
* - Track position (uint32_t)
* - CCID (uint8_t)
****************************************************************************************
*/
typedef void (*acc_mcc_cb_value)(uint8_t con_lid, uint8_t media_lid, uint8_t char_type,
uint32_t val);
/**
****************************************************************************************
* @brief Callback function called when an instance of (Generic) Media Control Control
* Service has been discovered
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] p_mcs_info Pointer to Content description structure
****************************************************************************************
*/
typedef void (*acc_mcc_cb_bond_data)(uint8_t con_lid, uint8_t media_lid, acc_mcc_mcs_info_t* p_mcs_info);
/**
****************************************************************************************
* @brief Callback function called when an included Object Transfer Service instance has been
* discovered
*
* @param[in] con_lid Connection local index
* @param[in] shdl Start handle
* @param[in] ehdl End handle
****************************************************************************************
*/
typedef void (*acc_mcc_cb_included_svc)(uint8_t con_lid, uint16_t shdl, uint16_t ehdl);
/**
****************************************************************************************
* @brief Callback function called when a service changed indication has been received from a Server device
*
* @param[in] con_lid Connection local index
****************************************************************************************
*/
typedef void (*acc_mcc_cb_svc_changed)(uint8_t con_lid);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Media Control Client
typedef struct acc_mcc_cb
{
/// Callback function called when handling of a command has been completed
acc_mcc_cb_cmp_evt cb_cmp_evt;
/// Callback function called when Client Characteristic Configuration of a notification-capable
/// characteristic has been received
acc_mcc_cb_cfg cb_cfg;
/// Callback function called when value of one of the following characteristic is
/// received:
/// - Media Player Icon Object ID characteristic
/// - Current Track Segments Object ID characteristic
/// - Current Track Object ID characteristic
/// - Next Track Object ID characteristic
/// - Current Group Object ID characteristic
/// - Parent Group Object ID characteristic
/// - Search Results Object ID characteristic
acc_mcc_cb_object_id cb_object_id;
/// Callback function called when a notification indicating that current track has
/// changed has been received
acc_mcc_cb_track_changed cb_track_changed;
/// Callback function called when value of one of the following characteristic is
/// received:
/// - Media Player Name characteristic
/// - Media Player Icon URL characteristic
/// - Track Title characteristic
acc_mcc_cb_value_long cb_value_long;
/// Callback function called when value of one of the following characteristic is
/// received:
/// - Track Duration characteristic
/// - Track Position characteristic
/// - Playback Speed characteristic
/// - Seeking Speed characteristic
/// - Playing Order characteristic
/// - Playing Order Supported characteristic
/// - Media State characteristic
/// - Media Control Point Opcodes Supported characteristic
/// - Content Control ID characteristic
acc_mcc_cb_value cb_value;
/// Callback function called when an instance of (Generic) Media Control Control
/// Service has been discovered
acc_mcc_cb_bond_data cb_bond_data;
/// Callback function called when an included Object Transfer Service instance has been
/// discovered
acc_mcc_cb_included_svc cb_included_svc;
/// Callback function called when a service changed indication has been received from a Server device
acc_mcc_cb_svc_changed cb_svc_changed;
} acc_mcc_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure use of Media Control Client module as Client
*
* @param[in] p_cb Pointer to set of callback functions for communication with upper
* layers
* @param[in] pref_mtu Preferred MTU. Values from 0 to 63 are equivalent to 64
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_configure(const acc_mcc_cb_t* p_cb, uint16_t pref_mtu);
/**
****************************************************************************************
* @brief Enable use of Media Control Service block as Client for a Server device with which
* a bonding has been established during a previous connection.
*
* @param[in] con_lid Connection local index
* @param[in] nb_media Number of instances of the (Generic) Media Control Service
* @param[in] p_mcs_info Pointer to Content description structures
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_restore_bond_data(uint8_t con_lid, uint8_t nb_media, acc_mcc_mcs_info_t* p_mcs_info);
/**
****************************************************************************************
* @brief Enable use of Media Control Service block as Client for a connected device with which
* no bonding has been established during a previous connection.
*
* @param[in] con_lid Connection local index
* @param[in] nb_mcs_max Maximum number of (Generic) Media Control Service instances that can be
* found in peer device database
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_discover(uint8_t con_lid, uint8_t nb_tbs_max);
/**
****************************************************************************************
* @brief Get value for one of the following characteristics for a Media exposed by a Server
* device:
* - Media Player Name characteristic
* - Media Player Icon Object ID if characteristic is supported for the indicated Media
* - Media Player Icon URL characteristic if characteristic is supported for the indicated Media
* - Track Title characteristic
* - Track Duration characteristic
* - Track Position characteristic
* - Playback Speed characteristic if characteristic is supported for the indicated Media
* - Seeking Speed characteristic if characteristic is supported for the indicated Media
* - Current Track Segments Object ID characteristic if characteristic is supported for the
* indicated Media
* - Current Track Object ID characteristic if characteristic is supported for the indicated Media
* - Next Track Object ID characteristic if characteristic is supported for the indicated Media
* - Current Group Object ID characteristic if characteristic is supported for the indicated Media
* - Parent Group Object ID characteristic if characteristic is supported for the indicated Media
* - Playing Order characteristic if characteristic is supported for the indicated Media
* - Playing Order Supported characteristic if characteristic is supported for the indicated Media
* - Media State characteristic
* - Media Control Point Opcodes Supported characteristic if characteristic is supported for
* the indicated Media
* - Search Results Object ID characteristic if characteristic is supported for the indicated Media
* - Content Control ID characteristic
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_get(uint8_t con_lid, uint8_t media_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Enable or disable sending of notifications for one of the following characteristics for
* a Media exposed by a Server device:
* - Media Player Name characteristic if sending of notifications is supported for the characteristic
* - Track Changed characteristic
* - Track Title characteristic if sending of notifications is supported for the characteristic
* - Track Duration characteristic if sending of notifications is supported for the characteristic
* - Track Position characteristic if sending of notifications is supported for the characteristic
* - Playback Speed characteristic if characteristic is supported for the indicated Media and if
* sending of notifications if supported for the characteristic
* - Seeking Speed characteristic if characteristic is supported for the indicated Media and if
* sending of notifications if supported for the characteristic
* - Current Track Object ID characteristic if characteristic is supported for the indicated Media
* and if sending of notifications if supported for the characteristic
* - Next Track Object ID characteristic if characteristic is supported for the indicated Media and
* if sending of notifications if supported for the characteristic
* - Current Group Object ID characteristic if characteristic is supported for the indicated Media
* and if sending of notifications if supported for the characteristic
* - Parent Group Object ID characteristic if characteristic is supported for the indicated Media and
* if sending of notifications if supported for the characteristic
* - Playing Order characteristic if characteristic is supported for the indicated Media and if
* sending of notifications if supported for the characteristic
* - Media State characteristic
* - Media Control Point characteristic if characteristic is supported for the indicated Media
* - Media Control Point Opcodes Supported characteristic if characteristic is supported for the
* indicated Media and if sending of notifications if supported for the characteristic
* - Search Results Object ID characteristic if characteristic is supported for the indicated Media
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] char_type Characteristic type
* @param[in] enable Indicate if sending of notifications must be enabled (!= 0) or
* disabled for the indicated characteristic
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_set_cfg(uint8_t con_lid, uint8_t media_lid, uint8_t char_type,
uint8_t enable);
/**
****************************************************************************************
* @brief Get current client configuration for one of the following characteristics for a Media
* exposed by a Server device:
* - Media Player Name characteristic if sending of notifications is supported for the characteristic
* - Track Changed characteristic
* - Track Title characteristic if sending of notifications is supported for the characteristic
* - Track Duration characteristic if sending of notifications is supported for the characteristic
* - Track Position characteristic if sending of notifications is supported for the characteristic
* - Playback Speed characteristic if characteristic is supported for the indicated Media and if
* sending of notifications if supported for the characteristic
* - Seeking Speed characteristic if characteristic is supported for the indicated Media and if
* sending of notifications if supported for the characteristic
* - Current Track Object ID characteristic if characteristic is supported for the indicated Media
* and if sending of notifications if supported for the characteristic
* - Next Track Object ID characteristic if characteristic is supported for the indicated Media and
* if sending of notifications if supported for the characteristic
* - Current Group Object ID characteristic if characteristic is supported for the indicated Media
* and if sending of notifications if supported for the characteristic
* - Parent Group Object ID characteristic if characteristic is supported for the indicated Media and
* if sending of notifications if supported for the characteristic
* - Playing Order characteristic if characteristic is supported for the indicated Media and if
* sending of notifications if supported for the characteristic
* - Media State characteristic
* - Media Control Point characteristic if characteristic is supported for the indicated Media
* - Media Control Point Opcodes Supported characteristic if characteristic is supported for the
* indicated Media and if sending of notifications if supported for the characteristic
* - Search Results Object ID characteristic if characteristic is supported for the indicated Media
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_get_cfg(uint8_t con_lid, uint8_t media_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Set value of one of the following characteristics for a Media exposed by a Server device:
* - Track Position characteristic
* - Playback Speed characteristic if characteristic is supported for the indicated Media
* - Playing Order characteristic if characteristic is supported for the indicated Media
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] char_type Characteristic type
* @param[in] reliable Indicate if feedback from Server device is required (!= 0)
* or not
* @param[in] val Value to be casted as follow:
* - Track position (uint32_t)
* - Playback speed (int8_t)
* - Playing order (uint8_t)
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_set(uint8_t con_lid, uint8_t media_lid, uint8_t char_type,
uint8_t reliable, uint32_t val);
#if (GAF_ACC_OTC)
/**
****************************************************************************************
* @brief Set value of one of the following characteristics for a Media exposed by a Server device:
* - Current Track Segments Object ID characteristic if characteristic is supported
* for the indicated Media
* - Next Track Object ID characteristic if characteristic is supported for the
* indicated Media
* - Current Group Object ID characteristic if characteristic is supported for the
* indicated Media
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] char_type Characteristic type
* @param[in] reliable Indicate if feedback from Server device is required (!= 0)
* or not
* @param[in] p_object_id Pointer to Object ID
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_set_object_id(uint8_t con_lid, uint8_t media_lid, uint8_t char_type,
uint8_t reliable, acc_mc_object_id_t* p_obj_id);
#endif //(GAF_ACC_OTC)
/**
****************************************************************************************
* @brief Control behavior of a Media exposed by a Server device if Media Control Point
* characteristic is supported for this Media.
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] opcode Operation code
* @param[in] reliable Indicate if feedback from Server device is required (!= 0)
* or not
* @param[in] val Value (for Goto Segment or Move Relative or Goto Track or
* Goto Group)
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_control(uint8_t con_lid, uint8_t media_lid, uint8_t opcode,
uint8_t reliable, uint32_t val);
#if (GAF_ACC_OTC)
/**
****************************************************************************************
* @brief Request from a Service device to perform a search of all the media for one of its
* exposed Media.
*
* @param[in] con_lid Connection local index
* @param[in] media_lid Media local index
* @param[in] reliable Indicate if feedback from Server device is required (!= 0)
* or not
* @param[in] param_len Length of parameter value
* @param[in] p_param Pointer to parameter value
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcc_search(uint8_t con_lid, uint8_t media_lid, uint8_t reliable,
uint8_t param_len, uint8_t* p_param);
#endif //(GAF_ACC_OTC)
#endif //(GAF_ACC_MCC)
/// @}
#endif // ACC_MCC_H_
@@ -0,0 +1,369 @@
/**
****************************************************************************************
*
* @file acc_mcc_msg.h
*
* @brief Audio Content Control - Definition of Kernel Messages (Media Control Client)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_MCC_MSG_H_
#define ACC_MCC_MSG_H_
/**
****************************************************************************************
* @addtogroup ACC_MCC_MSG Audio Content Control - Definition of Kernel Messages
* (Media Control Client)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc_msg.h" // ACC Message Definitions
#include "rwip_task.h" // RW IP Task Definition
#include "acc_mcc.h" // Audio Content Control - Media Control Client Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ACC_MCC_DISCOVER command message
typedef struct acc_mcc_discover_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Maximum number of (Generic) Media Control Service instance that can be found
uint8_t nb_mcs_max;
} acc_mcc_discover_cmd_t;
/// Structure for ACC_MCC_GET command message
typedef struct acc_mcc_get_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
} acc_mcc_get_cmd_t;
/// Structure for ACC_MCC_SET_CFG command message
typedef struct acc_mcc_set_cfg_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
/// Indicate if sending of notifications must be enabled (!=0) or disabled
uint8_t enable;
} acc_mcc_set_cfg_cmd_t;
/// Structure for ACC_MCC_GET_CFG command message
typedef struct acc_mcc_get_cfg_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
} acc_mcc_get_cfg_cmd_t;
/// Structure for ACC_MCC_SET command message
typedef struct acc_mcc_set_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
/// Indicate if feedback from Server device is required (!= 0) or not
uint8_t reliable;
union
{
/// Value
uint32_t val;
/// Track position
int32_t track_pos;
/// Playback speed
int8_t playback_speed;
/// Playing order
uint8_t playing_order;
} u;
} acc_mcc_set_cmd_t;
/// Structure for ACC_MCC_SET_OBJECT_ID command message
typedef struct acc_mcc_set_object_id_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
/// Indicate if feedback from Server device is required (!= 0) or not
uint8_t reliable;
/// Object ID
acc_mc_object_id_t obj_id;
} acc_mcc_set_object_id_cmd_t;
/// Structure for ACC_MCC_CONTROL command message
typedef struct acc_mcc_control_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Operation code
uint8_t opcode;
/// Indicate if feedback from Server device is required (!= 0) or not
uint8_t reliable;
union
{
/// Value
uint32_t val;
/// Parameter for Goto Segment operation code
uint32_t segment;
/// Parameter for Move Relative operation code
uint32_t offset;
/// Parameter for Goto Track operation code
uint32_t track;
/// Parameter for Goto Group operation code
uint32_t group;
} u;
} acc_mcc_control_cmd_t;
/// Structure for ACC_MCC_SEARCH command message
typedef struct acc_mcc_search_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Indicate if feedback from Server device is required (!= 0) or not
uint8_t reliable;
/// Length of parameter value
uint8_t param_len;
/// Pointer to parameter value
uint8_t param[__ARRAY_EMPTY];
} acc_mcc_search_cmd_t;
/// Structure for command complete event message
typedef struct acc_mcc_cmp_evt
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
union
{
/// Additional parameter
uint8_t param;
/// Characteristic type
uint8_t char_type;
/// Operation code
uint8_t opcode;
} u;
/// Result
uint8_t result;
} acc_mcc_cmp_evt_t;
/// Structure for ACC_MCC_CONFIGURE request message
typedef struct acc_mcc_configure_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Preferred MTU
uint16_t pref_mtu;
} acc_mcc_configure_req_t;
/// Structure for ACC_MCC_RESTORE_BOND_DATA request message
typedef struct acc_mcc_restore_bond_data_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Connection local index
uint8_t con_lid;
/// Number of instances of the (Generic) Media Control Service discovered
uint8_t nb_media;
/// Content description of (Generic) Media Control Service instances
acc_mcc_mcs_info_t mcs_info[__ARRAY_EMPTY];
} acc_mcc_restore_bond_data_req_t;
/// Structure for response message
typedef struct acc_mcc_rsp
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
} acc_mcc_rsp_t;
/// Structure for ACC_MCC_BOND_DATA indication message
typedef struct acc_mcc_bond_data_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Content description of (Generic) Media Control Service instance
acc_mcc_mcs_info_t mcs_info;
} acc_mcc_bond_data_ind_t;
/// Structure for ACC_MCC_CFG indication message
typedef struct acc_mcc_cfg_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
/// Indicate if sending of notifications is enabled (!= 0) or not
uint8_t enabled;
} acc_mcc_cfg_ind_t;
/// Structure for ACC_MCC_OBJECT_ID indication message
typedef struct acc_mcc_object_id_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
/// Object ID
acc_mc_object_id_t obj_id;
} acc_mcc_object_id_ind_t;
/// Structure for ACC_MCC_INCLUDED_SVC indication message
typedef struct acc_mcc_included_svc_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Start handle
uint16_t shdl;
/// End handle
uint16_t ehdl;
} acc_mcc_included_svc_ind_t;
/// Structure for ACC_MCC_TRACK_CHANGED indication message
typedef struct acc_mcc_track_changed_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
} acc_mcc_track_changed_ind_t;
/// Structure for ACC_MCC_VALUE_LONG indication message
typedef struct acc_mcc_value_long_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
/// Length of value
uint16_t val_len;
/// Value
uint8_t val[__ARRAY_EMPTY];
} acc_mcc_value_long_ind_t;
/// Structure for ACC_MCC_VALUE indication message
typedef struct acc_mcc_value_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
/// Value
union
{
/// Value
uint32_t val;
/// Playback speed
int8_t playback_speed;
/// Seeking speed
int8_t seeking_speed;
/// Media state
uint8_t state;
/// Supported media control operation codes bit field
uint32_t opcodes_supp_bf;
/// Playing Order
uint8_t playing_order;
/// Supported Playing Order bit field
uint32_t playing_order_supp_bf;
/// Track duration of the current track in 0.01 second resolution
int32_t track_dur;
/// Track position of the current track in 0.01 second resolution
int32_t track_pos;
/// Content Control ID
uint8_t ccid;
} val;
} acc_mcc_value_ind_t;
/// Structure for ACC_MCC_SVC_CHANGED indication message
typedef struct acc_mcc_svc_changed_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
} acc_mcc_svc_changed_ind_t;
/// @}
#endif // ACC_MCC_MSG_H_
@@ -0,0 +1,529 @@
/**
****************************************************************************************
*
* @file acc_mcs.h
*
* @brief Audio Content Control - Media Control Server - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_MCS_H_
#define ACC_MCS_H_
/**
****************************************************************************************
* @addtogroup ACC_MCS Audio Content Control - Media Control Server
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc_mc.h" // Audio Content Control - Media Control Definition
#if (GAF_ACC_MCS)
#include "gaf.h" // Generic Audio Framework Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes
enum acc_mcs_msg_req_codes
{
ACC_MCS_CONFIGURE = GAF_CODE(ACC, MCS, 0),
ACC_MCS_ADD = GAF_CODE(ACC, MCS, 1),
ACC_MCS_ENABLE = GAF_CODE(ACC, MCS, 2),
ACC_MCS_RESTORE_BOND_DATA = GAF_CODE(ACC, MCS, 3),
ACC_MCS_SET = GAF_CODE(ACC, MCS, 4),
ACC_MCS_SET_OBJECT_ID = GAF_CODE(ACC, MCS, 5),
ACC_MCS_SET_PLAYER_NAME = GAF_CODE(ACC, MCS, 6),
ACC_MCS_ACTION = GAF_CODE(ACC, MCS, 7),
ACC_MCS_TRACK_CHANGE = GAF_CODE(ACC, MCS, 8),
};
/// List of GAF_IND indication codes
enum acc_mcs_msg_ind_codes
{
ACC_MCS_BOND_DATA = GAF_CODE(ACC, MCS, 0),
};
/// List of GAF_REQ_IND request indication codes
enum acc_mcs_msg_req_ind_codes
{
ACC_MCS_SET_OBJECT_ID_RI = GAF_CODE(ACC, MCS, 0),
ACC_MCS_CONTROL = GAF_CODE(ACC, MCS, 1),
ACC_MCS_SEARCH = GAF_CODE(ACC, MCS, 2),
ACC_MCS_GET = GAF_CODE(ACC, MCS, 3),
ACC_MCS_GET_POSITION = GAF_CODE(ACC, MCS, 4),
ACC_MCS_SET_RI = GAF_CODE(ACC, MCS, 5),
};
/// Media configuration bit field
enum acc_mcs_cfg_bf
{
/// Indicate if added Service if the Generic Media Control Service (= 1) or an instance
/// of the Media Control Service
ACC_MCS_CFG_GENERIC_POS = 0,
ACC_MCS_CFG_GENERIC_BIT = CO_BIT(ACC_MCS_CFG_GENERIC_POS),
/// Indicate if sending of notifications is supported (= 1) for the Media Player Name
/// characteristic
/// Meaningless for Generic Media Control Service as support is mandatory
ACC_MCS_CFG_PLAYER_NAME_NTF_SUPP_POS = 1,
ACC_MCS_CFG_PLAYER_NAME_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_PLAYER_NAME_NTF_SUPP_POS),
/// Indicate if Media Player Icon Object ID characteristic is supported (= 1) or not
ACC_MCS_CFG_PLAYER_ICON_OBJ_ID_SUPP_POS = 2,
ACC_MCS_CFG_PLAYER_ICON_OBJ_ID_SUPP_BIT = CO_BIT(ACC_MCS_CFG_PLAYER_ICON_OBJ_ID_SUPP_POS),
/// Indicate if Media Player Icon URL characteristic is supported
ACC_MCS_CFG_PLAYER_ICON_URL_SUPP_POS = 3,
ACC_MCS_CFG_PLAYER_ICON_URL_SUPP_BIT = CO_BIT(ACC_MCS_CFG_PLAYER_ICON_URL_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Track Title characteristic
ACC_MCS_CFG_TRACK_TITLE_NTF_SUPP_POS = 4,
ACC_MCS_CFG_TRACK_TITLE_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_TRACK_TITLE_NTF_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Track Duration characteristic
ACC_MCS_CFG_TRACK_DURATION_NTF_SUPP_POS = 5,
ACC_MCS_CFG_TRACK_DURATION_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_TRACK_DURATION_NTF_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Track Position characteristic
ACC_MCS_CFG_TRACK_POSITION_NTF_SUPP_POS = 6,
ACC_MCS_CFG_TRACK_POSITION_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_TRACK_POSITION_NTF_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Playback Speed characteristic
ACC_MCS_CFG_PLAYBACK_SPEED_NTF_SUPP_POS = 7,
ACC_MCS_CFG_PLAYBACK_SPEED_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_PLAYBACK_SPEED_NTF_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Seeking Speed characteristic
ACC_MCS_CFG_SEEKING_SPEED_NTF_SUPP_POS = 8,
ACC_MCS_CFG_SEEKING_SPEED_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_SEEKING_SPEED_NTF_SUPP_POS),
/// Indicate if Current Track Object ID characteristic is supported (= 1) or not
/// If supported, following characteristic are also supported:
/// - Current Track Segments Object ID characteristic
/// - Next Track Object ID characteristic
/// - Current Group Object ID characteristic
/// - Parent Group Object ID characteristic
ACC_MCS_CFG_CURR_TRACK_OBJ_ID_SUPP_POS = 9,
ACC_MCS_CFG_CURR_TRACK_OBJ_ID_SUPP_BIT = CO_BIT(ACC_MCS_CFG_CURR_TRACK_OBJ_ID_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Current Track Object ID
/// characteristic
ACC_MCS_CFG_CURR_TRACK_NTF_SUPP_POS = 10,
ACC_MCS_CFG_CURR_TRACK_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_CURR_TRACK_NTF_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Next Track Object ID
/// characteristic
ACC_MCS_CFG_NEXT_TRACK_NTF_SUPP_POS = 11,
ACC_MCS_CFG_NEXT_TRACK_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_NEXT_TRACK_NTF_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Current Group Object ID
/// characteristic
ACC_MCS_CFG_CURR_GROUP_NTF_SUPP_POS = 12,
ACC_MCS_CFG_CURR_GROUP_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_CURR_GROUP_NTF_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Parent Group Object ID
/// characteristic
ACC_MCS_CFG_PARENT_GROUP_NTF_SUPP_POS = 13,
ACC_MCS_CFG_PARENT_GROUP_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_PARENT_GROUP_NTF_SUPP_POS),
/// Indicate if Player Order characteristic is supported (= 1) or not
ACC_MCS_CFG_PLAYING_ORDER_SUPP_POS = 14,
ACC_MCS_CFG_PLAYING_ORDER_SUPP_BIT = CO_BIT(ACC_MCS_CFG_PLAYING_ORDER_SUPP_POS),
/// Indicate if Player Order Supported characteristic is supported (= 1) or not
ACC_MCS_CFG_PLAYING_ORDER_SUPP_SUPP_POS = 15,
ACC_MCS_CFG_PLAYING_ORDER_SUPP_SUPP_BIT = CO_BIT(ACC_MCS_CFG_PLAYING_ORDER_SUPP_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Playing Order characteristic
ACC_MCS_CFG_PLAYING_ORDER_NTF_SUPP_POS = 16,
ACC_MCS_CFG_PLAYING_ORDER_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_PLAYING_ORDER_NTF_SUPP_POS),
/// Indicate if Media Control Point characteristic (= 1) is supported or not
/// If supported, the Media Control Point Opcodes Supported characteristic is also supported
ACC_MCS_CFG_MEDIA_CP_SUPP_POS = 17,
ACC_MCS_CFG_MEDIA_CP_SUPP_BIT = CO_BIT(ACC_MCS_CFG_MEDIA_CP_SUPP_POS),
/// Indicate if sending of notifications is supported (= 1) for the Media Control Point
/// Opcodes Supported characteristic
ACC_MCS_CFG_MEDIA_CP_OPCODE_NTF_SUPP_POS = 18,
ACC_MCS_CFG_MEDIA_CP_OPCODE_NTF_SUPP_BIT = CO_BIT(ACC_MCS_CFG_MEDIA_CP_OPCODE_NTF_SUPP_POS),
/// Indicate if Search Results Object ID characteristic is supported (= 1) or not
/// If supported, the Search Control Point characteristic is also supported
ACC_MCS_CFG_SEARCH_RESULT_OBJ_ID_SUPP_POS = 19,
ACC_MCS_CFG_SEARCH_RESULT_OBJ_ID_SUPP_BIT = CO_BIT(ACC_MCS_CFG_SEARCH_RESULT_OBJ_ID_SUPP_POS),
/// Indicate if Seeking Speed characteristic is supported
ACC_MCS_CFG_SEEKING_SPEED_SUPP_POS = 20,
ACC_MCS_CFG_SEEKING_SPEED_SUPP_BIT = CO_BIT(ACC_MCS_CFG_SEEKING_SPEED_SUPP_POS),
/// Indicate if Playback Speed characteristic is supported
ACC_MCS_CFG_PLAYBACK_SPEED_SUPP_POS = 21,
ACC_MCS_CFG_PLAYBACK_SPEED_SUPP_BIT = CO_BIT(ACC_MCS_CFG_PLAYBACK_SPEED_SUPP_POS),
};
/// Action type values
enum acc_mcs_action
{
/// No action
ACC_MCS_ACTION_NO_ACTION = 0,
/// Play
ACC_MCS_ACTION_PLAY,
/// Pause
ACC_MCS_ACTION_PAUSE,
/// Stop
ACC_MCS_ACTION_STOP,
/// Fast Forward or Fast Rewind
ACC_MCS_ACTION_SEEK,
/// Current Track becomes invalid
ACC_MCS_ACTION_INACTIVE,
/// Change track
ACC_MCS_ACTION_CHANGE_TRACK,
ACC_MCS_ACTION_MAX
};
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration of a
* notification-capable characteristic has been updated by a peer client
*
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
****************************************************************************************
*/
typedef void (*acc_mcs_cb_bond_data)(uint8_t media_lid, uint8_t con_lid, uint32_t cli_cfg_bf);
/**
****************************************************************************************
* @brief Callback function called when either Current Track Object ID or Next Track Object
* ID or CUrrent Group Object ID characteristic value has been written by a Client device
*
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
* @param[in] p_obj_id Pointer to Object ID
****************************************************************************************
*/
typedef void (*acc_mcs_cb_set_object_id_req)(uint8_t media_lid, uint8_t con_lid, uint8_t char_type,
acc_mc_object_id_t* p_obj_id);
/**
****************************************************************************************
* @brief Callback function called when a Client device request a control on a Media
*
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] opcode Operation code
* @param[in] val Value
****************************************************************************************
*/
typedef void (*acc_mcs_cb_control_req)(uint8_t media_lid, uint8_t con_lid,
uint8_t opcode, uint32_t val);
/**
****************************************************************************************
* @brief Callback function called when a Search request has been received from Client device
*
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] param_len Length of Search Parameters value
* @param[in] p_param Pointer to Search Parameters value
****************************************************************************************
*/
typedef void (*acc_mcs_cb_search_req)(uint8_t media_lid, uint8_t con_lid,
uint8_t param_len, uint8_t* p_param);
/**
****************************************************************************************
* @brief Callback function called when a Client device request to set value for either
* Media Player Name or Media Player Icon Object URL or Track Title characteristic
*
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
* @param[in] token Token
* @param[in] offset Offset
* @param[in] length Maximum length
****************************************************************************************
*/
typedef void (*acc_mcs_cb_get_req)(uint8_t media_lid, uint8_t con_lid, uint8_t char_type,
uint16_t token, uint16_t offset, uint16_t length);
/**
****************************************************************************************
* @brief Callback function called when Client device tries to get the current Track Position
*
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] token Token
****************************************************************************************
*/
typedef void (*acc_mcs_cb_get_position_req)(uint8_t media_lid, uint8_t con_lid, uint16_t token);
/**
****************************************************************************************
* @brief Callback function called when a Client device request to set value for either
* Track Position or Playback Speed or Playing Order characteristic
*
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
* @param[in] val Value
****************************************************************************************
*/
typedef void (*acc_mcs_cb_set_req)(uint8_t media_lid, uint8_t con_lid, uint8_t char_type,
uint32_t val);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Media Control Server
typedef struct acc_mcs_cb
{
/// Callback function called when Client Characteristic Configuration of a notification-capable
/// characteristic has been updated by a peer client
acc_mcs_cb_bond_data cb_bond_data;
/// Callback function called when either Current Track Object ID or Next Track Object
/// ID or CUrrent Group Object ID characteristic value has been written by a Client device
acc_mcs_cb_set_object_id_req cb_set_object_id_req;
/// Callback function called when a Search request has been received from Client device
acc_mcs_cb_search_req cb_search_req;
/// Callback function called when a Client device request a control on a Media
acc_mcs_cb_control_req cb_control_req;
/// Callback function called when a Client device request to set value for either
/// Media Player Name or Media Player Icon Object URL or Track Title characteristic
acc_mcs_cb_get_req cb_get_req;
/// Callback function called when Client device tries to get the current Track Position
acc_mcs_cb_get_position_req cb_get_position_req;
/// Callback function called when a Client device request to set value for either
/// Track Position or Playback Speed or Playing Order characteristic
acc_mcs_cb_set_req cb_set_req;
} acc_mcs_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure use of Media Control Server module as Server
*
* @param[in] nb_mcs Number of instances of the (Generic) Media Control Service
* Value 0 is prohibited
* @param[in] p_cb Pointer to set of callback functions for communication with upper
* layer
* @param[in] pref_mtu Preferred MTU
* Values from 0 to 63 are equivalent to 64
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcs_configure(uint8_t nb_mcs, const acc_mcs_cb_t* p_cb, uint16_t pref_mtu);
/**
****************************************************************************************
* @brief Add and configure an instance of the Media Control Service in the database
*
* @param[in] cfg_bf Configuration bit field
* @param[in] playing_order_supp_bf Supported playing order bit field
* @param[in] ots_shdl Start handle of included Object Transfer Service
* @param[in] ots_ehdl End handle of included Object Transfer Service
* @param[in] ccid Content Control ID
* @param[in] p_icon_obj_id Pointer to Media Player Icon Object ID
* @param[in] nb_att_rsvd Number of attributes reserved
* @param[out] p_media_lid Pointer at which allocated Media local index is returned
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcs_add(uint32_t cfg_bf, uint32_t playing_order_supp_bf, uint16_t ots_shdl,
uint16_t ots_ehdl, uint8_t ccid, acc_mc_object_id_t* p_icon_obj_id,
uint8_t nb_att_rsvd, uint8_t* p_media_lid);
/**
****************************************************************************************
* @brief Enable use of Media Control Server module as Server
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcs_enable(void);
/**
****************************************************************************************
* @brief Set bonding information for either the Generic Media Control Service or an instance
* of the Media Control Service Service after connection with a Client device with which a
* bonded relationship had been established during a previous connection.
*
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcs_restore_bond_data(uint8_t media_lid, uint8_t con_lid, uint32_t cli_cfg_bf);
/**
****************************************************************************************
* @brief Set value for either of Track Position characteristic or Playback Speed characteristic
* or Media Control Point Opcodes Supported characteristic or Playing Order characteristic
*
* @param[in] media_lid Media local index
* @param[in] char_type Characteristic type
* @param[in] val Value
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcs_set(uint8_t media_lid, uint8_t char_type, uint32_t val);
#if (GAF_ACC_OTS)
/**
****************************************************************************************
* @brief Set value for Next Track Object ID characteristic
*
* @param[in] media_lid Media local index
* @param[in] p_obj_id Pointer to Object ID
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcs_set_object_id(uint8_t media_lid, acc_mc_object_id_t* p_obj_id);
#endif //(GAF_ACC_OTS)
/**
****************************************************************************************
* @brief Indicate an update of the Media Player Name value
*
* @param[in] media_lid Media local index
* @param[in] name_len Length of Media Player Name value
* @param[in] p_name Pointer to Media Player Name value
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcs_set_player_name(uint8_t media_lid, uint8_t name_len, uint8_t* p_name);
/**
****************************************************************************************
* @brief Indicate that an action has been performed on a media (play, pause, stop, ...)
*
* @param[in] media_lid Media local index
* @param[in] action Action
* @param[in] track_pos Track Position
* @param[in] seeking_speed Seeking Speed
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcs_action(uint8_t media_lid, uint8_t action, int32_t track_pos,
int8_t seeking_speed);
/**
****************************************************************************************
* @brief Indicate that current track has changed for a media
*
* @param[in] media_lid Media local index
* @param[in] track_dur Track Duration
* @param[in] p_segments_obj_id Pointer to Current Track Segments Object ID value
* @param[in] p_current_obj_id Pointer to Current Track Object ID value
* @param[in] p_next_obj_id Pointer to Next Track Object ID value
* @param[in] p_group_obj_id Pointer to Current Group Object ID value
* @param[in] p_parent_obj_id Pointer to Parent Group Object ID value
* @param[in] title_len Length of Track Title value
* @param[in] p_title Pointer to Track Title value
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_mcs_track_change(uint8_t media_lid, int32_t track_dur,
acc_mc_object_id_t* p_segments_obj_id, acc_mc_object_id_t* p_current_obj_id,
acc_mc_object_id_t* p_next_obj_id, acc_mc_object_id_t* p_group_obj_id,
acc_mc_object_id_t* p_parent_obj_id,
uint16_t title_len, uint8_t* p_title);
/**
****************************************************************************************
* @brief Confirmation for ACC_MCS_SET_OBJECT_ID or ACC_MCS_SET request indication.
*
* @param[in] status Status
* @param[in] media_lid Media local index
* @param[in] val Track position or Playback Speed value
*
* @return An error status
****************************************************************************************
*/
void acc_mcs_cfm_set(uint16_t status, uint8_t media_lid, uint32_t val);
/**
****************************************************************************************
* @brief Confirmation for ACC_MCS_CONTROL request indication.
*
* @param[in] media_lid Media local index
* @param[in] result Result
* @param[in] action Action
* @param[in] track_pos Track Position
* @param[in] seeking_speed Seeking Speed
*
* @return An error status
****************************************************************************************
*/
void acc_mcs_cfm_control(uint8_t media_lid, uint8_t result,
uint8_t action, int32_t track_pos, int8_t seeking_speed);
#if (GAF_ACC_OTS)
/**
****************************************************************************************
* @brief Confirmation for ACC_MCS_SEARCH request indication.
*
* @param[in] status Status
* @param[in] media_lid Media local index
* @param[in] p_obj_id Pointer to Search Result Object ID value
*
* @return An error status
****************************************************************************************
*/
void acc_mcs_cfm_search(uint16_t status, uint8_t media_lid, acc_mc_object_id_t* p_obj_id);
#endif //(GAF_ACC_OTS)
/**
****************************************************************************************
* @brief Confirmation for ACC_MCS_GET request indication.
*
* @param[in] status Status
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
* @param[in] token Token
* @param[in] length Length
* @param[in] p_val Pointer to value
*
* @return An error status
****************************************************************************************
*/
void acc_mcs_cfm_get(uint16_t status, uint8_t media_lid, uint8_t con_lid, uint8_t char_type,
uint16_t token, uint16_t length, uint8_t* p_val);
/**
****************************************************************************************
* @brief Confirmation for ACC_MCS_GET_POSITION request indication.
*
* @param[in] status Status
* @param[in] media_lid Media local index
* @param[in] con_lid Connection local index
* @param[in] token Token
* @param[in] track_pos Track Position
*
* @return An error status
****************************************************************************************
*/
void acc_mcs_cfm_get_position(uint16_t status, uint8_t media_lid, uint8_t con_lid, uint16_t token,
int32_t track_pos);
#endif //(GAF_ACC_MCS)
/// @}
#endif // ACC_MCS_H_
@@ -0,0 +1,433 @@
/**
****************************************************************************************
*
* @file acc_mcs_msg.h
*
* @brief Audio Content Control - Definition of Kernel Messages (Media Control Server)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_MCS_MSG_H_
#define ACC_MCS_MSG_H_
/**
****************************************************************************************
* @addtogroup ACC_MCS_MSG Audio Content Control - Definition of Kernel Messages
* (Media Control Server)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc_msg.h" // ACC Message Definitions
#include "rwip_task.h" // RW IP Task Definition
#include "acc_mcs.h" // Audio Content Control - Media Control Server Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ACC_MCS_CONFIGURE request message
typedef struct acc_mcs_configure_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Number of instances of the (Generic) Media Control Service
/// Value 0 is prohibited
uint8_t nb_mcs;
/// Preferred MTU
/// Values from 0 to 63 are equivalent to 64
uint16_t pref_mtu;
} acc_mcs_configure_req_t;
/// Structure for ACC_MCS_ADD request message
typedef struct acc_mcs_add_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Configuration bit field
uint32_t cfg_bf;
/// Supported playing order bit field
uint32_t playing_order_supp_bf;
/// Start handle of associated Object Transfer Service
uint16_t ots_shdl;
/// End handle of associated Object Transfer Service
uint16_t ots_ehdl;
/// Content Control ID
uint8_t ccid;
/// Number of attributes reserved for the service
uint8_t nb_att_rsvd;
/// Media Player Icon Object ID
acc_mc_object_id_t icon_obj_id;
} acc_mcs_add_req_t;
/// Structure for ACC_MCS_ENABLE request message
typedef struct acc_mcs_enable_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
} acc_mcs_enable_req_t;
/// Structure for ACC_MCS_RESTORE_BOND_DATA request message
typedef struct acc_mcs_restore_bond_data_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint32_t cli_cfg_bf;
} acc_mcs_restore_bond_data_req_t;
/// Structure for ACC_MCS_SET request message
typedef struct acc_mcs_set_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Media local index
uint8_t media_lid;
/// Characteristic type
uint8_t char_type;
union
{
/// Value
uint32_t val;
/// Track position
int32_t track_pos;
/// Playback speed
int8_t playback_speed;
/// Playing order
uint8_t play_order;
/// Supported Media Control Operation Codes bit field
uint32_t opcodes_supp_bf;
} val;
} acc_mcs_set_req_t;
/// Structure for ACC_MCS_SET_OBJECT_ID request message
typedef struct acc_mcs_set_object_id_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Media local index
uint8_t media_lid;
/// Object ID
acc_mc_object_id_t obj_id;
} acc_mcs_set_object_id_req_t;
/// Structure for ACC_MCS_SET_PLAYER_NAME request message
typedef struct acc_mcs_set_player_name_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Media local index
uint8_t media_lid;
/// Length of Media Player Name value
uint8_t name_len;
/// Media Player Name value
uint8_t name[__ARRAY_EMPTY];
} acc_mcs_set_player_name_req_t;
/// Structure for ACC_MCS_ACTION request message
typedef struct acc_mcs_action_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Media local index
uint8_t media_lid;
/// Action
uint8_t action;
/// Track Position
int32_t track_pos;
/// Seeking speed
int8_t seeking_speed;
} acc_mcs_action_req_t;
/// Structure for ACC_MCS_TRACK_CHANGE request message
typedef struct acc_mcs_track_change_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Media local index
uint8_t media_lid;
/// Track duration in multiple of 0.01 seconds
/// Shall be higher than 0
int32_t track_dur;
/// Current Track Segments Object ID
acc_mc_object_id_t segments_obj_id;
/// Current Track Object ID
acc_mc_object_id_t current_obj_id;
/// Next Track Object ID
acc_mc_object_id_t next_obj_id;
/// Current Group Object ID
acc_mc_object_id_t group_obj_id;
/// Parent Group Object ID
acc_mc_object_id_t parent_obj_id;
/// Length of Track Title value
uint8_t title_len;
/// Track title value
uint8_t title[__ARRAY_EMPTY];
} acc_mcs_track_change_req_t;
/// Structure for response message
typedef struct acc_mcs_rsp
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Status
uint16_t status;
/// Media local index
uint8_t media_lid;
union
{
/// Additional parameter
uint8_t param;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
/// Action
uint8_t action;
} param;
} acc_mcs_rsp_t;
/// Structure for ACC_MCS_BOND_DATA indication message
typedef struct acc_mcs_cfg_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint32_t cli_cfg_bf;
} acc_mcs_cfg_ind_t;
/// Structure for ACC_MCS_SET_OBJECT_ID request indication message
typedef struct acc_mcs_set_object_id_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
/// Object ID
acc_mc_object_id_t obj_id;
} acc_mcs_set_object_id_req_ind_t;
/// Structure for ACC_MCS_CONTROL request indication message
typedef struct acc_mcs_control_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Operation code
uint8_t opcode;
union
{
/// Value
uint32_t val;
/// Parameter for Goto Segment operation code
uint32_t segment;
/// Parameter for Move Relative operation code
int32_t offset;
/// Parameter for Goto Track operation code
uint32_t track;
/// Parameter for Goto Group operation code
uint32_t group;
} val;
} acc_mcs_control_req_ind_t;
/// Structure for ACC_MCS_SEARCH request indication message
typedef struct acc_mcs_search_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Length of Search Parameters value
uint8_t param_len;
/// Search Parameters value
uint8_t param[__ARRAY_EMPTY];
} acc_mcs_search_req_ind_t;
/// Structure for ACC_MCS_GET request indication message
typedef struct acc_mcs_get_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
/// Token
uint16_t token;
/// Offset
uint16_t offset;
/// Maximum length
uint16_t length;
} acc_mcs_get_req_ind_t;
/// Structure for ACC_MCS_GET_POSITION request indication message
typedef struct acc_mcs_get_position_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Token
uint16_t token;
} acc_mcs_get_position_req_ind_t;
/// Structure for ACC_MCS_SET request indication message
typedef struct acc_mcs_set_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
union
{
/// Additional parameter
uint32_t param;
/// Track position offset
int32_t track_pos_offset;
/// Playback speed
int8_t playback_speed;
/// Playing order
uint8_t playing_order;
} param;
} acc_mcs_set_req_ind_t;
/// Structure for ACC_MCS_SET_OBJECT_ID confirmation message
typedef struct acc_mcs_set_object_id_cfm
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Media local index
uint8_t media_lid;
} acc_mcs_set_object_id_cfm_t;
/// Structure for ACC_MCS_CONTROL confirmation message
typedef struct acc_mcs_control_cfm
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Media local index
uint8_t media_lid;
/// Result
uint8_t result;
/// Action
uint8_t action;
/// Track Position
int32_t track_pos;
/// Seeking speed
int8_t seeking_speed;
} acc_mcs_control_cfm_t;
/// Structure for ACC_MCS_SEARCH confirmation message
typedef struct acc_mcs_search_cfm
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Media local index
uint8_t media_lid;
/// Object ID
acc_mc_object_id_t obj_id;
} acc_mcs_search_cfm_t;
/// Structure for ACC_MCS_GET confirmation message
typedef struct acc_mcs_get_cfm
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
/// Token
uint16_t token;
/// Length
uint16_t length;
/// Requested value
uint8_t val[__ARRAY_EMPTY];
} acc_mcs_get_cfm_t;
/// Structure for ACC_MCS_GET_POSITION confirmation message
typedef struct acc_mcs_get_position_cfm
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Media local index
uint8_t media_lid;
/// Connection local index
uint8_t con_lid;
/// Token
uint16_t token;
/// Track position
int32_t track_pos;
} acc_mcs_get_position_cfm_t;
/// Structure for ACC_MCS_SET confirmation message
typedef struct acc_mcs_set_cfm
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Media local index
uint8_t media_lid;
union
{
/// Value
uint32_t val;
/// Track position
int32_t track_pos;
/// Playback speed
int8_t playback_speed;
} val;
} acc_mcs_set_cfm_t;
/// @}
#endif // ACC_MCS_MSG_H_
@@ -0,0 +1,36 @@
/**
****************************************************************************************
*
* @file acc_ot.h
*
* @brief Audio Content Control - Object Transfer - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_OT_H_
#define ACC_OT_H_
/**
****************************************************************************************
* @addtogroup ACC_OT Audio Content Control - Object Transfer
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc.h" // Audio Content Control Definitions
#if (GAF_ACC_OTS || GAF_ACC_OTC)
#include "otp.h" // Object Transfer Profile Definitions
#endif //(GAF_ACC_OTS || GAF_ACC_OTC)
/// @}
#endif // ACC_OT_H_
@@ -0,0 +1,147 @@
/**
****************************************************************************************
*
* @file acc_otc.h
*
* @brief Audio Content Control - Object Transfer Client - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_OTC_H_
#define ACC_OTC_H_
/**
****************************************************************************************
* @addtogroup ACC_OTC Audio Content Control - Object Transfer Client
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc_ot.h" // Audio Content Control - Object Tranfer Definitions
#if (GAF_ACC_OTC)
#include "gaf.h" // GAF Defines
#include "otc.h" // Object Transfer Client Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of ACC_CMD command codes for Object Transfer Client
enum acc_otc_cmd_codes
{
ACC_OTC_DISCOVER = GAF_CODE(ACC, OTC, 0),
ACC_OTC_GET = GAF_CODE(ACC, OTC, 1),
ACC_OTC_GET_CFG = GAF_CODE(ACC, OTC, 2),
ACC_OTC_SET_CFG = GAF_CODE(ACC, OTC, 3),
ACC_OTC_SET_NAME = GAF_CODE(ACC, OTC, 4),
ACC_OTC_SET_TIME = GAF_CODE(ACC, OTC, 5),
ACC_OTC_SET_PROPERTIES = GAF_CODE(ACC, OTC, 6),
ACC_OTC_OBJECT_CREATE = GAF_CODE(ACC, OTC, 7),
ACC_OTC_OBJECT_CONTROL = GAF_CODE(ACC, OTC, 8),
ACC_OTC_OBJECT_MANIPULATE = GAF_CODE(ACC, OTC, 9),
ACC_OTC_OBJECT_EXECUTE = GAF_CODE(ACC, OTC, 10),
ACC_OTC_LIST_CONTROL = GAF_CODE(ACC, OTC, 11),
ACC_OTC_LIST_GOTO = GAF_CODE(ACC, OTC, 12),
ACC_OTC_FILTER_SET = GAF_CODE(ACC, OTC, 13),
ACC_OTC_FILTER_SET_TIME = GAF_CODE(ACC, OTC, 14),
ACC_OTC_FILTER_SET_SIZE = GAF_CODE(ACC, OTC, 15),
ACC_OTC_FILTER_SET_NAME = GAF_CODE(ACC, OTC, 16),
ACC_OTC_FILTER_SET_TYPE = GAF_CODE(ACC, OTC, 17),
ACC_OTC_COC_CONNECT = GAF_CODE(ACC, OTC, 18),
ACC_OTC_COC_DISCONNECT = GAF_CODE(ACC, OTC, 19),
ACC_OTC_COC_SEND = GAF_CODE(ACC, OTC, 20),
ACC_OTC_COC_RELEASE = GAF_CODE(ACC, OTC, 21),
};
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Object Transfer Client
typedef otc_cb_t acc_otc_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Create and configure Object Transfer Client module
*
* @param[in] p_cb Pointer to set of callback functions for communications with
* upper layers
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_otc_configure(const acc_otc_cb_t* p_cb);
/// Wrapper for functions defined in otc.h
#define acc_otc_discover(con_lid, nb_ots_max, svc_type, shdl, ehdl) \
(otc_discover(con_lid, nb_ots_max, svc_type, shdl, ehdl))
#define acc_otc_get(con_lid, transfer_lid, get_type, char_type) \
(otc_get(con_lid, transfer_lid, get_type, char_type))
#define acc_otc_get_cfg(con_lid, transfer_lid, ind_char_type) \
(otc_get_cfg(con_lid, transfer_lid, ind_char_type))
#define acc_otc_set_cfg(con_lid, transfer_lid, ind_char_type, enable) \
(otc_set_cfg(con_lid, transfer_lid, ind_char_type, enable))
#define acc_otc_set_name(con_lid, transfer_lid, name_len, p_name) \
(otc_set_name(con_lid, transfer_lid, name_len, p_name))
#define acc_otc_set_time(con_lid, transfer_lid, char_type, p_time) \
(otc_set_time(con_lid, transfer_lid, char_type, p_time))
#define acc_otc_set_properties(con_lid, transfer_lid, properties) \
(otc_set_properties(con_lid, transfer_lid, properties))
#define acc_otc_object_create(con_lid, transfer_lid, size, uuid_type, p_uuid) \
(otc_object_create(con_lid, transfer_lid, size, uuid_type, p_uuid))
#define acc_otc_object_control(con_lid, transfer_lid, opcode) \
(otc_object_control(con_lid, transfer_lid, opcode))
#define acc_otc_object_manipulate(con_lid, transfer_lid, opcode, offset, length, mode) \
(otc_object_manipulate(con_lid, transfer_lid, opcode, offset, length, mode))
#define acc_otc_object_execute(con_lid, transfer_lid, param_len, p_param) \
(otc_object_execute(con_lid, transfer_lid, param_len, p_param))
#define acc_otc_list_control(con_lid, transfer_lid, opcode, order) \
(otc_list_control(con_lid, transfer_lid, opcode, order))
#define acc_otc_list_goto(con_lid, transfer_lid, opcode, p_object_id) \
(otc_list_goto(con_lid, transfer_lid, opcode, p_object_id))
#define acc_otc_filter_set(con_lid, transfer_lid, filter_lid, filter_val) \
(otc_filter_set(con_lid, transfer_lid, filter_lid, filter_val))
#define acc_otc_filter_set_time(con_lid, transfer_lid, filter_lid, filter_val, p_time_start, p_time_end) \
(otc_filter_set_time(con_lid, transfer_lid, filter_lid, filter_val, \
p_time_start, p_time_end))
#define acc_otc_filter_set_size(con_lid, transfer_lid, filter_lid, filter_val, size_min, size_max) \
(otc_filter_set_size(con_lid, transfer_lid, filter_lid, filter_val, \
size_min, size_max))
#define acc_otc_filter_set_name(con_lid, transfer_lid, filter_lid, filter_val, name_len, p_name) \
(otc_filter_set_name(con_lid, transfer_lid, filter_lid, filter_val, \
name_len, p_name))
#define acc_otc_filter_set_type(con_lid, transfer_lid, filter_lid, uuid_type, p_uuid) \
(otc_filter_set_type(con_lid, transfer_lid, filter_lid, uuid_type, p_uuid))
#define acc_otc_coc_connect(con_lid, local_max_sdu) \
(otc_coc_connect(con_lid, local_max_sdu))
#define acc_otc_coc_disconnect(con_lid) \
(otc_coc_disconnect(con_lid))
#define acc_otc_coc_send(con_lid, length, p_sdu) \
(otc_coc_send(con_lid, length, p_sdu))
#define acc_otc_coc_release(con_lid) \
(otc_coc_release(con_lid))
#define acc_otc_restore_bond_data(con_lid, nb_ots, p_ots_info) \
(otc_restore_bond_data(con_lid, nb_ots, p_ots_info))
#endif //(GAF_ACC_OTC)
/// @}
#endif // ACC_OTC_H_
@@ -0,0 +1,212 @@
/**
****************************************************************************************
*
* @file acc_otc_msg.h
*
* @brief Audio Content Control - Definition of Kernel Messages (Object Transfer Client)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_OTC_MSG_H_
#define ACC_OTC_MSG_H_
/**
****************************************************************************************
* @addtogroup ACC_OTC_MSG Audio Content Control - Definition of Kernel Messages
* (Object Transfer Client)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc_msg.h" // Audio Content Control Kernel Messages Definitions
#include "otc_msg.h" // Object Transfer Client - Message API Definitions
#include "gaf.h" // GAF API
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes for Object Transfer Client
enum acc_otc_msg_req_codes
{
ACC_OTC_CONFIGURE = GAF_CODE(ACC, OTC, 0),
ACC_OTC_RESTORE_BOND_DATA = GAF_CODE(ACC, OTC, 1),
};
/// List of GAF_IND indication codes for Object Transfer Client
enum acc_otc_msg_ind_codes
{
ACC_OTC_BOND_DATA = GAF_CODE(ACC, OTC, 0),
ACC_OTC_EXECUTE_RSP = GAF_CODE(ACC, OTC, 1),
ACC_OTC_VALUE = GAF_CODE(ACC, OTC, 2),
ACC_OTC_TIME = GAF_CODE(ACC, OTC, 3),
ACC_OTC_OBJECT_ID = GAF_CODE(ACC, OTC, 4),
ACC_OTC_TYPE = GAF_CODE(ACC, OTC, 5),
ACC_OTC_NAME = GAF_CODE(ACC, OTC, 6),
ACC_OTC_FILTER = GAF_CODE(ACC, OTC, 7),
ACC_OTC_FILTER_TIME = GAF_CODE(ACC, OTC, 8),
ACC_OTC_FILTER_SIZE = GAF_CODE(ACC, OTC, 9),
ACC_OTC_FILTER_NAME = GAF_CODE(ACC, OTC, 10),
ACC_OTC_FILTER_TYPE = GAF_CODE(ACC, OTC, 11),
ACC_OTC_CFG = GAF_CODE(ACC, OTC, 12),
ACC_OTC_CHANGED = GAF_CODE(ACC, OTC, 13),
ACC_OTC_COC_CONNECTED = GAF_CODE(ACC, OTC, 14),
ACC_OTC_COC_DISCONNECTED = GAF_CODE(ACC, OTC, 15),
ACC_OTC_COC_DATA = GAF_CODE(ACC, OTC, 16),
ACC_OTC_SVC_CHANGED = GAF_CODE(ACC, OTC, 17),
};
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ACC_OTC_DISCOVER command message
typedef otc_discover_cmd_t acc_otc_discover_cmd_t;
/// Structure for ACC_OTC_GET command message
typedef otc_get_cmd_t acc_otc_get_cmd_t;
/// Structure for ACC_OTC_GET_CFG command message
typedef otc_get_cfg_cmd_t acc_otc_get_cfg_cmd_t;
/// Structure for ACC_OTC_SET_NAME command message
typedef otc_set_name_cmd_t acc_otc_set_name_cmd_t;
/// Structure for ACC_OTC_SET_TIME command message
typedef otc_set_time_cmd_t acc_otc_set_time_cmd_t;
/// Structure for ACC_OTC_SET_PROPERTIES command message
typedef otc_set_properties_cmd_t acc_otc_set_properties_cmd_t;
/// Structure for ACC_OTC_SET_CFG command message
typedef otc_set_cfg_cmd_t acc_otc_set_cfg_cmd_t;
/// Structure for ACC_OTC_OBJECT_CREATE command message
typedef otc_object_create_cmd_t acc_otc_object_create_cmd_t;
/// Structure for ACC_OTC_OBJECT_CONTROL command message
typedef otc_object_control_cmd_t acc_otc_object_control_cmd_t;
/// Structure for ACC_OTC_OBJECT_MANIPULATE command message
typedef otc_object_manipulate_cmd_t acc_otc_object_manipulate_cmd_t;
/// Structure for ACC_OTC_OBJECT_EXECUTE command message
typedef otc_object_execute_cmd_t acc_otc_object_execute_cmd_t;
/// Structure for ACC_OTC_LIST_CONTROL command message
typedef otc_list_control_cmd_t acc_otc_list_control_cmd_t;
/// Structure for ACC_OTC_LIST_GOTO command message
typedef otc_list_goto_cmd_t acc_otc_list_goto_cmd_t;
/// Structure for ACC_OTC_FILTER_SET command message
typedef otc_filter_set_cmd_t acc_otc_filter_set_cmd_t;
/// Structure for ACC_OTC_FILTER_SET_TIME command message
typedef otc_filter_set_time_cmd_t acc_otc_filter_set_time_cmd_t;
/// Structure for ACC_OTC_FILTER_SET_SIZE command message
typedef otc_filter_set_size_cmd_t acc_otc_filter_set_size_cmd_t;
/// Structure for ACC_OTC_FILTER_SET_NAME command message
typedef otc_filter_set_name_cmd_t acc_otc_filter_set_name_cmd_t;
/// Structure for ACC_OTC_FILTER_SET_TYPE command message
typedef otc_filter_set_type_cmd_t acc_otc_filter_set_type_cmd_t;
/// Structure for ACC_OTC_COC_CONNECT command message
typedef otc_coc_connect_cmd_t acc_otc_coc_connect_cmd_t;
/// Structure for ACC_OTC_COC_DISCONNECT command message
typedef otc_coc_disconnect_cmd_t acc_otc_coc_disconnect_cmd_t;
/// Structure for ACC_OTC_COC_SEND command message
typedef otc_coc_send_cmd_t acc_otc_coc_send_cmd_t;
/// Structure for ACC_OTC_RELEASE_SEND command message
typedef otc_coc_release_cmd_t acc_otc_coc_release_cmd_t;
/// Structure command complete event
typedef otc_cmp_evt_t acc_otc_cmp_evt_t;
/// Structure for ACC_OTC_CONFIGURE request message
typedef struct acc_otc_configure_req
{
/// Request code
uint16_t req_code;
} acc_otc_configure_req_t;
/// Structure for ACC_OTC_RESTORE_BOND_DATA request message
typedef otc_restore_bond_data_req_t acc_otc_restore_bond_data_req_t;
/// Structure for response message
typedef otc_rsp_t acc_otc_rsp_t;
/// Structure for ACC_OTC_BOND_DATA indication message
typedef otc_bond_data_ind_t acc_otc_bond_data_ind_t;
/// Structure for ACC_OTC_EXECUTE_RSP indication message
typedef otc_execute_rsp_ind_t acc_otc_execute_rsp_ind_t;
/// Structure for ACC_OTC_VALUE indication message
typedef otc_value_ind_t acc_otc_value_ind_t;
/// Structure for ACC_OTC_TIME indication message
typedef otc_time_ind_t acc_otc_time_ind_t;
/// Structure for ACC_OTC_OBJECT_ID indication message
typedef otc_object_id_ind_t acc_otc_object_id_ind_t;
/// Structure for ACC_OTC_TYPE indication message
typedef otc_type_ind_t acc_otc_type_ind_t;
/// Structure for ACC_OTC_NAME indication message
typedef otc_name_ind_t acc_otc_name_ind_t;
/// Structure for ACC_OTC_FILTER indication message
typedef otc_filter_ind_t acc_otc_filter_ind_t;
/// Structure for ACC_OTC_FILTER_TIME indication message
typedef otc_filter_time_ind_t acc_otc_filter_time_ind_t;
/// Structure for ACC_OTC_FILTER_SIZE indication message
typedef otc_filter_size_ind_t acc_otc_filter_size_ind_t;
/// Structure for ACC_OTC_FILTER_NAME indication message
typedef otc_filter_name_ind_t acc_otc_filter_name_ind_t;
/// Structure for ACC_OTC_FILTER_TYPE indication message
typedef otc_filter_type_ind_t acc_otc_filter_type_ind_t;
/// Structure for ACC_OTC_CFG indication message
typedef otc_cfg_ind_t acc_otc_cfg_ind_t;
/// Structure for ACC_OTC_CHANGED indication message
typedef otc_changed_ind_t acc_otc_changed_ind_t;
/// Structure for ACC_OTC_COC_CONNECTED indication message
typedef otc_coc_connected_ind_t acc_otc_coc_connected_ind_t;
/// Structure for ACC_OTC_COC_DISCONNECTED indication message
typedef otc_coc_disconnected_ind_t acc_otc_coc_disconnected_ind_t;
/// Structure for ACC_OTC_COC_DATA indication message
typedef otc_coc_data_ind_t acc_otc_coc_data_ind_t;
/// Structure for ACC_OTC_SVC_CHANGED indication message
typedef otc_svc_changed_ind_t acc_otc_svc_changed_ind_t;
/// @}
#endif // ACC_OTC_MSG_H_
@@ -0,0 +1,156 @@
/**
****************************************************************************************
*
* @file acc_ots.h
*
* @brief Audio Content Control - Object Transfer Server - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_OTS_H_
#define ACC_OTS_H_
/**
****************************************************************************************
* @addtogroup ACC_OTS Audio Content Control - Object Transfer Server
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc_ot.h" // Audio Content Control - Object Tranfer Definitions
#if (GAF_ACC_OTS)
#include "gaf.h" // GAF Defines
#include "ots.h" // Object Transfer Server Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_CMD command codes for Object Transfer Server
enum acc_ots_cmd_codes
{
ACC_OTS_COC_DISCONNECT = GAF_CODE(ACC, OTS, 0),
ACC_OTS_COC_SEND = GAF_CODE(ACC, OTS, 1),
ACC_OTS_COC_RELEASE = GAF_CODE(ACC, OTS, 2),
};
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Object Transfer Server
typedef ots_cb_t acc_ots_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Create and configure Object Transfer Client module
*
* @param[in] nb_transfers Number of Object Transfer Service instances
* @param[in] p_cb Pointer to set of callback functions for communications with
* upper layers
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_ots_configure(uint8_t nb_transfers, const acc_ots_cb_t* p_cb);
/// Wrapper for functions defined in ots.h
#define acc_ots_coc_disconnect(con_lid) \
ots_coc_disconnect(con_lid)
#define acc_ots_coc_release(con_lid) \
ots_coc_release(con_lid)
#define acc_ots_coc_send(con_lid, length, p_sdu) \
ots_coc_send(con_lid, length, p_sdu)
#define acc_ots_add(cfg_bf, nb_att_rsvd, oacp_features, olcp_features, \
p_transfer_lid, p_start_handle, p_end_handle) \
ots_add(cfg_bf, nb_att_rsvd, oacp_features, olcp_features, \
p_transfer_lid, p_start_handle, p_end_handle)
#define acc_ots_restore_bond_data(con_lid, transfer_lid, cli_cfg_bf, evt_cfg_bf, \
nb_changes, p_changed_info) \
ots_restore_bond_data(con_lid, transfer_lid, cli_cfg_bf, \
evt_cfg_bf, nb_changes, p_changed_info)
#define acc_ots_object_add(p_object_id, current_size, allocated_size, \
p_first_created_time, p_last_modified_time, \
properties, uuid_type, p_uuid, p_object_lid) \
ots_object_add(p_object_id, current_size, allocated_size, \
p_first_created_time, p_last_modified_time, \
properties, uuid_type, p_uuid, p_object_lid)
#define acc_ots_object_remove(object_lid) \
ots_object_remove(object_lid)
#define acc_ots_object_change(con_lid, transfer_lid, object_lid) \
ots_object_change(con_lid, transfer_lid, object_lid)
#define acc_ots_object_changed(flags, p_object_id) \
ots_object_changed(flags, p_object_id)
#define acc_ots_set(object_lid, set_type, value) \
ots_set(object_lid, set_type, value)
#define acc_ots_set_time(object_lid, p_time) \
ots_set_time(object_lid, p_time)
#define acc_ots_cfm_get_name(status, con_lid, token, name_len, p_name) \
ots_cfm_get_name(status, con_lid, \
token, name_len, p_name)
#define acc_ots_cfm_set_name(status, con_lid, token) \
ots_cfm_set_name(status, con_lid, token)
#define acc_ots_cfm_object_control(status, con_lid, transfer_lid, \
token, opcode, result_code, checksum) \
ots_cfm_object_control(status, con_lid, \
transfer_lid, token, opcode, \
result_code, checksum)
#define acc_ots_cfm_object_execute(status, con_lid, transfer_lid, token, \
result_code, rsp_len, p_rsp) \
ots_cfm_object_execute(status, con_lid, transfer_lid, token, \
result_code, rsp_len, p_rsp)
#define acc_ots_cfm_filter_get(status, con_lid, transfer_lid, \
token, filter_val) \
ots_cfm_filter_get(status, con_lid, transfer_lid, \
token, filter_val)
#define acc_ots_cfm_filter_get_time(status, con_lid, transfer_lid, \
token, filter_val, p_time_start, p_time_end) \
ots_cfm_filter_get_time(status, con_lid, transfer_lid, \
token, filter_val, \
p_time_start, p_time_end)
#define acc_ots_cfm_filter_get_size(status, con_lid, transfer_lid, \
token, filter_val, size_min, size_max) \
ots_cfm_filter_get_size(status, con_lid, transfer_lid, \
token, filter_val, \
size_min, size_max)
#define acc_ots_cfm_filter_get_name(status, con_lid, transfer_lid, \
token, filter_val, name_len, p_name) \
ots_cfm_filter_get_name(status, con_lid, transfer_lid, \
token, filter_val, \
name_len, p_name)
#define acc_ots_cfm_filter_get_type(status, con_lid, transfer_lid, \
token, uuid_type, p_uuid) \
ots_cfm_filter_get_type(status, con_lid, transfer_lid, \
token, uuid_type, p_uuid)
#define acc_ots_cfm_list_control(status, con_lid, transfer_lid, \
token, opcode, result_code, nb_object) \
ots_cfm_list_control(status, con_lid, \
transfer_lid, token, opcode, result_code, \
nb_object)
#define acc_ots_cfm_filter_set(status, con_lid, transfer_lid, token) \
ots_cfm_filter_set(status, con_lid, transfer_lid, token)
#define acc_ots_cfm_coc_connect(status, con_lid, token, local_max_sdu) \
ots_cfm_coc_connect(status, con_lid, token, local_max_sdu)
#endif //(GAF_ACC_OTS)
/// @}
#endif // ACC_OTS_H_
@@ -0,0 +1,243 @@
/**
****************************************************************************************
*
* @file acc_ots_msg.h
*
* @brief Audio Content Control - Definition of Kernel Messages (Object Transfer Server)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_OTS_MSG_H_
#define ACC_OTS_MSG_H_
/**
****************************************************************************************
* @addtogroup ACC_OTS_MSG Audio Content Control - Definition of Kernel Messages
* (Object Transfer Server)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "acc_msg.h" // Audio Content Control Kernel Messages Definitions
#include "ots_msg.h" // Object Transfer Server - Message API Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes for Object Transfer Server
enum acc_ots_msg_req_codes
{
ACC_OTS_CONFIGURE = GAF_CODE(ACC, OTS, 0),
ACC_OTS_ADD = GAF_CODE(ACC, OTS, 1),
ACC_OTS_RESTORE_BOND_DATA = GAF_CODE(ACC, OTS, 2),
ACC_OTS_OBJECT_ADD = GAF_CODE(ACC, OTS, 3),
ACC_OTS_OBJECT_REMOVE = GAF_CODE(ACC, OTS, 4),
ACC_OTS_OBJECT_CHANGE = GAF_CODE(ACC, OTS, 5),
ACC_OTS_OBJECT_CHANGED = GAF_CODE(ACC, OTS, 6),
ACC_OTS_SET = GAF_CODE(ACC, OTS, 7),
ACC_OTS_SET_TIME = GAF_CODE(ACC, OTS, 8),
};
/// List of GAF_IND indication codes for Object Transfer Server
enum acc_ots_msg_ind_codes
{
ACC_OTS_BOND_DATA = GAF_CODE(ACC, OTS, 0),
ACC_OTS_COC_CONNECTED = GAF_CODE(ACC, OTS, 1),
ACC_OTS_COC_DISCONNECTED = GAF_CODE(ACC, OTS, 2),
ACC_OTS_COC_DATA = GAF_CODE(ACC, OTS, 3),
};
/// List of GAF_IND request indication codes for Object Transfer Server
enum acc_ots_msg_req_ind_codes
{
ACC_OTS_GET_NAME = GAF_CODE(ACC, OTS, 0),
ACC_OTS_SET_NAME = GAF_CODE(ACC, OTS, 1),
ACC_OTS_OBJECT_CREATE = GAF_CODE(ACC, OTS, 2),
ACC_OTS_OBJECT_EXECUTE = GAF_CODE(ACC, OTS, 3),
ACC_OTS_OBJECT_MANIPULATE = GAF_CODE(ACC, OTS, 4),
ACC_OTS_OBJECT_CONTROL = GAF_CODE(ACC, OTS, 5),
ACC_OTS_FILTER_GET = GAF_CODE(ACC, OTS, 6),
ACC_OTS_LIST_CONTROL = GAF_CODE(ACC, OTS, 7),
ACC_OTS_LIST_GOTO = GAF_CODE(ACC, OTS, 8),
ACC_OTS_FILTER_SET = GAF_CODE(ACC, OTS, 9),
ACC_OTS_FILTER_SET_TIME = GAF_CODE(ACC, OTS, 10),
ACC_OTS_FILTER_SET_SIZE = GAF_CODE(ACC, OTS, 11),
ACC_OTS_FILTER_SET_NAME = GAF_CODE(ACC, OTS, 12),
ACC_OTS_FILTER_SET_TYPE = GAF_CODE(ACC, OTS, 13),
ACC_OTS_COC_CONNECT = GAF_CODE(ACC, OTS, 14),
};
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ACC_OTS_COC_DISCONNECT command message
typedef ots_coc_disconnect_cmd_t acc_ots_coc_disconnect_cmd_t;
/// Structure for ACC_OTS_COC_SEND command message
typedef ots_coc_send_cmd_t acc_ots_coc_send_cmd_t;
/// Structure for ACC_OTS_COC_RELEASE command message
typedef ots_coc_release_cmd_t acc_ots_coc_release_cmd_t;
/// Structure command complete event
typedef ots_cmp_evt_t acc_ots_cmp_evt_t;
/// Structure for ACC_OTS_CONFIGURE request message
typedef struct acc_ots_configure_req
{
/// Request code
uint16_t req_code;
/// Number of Object Transfer Service instances
uint8_t nb_transfers;
} acc_ots_configure_req_t;
/// Structure for ACC_OTS_ADD request message
typedef ots_add_req_t acc_ots_add_req_t;
/// Structure for ACC_OTS_RESTORE_BOND_DATA request message
typedef ots_restore_bond_data_req_t acc_ots_restore_bond_data_req_t;
/// Structure for ACC_OTS_OBJECT_ADD request message
typedef ots_object_add_req_t acc_ots_object_add_req_t;
/// Structure for ACC_OTS_OBJECT_REMOVE request message
typedef ots_object_remove_req_t acc_ots_object_remove_req_t;
/// Structure for ACC_OTS_OBJECT_CHANGE request message
typedef ots_object_change_req_t acc_ots_object_change_req_t;
/// Structure for ACC_OTS_OBJECT_CHANGED request message
typedef ots_object_changed_req_t acc_ots_object_changed_req_t;
/// Structure for ACC_OTS_SET request message
typedef ots_set_req_t acc_ots_set_req_t;
/// Structure for ACC_OTS_SET_TIME request message
typedef ots_set_time_req_t acc_ots_set_time_req_t;
/// Structure for response message
typedef ots_rsp_t acc_ots_rsp_t;
/// Structure for response message
typedef ots_add_rsp_t acc_ots_add_rsp_t;
/// Structure for ACC_OTS_BOND_DATA indication message
typedef ots_bond_data_ind_t acc_ots_bond_data_ind_t;
/// Structure for ACC_OTS_COC_CONNECTED indication message
typedef ots_coc_connected_ind_t acc_ots_coc_connected_ind_t;
/// Structure for ACC_OTS_COC_DISCONNECTED indication message
typedef ots_coc_disconnected_ind_t acc_ots_coc_disconnected_ind_t;
/// Structure for ACC_OTS_COC_DATA indication message
typedef ots_coc_data_ind_t acc_ots_coc_data_ind_t;
/// Structure for ACC_OTS_GET_NAME request indication message
typedef ots_get_name_req_ind_t acc_ots_get_name_req_ind_t;
/// Structure for ACC_OTS_SET_NAME request indication message
typedef ots_set_name_req_ind_t acc_ots_set_name_req_ind_t;
/// Structure for ACC_OTS_OBJECT_CREATE request indication message
typedef ots_object_create_req_ind_t acc_ots_object_create_req_ind_t;
/// Structure for ACC_OTS_OBJECT_EXECUTE request indication message
typedef ots_object_execute_req_ind_t acc_ots_object_execute_req_ind_t;
/// Structure for ACC_OTS_OBJECT_MANIPULATE request indication message
typedef ots_object_manipulate_req_ind_t acc_ots_object_manipulate_req_ind_t;
/// Structure for ACC_OTS_OBJECT_CONTROL request indication message
typedef ots_object_control_req_ind_t acc_ots_object_control_req_ind_t;
/// Structure for ACC_OTS_FILTER_GET request indication message
typedef ots_filter_get_req_ind_t acc_ots_filter_get_req_ind_t;
/// Structure for ACC_OTS_LIST_CONTROL request indication message
typedef ots_list_control_req_ind_t acc_ots_list_control_req_ind_t;
/// Structure for ACC_OTS_LIST_GOTO request indication message
typedef ots_list_goto_req_ind_t acc_ots_list_goto_req_ind_t;
/// Structure for ACC_OTS_FILTER_SET request indication message
typedef ots_filter_set_req_ind_t acc_ots_filter_set_req_ind_t;
/// Structure for ACC_OTS_FILTER_SET_TIME request indication message
typedef ots_filter_set_time_req_ind_t acc_ots_filter_set_time_req_ind_t;
/// Structure for ACC_OTS_FILTER_SET_SIZE request indication message
typedef ots_filter_set_size_req_ind_t acc_ots_filter_set_size_req_ind_t;
/// Structure for ACC_OTS_FILTER_SET_NAME request indication message
typedef ots_filter_set_name_req_ind_t acc_ots_filter_set_name_req_ind_t;
/// Structure for ACC_OTS_FILTER_SET_TYPE request indication message
typedef ots_filter_set_type_req_ind_t acc_ots_filter_set_type_req_ind_t;
/// Structure for ACC_OTS_COC_CONNECT request indication message
typedef ots_coc_connect_req_ind_t acc_ots_coc_connect_req_ind_t;
/// Structure for ACC_OTS_GET_NAME confirmation message
typedef ots_get_name_cfm_t acc_ots_get_name_cfm_t;
/// Structure for ACC_OTS_SET_NAME confirmation message
typedef ots_set_name_cfm_t acc_ots_set_name_cfm_t;
/// Structure for ACC_OTS_OBJECT_CREATE/MANIPULATE/CONTROL confirmation message
typedef ots_object_control_cfm_t acc_ots_object_control_cfm_t;
/// Structure for ACC_OTS_OBJECT_EXECUTE confirmation message
typedef ots_object_execute_cfm_t acc_ots_object_execute_cfm_t;
/// Structure for ACC_OTS_FILTER_GET confirmation message
/// Used for OTP_FILTER_TYPE_NO_FILTER, OTP_FILTER_TYPE_MARKED_OBJECTS
/// filter values
typedef ots_filter_get_empty_cfm_t acc_ots_filter_get_empty_cfm_t;
/// Structure for OTS_FILTER_GET confirmation message
/// Used for OTP_FILTER_TYPE_CREATED_BETW, OTP_FILTER_TYPE_MODIFIED_BETW
/// filter values
typedef ots_filter_get_time_cfm_t acc_ots_filter_get_time_cfm_t;
/// Structure for OTS_FILTER_GET confirmation message
/// Used for OTP_FILTER_TYPE_CURRENT_SIZE_BETW, OTP_FILTER_TYPE_ALLOCATED_SIZE_BETW
/// filter values
typedef ots_filter_get_size_cfm_t acc_ots_filter_get_size_cfm_t;
/// Structure for OTS_FILTER_GET confirmation message
/// Used for OTP_FILTER_TYPE_NAME_STARTS_WITH, OTP_FILTER_TYPE_NAME_ENDS_WITH
/// OTP_FILTER_TYPE_NAME_CONTAINS, OTP_FILTER_TYPE_NAME_IS_EXACTLY
/// filter values
typedef ots_filter_get_name_cfm_t acc_ots_filter_get_name_cfm_t;
/// Structure for OTS_FILTER_GET confirmation message
/// Used for OTP_FILTER_TYPE_OBJECT_TYPE filter value
typedef ots_filter_get_type_cfm_t acc_ots_filter_get_type_cfm_t;
/// Structure for OTS_LIST_CONTROL/GOTO confirmation message
typedef ots_list_control_cfm_t acc_ots_list_control_cfm_t;
/// Structure for OTS_FILTER_SET/SET_NAME/SET_TIME/SET_SIZE/SET_TYPE confirmation message
typedef ots_filter_set_cfm_t acc_ots_filter_set_cfm_t;
/// Structure for OTS_COC_CONNECT confirmation message
typedef ots_coc_connect_cfm_t acc_ots_coc_connect_cfm_t;
/// @}
#endif // ACC_OTS_MSG_H_
@@ -0,0 +1,395 @@
/**
****************************************************************************************
*
* @file acc_tb.h
*
* @brief Audio Content Control - Bearer Control - Header file
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_TB_H_
#define ACC_TB_H_
/**
****************************************************************************************
* @addtogroup ACC_TB Audio Content Control - Bearer Control
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc.h" // Audio Content Control Defintiions
/*
* DEFINES
****************************************************************************************
*/
/// Length of Bearer Technology characteristic value
#define ACC_TB_TECHNO_LEN (1)
/// Length of Bearer Signal Strength characteristic value
#define ACC_TB_SIGN_STRENGTH_LEN (1)
/// Length of Bearer Signal Strength Reporting Interval characteristic value
#define ACC_TB_SIGN_STRENGTH_INTV_LEN (1)
/// Length of Call Control Point Optional Opcodes characteristic value
#define ACC_TB_OPT_OPCODES_LEN (2)
/// Length of Status Flags characteristic value
#define ACC_TB_STATUS_FLAGS_LEN (1)
/// Minimum number of Calls for Join procedure
#define ACC_TB_JOIN_NB_CALL_MIN (2)
/// Maximum Incoming or Outgoing URI length
#define ACC_TB_URI_MAX_LEN (252)
/// Maximal Signal Strength value
#define ACC_TB_SIGN_STRENGTH_MAX (100)
/// Signal Strength unavailable or meaningless
#define ACC_TB_SIGN_STRENGTH_UNAVA (255)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Characteristic type values
enum acc_tb_char_type
{
/// Bearer Provider Name characteristic
ACC_TB_CHAR_TYPE_PROV_NAME = 0,
/// Bearer Technology characteristic
ACC_TB_CHAR_TYPE_TECHNO,
/// Bearer Signal Strength characteristic
ACC_TB_CHAR_TYPE_SIGN_STRENGTH,
/// Bearer List Current Calls characteristic
ACC_TB_CHAR_TYPE_CURR_CALLS_LIST,
/// Status Flags characteristic
ACC_TB_CHAR_TYPE_STATUS_FLAGS,
/// Incoming Call Target Bearer URI characteristic
ACC_TB_CHAR_TYPE_IN_TGT_CALLER_ID,
/// Call State characteristic
ACC_TB_CHAR_TYPE_CALL_STATE,
/// Call Control Point characteristic
ACC_TB_CHAR_TYPE_CALL_CTL_PT,
/// Termination Reason characteristic
ACC_TB_CHAR_TYPE_TERM_REASON,
/// Incoming Call characteristic
ACC_TB_CHAR_TYPE_INCOMING_CALL,
/// Call Friendly Name characteristic
ACC_TB_CHAR_TYPE_CALL_FRIENDLY_NAME,
/// Bearer URI Schemes Supported List characteristic
ACC_TB_CHAR_TYPE_URI_SCHEMES_LIST,
/// All characteristics above are notification-capable
ACC_TB_NTF_CHAR_TYPE_MAX,
/// Bearer UCI characteristic
ACC_TB_CHAR_TYPE_UCI = ACC_TB_NTF_CHAR_TYPE_MAX,
/// Bearer Signal Strength Reporting Interval characteristic
ACC_TB_CHAR_TYPE_SIGN_STRENGTH_INTV,
/// Content Control ID characteristic
ACC_TB_CHAR_TYPE_CCID,
/// Call Control Point Optional Opcodes characteristic
ACC_TB_CHAR_TYPE_CALL_CTL_PT_OPT_OPCODES,
ACC_TB_CHAR_TYPE_MAX,
};
/// Descriptor type values
enum acc_tb_desc_type
{
/// Client Characteristic Configuration descriptor for Bearer Provider Name characteristic
ACC_TB_DESC_TYPE_CCC_PROV_NAME = 0,
/// Client Characteristic Configuration descriptor for Bearer Technology characteristic
ACC_TB_DESC_TYPE_CCC_TECHNO,
/// Client Characteristic Configuration descriptor for Bearer Signal Strength characteristic
ACC_TB_DESC_TYPE_CCC_SIGN_STRENGTH,
/// Client Characteristic Configuration descriptor for Bearer List Current Calls characteristic
ACC_TB_DESC_TYPE_CCC_CURR_CALLS_LIST,
/// Client Characteristic Configuration descriptor for Status Flags characteristic
ACC_TB_DESC_TYPE_CCC_STATUS_FLAGS,
/// Client Characteristic Configuration descriptor for Incoming Call Target Bearer
/// URI characteristic
ACC_TB_DESC_TYPE_CCC_IN_TGT_CALLER_ID,
/// Client Characteristic Configuration descriptor for Call State characteristic
ACC_TB_DESC_TYPE_CCC_CALL_STATE,
/// Client Characteristic Configuration descriptor for Call Control Point characteristic
ACC_TB_DESC_TYPE_CCC_CALL_CTL_PT,
/// Client Characteristic Configuration descriptor for Termination Reason characteristic
ACC_TB_DESC_TYPE_CCC_TERM_REASON,
/// Client Characteristic Configuration descriptor for Incoming Call characteristic
ACC_TB_DESC_TYPE_CCC_INCOMING_CALL,
/// Client Characteristic Configuration descriptor for Call Friendly Name characteristic
ACC_TB_DESC_TYPE_CCC_CALL_FRIENDLY_NAME,
/// Client Characteristic Configuration descriptor for Bearer URI Schemes Supported
/// List characteristic
ACC_TB_DESC_TYPE_CCC_URI_SCHEMES_LIST,
ACC_TB_DESC_TYPE_MAX,
};
/// Bearer technology values
enum acc_tb_techno
{
/// 3G technology
ACC_TB_TECHNO_3G = 0,
/// 4G technology
ACC_TB_TECHNO_4G,
/// LTE technology
ACC_TB_TECHNO_LTE,
/// Wi-Fi technology
ACC_TB_TECHNO_WIFI,
/// 5G technology
ACC_TB_TECHNO_5G,
/// GSM technology
ACC_TB_TECHNO_GSM,
/// CDMA technology
ACC_TB_TECHNO_CDMA,
/// 2G technology
ACC_TB_TECHNO_2G,
/// WCDMA technology
ACC_TB_TECHNO_WCDMA,
/// IP technology
ACC_TB_TECHNO_IP,
ACC_TB_TECHNO_MAX,
};
/// Call state values
enum acc_tb_call_state
{
/// Incoming
ACC_TB_CALL_STATE_INCOMING = 0,
/// Dialing
ACC_TB_CALL_STATE_DIALING,
/// Alerting
ACC_TB_CALL_STATE_ALERTING,
/// Active
ACC_TB_CALL_STATE_ACTIVE,
/// Locally Held
ACC_TB_CALL_STATE_LOC_HELD,
/// Remotely Held
ACC_TB_CALL_STATE_REMOTE_HELD,
/// Locally and Remotely Held
ACC_TB_CALL_STATE_LOC_REMOTE_HELD,
ACC_TB_CALL_STATE_MAX,
};
/// Termination reason values
enum acc_tb_term_reason
{
/// URI value improperly formed
ACC_TB_TERM_REASON_URI = 0,
/// Call fail
ACC_TB_TERM_REASON_CALL_FAIL,
/// Remote party ended Call
ACC_TB_TERM_REASON_REMOTE_END,
/// Call ended from the Server
ACC_TB_TERM_REASON_SRV_END,
/// Line Busy
ACC_TB_TERM_REASON_BUSY,
/// Network Congestion
ACC_TB_TERM_REASON_CONGESTION,
/// Call ended from the Client
ACC_TB_TERM_REASON_CLI_END,
/// No service
ACC_TB_TERM_REASON_NO_SVC,
/// No answer
ACC_TB_TERM_REASON_NO_ANSWER,
/// Unspecified
ACC_TB_TERM_REASON_UNSPECIFIED,
ACC_TB_TERM_REASON_MAX,
};
/// Operation code values
enum acc_tb_opcode
{
/// Accept
ACC_TB_OPCODE_ACCEPT = 0,
/// Terminate
ACC_TB_OPCODE_TERMINATE,
/// Hold
ACC_TB_OPCODE_HOLD,
/// Retrieve
ACC_TB_OPCODE_RETRIEVE,
/// Originate
ACC_TB_OPCODE_ORIGINATE,
/// Join
ACC_TB_OPCODE_JOIN,
ACC_TB_OPCODE_MAX
};
/// Direction values
enum acc_tb_direction
{
/// Incoming
ACC_TB_DIRECTION_INCOMING = 0,
/// Outgoing
ACC_TB_DIRECTION_OUTGOING,
};
/// Call control point notification result code values
enum acc_tb_cp_ntf_result
{
/// Opcode write was successful
ACC_TB_CP_NTF_RESULT_SUCCESS = 0,
/// An invalid opcode was used for the Call Control Point write
ACC_TB_CP_NTF_RESULT_OPCODE_NOT_SUPPORTED,
/// Requested operation cannot be completed
ACC_TB_CP_NTF_RESULT_OP_NOT_POSSIBLE,
/// The Call Index used for the Call Control Point write is invalid
ACC_TB_CP_NTF_RESULT_INVALID_CALL_INDEX,
/// The opcode written to the Call Control Point was received when the current Call State
/// for the Call Index is not in the expected state
ACC_TB_CP_NTF_RESULT_STATE_MISMATCH,
/// Lack of internal resources to complete the requested action
ACC_TB_CP_NTF_RESULT_LACK_OF_RESSOURCES,
/// The Outgoing URI is incorrect or invalid when an Originate opcode is sent
ACC_TB_CP_NTF_RESULT_INVALID_URI,
ACC_TB_CP_NTF_RESULT_MAX,
};
/// Call Control Point Optional Opcodes bit field meaning
enum acc_tb_opt_opcodes_bf
{
/// Indicate if Local Hold and Local Retrieve operation codes are supported (= 1) or not
ACC_TB_OPT_OPCODES_LOCAL_HOLD_POS = 0,
ACC_TB_OPT_OPCODES_LOCAL_HOLD_BIT = CO_BIT(ACC_TB_OPT_OPCODES_LOCAL_HOLD_POS),
/// Indicate if Join operation code is supported (= 1) or not
ACC_TB_OPT_OPCODES_JOIN_POS = 1,
ACC_TB_OPT_OPCODES_JOIN_BIT = CO_BIT(ACC_TB_OPT_OPCODES_JOIN_POS),
ACC_TB_OPT_OPCODES_MASK = (ACC_TB_OPT_OPCODES_LOCAL_HOLD_BIT | ACC_TB_OPT_OPCODES_JOIN_BIT),
};
/// Status Flags bit field meaning
enum acc_tb_status_flags_bf
{
/// Inband Ringtone
ACC_TB_STATUS_FLAGS_INBAND_RINGTONE_POS = 0,
ACC_TB_STATUS_FLAGS_INBAND_RINGTONE_BIT = CO_BIT(ACC_TB_STATUS_FLAGS_INBAND_RINGTONE_POS),
/// Silent Mode
ACC_TB_STATUS_FLAGS_SILENT_POS = 1,
ACC_TB_STATUS_FLAGS_SILENT_BIT = CO_BIT(ACC_TB_STATUS_FLAGS_SILENT_POS),
ACC_TB_STATUS_FLAGS_MASK = (ACC_TB_STATUS_FLAGS_INBAND_RINGTONE_BIT | ACC_TB_STATUS_FLAGS_SILENT_BIT),
};
/// Bearer List Current Calls characteristic value description
enum acc_tb_curr_call_pos
{
/// Position of List Item length field
ACC_TB_CURR_CALL_LIST_ITEM_LEN_POS = 0,
/// Position of Call Index field
ACC_TB_CURR_CALL_INDEX_POS,
/// Position of Call State field
ACC_TB_CURR_CALL_STATE_POS,
/// Position of Call Flags field
ACC_TB_CURR_CALL_FLAGS_POS,
/// Minimum length
ACC_TB_CURR_CALL_MIN_LEN,
/// Minimum List Item length value
ACC_TB_CURR_CALL_MIN_LIST_ITEM_LEN = ACC_TB_CURR_CALL_MIN_LEN - 1,
/// Position of URI field
ACC_TB_CURR_CALL_URI_POS = ACC_TB_CURR_CALL_MIN_LEN
};
/// Call State characteristic value description
enum acc_tb_call_state_pos
{
/// Position of Call Index field
ACC_TB_CALL_STATE_INDEX_POS = 0,
/// Position of Call State field
ACC_TB_CALL_STATE_STATE_POS,
/// Position of Call Flags field
ACC_TB_CALL_STATE_FLAGS_POS,
/// Minimum length
ACC_TB_CALL_STATE_MIN_LEN,
};
/// Incoming Call characteristic value description
enum acc_tb_incoming_call_pos
{
/// Position of Call Index field
ACC_TB_INCOMING_CALL_INDEX_POS = 0,
/// Minimum length
ACC_TB_INCOMING_CALL_MIN_LEN,
/// Position of URI field
ACC_TB_INCOMING_CALL_URI_POS = ACC_TB_INCOMING_CALL_MIN_LEN,
};
/// Call Control Point characteristic value description
enum acc_tb_cp_pos
{
/// Position of Opcode field
ACC_TB_CP_OPCODE_POS = 0,
/// Minimum length
ACC_TB_CP_MIN_LEN,
/// Position of Parameter field
ACC_TB_CP_PARAM_POS = ACC_TB_CP_MIN_LEN,
/// Position of Call Index field for Accept, Terminate, Local Hold, Local Retrieve
/// and Join operations
ACC_TB_CP_CALL_ID_POS = ACC_TB_CP_PARAM_POS,
/// Position of URI field for Originate field
ACC_TB_CP_URI_POS = ACC_TB_CP_PARAM_POS,
/// Length when only Call Index is provided
ACC_TB_CP_CALL_ID_LEN = ACC_TB_CP_CALL_ID_POS + 1,
};
/// Termination Reason characteristic value description
enum acc_tb_term_reason_pos
{
/// Position of Call Index field
ACC_TB_TERM_REASON_INDEX_POS = 0,
/// Position of Reason Code field
ACC_TB_TERM_REASON_CODE_POS,
/// Length
ACC_TB_TERM_REASON_LEN,
};
/// Call Control Point characteristic notification value description
enum acc_tb_cp_ntf_pos
{
/// Requested opcode
ACC_TB_CP_NTF_OPCODE_POS = 0,
/// Call index
ACC_TB_CP_NTF_CALL_INDEX_POS,
/// Result
ACC_TB_CP_NTF_RESULT_POS,
ACC_TB_CP_NTF_LEN,
};
/// Call Flags bit field meaning
enum acc_tb_call_flags_bf
{
/// Indicate if call is an outgoing call
ACC_TB_CALL_FLAGS_OUTGOING_POS = 0,
ACC_TB_CALL_FLAGS_OUTGOING_BIT = CO_BIT(ACC_TB_CALL_FLAGS_OUTGOING_POS),
ACC_TB_CALL_FLAGS_MASK = ACC_TB_CALL_FLAGS_OUTGOING_BIT,
};
/// @}
#endif // ACC_TB_H_
@@ -0,0 +1,499 @@
/**
****************************************************************************************
*
* @file acc_tbc.h
*
* @brief Audio Content Control - Telephone Bearer Client - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_TBC_H_
#define ACC_TBC_H_
/**
****************************************************************************************
* @addtogroup ACC_TBC Audio Content Control - Telephone Bearer Client
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "acc_tb.h" // Audio Content Control - Telephone Bearer Definition
#if (GAF_ACC_TBC)
/*
* DEFINES
****************************************************************************************
*/
/// Maximum number of Telephone Bearer Service (Generic Telephone Bearer Service excluded)
/// that can be handled (limited by Bearer local index set in dummy value provided to GATT)
#define ACC_TBC_NB_TBS_MAX (126)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_CMD command codes
enum acc_tbc_cmd_codes
{
ACC_TBC_DISCOVER = GAF_CODE(ACC, TBC, 0),
ACC_TBC_GET = GAF_CODE(ACC, TBC, 1),
ACC_TBC_SET_CFG = GAF_CODE(ACC, TBC, 2),
ACC_TBC_GET_CFG = GAF_CODE(ACC, TBC, 3),
ACC_TBC_SET_REPORT_INTV = GAF_CODE(ACC, TBC, 4),
ACC_TBC_CALL_OUTGOING = GAF_CODE(ACC, TBC, 5),
ACC_TBC_CALL_ACTION = GAF_CODE(ACC, TBC, 6),
ACC_TBC_CALL_JOIN = GAF_CODE(ACC, TBC, 7),
};
/// List of GAF_REQ request codes
enum acc_tbc_msg_req_codes
{
ACC_TBC_CONFIGURE = GAF_CODE(ACC, TBC, 0),
ACC_TBC_RESTORE_BOND_DATA = GAF_CODE(ACC, TBC, 1),
};
/// List of GAF_IND indication codes
enum acc_tbc_msg_ind_codes
{
ACC_TBC_BOND_DATA = GAF_CODE(ACC, TBC, 0),
ACC_TBC_CFG = GAF_CODE(ACC, TBC, 1),
ACC_TBC_CALL_STATE = GAF_CODE(ACC, TBC, 2),
ACC_TBC_CALL_STATE_LONG = GAF_CODE(ACC, TBC, 3),
ACC_TBC_VALUE_LONG = GAF_CODE(ACC, TBC, 4),
ACC_TBC_VALUE = GAF_CODE(ACC, TBC, 5),
ACC_TBC_SVC_CHANGED = GAF_CODE(ACC, TBC, 6),
};
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// Content description structure for Telephone Bearer Service
typedef struct acc_tbc_tbs_info
{
/// Service description
prf_svc_t svc_info;
/// Characteristics description
prf_char_t char_info[ACC_TB_CHAR_TYPE_MAX];
/// Descriptors description
prf_desc_t desc_info[ACC_TB_DESC_TYPE_MAX];
} acc_tbc_tbs_info_t;
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called when handling of a command has been completed
*
* @param[in] cmd_code Command code
* @param[in] status Status
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* Meaningless for ACC_TBC_DISCOVER command
* @param[in] param Characteristic type for ACC_TBC_GET command
* Characteristic type for ACC_TBC_SET_CFG/GET_CFG commands
* Operation code for ACC_TBC_CALL_OUTGOING/ACTION/JOIN commands
* Meaningless for ACC_TBC_SET_REPORT_INTV command
* @param[in] call_id Call index for ACC_TBC_CALL_OUTGOING/ACTION/JOIN commands.
* Meaningless for ACC_TBC_CALL_OUTGOING command if sending of notifications
* not enabled for Call Control Point characteristic
* @param[in] result Control point result for ACC_TBC_CALL_OUTGOING/ACTION/JOIN commands.
* Meaningless if sending of notifications not enabled for Call Control
* Point characteristic
****************************************************************************************
*/
typedef void (*acc_tbc_cb_cmp_evt)(uint16_t cmd_code, uint16_t status,
uint8_t con_lid, uint8_t bearer_lid, uint8_t param,
uint8_t call_id, uint8_t result);
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration of a notification-capable
* characteristic has been received
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] char_type Characteristic type
* @param[in] enabled Indicate if sending of notifications is enabled or not
****************************************************************************************
*/
typedef void (*acc_tbc_cb_cfg)(uint8_t con_lid, uint8_t bearer_lid, uint8_t char_type,
uint8_t enabled);
/**
****************************************************************************************
* @brief Callback function called when Call state has been received through Call State
* characteristic
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] call_id Call Index
* @param[in] flags Call Flags
* @param[in] state Call State
****************************************************************************************
*/
typedef void (*acc_tbc_cb_call_state)(uint8_t con_lid, uint8_t bearer_lid, uint8_t call_id,
uint8_t flags, uint8_t state);
/**
****************************************************************************************
* @brief Callback function called when Call state has been received through Bearer List
* Current Calls characteristic
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] call_id Call Index
* @param[in] flags Call Flags
* @param[in] state Call State
* @param[in] uri_len Length of Incoming or Outgoing Call URI value
* @param[in] p_uri Pointer to Incoming or Outgoing Call URI value
****************************************************************************************
*/
typedef void (*acc_tbc_cb_call_state_long)(uint8_t con_lid, uint8_t bearer_lid, uint8_t call_id,
uint8_t flags, uint8_t state, uint8_t uri_len,
uint8_t* p_uri);
/**
****************************************************************************************
* @brief Callback function called when value of one of the following characteristic is
* received:
* - Bearer Provider Name characteristic
* - Bearer UCI characteristic
* - Bearer URI Schemes Supported List characteristic
* - Incoming Call Target Bearer URI characteristic
* - Incoming Call characteristic
* - Call Friendly Name characteristic
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] call_id Call ID
* @param[in] char_type Characteristic type
* @param[in] val_len Length of value
* @param[in] p_val Pointer to value
****************************************************************************************
*/
typedef void (*acc_tbc_cb_value_long)(uint8_t con_lid, uint8_t bearer_lid, uint8_t call_id,
uint8_t char_type, uint16_t val_len, uint8_t* p_val);
/**
****************************************************************************************
* @brief Callback function called when value of one of the following characteristic is
* received:
* - Bearer Technology characteristic
* - Bearer Signal Strength characteristic
* - Bearer Signal Strength Reporting Interval characteristic
* - Content Control ID characteristic
* - Status Flags characteristic
* - Call Control Point Optional Opcodes characteristic
* - Termination Reason characteristic
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] call_id Call index
* @param[in] char_type Characteristic type
* @param[in] val Value
****************************************************************************************
*/
typedef void (*acc_tbc_cb_value)(uint8_t con_lid, uint8_t bearer_lid, uint8_t call_id,
uint8_t char_type, uint16_t val);
/**
****************************************************************************************
* @brief Callback function called when an instance of (Generic) Telephone Bearer Control
* Service has been discovered
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] uuid UUID
* @param[in] p_tbs_info Pointer to Content description structure
****************************************************************************************
*/
typedef void (*acc_tbc_cb_bond_data)(uint8_t con_lid, uint8_t bearer_lid, uint16_t uuid,
acc_tbc_tbs_info_t* p_tbs_info);
/**
****************************************************************************************
* @brief Callback function called when a service changed indicated is received from a Server device
*
* @param[in] con_lid Connection local index
****************************************************************************************
*/
typedef void (*acc_tbc_cb_svc_changed)(uint8_t con_lid);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Telephone Bearer Client
typedef struct acc_tbc_cb
{
/// Callback function called when handling of a command has been completed
acc_tbc_cb_cmp_evt cb_cmp_evt;
/// Callback function called when Client Characteristic Configuration of a notification-capable
/// characteristic has been received
acc_tbc_cb_cfg cb_cfg;
/// Callback function called when Call state has been received through Call State
/// characteristic
acc_tbc_cb_call_state cb_call_state;
/// Callback function called when Call state has been received through Bearer List
/// Current Calls characteristic
acc_tbc_cb_call_state_long cb_call_state_long;
/// Callback function called when value of one of the following characteristic is
/// received:
/// - Bearer Provider Name characteristic
/// - Bearer UCI characteristic
/// - Bearer URI Schemes Supported List characteristic
/// - Incoming Call Target Bearer URI characteristic
/// - Incoming Call characteristic
/// - Call Friendly Name characteristic
acc_tbc_cb_value_long cb_value_long;
/// Callback function called when value of one of the following characteristic is
/// received:
/// - Bearer Technology characteristic
/// - Bearer Signal Strength characteristic
/// - Bearer Signal Strength Reporting Interval characteristic
/// - Content Control ID characteristic
/// - Status Flags characteristic
/// - Call Control Point Optional Opcodes characteristic
/// - Termination Reason characteristic
acc_tbc_cb_value cb_value;
/// Callback function called when an instance of (Generic) Telephone Bearer Control
/// Service has been discovered
acc_tbc_cb_bond_data cb_bond_data;
/// Callback function called when a service changed indicated is received from a Server device
acc_tbc_cb_svc_changed cb_svc_changed;
} acc_tbc_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure use of Telephone Bearer Client module as Client
*
* @param[in] p_cb Pointer to set of callback functions for communication with upper
* layers
* @param[in] pref_mtu Preferred MTU. Values from 0 to 63 are equivalent to 64
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_configure(const acc_tbc_cb_t* p_cb, uint16_t pref_mtu);
/**
****************************************************************************************
* @brief Enable use of Telephone Bearer Service block as Client for a Server device with which
* a bonding has been established during a previous connection.
*
* @param[in] con_lid Connection local index
* @param[in] nb_bearers Number of instances of the (Generic) Telephone Bearer Service
* @param[in] p_tbs_info Pointer to Content description structures
* Generic Telephone Bearer Service first
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_restore_bond_data(uint8_t con_lid, uint8_t nb_bearers, acc_tbc_tbs_info_t* p_tbs_info);
/**
****************************************************************************************
* @brief Enable use of Telephone Bearer Service block as Client for a connected device with which
* no bonding has been established during a previous connection.
* Sending of notifications for Termination Reason characteristic of each discovered (Generic)
* Telephone Bearer Service instance is enabled during the discovery procedure.
*
* @param[in] con_lid Connection local index
* @param[in] nb_tbs_max Maximum number of Telephone Bearer Service instances that can be found
* in peer device database additionally to the Generic Telephone Bearer
* Service
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_discover(uint8_t con_lid, uint8_t nb_tbs_max);
/**
****************************************************************************************
* @brief Get value for one of the following characteristics for a Bearer exposed by a Server device:
* - Bearer Provider Name characteristic
* - Bearer UCI characteristic
* - Bearer Technology characteristic
* - Bearer URI Schemes Supported List characteristic
* - Bearer Signal Strength characteristic if characteristic is supported for the indicated Bearer
* - Bearer Signal Strength Reporting Interval characteristic if characteristic is supported for the
* indicated Bearer
* - Bearer List Current Calles characteristic
* - Content Control ID characteristic
* - Status Flags characteristic
* - Incoming Call Target Bearer URI characteristic if characteristic is supported for the indicated Bearer
* - Call State characteristic
* - Call Control Point Optional Opcodes characteristic
* - Incoming Call characteristic
* - Call Friendly Name if characteristic is supported for the indicated Bearer
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_get(uint8_t con_lid, uint8_t bearer_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Enable or disable sending of notifications for one of the following characteristics for
* a Bearer exposed by a Server device:
* - Bearer Provider Name characteristic
* - Bearer Technology characteristic
* - Bearer Signal Strength characteristic if characteristic is supported for the indicated Bearer
* - Bearer List Current Calls characteristic
* - Status Flags characteristic
* - Incoming Call Target Bearer URI characteristic if characteristic is supported for the indicated
* Bearer
* - Call State characteristic
* - Termination Reason characteristic
* - Incoming Call characteristic
* - Call Friendly Name if characteristic is supported for the indicated Bearer
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] char_type Characteristic type
* @param[in] enable Indicate if sending of notifications must be enabled (!= 0) or
* disabled for the indicated characteristic
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_set_cfg(uint8_t con_lid, uint8_t bearer_lid, uint8_t char_type,
uint8_t enable);
/**
****************************************************************************************
* @brief Get current client configuration for one of the following characteristics for a Bearer
* exposed by a Server device:
* - Bearer Provider Name characteristic
* - Bearer Technology characteristic
* - Bearer Signal Strength characteristic if characteristic is supported for the indicated Bearer
* - Bearer List Current Calls characteristic
* - Status Flags characteristic
* - Incoming Call Target Bearer URI characteristic if characteristic is supported for the indicated
* Bearer
* - Call State characteristic
* - Termination Reason characteristic
* - Incoming Call characteristic
* - Call Friendly Name if characteristic is supported for the indicated Bearer
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_get_cfg(uint8_t con_lid, uint8_t bearer_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Configure Signal Strength Reporting Interval (by setting Bearer Signal Strength Reporting
* Interval characteristic value) for a Bearer exposed by a Service device if reporting of signal
* strength is supported by the Bearer.
* Upper layer can require use of either a Write Request or a Write Command by using the reliable
* parameter.
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] reliable Indicate if feedback from Server device is required (!= 0)
* or not
* @param[in] sign_strength_intv_s Signal Strength Reporting Interval in seconds
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_set_report_intv(uint8_t con_lid, uint8_t bearer_lid, uint8_t reliable,
uint8_t sign_strength_intv_s);
/**
****************************************************************************************
* @brief Require Server device to originate an outgoing call on one of its exposed Bearer
* (by setting Call Control Point characteristic value on the indicated Bearer).
* Upper layer can require use of either a Write Request or a Write Command by using the reliable
* parameter.
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] reliable Indicate if feedback from Server device is required (!= 0)
* or not
* @param[in] uri_len Length of Outgoing URI value
* @param[in] p_uri Pointer to Outgoing URI value
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_call_outgoing(uint8_t con_lid, uint8_t bearer_lid, uint8_t reliable,
uint8_t uri_len, uint8_t* p_uri);
/**
****************************************************************************************
* @brief Accept, terminate, hold or retrieve a call currently existing on a Bearer exposed
* by a Server device (by setting Call Control Point characteristic value on the indicated Bearer).
* Upper layer can require use of either a Write Request or a Write Command by using the reliable
* parameter.
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] reliable Indicate if feedback from Server device is required (!= 0)
* or not
* @param[in] call_id Call index
* @param[in] opcode Operation code
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_call_action(uint8_t con_lid, uint8_t bearer_lid, uint8_t reliable,
uint8_t call_id, uint8_t opcode);
/**
****************************************************************************************
* @brief Join two or more calls currently existing on a Bearer exposed by a Server device
* (by setting Call Control Point characteristic value on the indicated Bearer).
* Note that only the first provided Call index is returned in the command complete event.
* Upper layer can require use of either a Write Request or a Write Command by using the
* reliable parameter.
*
* @param[in] con_lid Connection local index
* @param[in] bearer_lid Bearer local index
* @param[in] reliable Indicate if feedback from Server device is required (!= 0)
* or not
* @param[in] nb_calls Number of calls to join
* @param[in] p_call_ids Pointer to lisst of Call indexes of calls to join
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbc_call_join(uint8_t con_lid, uint8_t bearer_lid, uint8_t reliable,
uint8_t nb_calls, uint8_t* p_call_ids);
#endif //(GAF_ACC_TBC)
/// @}
#endif // ACC_TBC_H_
@@ -0,0 +1,350 @@
/**
****************************************************************************************
*
* @file acc_tbc_msg.h
*
* @brief Audio Content Control - Definition of Kernel Messages (Telephone Bearer Client)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_TBC_MSG_H_
#define ACC_TBC_MSG_H_
/**
****************************************************************************************
* @addtogroup ACC_TBC_MSG Audio Content Control - Definition of Kernel Messages
* (Telephone Bearer Client)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc_msg.h" // ACC Message Definitions
#include "rwip_task.h" // RW IP Task Definition
#include "acc_tbc.h" // Audio Content Control - Telephone Bearer Client Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ACC_TBC_DISCOVER command message
typedef struct acc_tbc_discover_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Maximum number of Telephone Bearer Servie instance that can be found
uint8_t nb_tbs_max;
} acc_tbc_discover_cmd_t;
/// Structure for ACC_TBC_GET command message
typedef struct acc_tbc_get_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Characteristic type
uint8_t char_type;
} acc_tbc_get_cmd_t;
/// Structure for ACC_TBC_SET_CFG command message
typedef struct acc_tbc_set_cfg_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Characteristic type
uint8_t char_type;
/// Indicate if sending of notifications must be enabled (!=0) or disabled
uint8_t enable;
} acc_tbc_set_cfg_cmd_t;
/// Structure for ACC_TBC_GET_CFG command message
typedef struct acc_tbc_get_cfg_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Characteristic type
uint8_t char_type;
} acc_tbc_get_cfg_cmd_t;
/// Structure for ACC_TBC_SET_REPORT_INTV command message
typedef struct acc_tbc_set_report_intv_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Indicate if feedback from Server device is required (!= 0) or not
uint8_t reliable;
/// Signal Strength Reporting Interval in seconds
uint8_t sign_strength_intv_s;
} acc_tbc_set_report_intv_cmd_t;
/// Structure for ACC_TBC_CALL_OUTGOING command message
typedef struct acc_tbc_call_outgoing_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Indicate if feedback from Server device is required (!= 0) or not
uint8_t reliable;
/// Length of Outgoing URI value
uint8_t uri_len;
/// Outgoing URI value
uint8_t uri[__ARRAY_EMPTY];
} acc_tbc_call_outgoing_cmd_t;
/// Structure for ACC_TBC_CALL_ACTION command message
typedef struct acc_tbc_call_action_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Indicate if feedback from Server device is required (!= 0) or not
uint8_t reliable;
/// Call index
uint8_t call_id;
/// Operation code
uint8_t opcode;
} acc_tbc_call_action_cmd_t;
/// Structure for ACC_TBC_CALL_JOIN command message
typedef struct acc_tbc_call_join_cmd
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Indicate if feedback from Server device is required (!= 0) or not
uint8_t reliable;
/// Number of joined calls
uint8_t nb_calls;
/// Call index of calls to join
uint8_t call_ids[__ARRAY_EMPTY];
} acc_tbc_call_join_cmd_t;
/// Structure for command complete event message
typedef struct acc_tbc_cmp_evt
{
/// Command code (@see enum acc_cmd_codes)
uint16_t cmd_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
union
{
/// Value
uint8_t val;
/// Characteristic type
uint8_t char_type;
/// Operation code
uint8_t opcode;
} u;
/// Call index
uint8_t call_id;
/// Result
uint8_t result;
} acc_tbc_cmp_evt_t;
/// Structure for ACC_TBC_CONFIGURE request message
typedef struct acc_tbc_configure_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Preferred MTU
uint16_t pref_mtu;
} acc_tbc_configure_req_t;
/// Structure for ACC_TBC_RESTORE_BOND_DATA request message
typedef struct acc_tbc_restore_bond_data_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Connection local index
uint8_t con_lid;
/// Number of instances of the (Generic) Telephone Bearer Service discovered
uint8_t nb_bearers;
/// Content description of (Generic) Telephone Bearer Service instances
/// Generic Telephone Bearer Service is first service
acc_tbc_tbs_info_t tbs_info[__ARRAY_EMPTY];
} acc_tbc_restore_bond_data_req_t;
/// Structure for response message
typedef struct acc_tbc_rsp
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
} acc_tbc_rsp_t;
/// Structure for ACC_TBC_BOND_DATA indication message
typedef struct acc_tbc_bond_data_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// UUID
uint16_t uuid;
/// Content description of (Generic) Telephone Bearer Service instance
acc_tbc_tbs_info_t tbs_info;
} acc_tbc_bond_data_ind_t;
/// Structure for ACC_TBC_CFG indication message
typedef struct acc_tbc_cfg_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Characteristic type
uint8_t char_type;
/// Indicate if sending of notifications is enabled (!= 0) or not
uint8_t enabled;
} acc_tbc_cfg_ind_t;
/// Structure for ACC_TBC_CALL_STATE indication message
typedef struct acc_tbc_call_state_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Call index
uint8_t id;
/// Call flags
uint8_t flags;
/// Call state
uint8_t state;
} acc_tbc_call_state_ind_t;
/// Structure for ACC_TBC_CALL_STATE_LONG indication message
typedef struct acc_tbc_call_state_long_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Call index
uint8_t id;
/// Call flags
uint8_t flags;
/// Call state
uint8_t state;
/// Length of Incoming or Outgoing Call URI value
uint8_t uri_len;
/// Incoming or Outgoing Call URI value
uint8_t uri[__ARRAY_EMPTY];
} acc_tbc_call_state_long_ind_t;
/// Structure for ACC_TBC_VALUE_LONG indication message
typedef struct acc_tbc_value_long_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Call index
uint8_t call_id;
/// Characteristic type
uint8_t char_type;
/// Length of value
uint16_t val_len;
/// Value
uint8_t val[__ARRAY_EMPTY];
} acc_tbc_value_long_ind_t;
/// Structure for ACC_TBC_VALUE indication message
typedef struct acc_tbc_value_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Call index
/// Meaningful only for Termination Reason characteristic
uint8_t call_id;
/// Characteristic type
uint8_t char_type;
/// Value
union
{
/// Value
uint16_t val;
/// Bearer Technology
uint8_t techno;
/// Signal Strength
uint8_t sign_strength;
/// Signal Strength Reporting Interval in seconds
uint8_t sign_strength_intv_s;
/// Content Control ID
uint8_t ccid;
/// Status Flags bit field
uint16_t status_flags_bf;
/// Call Control Point Optional Opcodes bit field
uint16_t opt_opcodes_bf;
/// Termination Reason
uint8_t term_reason;
} val;
} acc_tbc_value_ind_t;
/// Structure for ACC_TBC_SVC_CHANGED indication message
typedef struct acc_tbc_svc_changed_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
} acc_tbc_svc_changed_ind_t;
/// @}
#endif // ACC_TBC_MSG_H_
@@ -0,0 +1,402 @@
/**
****************************************************************************************
*
* @file acc_tbs.h
*
* @brief Audio Content Control - Telephone Bearer Server - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_TBS_H_
#define ACC_TBS_H_
/**
****************************************************************************************
* @addtogroup ACC_TBS Audio Content Control - Telephone Bearer Server
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "acc_tb.h" // Audio Content Control - Telephone Bearer Definition
#if (GAF_ACC_TBS)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Bearer configuration bit field
enum acc_tbs_cfg_bf
{
/// Indicate if Bearer Signal Strength can be measured and reported to a Client device
ACC_TBS_CFG_SIGNAL_STRENGTH_SUPP_POS = 0,
ACC_TBS_CFG_SIGNAL_STRENGTH_SUPP_BIT = CO_BIT(ACC_TBS_CFG_SIGNAL_STRENGTH_SUPP_POS),
/// Indicate if Incoming Call Target Bearer URI characteristic is supported or not
ACC_TBS_CFG_INCOMING_TARGET_URI_SUPP_POS = 1,
ACC_TBS_CFG_INCOMING_TARGET_URI_SUPP_BIT = CO_BIT(ACC_TBS_CFG_INCOMING_TARGET_URI_SUPP_POS),
/// Indicate if Call Friendly Name characteristic is supported or not
ACC_TBS_CFG_FRIENDLY_NAME_SUPP_POS = 2,
ACC_TBS_CFG_FRIENDLY_NAME_SUPP_BIT = CO_BIT(ACC_TBS_CFG_FRIENDLY_NAME_SUPP_POS),
/// Indicate if sending of notifications is supported or not for Bearer URI Schemes
/// Supported List characteristic
ACC_TBS_CFG_URI_SCHEMES_NTF_SUPP_POS = 3,
ACC_TBS_CFG_URI_SCHEMES_NTF_SUPP_BIT = CO_BIT(ACC_TBS_CFG_URI_SCHEMES_NTF_SUPP_POS),
};
/// Call action values
enum acc_tbs_call_action
{
/// Accept call
ACC_TBS_ACTION_ACCEPT = 0,
/// Terminate call
ACC_TBS_ACTION_TERMINATE,
/// Hold call (local)
ACC_TBS_ACTION_HOLD_LOCAL,
/// Retrieve call (local)
ACC_TBS_ACTION_RETRIEVE_LOCAL,
/// Hold call (remote)
ACC_TBS_ACTION_HOLD_REMOTE,
/// Retrieve call (remote)
ACC_TBS_ACTION_RETRIEVE_REMOTE,
/// Remote alert started for a call
ACC_TBS_ACTION_ALERT_START,
/// Remote answer for a call
ACC_TBS_ACTION_ANSWER,
ACC_TBS_ACTION_MAX
};
/// Status type values
enum acc_tbs_status_type
{
/// Inband ringtone
ACC_TBS_STATUS_TYPE_INBAND_RINGTONE = 0,
/// Silent mode
ACC_TBS_STATUS_TYPE_SILENT_MODE,
ACC_TBS_STATUS_TYPE_MAX,
};
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration of a notification-capable
* characteristic has been updated by a peer client
*
* @param[in] bearer_lid Bearer local index
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
****************************************************************************************
*/
typedef void (*acc_tbs_cb_bond_data)(uint8_t bearer_lid, uint8_t con_lid, uint16_t cli_cfg_bf);
/**
****************************************************************************************
* @brief Callback function called when Input State characteristic value has been updated
*
* @param[in] bearer_lid Bearer local index
* @param[in] con_lid Connection local index
* @param[in] sign_strength_intv_s Signal Strength Reporting Interval in seconds
****************************************************************************************
*/
typedef void (*acc_tbs_cb_report_intv)(uint8_t bearer_lid, uint8_t con_lid, uint8_t sign_strength_intv_s);
/**
****************************************************************************************
* @brief Callback function called to request from upper layer complete or piece of value for
* one of the following characteristics:
* - Bearer Provider Name characteristic
* - Incoming Call Target Bearer URI characteristic
* - Call Friendly Name characteristic
*
* @param[in] bearer_lid Bearer local index
* @param[in] call_id Call index
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
* @param[in] token Token
* @param[in] offset Offset
* @param[in] length Length
****************************************************************************************
*/
typedef void (*acc_tbs_cb_get_req)(uint8_t bearer_lid, uint8_t call_id, uint8_t con_lid,
uint8_t char_type, uint16_t token, uint16_t offset,
uint16_t length);
/**
****************************************************************************************
* @brief Callback function called to inform upper layer that a client device has requested creation
* of an outgoing call
*
* @param[in] bearer_lid Bearer local index
* @param[in] con_lid Connection local index
* @param[in] opcode Operation code
* @param[in] call_id Call index
* @param[in] len Number of calls to join or Outgoing URI length
* @param[in] p_val Pointer to list of calls to join or to Outgoing URI value
****************************************************************************************
*/
typedef void (*acc_tbs_cb_call_req)(uint8_t bearer_lid, uint8_t con_lid, uint8_t opcode,
uint8_t call_id, uint8_t len, uint8_t* p_val);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Telephone Bearer Server
typedef struct acc_tbs_cb
{
/// Callback function called when Client Characteristic Configuration of a notification-capable
/// characteristic has been updated by a peer client
acc_tbs_cb_bond_data cb_bond_data;
/// Callback function called when Input State characteristic value has been updated
acc_tbs_cb_report_intv cb_report_intv;
/// Callback function called to request from upper layer complete or piece of value for
/// either Bearer Provider Name characteristic or Incoming Call Target Bearer URI characteristic
/// or Call Friendly Name characteristic
acc_tbs_cb_get_req cb_get_req;
/// Callback function called to inform upper layer that a client device has requested an action
/// for a call
acc_tbs_cb_call_req cb_call_req;
} acc_tbs_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure use of Telephone Bearer Server module as Server
*
* @param[in] nb_tbs Number of instances of the Telephone Bearer Service
* 0 means that only the Generic Telephone Bearer Service is
* supported
* @param[in] call_pool_size Size of pool containing pre-allocated structures used to manage
* Calls
* @param[in] call_pool_uri_len Maximum URI length allowed for pre-allocated Call structures
* @param[in] uri_len_max Maximum URI length for a Call. 0 means this is no limitation
* @param[in] p_cb Pointer to set of callback functions for communication with upper
* layer
* @param[in] pref_mtu Preferred MTU
* Values from 0 to 63 are equivalent to 64
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_configure(uint8_t nb_tbs, uint8_t call_pool_size, uint8_t call_pool_uri_len,
uint8_t uri_len_max, const acc_tbs_cb_t* p_cb, uint16_t pref_mtu);
/**
****************************************************************************************
* @brief Add and configure an instance of the Telephone Bearer Service in the database
*
* @param[in] cfg_bf Configuration bit field
* @param[in] nb_att_rsvd Number of attributes reserved for the service
* @param[in] ccid Content Control ID
* @param[in] opt_opcodes_bf Optional operation codes bit field
* @param[in] bearer_uci_len Length of Bearer UCI value
* @param[in] p_bearer_uci Pointer to Bearer UCI value
* @param[in] p_bearer_lid Pointer at which allocated Bearer local index is returned
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_add(uint8_t cfg_bf, uint8_t nb_att_rsvd, uint8_t ccid, uint8_t opt_opcodes_bf,
uint8_t bearer_uci_len, uint8_t* p_bearer_uci, uint8_t* p_bearer_lid);
/**
****************************************************************************************
* @brief Enable use of Telephone Bearer Server module as Server
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_enable(void);
/**
****************************************************************************************
* @brief Set bonding information for either the Generic Telephone Bearer Service or an instance
* of the Telephone Bearer Service Service after connection with a Client device with which a
* bonded relationship had been established during a previous connection.
*
* @param[in] bearer_lid Bearer local index
* @param[in] con_lid Connection local index
* @param[in] sign_strength_intv_s Signal strength reporting interval in seconds
* @param[in] cli_cfg_bf Client configuration bit field
* @param[in] evt_cfg_bf Event configuration bit field
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_restore_bond_data(uint8_t bearer_lid, uint8_t con_lid, uint8_t sign_strength_intv_s,
uint16_t cli_cfg_bf, uint16_t evt_cfg_bf);
/**
****************************************************************************************
* @brief Set value of one of the following characteristics for a specific bearer.
*
* @param[in] bearer_lid Bearer local index
* @param[in] char_type Characteristic type
* @param[in] val Bearer technology
* or Signal Strength (from 0 to 100 or 255)
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_set(uint8_t bearer_lid, uint8_t char_type, uint8_t val);
/**
****************************************************************************************
* @brief Enable or disable Silent Mode or Inband Ringtone for a Bearer.
*
* @param[in] bearer_lid Bearer local index
* @param[in] status_type Status type
* @param[in] val Value
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_set_status(uint8_t bearer_lid, uint8_t status_type, uint8_t val);
/**
****************************************************************************************
* @brief Indicate an update of the Bearer Provider Name or the Bearer URI Scheme Supported
* List characteristic
*
* @param[in] bearer_lid Bearer local index
* @param[in] char_type Characteristic type
* @param[in] len Length of value
* @param[in] name Pointer to value
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_set_long(uint8_t bearer_lid, uint8_t char_type, uint8_t len, uint8_t* p_val);
/**
****************************************************************************************
* @brief Add an incoming call.
*
* @param[in] bearer_lid Bearer local index
* @param[in] uri_len Length of Incoming URI value
* @param[in] tgt_uri_len Length of Incoming Call Target URI value
* Meaningful only if Incoming Call Target Bearer URI characteristic is supported
* @param[in] friendly_name_len Length of Friendly Name value
* Meaningful only if Call Friendly Name characteristic is supported
* @param[in] p_uri Pointer to Incoming URI value
* @param[in] p_tgt_uri Pointer to Incoming Call Target URI value
* @param[in] p_friendly_name Pointer to Friendly Name value
* @param[out] p_call_id Pointer at which allocated Call index is returned
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_call_incoming(uint8_t bearer_lid, uint8_t uri_len, uint8_t tgt_uri_len,
uint8_t friendly_name_len, uint8_t* p_uri, uint8_t* p_tgt_uri,
uint8_t* p_friendly_name, uint8_t* p_call_id);
/**
****************************************************************************************
* @brief Add an outgoing call.
*
* @param[in] bearer_lid Bearer local index
* @param[in] uri_len Length of Outgoing URI value
* @param[in] friendly_name_len Length of Friendly Name value
* Meaningful only if Call Friendly Name characteristic is supported
* @param[in] p_uri Pointer to Outgoing URI value
* @param[in] p_friendly_name Pointer to Friendly Name value
* @param[out] p_call_id Pointer at which allocated Call index is returned
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_call_outgoing(uint8_t bearer_lid, uint8_t uri_len,
uint8_t friendly_name_len, uint8_t* p_uri,
uint8_t* p_friendly_name, uint8_t* p_call_id);
/**
****************************************************************************************
* @brief Update state of a call existing a Bearer.
*
* @param[in] bearer_lid Bearer local index
* @param[in] call_id Call index
* @param[in] action Action
* @param[in] reason Termination reason
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_call_action(uint8_t bearer_lid, uint8_t call_id, uint8_t action, uint8_t reason);
/**
****************************************************************************************
* @brief Join two or more calls currently existing on a Bearer.
* Note that only the first provided Call index is returned in the response.
*
* @param[in] bearer_lid Bearer local index
* @param[in] nb_calls Number of calls to join
* @param[in] p_call_lids Pointer to list of Call indexes of call to join
*
* @return An error status
****************************************************************************************
*/
uint16_t acc_tbs_call_join(uint8_t bearer_lid, uint8_t nb_calls, uint8_t* p_call_ids);
/**
****************************************************************************************
* @brief Confirmation for ACC_TBS_GET request indication
*
* @param[in] status Status
* @param[in] bearer_lid Bearer local index
* @param[in] call_id Call index
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
* @param[in] token Token
* @param[in] offset Offset
* @param[in] length Length
* @param[in] p_val Pointer to requested value
*
* @return An error status
****************************************************************************************
*/
void acc_tbs_cfm_get(uint16_t status, uint8_t bearer_lid, uint8_t call_id, uint8_t con_lid,
uint8_t char_type, uint16_t token, uint16_t offset, uint16_t length, uint8_t* p_val);
/**
****************************************************************************************
* @brief Confirmation for ACC_TBS_CALL_OUTGOING or ACC_TBS_CALL_ACTION or
* ACC_TBS_CALL_JOIN request indication.
*
* @param[in] status Status
* @param[in] bearer_lid Bearer local index
* @param[in] friendly_name_len Length of friendly name value for Originate action
* @param[in] p_friendly_name Pointer to friendly name value
*
* @return An error status
****************************************************************************************
*/
void acc_tbs_cfm_call(uint16_t status, uint8_t bearer_lid,
uint8_t friendly_name_len, uint8_t* p_friendly_name);
#endif //(GAF_ACC_TBS)
/// @}
#endif // ACC_TBS_H_
@@ -0,0 +1,427 @@
/**
****************************************************************************************
*
* @file acc_tbs_msg.h
*
* @brief Audio Content Control - Definition of Kernel Messages (Telephone Bearer Server)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ACC_TBS_MSG_H_
#define ACC_TBS_MSG_H_
/**
****************************************************************************************
* @addtogroup ACC_TBS_MSG Audio Content Control - Definition of Kernel Messages
* (Telephone Bearer Server)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "acc_msg.h" // ACC Message Definitions
#include "rwip_task.h" // RW IP Task Definition
#include "acc_tbs.h" // Audio Content Control - Telephone Bearer Server Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes
enum acc_tbs_msg_req_codes
{
ACC_TBS_CONFIGURE = GAF_CODE(ACC, TBS, 0),
ACC_TBS_ADD = GAF_CODE(ACC, TBS, 1),
ACC_TBS_ENABLE = GAF_CODE(ACC, TBS, 2),
ACC_TBS_RESTORE_BOND_DATA = GAF_CODE(ACC, TBS, 3),
ACC_TBS_SET = GAF_CODE(ACC, TBS, 4),
ACC_TBS_SET_STATUS = GAF_CODE(ACC, TBS, 5),
ACC_TBS_SET_LONG = GAF_CODE(ACC, TBS, 6),
ACC_TBS_CALL_INCOMING = GAF_CODE(ACC, TBS, 7),
ACC_TBS_CALL_OUTGOING = GAF_CODE(ACC, TBS, 8),
ACC_TBS_CALL_ACTION = GAF_CODE(ACC, TBS, 9),
ACC_TBS_CALL_JOIN = GAF_CODE(ACC, TBS, 10),
};
/// List of GAF_IND indication codes
enum acc_tbs_msg_ind_codes
{
ACC_TBS_BOND_DATA = GAF_CODE(ACC, TBS, 0),
ACC_TBS_REPORT_INTV = GAF_CODE(ACC, TBS, 1),
};
/// List of GAF_REQ_IND request indication codes
enum acc_tbs_msg_req_ind_codes
{
ACC_TBS_GET = GAF_CODE(ACC, TBS, 0),
ACC_TBS_CALL_OUTGOING_RI = GAF_CODE(ACC, TBS, 1),
ACC_TBS_CALL_ACTION_RI = GAF_CODE(ACC, TBS, 2),
ACC_TBS_CALL_JOIN_RI = GAF_CODE(ACC, TBS, 3),
};
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ACC_TBS_CONFIGURE request message
typedef struct acc_tbs_configure_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Number of instances of the Telephone Bearer Service
/// 0 means that only the Generic Telephone Bearer Service is supported
uint8_t nb_tbs;
/// Size of pool containing pre-allocated structures used to manage calls
uint8_t call_pool_size;
/// Maximum URI length allowed for pre-allocated call structure
uint8_t call_pool_uri_len;
/// Maximum URI length for a call
uint8_t uri_len_max;
/// Preferred MTU
/// Values from 0 to 63 are equivalent to 64
uint16_t pref_mtu;
} acc_tbs_configure_req_t;
/// Structure for ACC_TBS_ADD request message
typedef struct acc_tbs_add_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Configuration bit field
uint8_t cfg_bf;
/// Number of attributes reserved for the service
uint8_t nb_att_rsvd;
/// Content Control ID
uint8_t ccid;
/// Optional operation codes bit field
uint8_t opt_opcodes_bf;
/// Length of Bearer UCI value
uint8_t bearer_uci_len;
/// Bearer UCI value
uint8_t val[__ARRAY_EMPTY];
} acc_tbs_add_req_t;
/// Structure for ACC_TBS_ENABLE request message
typedef struct acc_tbs_enable_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
} acc_tbs_enable_req_t;
/// Structure for ACC_TBS_RESTORE_BOND_DATA request message
typedef struct acc_tbs_restore_bond_data_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Bearer local index
uint8_t bearer_lid;
/// Connection local index
uint8_t con_lid;
/// Signal strength reporting interval in seconds
/// Meaningful only if Bearer Signal Strength characteristic is supported for the indication bearer
uint8_t sign_strength_intv_s;
/// Client configuration bit field
uint16_t cli_cfg_bf;
/// Event configuration bit field
uint16_t evt_cfg_bf;
} acc_tbs_restore_bond_data_req_t;
/// Structure for ACC_TBS_SET request message
typedef struct acc_tbs_set_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Bearer local index
uint8_t bearer_lid;
/// Characteristic type
uint8_t char_type;
union
{
/// Value
uint8_t val;
/// Bearer technology
uint8_t techno;
/// Signal strength. Value from 101 to 254 are prohibited
/// 255 means that signal strength values cannot be measured or has no meaning
uint8_t signal_strength;
} val;
} acc_tbs_set_req_t;
/// Structure for ACC_TBS_SET_STATUS request message
typedef struct acc_tbs_set_status_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Bearer local index
uint8_t bearer_lid;
/// Status type
uint8_t status_type;
/// Value
uint8_t val;
} acc_tbs_set_status_req_t;
/// Structure for ACC_TBS_SET_LONG request message
typedef struct acc_tbs_set_long_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Bearer local index
uint8_t bearer_lid;
/// Characteristic type
uint8_t char_type;
/// Length of value
uint8_t len;
/// Value
uint8_t val[__ARRAY_EMPTY];
} acc_tbs_set_long_req_t;
/// Structure for ACC_TBS_CALL_INCOMING request message
typedef struct acc_tbs_call_incoming_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Bearer local index
uint8_t bearer_lid;
/// Length of Incoming URI value
uint8_t uri_len;
/// Length of Incoming Call Target URI value
/// Meaningful only if Incoming Call Target Bearer URI characteristic is supported
uint8_t tgt_uri_len;
/// Length of Friendly Name value
/// Meaningful only if Call Friendly Name characteristic is supported
uint8_t friendly_name_len;
/// Incoming URI value followed by Incoming Call Target URI value followed by
/// Friendly Name value
uint8_t val[__ARRAY_EMPTY];
} acc_tbs_call_incoming_req_t;
/// Structure for ACC_TBS_CALL_OUTGOING request message
typedef struct acc_tbs_call_outgoing_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Bearer local index
uint8_t bearer_lid;
/// Length of Outgoing URI value
uint8_t uri_len;
/// Length of Friendly Name value
/// Meaningful only if Call Friendly Name characteristic is supported
uint8_t friendly_name_len;
/// Incoming URI value followed by Outgoing URI value followed by Friendly Name value
uint8_t val[__ARRAY_EMPTY];
} acc_tbs_call_outgoing_req_t;
/// Structure for ACC_TBS_CALL_ACTION request message
typedef struct acc_tbs_call_action_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Bearer local index
uint8_t bearer_lid;
/// Call index
uint8_t call_id;
/// Action
uint8_t action;
/// Termination reason
uint8_t reason;
} acc_tbs_call_action_req_t;
/// Structure for ACC_TBS_CALL_JOIN request message
typedef struct acc_tbs_call_join_req
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Bearer local index
uint8_t bearer_lid;
/// Number of joined calls
uint8_t nb_calls;
/// Call index of calls to join
uint8_t call_ids[__ARRAY_EMPTY];
} acc_tbs_call_join_req_t;
/// Structure for response message
typedef struct acc_tbs_rsp
{
/// Request code (@see enum acc_req_codes)
uint16_t req_code;
/// Status
uint16_t status;
/// Bearer local index
uint8_t bearer_lid;
/// Union
union
{
/// Value
uint8_t val;
/// Characteristic type for ACC_TBS_SET request
uint8_t char_type;
/// Status type for ACC_TBS_SET_STATUS request
uint8_t status_type;
/// Connection local index for ACC_TBS_RESTORE_BOND_DATA request
uint8_t con_lid;
/// Allocated Call index
uint8_t call_id;
} u;
/// Action for ACC_TBS_CALL_ACTION request
uint8_t action;
} acc_tbs_rsp_t;
/// Structure for ACC_TBS_BOND_DATA indication message
typedef struct acc_tbs_cfg_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Bearer local index
uint8_t bearer_lid;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint16_t cli_cfg_bf;
} acc_tbs_cfg_ind_t;
/// Structure for ACC_TBS_REPORT_INTV indication message
typedef struct acc_tbs_report_intv_ind
{
/// Indication code (@see enum acc_ind_codes)
uint16_t ind_code;
/// Bearer local index
uint8_t bearer_lid;
/// Connection local index
uint8_t con_lid;
/// Signal Strength Reporting Interval in seconds
uint8_t sign_strength_intv_s;
} acc_tbs_report_intv_ind_t;
/// Structure for ACC_TBS_GET request indication message
typedef struct acc_tbs_get_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Bearer local index
uint8_t bearer_lid;
/// Call index
uint8_t call_id;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
/// Token value to return in the confirmation
uint16_t token;
/// Offset
uint16_t offset;
/// Maximum length
uint16_t length;
} acc_tbs_get_req_ind_t;
/// Structure for ACC_TBS_CALL_OUTGOING request indication message
typedef struct acc_tbs_call_out_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Bearer local index
uint8_t bearer_lid;
/// Connection local index
uint8_t con_lid;
/// Call index
uint8_t call_id;
/// Length of Outgoing URI value
uint8_t uri_len;
/// Outgoing URI value
uint8_t uri[__ARRAY_EMPTY];
} acc_tbs_call_out_req_ind_t;
/// Structure for ACC_TBS_CALL_ACTION request indication message
typedef struct acc_tbs_call_action_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Bearer local index
uint8_t bearer_lid;
/// Connection local index
uint8_t con_lid;
/// Operation code
uint8_t opcode;
/// Call index
uint8_t call_id;
} acc_tbs_call_action_req_ind_t;
/// Structure for ACC_TBS_CALL_JOIN request indication message
typedef struct acc_tbs_call_join_req_ind
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Connection local index
uint8_t con_lid;
/// Bearer local index
uint8_t bearer_lid;
/// Number of calls
uint8_t nb_calls;
/// List of call indexes
uint8_t call_ids[__ARRAY_EMPTY];
} acc_tbs_call_join_req_ind_t;
/// Structure for ACC_TBS_GET confirmation message
typedef struct acc_tbs_get_cfm
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Bearer local index
uint8_t bearer_lid;
/// Call index
uint8_t call_id;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
/// Token value to return in the confirmation
uint16_t token;
/// Offset
uint16_t offset;
/// Length
uint16_t length;
/// Request value
uint8_t val[__ARRAY_EMPTY];
} acc_tbs_get_cfm_t;
/// Structure for ACC_TBS_CALL_ACTION/JOIN confirmation message
typedef struct acc_tbs_call_cfm
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Bearer local index
uint8_t bearer_lid;
} acc_tbs_call_cfm_t;
/// Structure for ACC_TBS_CALL_OUTGOING confirmation message
typedef struct acc_tbs_call_out_cfm
{
/// Request Indication code (@see enum acc_req_ind_codes)
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Bearer local index
uint8_t bearer_lid;
/// Length of Call Friendly Name value
uint8_t friendly_name_len;
/// Call Friendly Name value
uint8_t friendly_name[__ARRAY_EMPTY];
} acc_tbs_call_out_cfm_t;
/// @}
#endif // ACC_TBS_MSG_H_
@@ -0,0 +1,244 @@
/**
****************************************************************************************
*
* @file arc_aic.h
*
* @brief Audio Rendering Control - Audio Input Control - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_AIC_H_
#define ARC_AIC_H_
/**
****************************************************************************************
* @addtogroup ARC_AIC Audio Rendering Control - Audio Input Control
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc.h" // Audio Rendering Control Defintiions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Position of fields in Input State characteristic value
enum arc_aic_state_pos
{
/// Gain Setting field
ARC_AIC_STATE_POS_GAIN = 0,
/// Mute field
ARC_AIC_STATE_POS_MUTE,
/// Gain Mode field
ARC_AIC_STATE_POS_GAIN_MODE,
/// Change Counter field
ARC_AIC_STATE_POS_CHANGE_CNT,
/// Length of Input State characteristic value
ARC_AIC_STATE_LEN
};
/// Position of fields in Gain Setting Properties characteristic value
enum arc_aic_gain_prop_pos
{
/// Gain Settings Units field
ARC_AIC_GAIN_PROP_POS_UNITS = 0,
/// Gain Settings Minimum field
ARC_AIC_GAIN_PROP_POS_MIN,
/// Gain Settings Maximum field
ARC_AIC_GAIN_PROP_POS_MAX,
/// Length of Gain Setting Properties characteristic value
ARC_AIC_GAIN_PROP_LEN
};
/// Position of fields in Input Type characteristic value
enum arc_aic_type_pos
{
/// Input Type
ARC_AIC_TYPE_POS_TYPE = 0,
/// Length of Input Type characteristic value
ARC_AIC_TYPE_LEN,
};
/// Position of fields in Input Status characteristic value
enum arc_aic_status_pos
{
/// Input Status
ARC_AIC_STATUS_POS_STATUS = 0,
/// Length of Input Status characteristic value
ARC_AIC_STATUS_LEN,
};
/// Position of fields in value written in Audio Input Control Point characteristic
enum arc_aic_cp_pos
{
/// Operation Code field
ARC_AIC_CP_POS_OPCODE = 0,
/// Change Counter field
ARC_AIC_CP_POS_CHANGE_CNT,
/// Gain Setting field
ARC_AIC_CP_POS_GAIN,
/// Minimal length of Audio Input Control Point characteristic value
ARC_AIC_CP_LEN_MIN = ARC_AIC_CP_POS_CHANGE_CNT + 1,
ARC_AIC_CP_LEN_MAX = ARC_AIC_CP_POS_GAIN + 1,
};
/// Operation Code values for Audio Input Control Point characteristic
enum arc_aic_opcode
{
/// Set Gain Setting
ARC_AIC_OPCODE_SET_GAIN = 1,
/// Unmute
ARC_AIC_OPCODE_UNMUTE,
/// Mute
ARC_AIC_OPCODE_MUTE,
/// Set Manual Gain Mode
ARC_AIC_OPCODE_SET_MANUAL_MODE,
/// Set Automatic Gain Mode
ARC_AIC_OPCODE_SET_AUTO_MODE,
};
/// Application error codes
enum arc_aic_err
{
/// Invalid Change Counter
ARC_AIC_ERR_INVALID_CHANGE_CNT = 0x80,
/// Opcode Not Supported
ARC_AIC_ERR_OPCODE_NOT_SUPP,
/// Mute Disabled
ARC_AIC_ERR_MUTE_DISABLED,
/// Value Out of Range
ARC_AIC_ERR_OUT_OF_RANGE,
/// Gain Mode Change Not Allowed
ARC_AIC_ERR_GAIN_MODE_CHANGE_NOT_ALLOWED,
};
/// List of Audio Input Control Service characteristics
enum arc_aic_char_type
{
/// Input State characteristic
ARC_AIC_CHAR_TYPE_STATE = 0,
/// Input Status characteristic
ARC_AIC_CHAR_TYPE_STATUS,
/// Audio Input Description characteristic
ARC_AIC_CHAR_TYPE_DESC,
ARC_AIC_NTF_CHAR_TYPE_MAX,
/// Gain Setting Properties characteristic
ARC_AIC_CHAR_TYPE_GAIN_PROP = ARC_AIC_NTF_CHAR_TYPE_MAX,
/// Input Type characteristic
ARC_AIC_CHAR_TYPE_TYPE,
/// Audio Input Control Point characteristic
ARC_AIC_CHAR_TYPE_CP,
ARC_AIC_CHAR_TYPE_MAX,
};
/// List of Audio Input Control Service descriptors
enum arc_aic_desc_type
{
/// Input State characteristic
ARC_AIC_DESC_TYPE_CCC_STATE = 0,
/// Input Status characteristic
ARC_AIC_DESC_TYPE_CCC_STATUS,
/// Audio Input Description characteristic
ARC_AIC_DESC_TYPE_CCC_DESC,
ARC_AIC_DESC_TYPE_MAX,
};
/// Mute values
enum arc_aic_mute
{
/// Not muted
ARC_AIC_MUTE_NOT_MUTED = 0,
/// Muted
ARC_AIC_MUTE_MUTED,
/// Disabled
ARC_AIC_MUTE_DISABLED,
ARC_AIC_MUTE_MAX,
};
/// Gain Mode values
enum arc_aic_gain_mode
{
/// Manual only
ARC_AIC_GAIN_MODE_MANUAL_ONLY = 0,
/// Automatic only
ARC_AIC_GAIN_MODE_AUTO_ONLY,
/// Manual
ARC_AIC_GAIN_MODE_MANUAL,
/// Automatic
ARC_AIC_GAIN_MODE_AUTO,
ARC_AIC_GAIN_MODE_MAX
};
/// Input Status values
enum arc_aic_input_status
{
/// Inactive
ARC_AIC_INPUT_STATUS_INACTIVE = 0,
/// Active
ARC_AIC_INPUT_STATUS_ACTIVE,
ARC_AIC_INPUT_STATUS_MAX,
};
/// Input Type values
enum arc_aic_input_type
{
/// Microphone
ARC_AIC_INPUT_TYPE_MICROPHONE = 0,
/// Other
ARC_AIC_INPUT_TYPE_OTHER,
ARC_AIC_INPUT_TYPE_MAX,
};
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// Input state structure
typedef struct arc_aic_state
{
/// Gain
int8_t gain;
/// Mute
uint8_t mute;
/// Gain mode
uint8_t gain_mode;
} arc_aic_state_t;
/// Gain Setting Properties structure
typedef struct arc_aic_gain_prop
{
/// Gain Units
uint8_t gain_units;
/// Gain Minimum
int8_t gain_min;
/// Gain Maximum
int8_t gain_max;
} arc_aic_gain_prop_t;
/// @}
#endif // ARC_AIC_H_
@@ -0,0 +1,340 @@
/**
****************************************************************************************
*
* @file arc_aicc.h
*
* @brief Audio Rendering Control - Audio Input Control Client - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_AICC_H_
#define ARC_AICC_H_
/**
****************************************************************************************
* @addtogroup ARC_AICC Audio Rendering Control - Audio Input Control Client
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "arc_aic.h" // Audio Rendering Control - Audio Input Control Definitions
#if (GAF_ARC_AICC)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_CMD command codes for Audio Input Control Client
enum arc_aicc_cmd_code
{
ARC_AICC_DISCOVER = GAF_CODE(ARC, AICC, 0),
ARC_AICC_GET = GAF_CODE(ARC, AICC, 1),
ARC_AICC_CONTROL = GAF_CODE(ARC, AICC, 2),
ARC_AICC_SET_DESCRIPTION = GAF_CODE(ARC, AICC, 3),
ARC_AICC_GET_CFG = GAF_CODE(ARC, AICC, 4),
ARC_AICC_SET_CFG = GAF_CODE(ARC, AICC, 5),
};
/// List of GAF_REQ request codes for Audio Input Control Client
enum arc_aicc_req_code
{
ARC_AICC_CONFIGURE = GAF_CODE(ARC, AICC, 0),
ARC_AICC_RESTORE_BOND_DATA = GAF_CODE(ARC, AICC, 1),
};
/// List of GAF_IND indication codes for Audio Input Control Client
enum arc_aicc_ind_code
{
/// Audio Input Control Client indications
ARC_AICC_BOND_DATA = GAF_CODE(ARC, AICC, 0),
ARC_AICC_GAIN = GAF_CODE(ARC, AICC, 1),
ARC_AICC_GAIN_PROP = GAF_CODE(ARC, AICC, 2),
ARC_AICC_VALUE = GAF_CODE(ARC, AICC, 3),
ARC_AICC_DESCRIPTION = GAF_CODE(ARC, AICC, 4),
ARC_AICC_CFG = GAF_CODE(ARC, AICC, 5),
ARC_AICC_SVC_CHANGED = GAF_CODE(ARC, AICC, 6),
};
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// Audio Input Control Service content description structure
typedef struct arc_aicc_aics
{
/// Service description
prf_svc_t svc_info;
/// Characteristics description
prf_char_t char_info[ARC_AIC_CHAR_TYPE_MAX];
/// Descriptors description
prf_desc_t desc_info[ARC_AIC_DESC_TYPE_MAX];
} arc_aicc_aics_t;
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called each time a command has been completed
*
* @param[in] cmd_code Command code (@see enum arc_cmd_codes)
* @param[in] status Status
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] param Additional parameter
****************************************************************************************
*/
typedef void (*arc_aicc_cb_cmp_evt)(uint16_t cmd_code, uint16_t status, uint8_t con_lid, uint8_t input_lid,
uint8_t param);
/**
****************************************************************************************
* @brief Callback function called when Audio Input Control Service instance has been discovered in a peer server
* database
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] p_aics_info Pointer to service content description
****************************************************************************************
*/
typedef void (*arc_aicc_cb_bond_data)(uint8_t con_lid, uint8_t input_lid, arc_aicc_aics_t* p_aics_info);
/**
****************************************************************************************
* @brief Callback function called when value for Input State characteristic has been received from a peer server
* device
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] gain Gain
* @param[in] mute Mute
* @param[in] mode Gain Mode
****************************************************************************************
*/
typedef void (*arc_aicc_cb_gain)(uint8_t con_lid, uint8_t input_lid, int8_t gain, uint8_t mute, uint8_t mode);
/**
****************************************************************************************
* @brief Callback function called when value for Gain Setting Properties characteristic has been received from a peer
* server device
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] units Gain Setting Units
* @param[in] min Gain Setting Minimum
* @param[in] max Gain Setting Maximum
****************************************************************************************
*/
typedef void (*arc_aicc_cb_gain_prop)(uint8_t con_lid, uint8_t input_lid, uint8_t units, int8_t min, int8_t max);
/**
****************************************************************************************
* @brief Callback function called when value for Audio Input Description characteristic has been received from a peer
* server device
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] desc_len Audio input description length
* @param[in] p_desc Pointer to audio input description value
****************************************************************************************
*/
typedef void (*arc_aicc_cb_description)(uint8_t con_lid, uint8_t input_lid, uint16_t desc_len, uint8_t* p_desc);
/**
****************************************************************************************
* @brief Callback function called when value for Input Type or Input Status characteristic has been received from a
* peer server device
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] char_type Characteristic type
* @param[in] val Value
****************************************************************************************
*/
typedef void (*arc_aicc_cb_value)(uint8_t con_lid, uint8_t input_lid, uint8_t char_type, uint8_t val);
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration value has been received for a
* characteristic
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] char_type Characteristic type
* @param[in] enabled Indicate if sending of notifications is enabled
****************************************************************************************
*/
typedef void (*arc_aicc_cb_cfg)(uint8_t con_lid, uint8_t input_lid, uint8_t char_type, uint8_t enabled);
/**
****************************************************************************************
* @brief Callback function called when a service changed indication has been received from Server device
*
* @param[in] con_lid Connection local index
****************************************************************************************
*/
typedef void (*arc_aicc_cb_svc_changed)(uint8_t con_lid);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Audio Input Control Client
typedef struct arc_aicc_cb
{
/// Callback function called when a command has been completed
arc_aicc_cb_cmp_evt cb_cmp_evt;
/// Callback function called when value for Input State characteristic has been received from a peer server device
arc_aicc_cb_gain cb_gain;
/// Callback function called when value for Gain Setting Properties have been received from a peer server device
arc_aicc_cb_gain_prop cb_gain_prop;
/// Callback function called when value for Audio Input Description characteristic has been received from a peer
/// server device
arc_aicc_cb_description cb_description;
/// Callback function called when value for Input Type or Input Status characteristic has been received from a peer
/// server device
arc_aicc_cb_value cb_value;
/// Callback function called when a client characteristic configuration value has been received from a peer server
/// device
arc_aicc_cb_cfg cb_cfg;
/// Callback function called when Audio Input Control Service instance has been discovered in a peer server
/// database
arc_aicc_cb_bond_data cb_bond_data;
/// Callback function called when a service changed indication has been received from Server device
arc_aicc_cb_svc_changed cb_svc_changed;
} arc_aicc_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure Audio Input Control Client module
*
* @param[in] p_cb Pointer to set of callback functions for communication with upper layers
* @param[in] pref_mtu Preferred MTU
* Values from 0 to 63 are equivalent to 64
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aicc_configure(const arc_aicc_cb_t* p_cb, uint16_t pref_mtu);
/**
****************************************************************************************
* @brief Discover Audio Input Control Service Services in peer server device database
*
* @param[in] con_lid Connection local index
* @param[in] nb_inputs Number of inputs
* @param[in] p_svc_hdl Pointer to service handles
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aicc_discover(uint8_t con_lid, uint8_t nb_inputs, prf_svc_t* p_svc_hdl);
/**
****************************************************************************************
* @brief Set bonding information related to Audio Input Control after connection with a peer device
*
* @param[in] con_lid Connection local index
* @param[in] nb_inputs Number of inputs
* @param[in] p_aics_info Pointer to Audio Input Control Service description structures
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aicc_restore_bond_data(uint8_t con_lid, uint8_t nb_inputs, arc_aicc_aics_t* p_aics_info);
/**
****************************************************************************************
* @brief Control peer server device's Gain value for one of its inputs
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] opcode Operation code
* @param[in] gain Gain Setting value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aicc_control(uint8_t con_lid, uint8_t input_lid, uint8_t opcode, int8_t gain);
/**
****************************************************************************************
* @brief Set value for Audio Input Description characteristic of a peer server device input
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] desc_len Audio input description length
* @param[in] p_desc Pointer to audio input description value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aicc_set_description(uint8_t con_lid, uint8_t input_lid, uint16_t desc_len, uint8_t* p_desc);
/**
****************************************************************************************
* @brief Get value for either Input State or Gain Setting Properties or Input Type or Input Status or Audio Input
* Description characteristic of a peer server device output
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aicc_get(uint8_t con_lid, uint8_t input_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Get Client Characteristic Configuration value for either Input State or Input Status or Audio Input
* Description characteristic of a peer server device input
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aicc_get_cfg(uint8_t con_lid, uint8_t input_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Set Client Characteristic Configuration value for either Input State or Input Status or Audio Input
* Description characteristic of a peer server device input
*
* @param[in] con_lid Connection local index
* @param[in] input_lid Input local index
* @param[in] char_type Characteristic type
* @param[in] enable Indicate if sending of notifications must be enabled or disabled
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aicc_set_cfg(uint8_t con_lid, uint8_t input_lid, uint8_t char_type, uint8_t enable);
#endif //(GAF_ARC_AICC)
/// @}
#endif // ARC_AICC_H_
@@ -0,0 +1,295 @@
/**
****************************************************************************************
*
* @file arc_aicc_msg.h
*
* @brief Audio Rendering Control - Definition of Kernel Messages (Audio Input Control Client)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_AICC_MSG_H_
#define ARC_AICC_MSG_H_
/**
****************************************************************************************
* @addtogroup ARC_AICC_MSG Audio Rendering Control - Definition of Kernel Messages (Audio Input Control Client)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc_msg.h" // Audio Rendering Control Kernel Messages Definitions
#include "arc_aicc.h" // Audio Rendering Control - Audio Input Control Client Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ARC_AICC_DISCOVER command message
typedef struct arc_aicc_discover_cmd
{
/// Command code (@see enum arc_aicc_cmd_code)
/// - ARC_AICC_DISCOVER
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Number of inputs
uint8_t nb_inputs;
/// Service handles
prf_svc_t svc_hdl[__ARRAY_EMPTY];
} arc_aicc_discover_cmd_t;
/// Structure for ARC_AICC_CONTROL command message
typedef struct arc_aicc_control_cmd
{
/// Command code (@see enum arc_aicc_cmd_code)
/// - ARC_AICC_CONTROL
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Operation code
uint8_t opcode;
/// Gain
int8_t gain;
} arc_aicc_control_cmd_t;
/// Structure for ARC_AICC_GET command message
typedef struct arc_aicc_get_cmd
{
/// Command code (@see enum arc_aicc_cmd_code)
/// - ARC_AICC_GET
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Characteristic type
uint8_t char_type;
} arc_aicc_get_cmd_t;
/// Structure for ARC_AICC_SET_DESCRIPTION command message
typedef struct arc_aicc_set_description_cmd
{
/// Command code (@see enum arc_aicc_cmd_code)
/// - ARC_AICC_SET_DESCRIPTION
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Audio input description length
uint16_t desc_len;
/// Audio input description
uint8_t desc[__ARRAY_EMPTY];
} arc_aicc_set_description_cmd_t;
/// Structure for ARC_AICC_GET_CFG command message
typedef struct arc_aicc_get_cfg_cmd
{
/// Command code (@see enum arc_aicc_cmd_code)
/// - ARC_AICC_GET_CFG
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Characteristic type
uint8_t char_type;
} arc_aicc_get_cfg_cmd_t;
/// Structure for ARC_AICC_SET_CFG command message
typedef struct arc_aicc_set_cfg_cmd
{
/// Command code (@see enum arc_aicc_cmd_code)
/// - ARC_AICC_SET_CFG
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Characteristic type
uint8_t char_type;
/// Enable or disable
uint8_t enable;
} arc_aicc_set_cfg_cmd_t;
/// Structure for command complete event message
typedef struct arc_aicc_cmp_evt
{
/// Command code (@see enum arc_aicc_cmd_code)
uint16_t cmd_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Union
union
{
/// Value
uint8_t value;
/// Operation code
uint8_t opcode;
/// Characteristic type
uint8_t char_type;
} u;
} arc_aicc_cmp_evt_t;
/// Structure for ARC_AICC_CONFIGURE request message
typedef struct arc_aicc_configure_req
{
/// Request code (@see enum arc_aicc_req_code)
/// - ARC_AICC_CONFIGURE
uint16_t req_code;
/// Preferred MTU
/// Values from 0 to 63 are equivalent to 64
uint16_t pref_mtu;
} arc_aicc_configure_req_t;
/// Structure for ARC_AICC_RESTORE_BOND_DATA request message
typedef struct arc_aicc_restore_bond_data_req
{
/// Request code (@see enum arc_aicc_req_code)
/// - ARC_AICC_RESTORE_BOND_DATA
uint16_t req_code;
/// Connection local index
uint8_t con_lid;
/// Number of inputs
uint8_t nb_inputs;
/// Description of found Audio Input Control Service instances
arc_aicc_aics_t aics_info[__ARRAY_EMPTY];
} arc_aicc_restore_bond_data_req_t;
/// Structure for response message
typedef struct arc_aicc_rsp
{
/// Request code (@see enum arc_aicc_req_code)
uint16_t req_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
} arc_aicc_rsp_t;
/// Structure for ARC_AICC_BOND_DATA indication message
typedef struct arc_aicc_bond_data_ind
{
/// Indication code (@see enum arc_aicc_ind_code)
/// - ARC_AICC_BOND_DATA
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Description of found Audio Input Control Service instance
arc_aicc_aics_t aics_info;
} arc_aicc_bond_data_ind_t;
/// Structure for ARC_AICC_GAIN indication message
typedef struct arc_aicc_gain_ind
{
/// Indication code (@see enum arc_aicc_ind_code)
/// - ARC_AICC_GAIN
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Gain
int8_t gain;
/// Mute
uint8_t mute;
/// Gain mode
uint8_t gain_mode;
} arc_aicc_gain_ind_t;
/// Structure for ARC_AICC_GAIN_PROP indication message
typedef struct arc_aicc_gain_prop_ind
{
/// Indication code (@see enum arc_aicc_ind_code)
/// - ARC_AICC_GAIN_PROP
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Gain Setting Units
uint8_t units;
/// Gain Setting Minimum
int8_t min;
/// Gain Setting Maximum
int8_t max;
} arc_aicc_gain_prop_ind_t;
/// Structure for ARC_AICC_DESCRIPTION indication message
typedef struct arc_aicc_description_ind
{
/// Indication code (@see enum arc_aicc_ind_code)
/// - ARC_AICC_DESCRIPTION
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Audio input description length
uint16_t desc_len;
/// Audio input description
uint8_t desc[__ARRAY_EMPTY];
} arc_aicc_description_ind_t;
/// Structure for ARC_AICC_VALUE indication message
typedef struct arc_aicc_value_ind
{
/// Indication code (@see enum arc_aicc_ind_code)
/// - ARC_AICC_VALUE
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Characteristic type
uint8_t char_type;
/// Value
uint8_t val;
} arc_aicc_value_ind_t;
/// Structure for ARC_AICC_CFG indication message
typedef struct arc_aicc_cfg_ind
{
/// Indication code (@see enum arc_aicc_ind_code)
/// - ARC_AICC_CFG
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Input local index
uint8_t input_lid;
/// Characteristic type
uint8_t char_type;
/// Enabled or disabled
uint8_t enabled;
} arc_aicc_cfg_ind_t;
/// Structure for ARC_AICC_SVC_CHANGED indication message
typedef struct arc_aicc_svc_changed_ind
{
/// Indication code (@see enum arc_aicc_ind_code)
/// - ARC_AICC_GAIN
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
} arc_aicc_svc_changed_ind_t;
/// @}
#endif // ARC_AICC_MSG_H_
@@ -0,0 +1,246 @@
/**
****************************************************************************************
*
* @file arc_aics.h
*
* @brief Audio Rendering Control - Audio Input Control Server - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_AICS_H_
#define ARC_AICS_H_
/**
****************************************************************************************
* @addtogroup ARC_AICS Audio Rendering Control - Audio Input Control Server
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc_aic.h" // Audio Rendering Control - Audio Input Control Definition
#if (GAF_ARC_AICS)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes for Audio Input Control Server
enum arc_aics_req_code
{
ARC_AICS_CONFIGURE = GAF_CODE(ARC, AICS, 0),
ARC_AICS_ADD = GAF_CODE(ARC, AICS, 1),
ARC_AICS_ENABLE = GAF_CODE(ARC, AICS, 2),
ARC_AICS_RESTORE_BOND_DATA = GAF_CODE(ARC, AICS, 3),
ARC_AICS_SET = GAF_CODE(ARC, AICS, 4),
ARC_AICS_SET_DESCRIPTION = GAF_CODE(ARC, AICS, 5),
};
/// List of GAF_IND indication codes for Audio Input Control Server
enum arc_aics_ind_code
{
ARC_AICS_STATE = GAF_CODE(ARC, AICS, 0),
ARC_AICS_BOND_DATA = GAF_CODE(ARC, AICS, 1),
};
/// List of GAF_REQ_IND indication codes for Audio Input Control Server
enum arc_aics_req_ind_code
{
ARC_AICS_SET_DESCRIPTION_RI = GAF_CODE(ARC, AICS, 0),
};
/// Input configuration bit field
enum arc_aics_cfg_bf
{
/// Set to 1 if Audio Input Description characteristic is writable
ARC_AICS_CFG_DESC_WR_POS = 0,
ARC_AICS_CFG_DESC_WR_BIT = CO_BIT(ARC_AICS_CFG_DESC_WR_POS),
/// Set to 1 if Audio Input Description characteristic supports sending of notifications
ARC_AICS_CFG_DESC_NTF_POS = 1,
ARC_AICS_CFG_DESC_NTF_BIT = CO_BIT(ARC_AICS_CFG_DESC_NTF_POS),
};
/// Set type values
enum arc_aics_set_type
{
/// Set Input Status
ARC_AICS_SET_TYPE_INPUT_STATUS = 0,
/// Set Gain Setting
ARC_AICS_SET_TYPE_GAIN,
/// Set Mute
ARC_AICS_SET_TYPE_MUTE,
/// Set Gain Mode
ARC_AICS_SET_TYPE_GAIN_MODE,
ARC_AICS_SET_TYPE_MAX,
};
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration of a notification-capable
* characteristic has been updated by a peer client
*
* @param[in] input_lid Input local index
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field (@see enum arc_aics_cli_cfg_bf)
****************************************************************************************
*/
typedef void (*arc_aics_cb_bond_data)(uint8_t input_lid, uint8_t con_lid, uint8_t cli_cfg_bf);
/**
****************************************************************************************
* @brief Callback function called when Input State characteristic value has been updated
*
* @param[in] input_lid Input local index
* @param[in] p_state Pointer to Input State value
****************************************************************************************
*/
typedef void (*arc_aics_cb_state)(uint8_t input_lid, arc_aic_state_t* p_state);
/**
****************************************************************************************
* @brief Callback function called when Audio Input Description characteristic value has been updated
*
* @param[in] input_lid Input local index
* @param[in] con_lid Connection local index
* @param[in] desc_len Value length
* @param[in] p_desc Pointer to value
****************************************************************************************
*/
typedef void (*arc_aics_cb_description)(uint8_t input_lid, uint8_t con_lid, uint8_t desc_len, uint8_t* p_desc);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Audio Input Control Server
typedef struct arc_aics_cb
{
/// Callback function called when Client Characteristic Configuration of a notification-capable characteristic has
/// been updated by a peer client
arc_aics_cb_bond_data cb_bond_data;
/// Callback function called when Input State characteristic value has been updated
arc_aics_cb_state cb_state;
/// Callback function called when Audio Input Description characteristic value has been updated
arc_aics_cb_description cb_description;
} arc_aics_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure Audio Input Control Server module
*
* @param[in] p_cb Pointer to set of callback functions
* @param[in] nb_inputs Number of inputs
* @param[in] pref_mtu Preferred MTU
* Values from 0 to 63 are equivalent to 64
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aics_configure(const arc_aics_cb_t* p_cb, uint8_t nb_inputs, uint16_t pref_mtu);
/**
****************************************************************************************
* @brief Add an input
*
* @param[in] p_gain_prop Pointer to Gain Setting Properties initial value
* @param[in] input_type Input Type
* @param[in] input_status Input Status
* @param[in] desc_max_len Maximum length of Audio Input Description
* @param[in] cfg_bf Configuration bit field (@see enum arc_aics_cfg_bf)
* @param[in] nb_att_rsvd Number of attributes reserved for the service
* @param[out] p_input_lid Pointer at which allocated input local index is returned
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aics_add(arc_aic_gain_prop_t* p_gain_prop, uint8_t input_type,uint8_t desc_max_len, uint8_t cfg_bf,
uint16_t nb_att_rsvd, uint8_t* p_input_lid);
/**
****************************************************************************************
* @brief Enable Audio Input Control Server module
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aics_enable(void);
/**
****************************************************************************************
* @brief Set bonding information related to an input after establishment of a connection
*
* @param[in] input_lid Input local index
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
* @param[in] evt_cfg_bf Event configuration bit field
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aics_restore_bond_data(uint8_t input_lid, uint8_t con_lid, uint8_t cli_cfg_bf, uint8_t evt_cfg_bf);
/**
****************************************************************************************
* @brief Set value of Input Status characteristic
*
* @param[in] input_lid Input local index
* @param[in] set_type Set type
* @param[in] value Value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aics_set(uint8_t input_lid, uint8_t set_type, uint32_t val);
/**
****************************************************************************************
* @brief Set value of Audio Input Description characteristic value
*
* @param[in] input_lid Input local index
* @param[in] desc_len Value length
* @param[in] p_desc Pointer to value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_aics_set_description(uint8_t input_lid, uint8_t desc_len, uint8_t *p_desc);
/**
****************************************************************************************
* @brief Confirm or not value written for Audio Input Description characteristic
*
* @param[in] cfm_status Confirmation status
* @param[in] input_lid Input local index
* @param[in] desc_len Audio input description length
* @param[in] p_desc Pointer to Audio input description value
****************************************************************************************
*/
void arc_aics_cfm_set_description(uint16_t cfm_status, uint8_t input_lid, uint8_t desc_len, uint8_t *p_desc);
#endif //(GAF_ARC_AICS)
/// @}
#endif // ARC_AICS_H_
@@ -0,0 +1,202 @@
/**
****************************************************************************************
*
* @file arc_aics_msg.h
*
* @brief Audio Rendering Control - Definition of Kernel Messages (Audio Input Control Server)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_AICS_MSG_H_
#define ARC_AICS_MSG_H_
/**
****************************************************************************************
* @addtogroup ARC_AICS_MSG Audio Rendering Control - Definition of Kernel Messages (Audio Input Control Server)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "arc_msg.h" // Audio Rendering Control Kernel Messages Definitions
#include "arc_aics.h" // Audio Rendering Control - Audio Input Control Server Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ARC_AICS_ADD request message
typedef struct arc_aics_add_req
{
/// Request code (@see enum arc_aics_req_code)
/// - ARC_AICS_ADD
uint16_t req_code;
/// Maximum length of Audio Input Description
uint8_t desc_max_len;
/// Gain Units
uint8_t gain_units;
/// Gain Minimum
int8_t gain_min;
/// Gain Maximum
int8_t gain_max;
/// Input Type
uint8_t input_type;
/// Service configuration bit field
uint8_t cfg_bf;
/// Number of attributes reserved for all Volume Offset Control Service instances inserted
/// in the database
uint16_t nb_att_rsvd;
} arc_aics_add_req_t;
/// Structure for ARC_AICS_RESTORE_BOND_DATA request message
typedef struct arc_aics_restore_bond_data_req
{
/// Request code (@see enum arc_aics_req_code)
/// - ARC_AICS_RESTORE_BOND_DATA
uint16_t req_code;
/// Input local index
uint8_t input_lid;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint8_t cli_cfg_bf;
/// Event configuration bit field
uint8_t evt_cfg_bf;
} arc_aics_restore_bond_data_req_t;
/// Structure for ARC_AICS_CONFIGURE request message
typedef struct arc_aics_configure_req
{
/// Request code (@see enum arc_aics_req_code)
/// - ARC_AICS_CONFIGURE
uint16_t req_code;
/// Number of inputs
uint8_t nb_inputs;
/// Preferred MTU
/// Values from 0 to 63 are equivalent to 64
uint16_t pref_mtu;
} arc_aics_configure_req_t;
/// Structure for ARC_AICS_SET request message
typedef struct arc_aics_set_req
{
/// Request code (@see enum arc_aics_req_code)
/// - ARC_AICS_SET
uint16_t req_code;
/// Input local index
uint8_t input_lid;
/// Set type
uint8_t set_type;
/// Value
uint32_t val;
} arc_aics_set_req_t;
/// Structure for ARC_AICS_SET_DESCRIPTION request message
typedef struct arc_aics_set_description_req
{
/// Request code (@see enum arc_aics_req_code)
/// - ARC_AICS_SET_DESCRIPTION
uint16_t req_code;
/// Input local index
uint8_t input_lid;
/// Value length
uint8_t desc_len;
/// Value
uint8_t desc[__ARRAY_EMPTY];
} arc_aics_set_description_req_t;
/// Structure for request message
typedef struct arc_aics_rsp
{
/// Request code (@see enum arc_aics_req_code)
uint16_t req_code;
/// Status
uint16_t status;
/// Input local index
uint8_t input_lid;
/// Union
union
{
/// Value
uint8_t value;
/// Connection local index
uint8_t con_lid;
/// Set type
uint8_t set_type;
} u;
} arc_aics_rsp_t;
/// Structure for ARC_AICS_STATE indication message
typedef struct arc_aics_state_ind
{
/// Indication code (@see enum arc_aics_ind_code)
/// - ARC_AICS_STATE
uint16_t ind_code;
/// Input local index
uint8_t input_lid;
/// Gain
int8_t gain;
/// Gain Mode
uint8_t gain_mode;
/// Mute
uint8_t mute;
} arc_aics_state_ind_t;
/// Structure for ARC_AICS_BOND_DATA indication message
typedef struct arc_aics_cfg_ind
{
/// Indication code (@see enum arc_aics_ind_code)
/// - ARC_AICS_BOND_DATA
uint16_t ind_code;
/// Input local index
uint8_t input_lid;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint8_t cli_cfg_bf;
} arc_aics_cfg_ind_t;
/// Structure for ARC_AICS_SET_DESCRIPTION request indication message
typedef struct arc_aics_set_description_req_ind
{
/// Request Indication code (@see enum arc_aics_req_ind_code)
/// - ARC_AICS_SET_DESCRIPTION_RI
uint16_t req_ind_code;
/// Input local index
uint8_t input_lid;
/// Connection local index
uint8_t con_lid;
/// Value length
uint8_t desc_len;
/// Value
uint8_t desc[__ARRAY_EMPTY];
} arc_aics_set_description_req_ind_t;
/// Structure for ARC_AICS_SET_DESCRIPTION confirmation message
typedef struct arc_aics_set_description_cfm
{
/// Request Indication code (@see enum arc_aics_req_ind_code)
/// - ARC_AICS_SET_DESCRIPTION_RI
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Input local index
uint8_t input_lid;
/// Value length
uint8_t desc_len;
/// Value
uint8_t desc[__ARRAY_EMPTY];
} arc_aics_set_description_cfm_t;
/// @}
#endif // ARC_AICS_MSG_H_
+68
View File
@@ -0,0 +1,68 @@
/**
****************************************************************************************
*
* @file arc.h
*
* @brief Audio Rendering Control - Header file
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_H_
#define ARC_H_
/**
****************************************************************************************
* @addtogroup ARC Audio Rendering Control
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf_cfg.h" // GAF Configuration
#include "gaf.h" // GAF defaut defines
/*
* MACROS
****************************************************************************************
*/
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Module type values
enum arc_module_type
{
/// Common
ARC_MODULE_COMMON = 0,
/// Volume Control Server
ARC_MODULE_VCS = 1,
/// Volume Control Client
ARC_MODULE_VCC = 2,
/// Audio Input Control Server
ARC_MODULE_AICS = 3,
/// Audio Input Control Client
ARC_MODULE_AICC = 4,
/// Volume Offset Control Server
ARC_MODULE_VOCS = 5,
/// Volume Offset Control Client
ARC_MODULE_VOCC = 6,
/// Microphone Control Server
ARC_MODULE_MICS = 7,
/// Microphone Control Client
ARC_MODULE_MICC = 8,
ARC_MODULE_MAX,
};
/// @}
#endif // ARC_H_
+111
View File
@@ -0,0 +1,111 @@
/**
****************************************************************************************
*
* @file arc_msg.h
*
* @brief Audio Rendering Control - Definition of Kernel Messages
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_MSG_H_
#define ARC_MSG_H_
/**
****************************************************************************************
* @addtogroup ARC Audio Rendering Control - Definition of Kernel Messages
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "arc.h" // ARC Definitions
#if (GAF_ARC)
#include "gaf_msg.h" // Generic Audio Framework API Message Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes
enum arc_msg_req_codes
{
ARC_GET_FEATURES = GAF_CODE(ARC, COMMON, 0),
};
/// Features bit field meaning
enum arc_msg_feat_bf
{
/// Volume Control Service Server supported
ARC_FEAT_VCS_SUPP_POS = 0,
ARC_FEAT_VCS_SUPP_BIT = CO_BIT(ARC_FEAT_VCS_SUPP_POS),
/// Volume Control Service Client supported
ARC_FEAT_VCC_SUPP_POS = 1,
ARC_FEAT_VCC_SUPP_BIT = CO_BIT(ARC_FEAT_VCC_SUPP_POS),
/// Audio Input Control Service Server supported
ARC_FEAT_AICS_SUPP_POS = 2,
ARC_FEAT_AICS_SUPP_BIT = CO_BIT(ARC_FEAT_AICS_SUPP_POS),
/// Audio Input Control Service Client supported
ARC_FEAT_AICC_SUPP_POS = 3,
ARC_FEAT_AICC_SUPP_BIT = CO_BIT(ARC_FEAT_AICC_SUPP_POS),
/// Volume Offset Control Service Server supported
ARC_FEAT_VOCS_SUPP_POS = 4,
ARC_FEAT_VOCS_SUPP_BIT = CO_BIT(ARC_FEAT_VOCS_SUPP_POS),
/// Volume Offset Control Service Client supported
ARC_FEAT_VOCC_SUPP_POS = 5,
ARC_FEAT_VOCC_SUPP_BIT = CO_BIT(ARC_FEAT_VOCC_SUPP_POS),
/// Microphone Control Service Server supported
ARC_FEAT_MICS_SUPP_POS = 6,
ARC_FEAT_MICS_SUPP_BIT = CO_BIT(ARC_FEAT_MICS_SUPP_POS),
/// Microphone Control Service Client supported
ARC_FEAT_MICC_SUPP_POS = 7,
ARC_FEAT_MICC_SUPP_BIT = CO_BIT(ARC_FEAT_MICC_SUPP_POS),
};
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ARC_GET_FEATURES request message
typedef struct arc_get_features_req
{
/// Request code (@see enum arc_msg_req_codes)
/// - ARC_GET_FEATURES
uint16_t req_code;
} arc_get_features_req_t;
/// Structure for ARC_GET_FEATURES response message
typedef struct arc_get_features_rsp
{
/// Request code (@see enum arc_msg_req_codes)
/// - ARC_GET_FEATURES
uint16_t req_code;
/// Status
uint16_t status;
/// Features bit field
uint32_t feat_bf;
} arc_get_features_rsp_t;
#endif //(GAF_ARC)
/// @}
#endif // ARC_MSG_H_
@@ -0,0 +1,89 @@
/**
****************************************************************************************
*
* @file arc_mic.h
*
* @brief Audio Rendering Control - Microphone Control - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_MIC_H_
#define ARC_MIC_H_
/**
****************************************************************************************
* @addtogroup ARC_MIC Audio Rendering Control - Microphone Control
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc.h" // Audio Rendering Control Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Position of fields in Mute characteristic value
enum arc_mic_mute_pos
{
/// Mute field
ARC_MIC_MUTE_POS_MUTE = 0,
/// Length of Mute characteristic value
ARC_MIC_MUTE_LEN
};
/// List of Microphone Control Service characteristics
enum arc_mic_char_type
{
/// Mute characteristic
ARC_MIC_CHAR_TYPE_MUTE = 0,
/// Number of characteristics
ARC_MIC_CHAR_TYPE_MAX,
};
/// List of Microphone Control Service descriptors
enum arc_mic_desc_type
{
/// Mute characteristic
ARC_MIC_DESC_TYPE_CCC_MUTE = 0,
/// Number of descriptors
ARC_MIC_DESC_TYPE_MAX,
};
/// List of Mute value for Microphone Control Service
enum arc_mic_mute
{
/// Not muted
ARC_MIC_MUTE_NOT_MUTED = 0,
/// Muted
ARC_MIC_MUTE_MUTED,
/// Disabled
ARC_MIC_MUTE_DISABLED,
ARC_MIC_MUTE_MAX,
};
/// Error codes for Microphone Control Service
enum arc_mic_err
{
/// Mute disabled
ARC_MIC_ERR_MUTE_DISABLED = 0x80,
/// Value out of range
ARC_MIC_ERR_OUT_OF_RANGE = 0x81,
};
/// @}
#endif // ARC_MIC_H_
@@ -0,0 +1,261 @@
/**
****************************************************************************************
*
* @file arc_micc.h
*
* @brief Audio Rendering Control - Microphone Control Client - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_MICC_H_
#define ARC_MICC_H_
/**
****************************************************************************************
* @addtogroup ARC_MICC Audio Rendering Control - Microphone Control Client
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "arc_mic.h" // Audio Rendering Control - Microphone Control Definitions
#if (GAF_ARC_MICC)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_CMD command codes for Microphone Control Client
enum arc_micc_cmd_code
{
ARC_MICC_DISCOVER = GAF_CODE(ARC, MICC, 0),
ARC_MICC_GET_MUTE = GAF_CODE(ARC, MICC, 1),
ARC_MICC_SET_MUTE = GAF_CODE(ARC, MICC, 2),
ARC_MICC_GET_CFG = GAF_CODE(ARC, MICC, 3),
ARC_MICC_SET_CFG = GAF_CODE(ARC, MICC, 4),
};
/// List of GAF_REQ request codes for Microphone Control Client
enum arc_micc_req_code
{
ARC_MICC_CONFIGURE = GAF_CODE(ARC, MICC, 0),
ARC_MICC_RESTORE_BOND_DATA = GAF_CODE(ARC, MICC, 1),
};
/// List of GAF_IND indication codes for Microphone Control Client
enum arc_micc_ind_code
{
ARC_MICC_BOND_DATA = GAF_CODE(ARC, MICC, 0),
ARC_MICC_INCLUDED_SVC = GAF_CODE(ARC, MICC, 1),
ARC_MICC_MUTE = GAF_CODE(ARC, MICC, 2),
ARC_MICC_CFG = GAF_CODE(ARC, MICC, 3),
ARC_MICC_SVC_CHANGED = GAF_CODE(ARC, MICC, 4),
};
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// Microphone Control Service content description structure
typedef struct arc_micc_mics
{
/// Service description
prf_svc_t svc_info;
/// Characteristics description
prf_char_t char_info[ARC_MIC_CHAR_TYPE_MAX];
/// Descriptors description
prf_desc_t desc_info[ARC_MIC_DESC_TYPE_MAX];
} arc_micc_mics_t;
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called each time a command has been completed
*
* @param[in] cmd_code Command code (@see enum arc_cmd_codes)
* @param[in] status Status
* @param[in] con_lid Connection local index
****************************************************************************************
*/
typedef void (*arc_micc_cb_cmp_evt)(uint16_t cmd_code, uint16_t status, uint8_t con_lid);
/**
****************************************************************************************
* @brief Callback function called when Microphone Control Service instance has been discovered in a peer server
* database
*
* @param[in] con_lid Connection local index
* @param[in] p_mics_info Pointer to service content description
****************************************************************************************
*/
typedef void (*arc_micc_cb_bond_data)(uint8_t con_lid, arc_micc_mics_t* p_mics_info);
/**
****************************************************************************************
* @brief Callback function called when Mute characteristic value has been received from a peer server device
*
* @param[in] con_lid Connection local index
* @param[in] mute Mute value
****************************************************************************************
*/
typedef void (*arc_micc_cb_mute)(uint8_t con_lid, uint8_t mute);
/**
****************************************************************************************
* @brief Callback function called when an Audio Input Control Service instance has been discovered in a peer server
*
* @param[in] con_lid Connection local index
* @param[in] shdl Start handle
* @param[in] ehdl End handle
****************************************************************************************
*/
typedef void (*arc_micc_cb_included_svc)(uint8_t con_lid, uint16_t shdl, uint16_t ehdl);
/**
****************************************************************************************
* @brief Callback function called when a Client Characteristic Configuration descriptor value for Mute
* characteristic has been received from a peer server device
*
* @param[in] con_lid Connection local index
* @param[in] enable Indicate if sending of notifications is enabled for Mute characteristic
****************************************************************************************
*/
typedef void (*arc_micc_cb_cfg)(uint8_t con_lid, uint8_t enable);
/**
****************************************************************************************
* @brief Callback function called when a service changed indication is received from a Server device
*
* @param[in] con_lid Connection local index
****************************************************************************************
*/
typedef void (*arc_micc_cb_svc_changed)(uint8_t con_lid);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for microphone management (client)
typedef struct arc_micc_cb
{
/// Callback function called when a command has been completed
arc_micc_cb_cmp_evt cb_cmp_evt;
/// Callback function called when Mute characteristic value has been received from a peer server device
arc_micc_cb_mute cb_mute;
/// Callback function called when a Client Characteristic Configuration descriptor value for Mute
/// characteristic has been received from a peer server device
arc_micc_cb_cfg cb_cfg;
/// Callback function called when Microphone Control Service instance has been discovered in a peer server database
arc_micc_cb_bond_data cb_bond_data;
/// Callback function called when an Audio Input Control Service instance has been discovered in a peer server
arc_micc_cb_included_svc cb_included_svc;
/// Callback function called when a service changed indication is received from a Server device
arc_micc_cb_svc_changed cb_svc_changed;
} arc_micc_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Create and configure Microphone Control Client module
*
* @param[in] p_cb Pointer to set of callback functions for communications with upper layers
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_micc_configure(const arc_micc_cb_t* p_cb);
/**
****************************************************************************************
* @brief Initiate discovery of Microphone Control Service in peer server device database
*
* @param[in] con_lid Connection local index
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_micc_discover(uint8_t con_lid);
/**
****************************************************************************************
* @brief Set bonding information related to Microphone Management after connection with a peer device
*
* @param[in] con_lid Connection local index
* @param[in] p_mics_info Pointer to Microphone Control Service description structures
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_micc_restore_bond_data(uint8_t con_lid, arc_micc_mics_t* p_mics_info);
/**
****************************************************************************************
* @brief Set value for Mute State characteristic of a peer server device output
*
* @param[in] con_lid Connection local index
* @param[in] mute Mute value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_micc_set_mute(uint8_t con_lid, uint8_t mute);
/**
****************************************************************************************
* @brief Get value for Mute State characteristic of a peer server device output
*
* @param[in] con_lid Connection local index
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_micc_get_mute(uint8_t con_lid);
/**
****************************************************************************************
* @brief Get Client Characteristic Configuration value for Mute characteristic of a peer server device
*
* @param[in] con_lid Connection local index
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_micc_get_cfg(uint8_t con_lid);
/**
****************************************************************************************
* @brief Set Client Characteristic Configuration value for Mute characteristic.
*
* @param[in] con_lid Connection local index
* @param[in] enable Indicate if sending of notifications must be enabled or disabled
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_micc_set_cfg(uint8_t con_lid, uint8_t enable);
#endif //(GAF_ARC_MICC)
/// @}
#endif // ARC_MICC_H_
@@ -0,0 +1,195 @@
/**
****************************************************************************************
*
* @file arc_micc_msg.h
*
* @brief Audio Rendering Control - Definition of Kernel Messages (Microphone Control Client)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_MICC_MSG_H_
#define ARC_MICC_MSG_H_
/**
****************************************************************************************
* @addtogroup ARC_MICC_MSG Audio Rendering Control - Definition of Kernel Messages (Microphone Control Client)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc_msg.h" // Audio Rendering Control Kernel Messages Definitions
#include "arc_micc.h" // Audio Rendering Control - Microphone Control Client Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ARC_MICC_DISCOVER request message
typedef struct arc_micc_discover_cmd
{
/// Command code (@see enum arc_micc_cmd_code)
/// - ARC_MICC_DISCOVER
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
} arc_micc_discover_cmd_t;
/// Structure for ARC_MICC_SET_MUTE command message
typedef struct arc_micc_set_mute_cmd
{
/// Command code (@see enum arc_micc_cmd_code)
/// - ARC_MICC_SET_MUTE
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Mute
uint8_t mute;
} arc_micc_set_mute_cmd_t;
/// Structure for ARC_MICC_GET_MUTE command message
typedef struct arc_micc_get_mute_cmd
{
/// Command code (@see enum arc_micc_cmd_code)
/// - ARR_MICC_GET_MUTE
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
} arc_micc_get_mute_cmd_t;
/// Structure for ARC_MICC_GET_CFG command message
typedef struct arc_micc_get_cfg_cmd
{
/// Command code (@see enum arc_micc_cmd_code)
/// - ARC_MICC_GET_CFG
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
} arc_micc_get_cfg_cmd_t;
/// Structure for ARC_MICC_SET_CFG command message
typedef struct arc_micc_set_cfg_cmd
{
/// Command code (@see enum arc_micc_cmd_code)
/// - ARC_MICC_SET_CFG
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Indicate if sending of notifications must be enabled or not
uint8_t enable;
} arc_micc_set_cfg_cmd_t;
/// Structure for command complete event message for ARC_MICC_DISCOVER, ARC_MICC_SET_MUTE, ARC_MICC_GET_MUTE,
/// ARC_MICC_GET_CFG, ARC_MICC_SET_CFG commands
typedef struct arc_micc_cmp_evt
{
/// Command code (@see enum arc_micc_cmd_code)
uint16_t cmd_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
} arc_micc_cmp_evt_t;
/// Structure for ARC_MICC_CONFIGURE request message
typedef struct arc_micc_configure_req
{
/// Request code (@see enum arc_micc_req_code)
/// - ARC_MICC_CONFIGURE
uint16_t req_code;
} arc_micc_configure_req_t;
/// Structure for ARC_MICC_RESTORE_BOND_DATA request message
typedef struct arc_micc_restore_bond_data_req
{
/// Request code (@see enum arc_micc_req_code)
/// - ARC_MICC_RESTORE_BOND_DATA
uint16_t req_code;
/// Connection local index
uint8_t con_lid;
/// Microphone Control Service description
arc_micc_mics_t mics_info;
} arc_micc_restore_bond_data_req_t;
/// Structure for response message
typedef struct arc_micc_rsp
{
/// Request code (@see enum arc_micc_req_code)
uint16_t req_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
} arc_micc_rsp_t;
/// Structure for ARC_MICC_BOND_DATA indication message
typedef struct arc_micc_bond_data_ind
{
/// Indication code (@see enum arc_micc_ind_code)
/// - ARC_MICC_BOND_DATA
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Description of found Microphone Control Service instance
arc_micc_mics_t mics_info;
} arc_micc_bond_data_ind_t;
/// Structure for ARC_MICC_INCLUDED_SVC indication message
typedef struct arc_micc_included_svc_ind
{
/// Indication code (@see enum arc_micc_ind_code)
/// - ARC_MICC_INCLUDED_SVC
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Start handle
uint16_t shdl;
/// End handle
uint16_t ehdl;
} arc_micc_included_svc_ind_t;
/// Structure for ARC_MICC_MUTE indication message
typedef struct arc_micc_mute_ind
{
/// Indication code (@see enum arc_micc_ind_code)
/// - ARC_MICC_MUTE
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Mute
uint8_t mute;
} arc_micc_mute_ind_t;
/// Structure for ARC_MICC_CFG indication message
typedef struct arc_micc_cfg_ind
{
/// Indication code (@see enum arc_micc_ind_code)
/// - ARC_MICC_CFG
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Enabled or disabled
uint8_t enabled;
} arc_micc_cfg_ind_t;
/// Structure for ARC_MICC_SVC_CHANGED indication message
typedef struct arc_micc_svc_changed_ind
{
/// Indication code (@see enum arc_micc_ind_code)
/// - ARC_MICC_SVC_CHANGED
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
} arc_micc_svc_changed_ind_t;
/// @}
#endif // ARC_MICC_MSG_H_
@@ -0,0 +1,146 @@
/**
****************************************************************************************
*
* @file arc_mics.h
*
* @brief Audio Rendering Control - Microphone Control Server - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_MICS_H_
#define ARC_MICS_H_
/**
****************************************************************************************
* @addtogroup ARC_MICS Audio Rendering Control - Microphone Control Server
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc_mic.h" // Microphone Control Definitions
#if (GAF_ARC_MICS)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes for Microphone Control Server
enum arc_mics_req_code
{
ARC_MICS_CONFIGURE = GAF_CODE(ARC, MICS, 0),
ARC_MICS_ENABLE = GAF_CODE(ARC, MICS, 1),
ARC_MICS_RESTORE_BOND_DATA = GAF_CODE(ARC, MICS, 2),
ARC_MICS_SET_MUTE = GAF_CODE(ARC, MICS, 3),
};
/// List of GAF_IND indication codes for Microphone Control Server
enum arc_mics_ind_code
{
ARC_MICS_BOND_DATA = GAF_CODE(ARC, MICS, 0),
ARC_MICS_MUTE = GAF_CODE(ARC, MICS, 1),
};
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration value has been updated by a peer client for
* Mute characteristic
*
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
****************************************************************************************
*/
typedef void (*arc_mics_cb_bond_data)(uint8_t con_lid, uint8_t cli_cfg_bf);
/**
****************************************************************************************
* @brief Callback function called when Mute characteristic value has been updated
*
* @param[in] mute Mute value
****************************************************************************************
*/
typedef void (*arc_mics_cb_mute)(uint8_t mute);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Microphone Control Server
typedef struct arc_mics_cb
{
/// Callback function called when Client Characteristic Configuration value has been updated by a peer client for
/// Mute characteristic
arc_mics_cb_bond_data cb_bond_data;
/// Callback function called when Mute characteristic value has been updated
arc_mics_cb_mute cb_mute;
} arc_mics_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure Microphone Control Server module
*
* @param[in] p_cb Pointer to set of callback functions for communication with upper layers
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_mics_configure(const arc_mics_cb_t* p_cb);
/**
****************************************************************************************
* @brief Enable Microphone Control Server module
*
* @param[in] nb_att_rsvd Number of attributes reserved for the service
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_mics_enable(uint16_t nb_att_rsvd);
/**
****************************************************************************************
* @brief Set bonding information related to Microphone Control after connection with a peer device
*
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
* @param[in] evt_cfg_bf Event configuration bit field
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_mics_restore_bond_data(uint8_t con_lid, uint8_t cli_cfg_bf, uint8_t evt_cfg_bf);
/**
****************************************************************************************
* @brief Set value of Mute characteristic
*
* @param[in] mute Mute value
****************************************************************************************
*/
uint16_t arc_mics_set_mute(uint8_t mute);
#endif //(GAF_ARC_MICS)
/// @}
#endif // ARC_MICS_H_
@@ -0,0 +1,106 @@
/**
****************************************************************************************
*
* @file arc_mics_msg.h
*
* @brief Audio Rendering Control - Microphone Control Server - Message API Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_MICS_MSG_H_
#define ARC_MICS_MSG_H_
/**
****************************************************************************************
* @addtogroup ARC_MICS_MSG Audio Rendering Control - Microphone Control Server - Message API Definitions
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "arc_msg.h" // Message API Definitions
#include "arc_mics.h" // Microphone Control Server Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ARC_MICS_ENABLE request message
typedef struct arc_mics_enable_req
{
/// Request code (@see enum arc_mics_req_code)
/// - ARC_MICS_ENABLE
uint16_t req_code;
/// Number of attributes reserved for the service
uint8_t nb_att_rsvd;
} arc_mics_enable_req_t;
/// Structure for ARC_MICS_RESTORE_BOND_DATA request message
typedef struct arc_mics_restore_bond_data_req
{
/// Request code (@see enum arc_mics_req_code)
/// - ARC_MICS_RESTORE_BOND_DATA
uint16_t req_code;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint8_t cli_cfg_bf;
/// Event configuration bit field
uint8_t evt_cfg_bf;
} arc_mics_restore_bond_data_req_t;
/// Structure for ARC_MICS_SET_MUTE command message
typedef struct arc_mics_set_mute_req
{
/// Request code (@see enum arc_mics_req_code)
/// - ARC_MICS_SET_MUTE
uint16_t req_code;
/// Mute value
uint8_t mute;
} arc_mics_set_mute_req_t;
/// Structure for request message
typedef struct arc_mics_rsp
{
/// Request code (@see enum arc_mics_req_code)
uint16_t req_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
} arc_mics_rsp_t;
/// Structure for ARC_MICS_BOND_DATA indication message
typedef struct arc_mics_cfg_ind
{
/// Indication code (@see enum arc_mics_ind_code)
/// - ARC_MICS_BOND_DATA
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint8_t cli_cfg_bf;
} arc_mics_cfg_ind_t;
/// Structure for ARC_MICS_MUTE indication message
typedef struct arc_mics_mute_ind
{
/// Indication code (@see enum arc_mics_ind_code)
/// - ARC_MICS_MUTE
uint16_t ind_code;
/// Mute value
uint8_t mute;
} arc_mics_mute_ind_t;
/// @}
#endif // ARC_MICS_MSG_H_
@@ -0,0 +1,160 @@
/**
****************************************************************************************
*
* @file arc_vc.h
*
* @brief Audio Rendering Control - Volume Control - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VC_H_
#define ARC_VC_H_
/**
****************************************************************************************
* @addtogroup ARC_VC Audio Rendering Control - Volume Control
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc.h" // Audio Rendering Control Definitions
/*
* DEFINES
****************************************************************************************
*/
/// Minimum volume value
#define ARC_VC_VOLUME_MIN (0)
/// Maximum volume value
#define ARC_VC_VOLUME_MAX (255)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Position of fields in Volume State characteristic value
enum arc_vc_state_pos
{
/// Volume Setting field
ARC_VC_STATE_POS_SETTING = 0,
/// Mute field
ARC_VC_STATE_POS_MUTE,
/// Change Counter field
ARC_VC_STATE_POS_CHANGE_CNT,
/// Length of Volume State characteristic value
ARC_VC_STATE_LEN
};
/// Position of fields in value written in Volume Control Point characteristic
enum arc_vc_cp_pos
{
/// Operation Code field
ARC_VC_CP_POS_OPCODE = 0,
/// Change Counter field
ARC_VC_CP_POS_CHANGE_CNT,
/// Volume Setting field
ARC_VC_CP_POS_SETTING,
/// Minimal length of Volume Control Point characteristic value
ARC_VC_CP_LEN_MIN = ARC_VC_CP_POS_CHANGE_CNT + 1,
ARC_VC_CP_LEN_MAX = ARC_VC_CP_POS_SETTING + 1,
};
/// Position of fields in Volume Flags characteristic value
enum arc_vc_flags_pos
{
/// Volume Flags field
ARC_VC_FLAGS_POS_FLAGS = 0,
/// Length of Volume Flags characteristic value
ARC_VC_FLAGS_LEN
};
/// Volume Operation Code values
enum arc_vc_opcode
{
/// Relative Volume Down
ARC_VC_OPCODE_VOL_DOWN = 0,
/// Relative Volume Up
ARC_VC_OPCODE_VOL_UP,
/// Unmute/Relative Volume Down
ARC_VC_OPCODE_VOL_DOWN_UNMUTE,
/// Unmute/Relative Volume Up
ARC_VC_OPCODE_VOL_UP_UNMUTE,
/// Set Absolute Volume
ARC_VC_OPCODE_VOL_SET_ABS,
/// Unmute
ARC_VC_OPCODE_VOL_UNMUTE,
/// Mute
ARC_VC_OPCODE_VOL_MUTE,
ARC_VC_OPCODE_MAX
};
/// Application error codes
enum arc_vc_err
{
/// Invalid change counter
ARC_VC_ERR_INVALID_CHANGE_CNT = 0x80,
/// Opcode not supported
ARC_VC_ERR_OPCODE_NOT_SUPP,
};
/// Volume Flags characteristic value bit field meaning
enum arc_vc_flags_bf
{
/// Volume Setting Persisted bit
ARC_VC_FLAGS_SETTING_PERSISTED_POS = 0,
ARC_VC_FLAGS_SETTING_PERSISTED_BIT = CO_BIT(ARC_VC_FLAGS_SETTING_PERSISTED_POS),
};
/// List of Volume Control Service characteristics
enum arc_vc_char_type
{
/// Volume State characteristic
ARC_VC_CHAR_TYPE_STATE = 0,
/// Volume Flags characteristic
ARC_VC_CHAR_TYPE_FLAGS,
ARC_VC_NTF_CHAR_TYPE_MAX,
/// Volume Control Point characteristic
ARC_VC_CHAR_TYPE_CP = ARC_VC_NTF_CHAR_TYPE_MAX,
ARC_VC_CHAR_TYPE_MAX,
};
/// List of Volume Control Service descriptors
enum arc_vc_desc_type
{
/// Volume State characteristic
ARC_VC_DESC_TYPE_CCC_STATE = 0,
/// Volume Flags characteristic
ARC_VC_DESC_TYPE_CCC_FLAGS,
ARC_VC_DESC_TYPE_MAX,
};
/// List of Mute value for Volume Control Service
enum arc_vc_mute
{
/// Not muted
ARC_VC_NOT_MUTED = 0,
/// Muted
ARC_VC_MUTED
};
/// @}
#endif // ARC_VC_H_
@@ -0,0 +1,286 @@
/**
****************************************************************************************
*
* @file arc_vcc.h
*
* @brief Audio Rendering Control - Volume Control Client - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VCC_H_
#define ARC_VCC_H_
/**
****************************************************************************************
* @addtogroup ARC_VCC Audio Rendering Control - Volume Control Client
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "arc_vc.h" // Audio Rendering Control - Volume Control Definitions
#if (GAF_ARC_VCC)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_CMD command codes for Volume Control Client
enum arc_vcc_cmd_code
{
ARC_VCC_DISCOVER = GAF_CODE(ARC, VCC, 0),
ARC_VCC_CONTROL = GAF_CODE(ARC, VCC, 1),
ARC_VCC_GET = GAF_CODE(ARC, VCC, 2),
ARC_VCC_GET_CFG = GAF_CODE(ARC, VCC, 3),
ARC_VCC_SET_CFG = GAF_CODE(ARC, VCC, 4),
};
/// List of GAF_REQ request codes for Volume Control Client
enum arc_vcc_req_code
{
ARC_VCC_CONFIGURE = GAF_CODE(ARC, VCC, 0),
ARC_VCC_RESTORE_BOND_DATA = GAF_CODE(ARC, VCC, 1),
};
/// List of GAF_IND indication codes for Volume Control Client
enum arc_vcc_ind_code
{
ARC_VCC_BOND_DATA = GAF_CODE(ARC, VCC, 0),
ARC_VCC_INCLUDED_SVC = GAF_CODE(ARC, VCC, 1),
ARC_VCC_VOLUME = GAF_CODE(ARC, VCC, 2),
ARC_VCC_FLAGS = GAF_CODE(ARC, VCC, 3),
ARC_VCC_CFG = GAF_CODE(ARC, VCC, 4),
ARC_VCC_SVC_CHANGED = GAF_CODE(ARC, VCC, 5),
};
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// Volume Control Service content description structure
typedef struct arc_vcc_vcs
{
/// Service description
prf_svc_t svc_info;
/// Characteristics description
prf_char_t char_info[ARC_VC_CHAR_TYPE_MAX];
/// Descriptors description
prf_desc_t desc_info[ARC_VC_DESC_TYPE_MAX];
} arc_vcc_vcs_t;
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called each time a command has been completed
*
* @param[in] cmd_code Command code (@see enum arc_cmd_codes)
* @param[in] status Status
* @param[in] con_lid Connection local index
* @param[in] param Additional parameter
****************************************************************************************
*/
typedef void (*arc_vcc_cb_cmp_evt)(uint16_t cmd_code, uint16_t status, uint8_t con_lid, uint8_t param);
/**
****************************************************************************************
* @brief Callback function called when Volume Control Service instance has been discovered in a peer server database
*
* @param[in] con_lid Connection local index
* @param[in] p_svc_info Pointer to service content description
****************************************************************************************
*/
typedef void (*arc_vcc_cb_bond_data)(uint8_t con_lid, arc_vcc_vcs_t* p_svc_info);
/**
****************************************************************************************
* @brief Callback function called when Volume State has been received from a peer server device
*
* @param[in] con_lid Connection local index
* @param[in] volume Volume Setting value
* @param[in] mute Mute value
****************************************************************************************
*/
typedef void (*arc_vcc_cb_volume)(uint8_t con_lid, uint8_t volume, uint8_t mute);
/**
****************************************************************************************
* @brief Callback function called when Volume Flags has been received from a peer server device
*
* @param[in] con_lid Connection local index
* @param[in] flags Volume Flags characteristic value
****************************************************************************************
*/
typedef void (*arc_vcc_cb_flags)(uint8_t con_lid, uint8_t flags);
/**
****************************************************************************************
* @brief Callback function called when a Volume Offset Control Service or an Audio Input Control Service instance has
* been discovered in a peer server
*
* @param[in] con_lid Connection local index
* @param[in] uuid UUID
* @param[in] shdl Start handle
* @param[in] ehdl End handle
****************************************************************************************
*/
typedef void (*arc_vcc_cb_included_svc)(uint8_t con_lid, uint16_t uuid, uint16_t shdl, uint16_t ehdl);
/**
****************************************************************************************
* @brief Callback function called each time a client characteristic configuration value has been received from a peer
* server device
*
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
* @param[in] enabled Indicate if sending of notifications is enabled or not
****************************************************************************************
*/
typedef void (*arc_vcc_cb_cfg)(uint8_t con_lid, uint8_t char_type, uint8_t enabled);
/**
****************************************************************************************
* @brief Callback function called when a service changed indication is received from a Service device
*
* @param[in] con_lid Connection local index
****************************************************************************************
*/
typedef void (*arc_vcc_cb_svc_changed)(uint8_t con_lid);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for volume management (client)
typedef struct arc_vcc_cb
{
/// Callback function called when a command has been completed
arc_vcc_cb_cmp_evt cb_cmp_evt;
/// Callback function called when Volume State has been received from a peer server device
arc_vcc_cb_volume cb_volume;
/// Callback function called when Volume Flags have been received from a peer server device
arc_vcc_cb_flags cb_flags;
/// Callback function called when a client characteristic configuration value has been received from a peer server
/// device
arc_vcc_cb_cfg cb_cfg;
/// Callback function called when Volume Control Service instance has been discovered in a peer server database
arc_vcc_cb_bond_data cb_bond_data;
/// Callback function called when a Volume Offset Control Service or an Audio Input Control Service instance has
/// been discovered in a peer server
arc_vcc_cb_included_svc cb_included_svc;
/// Callback function called when a service changed indication is received from a Service device
arc_vcc_cb_svc_changed cb_svc_changed;
} arc_vcc_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Create and configure Volume Control Client module
*
* @param[in] p_cb Pointer to set of callback functions for communications with upper layers
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcc_configure(const arc_vcc_cb_t* p_cb);
/**
****************************************************************************************
* @brief Initiate discovery of Volume Control Service in peer server device database
*
* @param[in] con_lid Connection local index
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcc_discover(uint8_t con_lid);
/**
****************************************************************************************
* @brief Set bonding information related to Volume Control after connection with a peer device
*
* @param[in] con_lid Connection local index
* @param[in] p_vcs_info Pointer to Volume Control Service description structures
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcc_restore_bond_data(uint8_t con_lid, arc_vcc_vcs_t* p_vcs_info);
/**
****************************************************************************************
* @brief Control peer server device's Volume State values
*
* @param[in] con_lid Connection local index
* @param[in] opcode Operation code
* @param[in] volume Volume
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcc_control(uint8_t con_lid, uint8_t opcode, uint8_t volume);
/**
****************************************************************************************
* @brief Get value for either Volume State or Volume Flags characteristic of a peer server device
*
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcc_get(uint8_t con_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Get Client Characteristic Configuration value for either Volume State or Volume Flags characteristic of a
* peer server device
*
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcc_get_cfg(uint8_t con_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Set Client Characteristic Configuration value for either Volume State or Volume Flags characteristic of a
* peer server device
*
* @param[in] con_lid Connection local index
* @param[in] char_type Characteristic type
* @param[in] enable Indicate if sending of notifications must be enabled or disabled
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcc_set_cfg(uint8_t con_lid, uint8_t char_type, uint8_t enable);
#endif //(GAF_ARC_VCC)
/// @}
#endif // ARC_VCC_H_
@@ -0,0 +1,230 @@
/**
****************************************************************************************
*
* @file arc_vcc_msg.h
*
* @brief Audio Rendering Control - Definition of Kernel Messages (Volume Control Client)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VCC_MSG_H_
#define ARC_VCC_MSG_H_
/**
****************************************************************************************
* @addtogroup ARC_VCC_MSG Audio Rendering Control - Definition of Kernel Messages (Volume Control Client)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc_msg.h" // Audio Rendering Control Kernel Messages Definitions
#include "arc_vcc.h" // Audio Rendering Control - Volume Control Client Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ARC_VCC_DISCOVER command message
typedef struct arc_vcc_discover_cmd
{
/// Command code (@see enum arc_vcc_cmd_code)
/// - ARC_VCC_DISCOVER
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
} arc_vcc_discover_cmd_t;
/// Structure for ARC_VCC_CONTROL command message
typedef struct arc_vcc_control_cmd
{
/// Command code (@see enum arc_vcc_cmd_code)
/// - ARC_VCC_CONTROL
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Operation code
uint8_t opcode;
/// Volume
uint8_t volume;
} arc_vcc_control_cmd_t;
/// Structure for ARC_VCC_GET command message
typedef struct arc_vcc_get_cmd
{
/// Command code (@see enum arc_vcc_cmd_code)
/// - ARC_VCC_GET
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
} arc_vcc_get_cmd_t;
/// Structure for ARC_VCC_GET_CFG command message
typedef struct arc_vcc_get_cfg_cmd
{
/// Command code (@see enum arc_vcc_cmd_code)
/// - ARC_VCC_GET_CFG
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
} arc_vcc_get_cfg_cmd_t;
/// Structure for ARC_VCC_SET_CFG command message
typedef struct arc_vcc_set_cfg_cmd
{
/// Command code (@see enum arc_vcc_cmd_code)
/// - ARC_VCC_SET_CFG
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
/// Enable
uint8_t enable;
} arc_vcc_set_cfg_cmd_t;
/// Structure for command complete event message
typedef struct arc_vcc_cmp_evt
{
/// Command code (@see enum arc_vcc_cmd_code)
uint16_t cmd_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
/// Union
union
{
/// Value
uint8_t value;
/// Operation code
uint8_t opcode;
/// Characteristic type
uint8_t char_type;
} u;
} arc_vcc_cmp_evt_t;
/// Structure for ARC_VCC_CONFIGURE request message
typedef struct arc_vcc_configure_req
{
/// Request code (@see enum arc_vcc_req_code)
/// - ARC_VCC_CONFIGURE
uint16_t req_code;
} arc_vcc_configure_req_t;
/// Structure for ARC_VCC_RESTORE_BOND_DATA request message
typedef struct arc_vcc_restore_bond_data_req
{
/// Request code (@see enum arc_vcc_req_code)
/// - ARC_VCC_RESTORE_BOND_DATA
uint16_t req_code;
/// Connection local index
uint8_t con_lid;
/// Volume Control Service description
arc_vcc_vcs_t vcs_info;
} arc_vcc_restore_bond_data_req_t;
/// Structure for response message
typedef struct arc_vcc_rsp
{
/// Request code (@see enum arc_vcc_req_code)
uint16_t req_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
} arc_vcc_rsp_t;
/// Structure for ARC_VCC_BOND_DATA indication message
typedef struct arc_vcc_bond_data_ind
{
/// Indication code (@see enum arc_vcc_ind_code)
/// - ARC_VCC_BOND_DATA
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Volume Control Service description
arc_vcc_vcs_t vcs_info;
} arc_vcc_bond_data_ind_t;
/// Structure for ARC_VCC_INCLUDED_SVC indication message
typedef struct arc_vcc_included_svc_ind
{
/// Indication code (@see enum arc_vcc_ind_code)
/// - ARC_VCC_INCLUDED_SVC
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// UUID
uint16_t uuid;
/// Start handle
uint16_t shdl;
/// End handle
uint16_t ehdl;
} arc_vcc_included_svc_ind_t;
/// Structure for ARC_VCC_VOLUME indication message
typedef struct arc_vcc_volume_ind
{
/// Indication code (@see enum arc_vcc_ind_code)
/// - ARC_VCC_VOLUME
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Volume
uint8_t volume;
/// Mute
uint8_t mute;
} arc_vcc_volume_ind_t;
/// Structure for ARC_VCC_FLAGS indication message
typedef struct arc_vcc_flags_ind
{
/// Indication code (@see enum arc_vcc_ind_code)
/// - ARC_VCC_FLAGS
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Volume Flags
uint8_t flags;
} arc_vcc_flags_ind_t;
/// Structure for ARC_VCC_CFG indication message
typedef struct arc_vcc_cfg_ind
{
/// Indication code (@see enum arc_vcc_ind_code)
/// - ARC_VCC_CFG
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Characteristic type
uint8_t char_type;
/// Indicate if sending of notifications is enabled for the indicated characteristic
uint8_t enabled;
} arc_vcc_cfg_ind_t;
/// Structure for ARC_VCC_SVC_CHANGED indication message
typedef struct arc_vcc_svc_changed_ind
{
/// Indication code (@see enum arc_vcc_ind_code)
/// - ARC_VCC_SVC_CHANGED
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
} arc_vcc_svc_changed_ind_t;
/// @}
#endif // ARC_VCC_MSG_H_
@@ -0,0 +1,162 @@
/**
****************************************************************************************
*
* @file arc_vcs.h
*
* @brief Audio Rendering Control - Volume Control Server - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VCS_H_
#define ARC_VCS_H_
/**
****************************************************************************************
* @addtogroup ARC_VCS Audio Rendering Control - Volume Control Server
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc_vc.h" // Volume Control Definitions
#if (GAF_ARC_VCS)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes for Volume Control Server
enum arc_vcs_req_code
{
ARC_VCS_CONFIGURE = GAF_CODE(ARC, VCS, 0),
ARC_VCS_ENABLE = GAF_CODE(ARC, VCS, 1),
ARC_VCS_RESTORE_BOND_DATA = GAF_CODE(ARC, VCS, 2),
ARC_VCS_CONTROL = GAF_CODE(ARC, VCS, 3),
};
/// List of GAF_IND indication codes for Volume Control Server
enum arc_vcs_ind_code
{
ARC_VCS_VOLUME = GAF_CODE(ARC, VCS, 0),
ARC_VCS_BOND_DATA = GAF_CODE(ARC, VCS, 1),
ARC_VCS_FLAGS = GAF_CODE(ARC, VCS, 2),
};
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration of a notification-capable
* characteristic has been updated by a peer client
*
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
****************************************************************************************
*/
typedef void (*arc_vcs_cb_bond_data)(uint8_t con_lid, uint8_t cli_cfg_bf);
/**
****************************************************************************************
* @brief Callback function called when Volume State characteristic value has been updated
*
* @param[in] volume Volume Setting value
* @param[in] mute Mute value
****************************************************************************************
*/
typedef void (*arc_vcs_cb_volume)(uint8_t volume, uint8_t mute);
/**
****************************************************************************************
* @brief Callback function called when Volume Flags characteristic value has been updated
*
* @param[in] flags Volume Flags value
****************************************************************************************
*/
typedef void (*arc_vcs_cb_flags)(uint8_t flags);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for volume management (server)
typedef struct arc_vcs_cb
{
/// Callback function called when Client Characteristic Configuration of a notification-capable characteristic has
/// been updated by a peer client
arc_vcs_cb_bond_data cb_bond_data;
/// Callback function called when Volume State characteristic value has been updated
arc_vcs_cb_volume cb_volume;
/// Callback function called when Volume Flags characteristic value has been updated
arc_vcs_cb_flags cb_flags;
} arc_vcs_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure Volume Control Server module
*
* @param[in] p_cb Pointer to set of callback functions
* @param[in] step_size Step Size value
* @param[in] flags Volume Flags value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcs_configure(const arc_vcs_cb_t* p_cb, uint8_t step_size, uint8_t flags);
/**
****************************************************************************************
* @brief Enable Volume Control Server module
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcs_enable(void);
/**
****************************************************************************************
* @brief Set bonding information related to Volume Control after connection with a peer device
*
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
* @param[in] evt_cfg_bf Event configuration bit field
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcs_restore_bond_data(uint8_t con_lid, uint8_t cli_cfg_bf, uint8_t evt_cfg_bf);
/**
****************************************************************************************
* @brief Control Volume State characteristic value
*
* @param[in] opcode Operation code
* @param[in] volume Volume
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vcs_control(uint8_t opcode, uint8_t volume);
#endif //(GAF_ARC_VCS)
/// @}
#endif // ARC_VCS_H_
@@ -0,0 +1,137 @@
/**
****************************************************************************************
*
* @file arc_vcs_msg.h
*
* @brief Audio Rendering Control - Volume Control Server - Message API Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VCS_MSG_H_
#define ARC_VCS_MSG_H_
/**
****************************************************************************************
* @addtogroup ARC_VCS_MSG Audio Rendering Control - Volume Control Server - Message API Definitions
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "arc_msg.h" // Message API Definitions
#include "arc_vcs.h" // Volume Control Server Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ARC_VCS_CONFIGURE request message
typedef struct arc_vcs_configure_req
{
/// Request code (@see enum arc_vcs_req_code)
/// - ARC_VCS_CONFIGURE
uint16_t req_code;
/// Step size
uint8_t step_size;
/// Volume Flags characteristic value
uint8_t flags;
} arc_vcs_configure_req_t;
/// Structure for ARC_VCS_ENABLE request message
typedef struct arc_vcs_enable_req
{
/// Request code (@see enum arc_vcs_req_code)
/// - ARC_VCS_ENABLE
uint16_t req_code;
} arc_vcs_enable_req_t;
/// Structure for ARC_VCS_RESTORE_BOND_DATA request message
typedef struct arc_vcs_restore_bond_data_req
{
/// Request code (@see enum arc_vcs_req_code)
/// - ARC_VCS_RESTORE_BOND_DATA
uint16_t req_code;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint8_t cli_cfg_bf;
/// Event configuration bit field
uint8_t evt_cfg_bf;
} arc_vcs_restore_bond_data_req_t;
/// Structure for ARC_VCS_CONTROL request message
typedef struct arc_vcs_control_req
{
/// Request code (@see enum arc_vcs_req_code)
/// - ARC_VCS_CONTROL
uint16_t req_code;
/// Operation code
uint8_t opcode;
/// Volume
uint8_t volume;
} arc_vcs_control_req_t;
/// Structure for request message
typedef struct arc_vcs_rsp
{
/// Request code (@see enum arc_vcs_req_code)
uint16_t req_code;
/// Status
uint16_t status;
union
{
/// Value
uint8_t value;
/// Connection local index
uint8_t con_lid;
/// Operation code
uint8_t opcode;
} u;
} arc_vcs_rsp_t;
/// Structure for ARC_VCS_BOND_DATA indication message
typedef struct arc_vcs_cfg_ind
{
/// Indication code (@see enum arc_vcs_ind_code)
/// - ARC_VCS_BOND_DATA
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint8_t cli_cfg_bf;
} arc_vcs_cfg_ind_t;
/// Structure for ARC_VCS_VOLUME indication message
typedef struct arc_vcs_volume_ind
{
/// Indication code (@see enum arc_vcs_ind_code)
/// - ARC_VCS_VOLUME
uint16_t ind_code;
/// Volume
uint8_t volume;
/// Mute
uint8_t mute;
} arc_vcs_volume_ind_t;
/// Structure for ARC_VCS_FLAGS indication message
typedef struct arc_vcs_flags_ind
{
/// Indication code (@see enum arc_vcs_ind_code)
/// - ARC_VCS_FLAGS
uint16_t ind_code;
/// Volume Flags
uint8_t flags;
} arc_vcs_flags_ind_t;
/// @}
#endif // ARC_VCS_MSG_H_
@@ -0,0 +1,146 @@
/**
****************************************************************************************
*
* @file arc_voc.h
*
* @brief Audio Rendering Control - Volume Offset Control - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VOC_H_
#define ARC_VOC_H_
/**
****************************************************************************************
* @addtogroup ARC_VOC Audio Rendering Control - Volume Offset Control
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc.h" // Audio Rendering Control Definitions
/*
* DEFINES
****************************************************************************************
*/
/// Minimum offset value
#define ARC_VOC_OFFSET_MIN (-255)
/// Maximum offset value
#define ARC_VOC_OFFSET_MAX (255)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Position of fields in Offset State characteristic value
enum arc_voc_offset_pos
{
/// Volume Offset field
ARC_VOC_OFFSET_POS_OFFSET = 0,
/// Change Counter field
ARC_VOC_OFFSET_POS_CHANGE_CNT = 2,
/// Length of Offset State characteristic value
ARC_VOC_OFFSET_LEN
};
/// Position of fields in Audio Location characteristic value
enum arc_voc_location_pos
{
/// Audio Location field
ARC_VOC_LOCATION_POS_LOC = 0,
/// Length of Audio Location characteristic value
ARC_VOC_LOCATION_LEN = 1
};
/// Position of fields in value written in Volume Offset Control Point characteristic
enum arc_voc_cp_pos
{
/// Operation Code field
ARC_VOC_CP_POS_OPCODE = 0,
/// Change Counter field
ARC_VOC_CP_POS_CHANGE_CNT,
/// Volume Offset field
ARC_VOC_CP_POS_OFFSET,
/// Length of Volume Offset Control Point characteristic value
ARC_VOC_CP_LEN = ARC_VOC_CP_POS_OFFSET + 2,
};
/// Volume Offset Operation Code values
enum arc_voc_opcode
{
/// Set Volume Offset
ARC_VOC_OPCODE_SET_OFFSET = 1,
ARC_VOC_OPCODE_MAX,
ARC_VOC_OPCODE_MIN = ARC_VOC_OPCODE_SET_OFFSET,
};
/// Application error codes
enum arc_voc_err
{
/// Invalid change counter
ARC_VOC_ERR_INVALID_CHANGE_CNT = 0x80,
/// Opcode not supported
ARC_VOC_ERR_OPCODE_NOT_SUPP,
/// Value out of range
ARC_VOC_ERR_VALUE_OUT_OF_RANGE,
};
/// Set type values
enum arc_voc_set_type
{
/// Volume offset
ARC_VOC_SET_TYPE_OFFSET = 0,
/// Audio location
ARC_VOC_SET_TYPE_LOCATION,
ARC_VOC_SET_TYPE_MAX,
};
/// List of Volume Offset Control Service characteristics
enum arc_voc_char_type
{
/// Offset characteristic
ARC_VOC_CHAR_TYPE_OFFSET = 0,
/// Audio Location characteristic
ARC_VOC_CHAR_TYPE_LOC,
/// Audio Output Description characteristic
ARC_VOC_CHAR_TYPE_DESC,
ARC_VOC_NTF_CHAR_TYPE_MAX,
/// Volume Offset Control Point characteristic
ARC_VOC_CHAR_TYPE_CP = ARC_VOC_NTF_CHAR_TYPE_MAX,
ARC_VOC_CHAR_TYPE_MAX,
};
/// List of Volume Control Service descriptors
enum arc_voc_desc_type
{
/// Offset State characteristic
ARC_VOC_DESC_TYPE_CCC_OFFSET = 0,
/// Audio Location characteristic
ARC_VOC_DESC_TYPE_CCC_LOC,
/// Audio Output Description characteristic
ARC_VOC_DESC_TYPE_CCC_DESC,
ARC_VOC_DESC_TYPE_MAX,
};
/// @}
#endif // ARC_VOC_H_
@@ -0,0 +1,306 @@
/**
****************************************************************************************
*
* @file arc_vocc.h
*
* @brief Audio Rendering Control - Volume Offset Control Client - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VOCC_H_
#define ARC_VOCC_H_
/**
****************************************************************************************
* @addtogroup ARC_VOCC Audio Rendering Control - Volume Offset Control Client
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "arc_voc.h" // Audio Rendering Control - Volume Offset Control Definitions
#if (GAF_ARC_VOCC)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_CMD command codes for Volume Offset Control Client
enum arc_vocc_cmd_codes
{
ARC_VOCC_DISCOVER = GAF_CODE(ARC, VOCC, 0),
ARC_VOCC_GET = GAF_CODE(ARC, VOCC, 1),
ARC_VOCC_SET_DESCRIPTION = GAF_CODE(ARC, VOCC, 2),
ARC_VOCC_SET = GAF_CODE(ARC, VOCC, 3),
ARC_VOCC_GET_CFG = GAF_CODE(ARC, VOCC, 4),
ARC_VOCC_SET_CFG = GAF_CODE(ARC, VOCC, 5),
};
/// List of GAF_REQ request codes for Volume Offset Control Client
enum arc_vocc_req_codes
{
ARC_VOCC_CONFIGURE = GAF_CODE(ARC, VOCC, 0),
ARC_VOCC_RESTORE_BOND_DATA = GAF_CODE(ARC, VOCC, 1),
};
/// List of GAF_IND indication codes for Volume Offset Control Client
enum arc_vocc_ind_codes
{
ARC_VOCC_BOND_DATA = GAF_CODE(ARC, VOCC, 0),
ARC_VOCC_VALUE = GAF_CODE(ARC, VOCC, 1),
ARC_VOCC_DESCRIPTION = GAF_CODE(ARC, VOCC, 2),
ARC_VOCC_CFG = GAF_CODE(ARC, VOCC, 3),
ARC_VOCC_SVC_CHANGED = GAF_CODE(ARC, VOCC, 4),
};
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/// Volume Offset Control Service content description structure
typedef struct arc_vocc_vocs
{
/// Service description
prf_svc_t svc_info;
/// Characteristics description
prf_char_t char_info[ARC_VOC_CHAR_TYPE_MAX];
/// Descriptors description
prf_desc_t desc_info[ARC_VOC_DESC_TYPE_MAX];
} arc_vocc_vocs_t;
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called each time a command has been completed
*
* @param[in] cmd_code Command code (@see enum arc_cmd_codes)
* @param[in] status Status
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] param Additional parameter
****************************************************************************************
*/
typedef void (*arc_vocc_cb_cmp_evt)(uint16_t cmd_code, uint16_t status, uint8_t con_lid, uint8_t output_lid,
uint8_t param);
/**
****************************************************************************************
* @brief Callback function called when a Volume Offset Control Service instance has been discovered in a peer server
* database
*
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] p_svc_info Pointer to service content description
****************************************************************************************
*/
typedef void (*arc_vocc_cb_bond_data)(uint8_t con_lid, uint8_t output_lid, arc_vocc_vocs_t* p_svc_info);
/**
****************************************************************************************
* @brief Callback function called when Audio Location or Offset Staet characteristic value has been received from a
* peer server device
*
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] char_type Characteristic type
* @param[in] val Value
****************************************************************************************
*/
typedef void (*arc_vocc_cb_value)(uint8_t con_lid, uint8_t output_lid, uint8_t char_type, uint16_t val);
/**
****************************************************************************************
* @brief Callback function called when Audio Output Description characteristic value has been received from a peer
* server device
*
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] desc_len Audio output description length
* @param[in] p_desc Pointer to audio output description value
****************************************************************************************
*/
typedef void (*arc_vocc_cb_description)(uint8_t con_lid, uint8_t output_lid, uint16_t desc_len, uint8_t* p_desc);
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration value has been received for a
* characteristic
*
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] char_type Characteristic type
* @param[in] enabled Indicate if sending of notifications is enabled
****************************************************************************************
*/
typedef void (*arc_vocc_cb_cfg)(uint8_t con_lid, uint8_t output_lid, uint8_t char_type, uint8_t enabled);
/**
****************************************************************************************
* @brief Callback function called when a service changed indication is received from a Server device
*
* @param[in] con_lid Connection local index
****************************************************************************************
*/
typedef void (*arc_vocc_cb_svc_changed)(uint8_t con_lid);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Volume Offset Control Client
typedef struct arc_vocc_cb
{
/// Callback function called when a command has been completed
arc_vocc_cb_cmp_evt cb_cmp_evt;
/// Callback function called when Audio Location or Offset State characteristic value has been received from a
/// peer server device
arc_vocc_cb_value cb_value;
/// Callback function called when Audio Output Description characteristic value has been received from a peer
/// server device
arc_vocc_cb_description cb_description;
/// Callback function called when a client characteristic configuration value has been received from a peer server
/// device
arc_vocc_cb_cfg cb_cfg;
/// Callback function called when a Volume Offset Control Service instance has been discovered in a peer server
/// database
arc_vocc_cb_bond_data cb_bond_data;
/// Callback function called when a service changed indication is received from a Server device
arc_vocc_cb_svc_changed cb_svc_changed;
} arc_vocc_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure use of Volume Offset Control Client module
*
* @param[in] p_cb Pointer to set of callback functions
* @param[in] pref_mtu Preferred MTU
* Values from 0 to 63 are equivalent to 64
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocc_configure(const arc_vocc_cb_t* p_cb, uint16_t pref_mtu);
/**
****************************************************************************************
* @brief Discover Volume Offset Control Service Services in peer server device database
*
* @param[in] con_lid Connection local index
* @param[in] nb_outputs Number of outputs
* @param[in] p_svc_hdl Pointer to service handles
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocc_discover(uint8_t con_lid, uint8_t nb_outputs, prf_svc_t* p_svc_hdl);
/**
****************************************************************************************
* @brief Set bonding information related to Volume Offset Control after connection with a peer device
*
* @param[in] con_lid Connection local index
* @param[in] nb_outputs Number of outputs
* @param[in] p_vocs_info Pointer to Volume Offset Control Service description structures
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocc_restore_bond_data(uint8_t con_lid, uint8_t nb_outputs, arc_vocc_vocs_t* p_vocs_info);
/**
****************************************************************************************
* @brief Set value for Audio Location characteristic of a peer server device output
*
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] set_type Set type
* @param[in] val Value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocc_set(uint8_t con_lid, uint8_t output_lid, uint8_t set_type, uint32_t val);
/**
****************************************************************************************
* @brief Set value for Audio Output Description characteristic of a peer server device output
*
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] desc_len Audio output description length
* @param[in] p_desc Pointer to audio output description value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocc_set_description(uint8_t con_lid, uint8_t output_lid, uint16_t desc_len, uint8_t* p_desc);
/**
****************************************************************************************
* @brief Get value for either Offset State or Audio Location or Audio Output Description characteristic of a peer
* server device output
*
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocc_get(uint8_t con_lid, uint8_t output_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Get Client Characteristic Configuration value for either Offset State or Audio Location or Audio Output
* Description characteristic of a peer server device output
*
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] char_type Characteristic type
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocc_get_cfg(uint8_t con_lid, uint8_t output_lid, uint8_t char_type);
/**
****************************************************************************************
* @brief Set Client Characteristic Configuration value for either Offset State or Audio Location or Audio Output
* Description characteristic of a peer server device output
*
* @param[in] con_lid Connection local index
* @param[in] output_lid Output local index
* @param[in] char_type Characteristic type
* @param[in] enable Indicate if sending of notifications must be enabled or disabled
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocc_set_cfg(uint8_t con_lid, uint8_t output_lid, uint8_t char_type, uint8_t enable);
#endif //(GAF_ARC_VOCC)
/// @}
#endif // ARC_VOCC_H_
@@ -0,0 +1,273 @@
/**
****************************************************************************************
*
* @file arc_vocc_msg.h
*
* @brief Audio Rendering Control - Definition of Kernel Messages (Volume Offset Control Client)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VOCC_MSG_H_
#define ARC_VOCC_MSG_H_
/**
****************************************************************************************
* @addtogroup ARC_VOCC_MSG Audio Rendering Control - Definition of Kernel Messages (Volume Offset Control Client)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc_msg.h" // Audio Rendering Control Kernel Messages Definitions
#include "arc_vocc.h" // Audio Rendering Control - Volume Offset Control Client Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ARC_VOCC_DISCOVER command message
typedef struct arc_vocc_discover_cmd
{
/// Command code (@see enum arc_vocc_cmd_code)
/// - ARC_VOCC_DISCOVER
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Number of outputs
uint8_t nb_outputs;
/// Service handles
prf_svc_t svc_hdl[__ARRAY_EMPTY];
} arc_vocc_discover_cmd_t;
/// Structure for ARC_VOCC_GET command message
typedef struct arc_vocc_get_cmd
{
/// Command code (@see enum arc_vocc_cmd_code)
/// - ARC_VOCC_GET
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Characteristic type
uint8_t char_type;
} arc_vocc_get_cmd_t;
/// Structure for ARC_VOCC_SET_DESCRIPTION command message
typedef struct arc_vocc_set_description_cmd
{
/// Command code (@see enum arc_vocc_cmd_code)
/// - ARC_VOCC_SET_DESCRIPTION
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Audio output description length
uint16_t desc_len;
/// Audio output description
uint8_t desc[__ARRAY_EMPTY];
} arc_vocc_set_description_cmd_t;
/// Structure for ARC_VOCC_SET command message
typedef struct arc_vocc_set_cmd
{
/// Command code (@see enum arc_vocc_cmd_code)
/// - ARC_VOCC_SET
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Set type
uint8_t set_type;
union
{
/// Value
uint16_t val;
/// Volume offset
int16_t offset;
/// Audio location
uint8_t location;
} u;
} arc_vocc_set_cmd_t;
/// Structure for ARC_VOCC_GET_CFG command message
typedef struct arc_vocc_get_cfg_cmd
{
/// Command code (@see enum arc_vocc_cmd_code)
/// - ARC_VOCC_GET_CFG
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Characteristic type
uint8_t char_type;
} arc_vocc_get_cfg_cmd_t;
/// Structure for ARC_VOCC_SET_CFG command message
typedef struct arc_vocc_set_cfg_cmd
{
/// Command code (@see enum arc_vocc_cmd_code)
/// - ARC_VOCC_SET_CFG
uint16_t cmd_code;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Characteristic type
uint8_t char_type;
/// Enable or disable
uint8_t enable;
} arc_vocc_set_cfg_cmd_t;
/// Structure for command complete event message
typedef struct arc_vocc_cmp_evt
{
/// Command code (@see enum arc_vocc_cmd_code)
uint16_t cmd_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Union
union
{
/// Value
uint8_t value;
/// Set type
uint8_t set_type;
/// Characteristic type
uint8_t char_type;
} u;
} arc_vocc_cmp_evt_t;
/// Structure for ARC_VOCC_CONFIGURE request message
typedef struct arc_vocc_configure_req
{
/// Request code (@see enum arc_vocc_req_code)
/// - ARC_VOCC_CONFIGURE
uint16_t req_code;
/// Preferred MTU
/// Values from 0 to 63 are equivalent to 64
uint16_t pref_mtu;
} arc_vocc_configure_req_t;
/// Structure for ARC_VOCC_RESTORE_BOND_DATA request message
typedef struct arc_vocc_restore_bond_data_req
{
/// Request code (@see enum arc_vocc_req_code)
/// - ARC_VOCC_RESTORE_BOND_DATA
uint16_t req_code;
/// Connection local index
uint8_t con_lid;
/// Number of outputs
uint8_t nb_outputs;
/// Description of found Volume Offset Control Service instances
arc_vocc_vocs_t vocs_info[__ARRAY_EMPTY];
} arc_vocc_restore_bond_data_req_t;
/// Structure for response message
typedef struct arc_vocc_rsp
{
/// Request code (@see enum arc_vocc_req_code)
uint16_t req_code;
/// Status
uint16_t status;
/// Connection local index
uint8_t con_lid;
} arc_vocc_rsp_t;
/// Structure for ARC_VOCC_BOND_DATA indication message
typedef struct arc_vocc_bond_data_ind
{
/// Indication code (@see enum arc_vocc_ind_code)
/// - ARC_VOCC_BOND_DATA
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Description of found Volume Offset Control Service instance
arc_vocc_vocs_t vocs_info;
} arc_vocc_bond_data_ind_t;
/// Structure for ARC_VOCC_VALUE indication message
typedef struct arc_vocc_value_ind
{
/// Indication code (@see enum arc_vocc_ind_code)
/// - ARC_VOCC_VALUE
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Characteristic type
uint8_t char_type;
union
{
/// Value
uint16_t val;
/// Volume offset
int16_t offset;
/// Audio location
uint8_t location;
} u;;
} arc_vocc_value_ind_t;
/// Structure for ARC_VOCC_DESCRIPTION indication message
typedef struct arc_vocc_description_ind
{
/// Indication code (@see enum arc_vocc_ind_code)
/// - ARC_VOCC_DESCRIPTION
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Audio output description length
uint16_t desc_len;
/// Audio output description
uint8_t desc[__ARRAY_EMPTY];
} arc_vocc_description_ind_t;
/// Structure for ARC_VOCC_CFG indication message
typedef struct arc_vocc_cfg_ind
{
/// Indication code (@see enum arc_vocc_ind_code)
/// - ARC_VOCC_CFG
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
/// Output local index
uint8_t output_lid;
/// Characteristic type
uint8_t char_type;
/// Enabled or disabled
uint8_t enabled;
} arc_vocc_cfg_ind_t;
/// Structure for ARC_VOCC_SVC_CHANGED indication message
typedef struct arc_vocc_svc_changed_ind
{
/// Indication code (@see enum arc_vocc_ind_code)
/// - ARC_VOCC_SVC_CHANGED
uint16_t ind_code;
/// Connection local index
uint8_t con_lid;
} arc_vocc_svc_changed_ind_t;
/// @}
#endif // ARC_VOCC_MSG_H_
@@ -0,0 +1,264 @@
/**
****************************************************************************************
*
* @file arc_vocs.h
*
* @brief Audio Rendering Control - Volume Offset Control Server - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VOCS_H_
#define ARC_VOCS_H_
/**
****************************************************************************************
* @addtogroup ARC_VOCS Audio Rendering Control - Volume Offset Control Server
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "arc_voc.h" // Audio Rendering Control - Volume Offset Control Definitions
#if (GAF_ARC_VOCS)
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes for Volume Offset Control Server
enum arc_vocs_req_code
{
ARC_VOCS_CONFIGURE = GAF_CODE(ARC, VOCS, 0),
ARC_VOCS_ADD = GAF_CODE(ARC, VOCS, 1),
ARC_VOCS_ENABLE = GAF_CODE(ARC, VOCS, 2),
ARC_VOCS_RESTORE_BOND_DATA = GAF_CODE(ARC, VOCS, 3),
ARC_VOCS_SET = GAF_CODE(ARC, VOCS, 4),
ARC_VOCS_SET_DESCRIPTION = GAF_CODE(ARC, VOCS, 5),
};
/// List of GAF_IND indication codes for Volume Offset Control Server
enum arc_vocs_ind_code
{
ARC_VOCS_OFFSET = GAF_CODE(ARC, VOCS, 0),
ARC_VOCS_BOND_DATA = GAF_CODE(ARC, VOCS, 1),
};
/// List of GAF_REQ_IND indication codes for Volume Offset Control Server
enum arc_vocs_req_ind_code
{
ARC_VOCS_SET_DESCRIPTION_RI = GAF_CODE(ARC, VOCS, 0),
ARC_VOCS_SET_LOCATION = GAF_CODE(ARC, VOCS, 1),
};
/// Output configuration bit field
enum arc_vocs_cfg_bf
{
/// Set to 1 if Audio Location characteristic is notification-capable
ARC_VOCS_CFG_LOC_NTF_POS = 0,
ARC_VOCS_CFG_LOC_NTF_BIT = CO_BIT(ARC_VOCS_CFG_LOC_NTF_POS),
/// Set to 1 if Audio Location characteristic is writable
ARC_VOCS_CFG_LOC_WR_POS = 1,
ARC_VOCS_CFG_LOC_WR_BIT = CO_BIT(ARC_VOCS_CFG_LOC_WR_POS),
/// Set to 1 if Audio Output Description characteristic is notification-capable
ARC_VOCS_CFG_DESC_NTF_POS = 2,
ARC_VOCS_CFG_DESC_NTF_BIT = CO_BIT(ARC_VOCS_CFG_DESC_NTF_POS),
/// Set to 1 if Audio Output Description characteristic is writable
ARC_VOCS_CFG_DESC_WR_POS = 3,
ARC_VOCS_CFG_DESC_WR_BIT = CO_BIT(ARC_VOCS_CFG_DESC_WR_POS),
};
/*
* CALLBACK FUNCTIONS DEFINITION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Callback function called when Offset State characteristic value has been updated
*
* @param[in] output_lid Output local index
* @param[in] offset Offset value
****************************************************************************************
*/
typedef void (*arc_vocs_cb_offset)(uint8_t output_lid, int16_t offset);
/**
****************************************************************************************
* @brief Callback function called when Client Characteristic Configuration of a notification-capable
* characteristic has been updated by a peer client
*
* @param[in] output_lid Output local index
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
****************************************************************************************
*/
typedef void (*arc_vocs_cb_bond_data)(uint8_t output_lid, uint8_t con_lid, uint8_t cli_cfg_bf);
/**
****************************************************************************************
* @brief Callback function called when value of Audio Output Description characteristic has been written so that it
* can be confirmed by upper layers
*
* @param[in] output_lid Output local index
* @param[in] con_lid Connection local index
* @param[in] desc_len Audio output description length
* @param[in] p_desc Pointer to audio output description value
****************************************************************************************
*/
typedef void (*arc_vocs_cb_description)(uint8_t output_lid, uint8_t con_lid, uint8_t desc_len, uint8_t* p_desc);
/**
****************************************************************************************
* @brief Callback function called when value of Audio Location characteristic has been written so that it can be
* confirmed by upper layers
*
* @param[in] output_lid Output local index
* @param[in] con_lid Connection local index
* @param[in] location Audio location
****************************************************************************************
*/
typedef void (*arc_vocs_cb_location)(uint8_t output_lid, uint8_t con_lid, uint8_t location);
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for volume management (server)
typedef struct arc_vocs_cb
{
/// Callback function called when Client Characteristic Configuration of a notification-capable
/// characteristic has been updated by a peer client
arc_vocs_cb_bond_data cb_bond_data;
/// Callback function called when Offset State characteristic value has been updated
arc_vocs_cb_offset cb_offset;
/// Callback function called when value of Audio Output Description characteristic has been written so that it can
/// be confirmed by upper layers
arc_vocs_cb_description cb_description;
/// Callback function called when value of Audio Location characteristic has been written so that it can be
/// confirmed by upper layers
arc_vocs_cb_location cb_location;
} arc_vocs_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Configure Volume Offset Control Server module
*
* @param[in] p_cb Pointer to set of callback functions for communication with upper layers
* @param[in] nb_outputs Number of outputs
* @param[in] pref_mtu Preferred MTU
* Values from 0 to 63 are equivalent to 64
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocs_configure(const arc_vocs_cb_t* p_cb, uint8_t nb_outputs, uint16_t pref_mtu);
/**
****************************************************************************************
* @brief Add an output
*
* @param[in] desc_max_len Audio Output Description maximum length
* @param[in] cfg_bf Configuration bit field
* @param[in] nb_att_rsvd Number of attributes reserved for the service
* @param[out] p_output_lid Pointer at which allocated output local index is returned
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocs_add(uint8_t desc_max_len, uint8_t cfg_bf, uint16_t nb_att_rsvd, uint8_t* p_output_lid);
/**
****************************************************************************************
* @brief Enable Volume Offset Control Server module
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocs_enable(void);
/**
****************************************************************************************
* @brief Set bonding information related to an input after establishment of a connection
*
* @param[in] output_lid Output local index
* @param[in] con_lid Connection local index
* @param[in] cli_cfg_bf Client configuration bit field
* @param[in] evt_bf Event bit field
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocs_restore_bond_data(uint8_t output_lid, uint8_t con_lid, uint8_t cli_cfg_bf, uint8_t evt_bf);
/**
****************************************************************************************
* @brief Set value of Audio Location or Offset State characteristic
*
* @param[in] output_lid Output local index
* @param[in] set_type Set type
* @param[in] value Value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocs_set(uint8_t output_lid, uint8_t set_type, uint32_t val);
/**
****************************************************************************************
* @brief Set value of Audio Output Description characteristic value
*
* @param[in] output_lid Output local index
* @param[in] desc_len Audio output description length
* @param[in] p_desc Pointer to Audio output description value
*
* @return An error status
****************************************************************************************
*/
uint16_t arc_vocs_set_description(uint8_t output_lid, uint8_t desc_len, uint8_t *p_desc);
/**
****************************************************************************************
* @brief Confirm or not value written for Audio Output Description characteristic
*
* @param[in] cfm_status Confirmation status
* @param[in] output_lid Output local index
* @param[in] desc_len Audio output description length
* @param[in] p_desc Pointer to Audio output description value
****************************************************************************************
*/
void arc_vocs_cfm_set_description(uint16_t cfm_status, uint8_t output_lid, uint8_t desc_len, uint8_t *p_desc);
/**
****************************************************************************************
* @brief Confirm or not value written for Audio Location characteristic
*
* @param[in] cfm_status Confirmation status
* @param[in] output_lid Output local index
* @param[in] location Audio location
****************************************************************************************
*/
void arc_vocs_cfm_set_location(uint16_t cfm_status, uint8_t output_lid, uint8_t location);
#endif //(GAF_ARC_VOCS)
/// @}
#endif // ARC_VOCS_H_
@@ -0,0 +1,236 @@
/**
****************************************************************************************
*
* @file arc_vocs_msg.h
*
* @brief Audio Rendering Control - Definition of Kernel Messages (Volume Offset Control Server)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ARC_VOCS_MSG_H_
#define ARC_VOCS_MSG_H_
/**
****************************************************************************************
* @addtogroup ARC_VOCS_MSG Audio Rendering Control - Definition of Kernel Messages (Volume Offset Control Server)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "arc_msg.h" // Audio Rendering Control Kernel Messages Definitions
#include "arc_vocs.h" // Audio Rendering Control - Volume Offset Control Server Definitions
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ARC_VOCS_ADD request message
typedef struct arc_vocs_add_req
{
/// Request code (@see enum arc_vocs_req_code)
/// - ARC_VOCS_ADD
uint16_t req_code;
/// Maximum length of Audio Output Description
uint8_t desc_max_len;
/// Service configuration bit field
uint8_t cfg_bf;
/// Number of attributes reserved for all Volume Offset Control Service instances inserted
/// in the database
uint16_t nb_att_rsvd;
} arc_vocs_add_req_t;
/// Structure for ARC_VOCS_ADD response message
typedef struct arc_vocs_add_rsp
{
/// Request code (@see enum arc_vocs_req_code)
uint16_t req_code;
/// Status
uint16_t status;
/// Allocated output local index
uint8_t output_lid;
} arc_vocs_add_rsp_t;
/// Structure for ARC_VOCS_RESTORE_BOND_DATA request message
typedef struct arc_vocs_restore_bond_data_req
{
/// Request code (@see enum arc_vocs_req_code)
/// - ARC_VOCS_RESTORE_BOND_DATA
uint16_t req_code;
/// Output local index
uint8_t output_lid;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint8_t cli_cfg_bf;
/// Event bit field
uint8_t evt_cfg_bf;
} arc_vocs_restore_bond_data_req_t;
/// Structure for ARC_VOCS_CONFIGURE request message
typedef struct arc_vocs_configure_req
{
/// Request code (@see enum arc_vocs_req_code)
/// - ARC_VOCS_CONFIGURE
uint16_t req_code;
/// Number of outputs
uint8_t nb_outputs;
/// Preferred MTU
/// Values from 0 to 63 are equivalent to 64
uint16_t pref_mtu;
} arc_vocs_configure_req_t;
/// Structure for ARC_VOCS_SET request message
typedef struct arc_vocs_set_req
{
/// Request code (@see enum arc_vocs_req_code)
/// - ARC_VOCS_SET
uint16_t req_code;
/// Output local index
uint8_t output_lid;
/// Set type
uint8_t set_type;
union
{
/// Value
uint32_t val;
/// Volume offset
int16_t offset;
/// Audio location
uint8_t location;
} u;
} arc_vocs_set_req_t;
/// Structure for ARC_VOCS_SET_DESCRIPTION request message
typedef struct arc_vocs_set_description_req
{
/// Request code (@see enum arc_vocs_req_code)
/// - ARC_VOCS_SET_DESCRPITION
uint16_t req_code;
/// Output local index
uint8_t output_lid;
/// Audio output description length
uint8_t desc_len;
/// Audio output description
uint8_t desc[__ARRAY_EMPTY];
} arc_vocs_set_description_req_t;
/// Structure for request message
typedef struct arc_vocs_rsp
{
/// Request code (@see enum arc_vocs_req_code)
uint16_t req_code;
/// Status
uint16_t status;
/// Output local index
uint8_t output_lid;
/// Union
union
{
/// Value
uint8_t value;
/// Connection local index
uint8_t con_lid;
/// Set type
uint8_t set_type;
} u;
} arc_vocs_rsp_t;
/// Structure for ARC_VOCS_OFFSET indication message
typedef struct arc_vocs_offset_ind
{
/// Indication code (@see enum arc_vocs_ind_code)
/// - ARC_VOCS_OFFSET
uint16_t ind_code;
/// Output local index
uint8_t output_lid;
/// Offset
int16_t offset;
} arc_vocs_offset_ind_t;
/// Structure for ARC_VOCS_BOND_DATA indication message
typedef struct arc_vocs_cfg_ind
{
/// Indication code (@see enum arc_vocs_ind_code)
/// - ARC_VOCS_BOND_DATA
uint16_t ind_code;
/// Output local index
uint8_t output_lid;
/// Connection local index
uint8_t con_lid;
/// Client configuration bit field
uint8_t cli_cfg_bf;
} arc_vocs_cfg_ind_t;
/// Structure for ARC_VOCS_SET_DESCRIPTION request indication message
typedef struct arc_vocs_set_description_req_ind
{
/// Request Indication code (@see enum arc_vocs_req_ind_code)
/// - ARC_VOCS_SET_DESCRPITION
uint16_t req_ind_code;
/// Output local index
uint8_t output_lid;
/// Connection local index
uint8_t con_lid;
/// Audio output description length
uint8_t desc_len;
/// Audio output description
uint8_t desc[__ARRAY_EMPTY];
} arc_vocs_set_description_req_ind_t;
/// Structure for ARC_VOCS_SET_DESCRIPTION confirmation message
typedef struct arc_vocs_set_description_cfm
{
/// Request Indication code (@see enum arc_vocs_req_ind_code)
/// - ARC_VOCS_SET_DESCRPITION
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Output local index
uint8_t output_lid;
/// Audio output description length
uint8_t desc_len;
/// Audio output description
uint8_t desc[__ARRAY_EMPTY];
} arc_vocs_set_description_cfm_t;
/// Structure for ARC_VOCS_SET_LOCATION request indication message
typedef struct arc_vocs_set_location_req_ind
{
/// Request Indication code (@see enum arc_vocs_req_ind_code)
/// - ARC_VOCS_SET_LOCATION
uint16_t req_ind_code;
/// Output local index
uint8_t output_lid;
/// Connection local index
uint8_t con_lid;
/// Audio location
uint8_t location;
} arc_vocs_set_location_req_ind_t;
/// Structure for ARC_VOCS_SET_LOCATION confirmation message
typedef struct arc_vocs_set_location_cfm
{
/// Request Indication code (@see enum arc_vocs_req_ind_code)
/// - ARC_VOCS_SET_LOCATION
uint16_t req_ind_code;
/// Status
uint16_t status;
/// Output local index
uint8_t output_lid;
/// Audio location
uint8_t location;
} arc_vocs_set_location_cfm_t;
/// @}
#endif // ARC_VOCS_MSG_H_
+60
View File
@@ -0,0 +1,60 @@
/**
****************************************************************************************
*
* @file atc.h
*
* @brief Audio Topology Control - Header file
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ATC_H_
#define ATC_H_
/**
****************************************************************************************
* @addtogroup ATC Audio Topology Control
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf_cfg.h" // GAF Configuration
/*
* MACROS
****************************************************************************************
*/
/*
* ENUMERATIONS
****************************************************************************************
*/
/// Module type values
enum atc_module_type
{
/// Common
ATC_MODULE_COMMON = 0,
/// Routing Active Audio Server
ATC_MODULE_RAAS = 1,
/// Routing Active Audio Client
ATC_MODULE_RAAC = 2,
/// Coordinated Set Identification Set Member
ATC_MODULE_CSISM = 3,
/// Coordinated Set Identification Set Coordinator
ATC_MODULE_CSISC = 4,
ATC_MODULE_MAX,
};
/// @}
#endif // ATC_H_
@@ -0,0 +1,94 @@
/**
****************************************************************************************
*
* @file atc_msg.h
*
* @brief Audio Topology Control - Definition of Kernel Messages
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ATC_MSG_H_
#define ATC_MSG_H_
/**
****************************************************************************************
* @addtogroup ATC Audio Topology Control - Definition of Kernel Messages
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "atc.h" // ATC Definitions
#if (GAF_ATC)
#include "gaf_msg.h" // Generic Audio Framework API Message Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_REQ request codes
enum atc_msg_req_codes
{
ATC_GET_FEATURES = GAF_CODE(ATC, COMMON, 0),
};
/// Features bit field meaning
enum atc_feat_bf
{
/// Routing Active Audio Service Server supported
ATC_FEAT_RAAS_SUPP_POS = 0,
ATC_FEAT_RAAS_SUPP_BIT = CO_BIT(ATC_FEAT_RAAS_SUPP_POS),
/// Routing Active Audio Service Server supported
ATC_FEAT_RAAC_SUPP_POS = 1,
ATC_FEAT_RAAC_SUPP_BIT = CO_BIT(ATC_FEAT_RAAC_SUPP_POS),
/// Coordinated Set Identification Set Member supported
ATC_FEAT_CSISM_SUPP_POS = 2,
ATC_FEAT_CSISM_SUPP_BIT = CO_BIT(ATC_FEAT_CSISM_SUPP_POS),
/// Coordinated Set Identification Set Coordinator supported
ATC_FEAT_CSISC_SUPP_POS = 3,
ATC_FEAT_CSISC_SUPP_BIT = CO_BIT(ATC_FEAT_CSISC_SUPP_POS),
};
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ATC_GET_FEATURES request message
typedef struct atc_get_features_req
{
/// Request code (@see enum atc_msg_req_codes)
uint16_t req_code;
} atc_get_features_req_t;
/// Structure for ATC_GET_FEATURES response message
typedef struct atc_get_features_rsp
{
/// Request code (@see enum atc_msg_req_codes)
uint16_t req_code;
/// Status
uint16_t status;
/// Features bit field
uint32_t feat_bf;
} atc_get_features_rsp_t;
#endif //(GAF_ATC)
/// @}
#endif // ATC_MSG_H_
@@ -0,0 +1,36 @@
/**
****************************************************************************************
*
* @file atc_csi.h
*
* @brief Audio Topology Control - Coordinated Set Identification - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ATC_CSI_H_
#define ATC_CSI_H_
/**
****************************************************************************************
* @addtogroup ATC_CSI Audio Topology Control - Coordinated Set Identification
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "atc.h" // Audio Topology Control Definitions
#if (GAF_ATC_CSISM || GAF_ATC_CSISC)
#include "csis.h" // Coordinated Set Identification Service Definitions
#endif //(GAF_ATC_CSISM || GAF_ATC_CSISC)
/// @}
#endif // ATC_CSI_H_
@@ -0,0 +1,115 @@
/**
****************************************************************************************
*
* @file atc_csisc.h
*
* @brief Audio Topology Control - Coordinated Set Identification Set Coordinator - Definitions
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ATC_CSISC_H_
#define ATC_CSISC_H_
/**
****************************************************************************************
* @addtogroup ATC_CSISC Audio Topology Control - Coordinated Set Identification Set Coordinator
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "gaf.h" // GAF Defines
#include "atc_csi.h" // Audio Topology Control - Coordinated Set Identification Definitions
#if (GAF_ATC_CSISC)
#include "csisc.h" // Coordinated Set Identification Set Coordinator Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/// List of GAF_CMD command codes for Coordinated Set Identification Set Coordinator
enum atc_csisc_cmd_codes
{
ATC_CSISC_RESOLVE = GAF_CODE(ATC, CSISC, 0),
ATC_CSISC_DISCOVER = GAF_CODE(ATC, CSISC, 1),
ATC_CSISC_LOCK = GAF_CODE(ATC, CSISC, 2),
ATC_CSISC_GET = GAF_CODE(ATC, CSISC, 3),
ATC_CSISC_GET_CFG = GAF_CODE(ATC, CSISC, 4),
ATC_CSISC_SET_CFG = GAF_CODE(ATC, CSISC, 5),
};
/// List of GAF_REQ request codes for Coordinated Set Identification Set Coordinator
enum atc_csisc_msg_req_codes
{
ATC_CSISC_CONFIGURE = GAF_CODE(ATC, CSISC, 0),
ATC_CSISC_RESTORE_BOND_DATA = GAF_CODE(ATC, CSISC, 1),
ATC_CSISC_ADD_SIRK = GAF_CODE(ATC, CSISC, 2),
ATC_CSISC_REMOVE_SIRK = GAF_CODE(ATC, CSISC, 3),
};
/// List of GAF_IND indication codes for Coordinated Set Identification Set Coordinator
enum atc_csisc_msg_ind_codes
{
ATC_CSISC_BOND_DATA = GAF_CODE(ATC, CSISC, 0),
ATC_CSISC_SIRK = GAF_CODE(ATC, CSISC, 1),
ATC_CSISC_INFO = GAF_CODE(ATC, CSISC, 2),
ATC_CSISC_CFG = GAF_CODE(ATC, CSISC, 3),
ATC_CSISC_SVC_CHANGED = GAF_CODE(ATC, CSISC, 4),
};
/*
* CALLBACK SET DEFINITION
****************************************************************************************
*/
/// Set of callback functions for Coordinated Set Identification Set Coordinator
typedef csisc_cb_t atc_csisc_cb_t;
/*
* API FUNCTIONS DECLARATION
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Create and configure Coordinated Set Identification Set Coordinator module
*
* @param[in] nb_sirk Number of SIRK value that can be stored
* @param[in] p_cb Pointer to set of callback functions for communications with
* upper layers
*
* @return An error status
****************************************************************************************
*/
uint16_t atc_csisc_configure(uint8_t nb_sirk, const atc_csisc_cb_t* p_cb);
/// Wrapper for functions defined in csisc.h
#define atc_csisc_resolve(p_psri) (csisc_resolve(p_psri))
#define atc_csisc_discover(con_lid, nb_sets_max, shdl, ehdl) \
(csisc_discover(con_lid, nb_sets_max, shdl, ehdl))
#define atc_csisc_restore_bond_data(con_lid, nb_sets, p_csis_info) \
(csisc_restore_bond_data(con_lid, nb_sets, p_csis_info))
#define atc_csisc_lock(con_lid, set_lid, lock) (csisc_lock(con_lid, set_lid, lock))
#define atc_csisc_get(con_lid, set_lid, char_type) (csisc_get(con_lid, set_lid, char_type))
#define atc_csisc_get_cfg(con_lid, set_lid, char_type) \
(csisc_get_cfg(con_lid, set_lid, char_type))
#define atc_csisc_set_cfg(con_lid, set_lid, char_type, enable) \
(csisc_set_cfg(con_lid, set_lid, char_type, enable))
#define atc_csisc_add_sirk(p_sirk, p_key_lid) (csisc_add_sirk(p_sirk, p_key_lid))
#define atc_csisc_remove_sirk(key_lid) (csisc_remove_sirk(key_lid))
#endif //(GAF_ATC_CSISC)
/// @}
#endif // ATC_CSISC_H_
@@ -0,0 +1,102 @@
/**
****************************************************************************************
*
* @file atc_csisc_msg.h
*
* @brief Audio Topology Control - Definition of Kernel Messages (Coordinated Set
* Identification Set Coordinator)
*
* Copyright (C) RivieraWaves 2019-2020
*
****************************************************************************************
*/
#ifndef ATC_CSISC_MSG_H_
#define ATC_CSISC_MSG_H_
/**
****************************************************************************************
* @addtogroup ATC_CSISC_MSG Audio Topology Control - Definition of Kernel Messages
* (Coordinated Set Identification Set Coordinator)
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "atc_msg.h" // Audio Topology Control Kernel Messages Definitions
#include "csisc_msg.h" // Coordinated Set Identification Set Coordinator - Message API Definitions
/*
* ENUMERATIONS
****************************************************************************************
*/
/*
* API MESSAGES
****************************************************************************************
*/
/// Structure for ATC_CSISC_RESOLVE command message
typedef csisc_resolve_cmd_t atc_csisc_resolve_cmd_t;
/// Structure for ATC_CSISC_DISCOVER command message
typedef csisc_discover_cmd_t atc_csisc_discover_cmd_t;
/// Structure for ATC_CSISC_LOCK command message
typedef csisc_lock_cmd_t atc_csisc_lock_cmd_t;
/// Structure for ATC_CSISC_GET command message
typedef csisc_get_cmd_t atc_csisc_get_cmd_t;
/// Structure for ATC_CSISC_GET_CFG command message
typedef csisc_get_cfg_cmd_t atc_csisc_get_cfg_cmd_t;
/// Structure for ATC_CSISC_SET_CFG command message
typedef csisc_set_cfg_cmd_t atc_csisc_set_cfg_cmd_t;
/// Structure command complete event
typedef csisc_cmp_evt_t atc_csisc_cmp_evt_t;
/// Structure for ATC_CSISC_CONFIGURE request message
typedef struct atc_csisc_configure_req
{
/// Request code
uint16_t req_code;
/// Number of SIRK values that can be stored
uint8_t nb_sirk;
} atc_csisc_configure_req_t;
/// Structure for ATC_CSISC_RESTORE_BOND_DATA request message
typedef csisc_restore_bond_data_req_t atc_csisc_restore_bond_data_req_t;
/// Structure for CSISC_ADD_SIRK request message
typedef csisc_add_sirk_req_t atc_csisc_add_sirk_req_t;
/// Structure for CSISC_REMOVE_SIRK request message
typedef csisc_remove_sirk_req_t atc_csisc_remove_sirk_req_t;
/// Structure for response message
typedef csisc_rsp_t atc_csisc_rsp_t;
/// Structure for ATC_CSISC_BOND_DATA indication message
typedef csisc_bond_data_ind_t atc_csisc_bond_data_ind_t;
/// Structure for ATC_CSISC_SIRK indication message
typedef csisc_sirk_ind_t atc_csisc_sirk_ind_t;
/// Structure for ATC_CSISC_INFO indication message
typedef csisc_info_ind_t atc_csisc_info_ind_t;
/// Structure for ATC_CSISC_CFG indication message
typedef csisc_cfg_ind_t atc_csisc_cfg_ind_t;
/// Structure for ATC_CSISC_SVC_CHANGED indication message
typedef csisc_svc_changed_ind_t atc_csisc_svc_changed_ind_t;
/// @}
#endif // ATC_CSISC_MSG_H_

Some files were not shown because too many files have changed in this diff Show More