rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

View file

View file

@ -0,0 +1,67 @@
#ifndef DATA_TYPES_H
#define DATA_TYPES_H
#ifndef NULL
#define NULL 0
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned long UINT32;
typedef unsigned long long int UINT64;
typedef signed long INT32;
typedef signed char INT8;
typedef signed short INT16;
typedef unsigned char BOOLEAN;
typedef UINT32 UINTPTR;
typedef UINT32 TIME_STAMP;
#ifndef TRUE
#define TRUE (!FALSE)
#endif
typedef unsigned char UBYTE;
#ifdef __arm
#define PACKED __packed
#define INLINE __inline
#else
#define PACKED
#define INLINE
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN FALSE
#endif
#define UINT16_LOW_BYTE(x) ((x) & 0xff)
#define UINT16_HI_BYTE(x) ((x) >> 8)
/* MACRO definitions for safe string functions */
/* Replace standard string functions with safe functions if available */
#define BCM_STRCAT_S(x1,x2,x3) strcat((x1),(x3))
#define BCM_STRNCAT_S(x1,x2,x3,x4) strncat((x1),(x3),(x4))
#define BCM_STRCPY_S(x1,x2,x3) strcpy((x1),(x3))
#define BCM_STRNCPY_S(x1,x2,x3,x4) strncpy((x1),(x3),(x4))
#define BCM_SPRINTF_S(x1,x2,x3,x4) sprintf((x1),(x3),(x4))
#define BCM_VSPRINTF_S(x1,x2,x3,x4) vsprintf((x1),(x3),(x4))
#define BT_MEMCPY(a,b,c) memcpy( (a), (b), (c) )
#define BT_MEMSET(a,b,c) memset( (a), (b), (c) )
#define BT_STRLEN(a) strlen( (a) )
#define BT_MEMCMP(a,b,c) memcmp( (a), (b), (c) )
#define BT_MEMCMP_OK 0 // memcmp success
/* Timer list entry callback type
*/
typedef void (TIMER_CBACK)(void *p_tle);
#ifndef TIMER_PARAM_TYPE
#define TIMER_PARAM_TYPE UINT32
#endif
#endif

View file

@ -0,0 +1,521 @@
/****************************************************************************
**
** Name gki.h
**
** Function This file contains GKI public definitions
**
*****************************************************************************/
#ifndef GKI_H
#define GKI_H
/* Include target-specific build configuration header */
#ifdef BUILDCFG
#if ((defined(NFC_HAL_TARGET) && (NFC_HAL_TARGET == TRUE)) && !defined(NFC_HAL_SHARED_GKI))
/* Building NFC HAL w/ non-shared GKI resources */
#include "buildcfg_hal.h"
#else
/* Default build configuration file */
#include "buildcfg.h"
#endif
#endif /* BUILDCFG */
/* Include target-specific GKI configuration */
#if ((defined(NFC_STANDALONE) && (NFC_STANDALONE == TRUE)) || defined(NFC_HAL_SHARED_GKI))
/* Building NFC stack, or NFC HAL w/ shared GKI resources (use shared NFC/HAL target files) */
#include "gki_target.h"
#include "nfc_target.h"
#include "nfc_types.h"
#elif (defined(NFC_HAL_TARGET) && (NFC_HAL_TARGET == TRUE))
/* Building NFC HAL w/ non-shared GKI resources (use HAL-specific target file) */
#include "gki_hal_target.h"
#include "nfc_types.h"
#else
/* Default: building all other targets */
#include "bt_target.h"
#include "bt_types.h"
#endif
/* Error codes */
#define GKI_SUCCESS 0x00
#define GKI_FAILURE 0x01
#define GKI_INVALID_TASK 0xF0
#define GKI_INVALID_POOL 0xFF
/************************************************************************
** Mailbox definitions. Each task has 4 mailboxes that are used to
** send buffers to the task.
*/
#define TASK_MBOX_0 0
#define TASK_MBOX_1 1
#define TASK_MBOX_2 2
#define TASK_MBOX_3 3
#ifndef NUM_TASK_MBOX
#define NUM_TASK_MBOX 4
#endif
/************************************************************************
** Event definitions.
**
** There are 4 reserved events used to signal messages rcvd in task mailboxes.
** There are 4 reserved events used to signal timeout events.
** There are 8 general purpose events available for applications.
*/
#define MAX_EVENTS 16
#define TASK_MBOX_0_EVT_MASK 0x0001
#define TASK_MBOX_1_EVT_MASK 0x0002
#define TASK_MBOX_2_EVT_MASK 0x0004
#define TASK_MBOX_3_EVT_MASK 0x0008
#define TIMER_0 0
#define TIMER_1 1
#define TIMER_2 2
#define TIMER_3 3
#define TIMER_0_EVT_MASK 0x0010
#define TIMER_1_EVT_MASK 0x0020
#define TIMER_2_EVT_MASK 0x0040
#define TIMER_3_EVT_MASK 0x0080
#define APPL_EVT_0 8
#define APPL_EVT_1 9
#define APPL_EVT_2 10
#define APPL_EVT_3 11
#define APPL_EVT_4 12
#define APPL_EVT_5 13
#define APPL_EVT_6 14
#define APPL_EVT_7 15
#define EVENT_MASK(evt) ((UINT16)(0x0001 << (evt)))
/************************************************************************
** Max Time Queue
**/
#ifndef GKI_MAX_TIMER_QUEUES
#define GKI_MAX_TIMER_QUEUES 3
#endif
/************************************************************************
** Macro to determine the pool buffer size based on the GKI POOL ID at compile time.
** Pool IDs index from 0 to GKI_NUM_FIXED_BUF_POOLS - 1
*/
#if (defined(GKI_DYNAMIC_POOL_CFG) && (GKI_DYNAMIC_POOL_CFG == TRUE))
#define GKI_POOL_ID_0 0
#define GKI_POOL_ID_1 1
#define GKI_POOL_ID_2 2
#define GKI_POOL_ID_3 3
#define GKI_POOL_ID_4 4
#define GKI_POOL_ID_5 5
#define GKI_POOL_ID_6 6
#define GKI_POOL_ID_7 7
#define GKI_POOL_ID_8 8
#define GKI_POOL_ID_9 9
#define GKI_POOL_ID_10 10
#define GKI_POOL_ID_11 11
#define GKI_POOL_ID_12 12
#define GKI_POOL_ID_13 13
#define GKI_POOL_ID_14 14
#define GKI_POOL_ID_15 15
#else /* GKI_DYNAMIC_POOL_CFG */
#if (GKI_NUM_FIXED_BUF_POOLS < 1)
#ifndef GKI_POOL_ID_0
#define GKI_POOL_ID_0 0
#endif /* ifndef GKI_POOL_ID_0 */
#ifndef GKI_BUF0_SIZE
#define GKI_BUF0_SIZE 0
#endif /* ifndef GKI_BUF0_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 1 */
#if (GKI_NUM_FIXED_BUF_POOLS < 2)
#ifndef GKI_POOL_ID_1
#define GKI_POOL_ID_1 0
#endif /* ifndef GKI_POOL_ID_1 */
#ifndef GKI_BUF1_SIZE
#define GKI_BUF1_SIZE 0
#endif /* ifndef GKI_BUF1_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 2 */
#if (GKI_NUM_FIXED_BUF_POOLS < 3)
#ifndef GKI_POOL_ID_2
#define GKI_POOL_ID_2 0
#endif /* ifndef GKI_POOL_ID_2 */
#ifndef GKI_BUF2_SIZE
#define GKI_BUF2_SIZE 0
#endif /* ifndef GKI_BUF2_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 3 */
#if (GKI_NUM_FIXED_BUF_POOLS < 4)
#ifndef GKI_POOL_ID_3
#define GKI_POOL_ID_3 0
#endif /* ifndef GKI_POOL_ID_4 */
#ifndef GKI_BUF3_SIZE
#define GKI_BUF3_SIZE 0
#endif /* ifndef GKI_BUF3_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 4 */
#if (GKI_NUM_FIXED_BUF_POOLS < 5)
#ifndef GKI_POOL_ID_4
#define GKI_POOL_ID_4 0
#endif /* ifndef GKI_POOL_ID_4 */
#ifndef GKI_BUF4_SIZE
#define GKI_BUF4_SIZE 0
#endif /* ifndef GKI_BUF4_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 5 */
#if (GKI_NUM_FIXED_BUF_POOLS < 6)
#ifndef GKI_POOL_ID_5
#define GKI_POOL_ID_5 0
#endif /* ifndef GKI_POOL_ID_5 */
#ifndef GKI_BUF5_SIZE
#define GKI_BUF5_SIZE 0
#endif /* ifndef GKI_BUF5_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 6 */
#if (GKI_NUM_FIXED_BUF_POOLS < 7)
#ifndef GKI_POOL_ID_6
#define GKI_POOL_ID_6 0
#endif /* ifndef GKI_POOL_ID_6 */
#ifndef GKI_BUF6_SIZE
#define GKI_BUF6_SIZE 0
#endif /* ifndef GKI_BUF6_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 7 */
#if (GKI_NUM_FIXED_BUF_POOLS < 8)
#ifndef GKI_POOL_ID_7
#define GKI_POOL_ID_7 0
#endif /* ifndef GKI_POOL_ID_7 */
#ifndef GKI_BUF7_SIZE
#define GKI_BUF7_SIZE 0
#endif /* ifndef GKI_BUF7_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 8 */
#if (GKI_NUM_FIXED_BUF_POOLS < 9)
#ifndef GKI_POOL_ID_8
#define GKI_POOL_ID_8 0
#endif /* ifndef GKI_POOL_ID_8 */
#ifndef GKI_BUF8_SIZE
#define GKI_BUF8_SIZE 0
#endif /* ifndef GKI_BUF8_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 9 */
#if (GKI_NUM_FIXED_BUF_POOLS < 10)
#ifndef GKI_POOL_ID_9
#define GKI_POOL_ID_9 0
#endif /* ifndef GKI_POOL_ID_9 */
#ifndef GKI_BUF9_SIZE
#define GKI_BUF9_SIZE 0
#endif /* ifndef GKI_BUF9_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 10 */
#if (GKI_NUM_FIXED_BUF_POOLS < 11)
#ifndef GKI_POOL_ID_10
#define GKI_POOL_ID_10 0
#endif /* ifndef GKI_POOL_ID_10 */
#ifndef GKI_BUF10_SIZE
#define GKI_BUF10_SIZE 0
#endif /* ifndef GKI_BUF10_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 11 */
#if (GKI_NUM_FIXED_BUF_POOLS < 12)
#ifndef GKI_POOL_ID_11
#define GKI_POOL_ID_11 0
#endif /* ifndef GKI_POOL_ID_11 */
#ifndef GKI_BUF11_SIZE
#define GKI_BUF11_SIZE 0
#endif /* ifndef GKI_BUF11_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 12 */
#if (GKI_NUM_FIXED_BUF_POOLS < 13)
#ifndef GKI_POOL_ID_12
#define GKI_POOL_ID_12 0
#endif /* ifndef GKI_POOL_ID_12 */
#ifndef GKI_BUF12_SIZE
#define GKI_BUF12_SIZE 0
#endif /* ifndef GKI_BUF12_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 13 */
#if (GKI_NUM_FIXED_BUF_POOLS < 14)
#ifndef GKI_POOL_ID_13
#define GKI_POOL_ID_13 0
#endif /* ifndef GKI_POOL_ID_13 */
#ifndef GKI_BUF13_SIZE
#define GKI_BUF13_SIZE 0
#endif /* ifndef GKI_BUF13_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 14 */
#if (GKI_NUM_FIXED_BUF_POOLS < 15)
#ifndef GKI_POOL_ID_14
#define GKI_POOL_ID_14 0
#endif /* ifndef GKI_POOL_ID_14 */
#ifndef GKI_BUF14_SIZE
#define GKI_BUF14_SIZE 0
#endif /* ifndef GKI_BUF14_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 15 */
#if (GKI_NUM_FIXED_BUF_POOLS < 16)
#ifndef GKI_POOL_ID_15
#define GKI_POOL_ID_15 0
#endif /* ifndef GKI_POOL_ID_15 */
#ifndef GKI_BUF15_SIZE
#define GKI_BUF15_SIZE 0
#endif /* ifndef GKI_BUF15_SIZE */
#endif /* GKI_NUM_FIXED_BUF_POOLS < 16 */
#endif /*GKI_DYNAMIC_POOL_CFG */
/* Timer list entry callback type
*/
//typedef void (TIMER_CBACK)(void *p_tle);
/* Define a timer list entry
*/
typedef struct _tle {
struct _tle *p_next;
struct _tle *p_prev;
TIMER_CBACK *p_cback;
INT32 ticks;
TIMER_PARAM_TYPE param;
UINT16 event;
UINT8 in_use;
} TIMER_LIST_ENT;
/* Define a timer list queue
*/
typedef struct {
TIMER_LIST_ENT *p_first;
TIMER_LIST_ENT *p_last;
INT32 last_ticks;
} TIMER_LIST_Q;
/***********************************************************************
** This queue is a general purpose buffer queue, for application use.
*/
typedef struct {
void *p_first;
void *p_last;
UINT16 count;
} BUFFER_Q;
#define GKI_IS_QUEUE_EMPTY(p_q) ((p_q)->count == 0)
/* Task constants
*/
#ifndef TASKPTR
typedef void (*TASKPTR)(UINT32);
#endif
#define GKI_PUBLIC_POOL 0 /* General pool accessible to GKI_getbuf() */
#define GKI_RESTRICTED_POOL 1 /* Inaccessible pool to GKI_getbuf() */
/***********************************************************************
** Mutex defintions
*/
typedef struct {
void *p_platform_mutex;
} GKI_MUTEX;
/***********************************************************************
** Function prototypes
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Task management
*/
GKI_API extern UINT8 GKI_create_task (TASKPTR, UINT8, INT8 *, UINT16 *, UINT16);
GKI_API extern void GKI_exit_task(UINT8);
GKI_API extern UINT8 GKI_get_taskid(void);
GKI_API extern void GKI_init(void);
GKI_API extern INT8 *GKI_map_taskname(UINT8);
GKI_API extern UINT8 GKI_resume_task(UINT8);
GKI_API extern void GKI_run(void *);
GKI_API extern void GKI_stop(void);
GKI_API extern UINT8 GKI_suspend_task(UINT8);
GKI_API extern UINT8 GKI_is_task_running(UINT8);
/* memory management
*/
GKI_API extern void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount);
GKI_API extern void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len);
/* To send buffers and events between tasks
*/
GKI_API extern UINT8 GKI_isend_event (UINT8, UINT16);
GKI_API extern void GKI_isend_msg (UINT8, UINT8, void *);
GKI_API extern void *GKI_read_mbox (UINT8);
GKI_API extern void GKI_send_msg (UINT8, UINT8, void *);
GKI_API extern UINT8 GKI_send_event (UINT8, UINT16);
/* To get and release buffers, change owner and get size
*/
GKI_API extern void GKI_change_buf_owner (void *, UINT8);
GKI_API extern UINT8 GKI_create_pool (UINT16, UINT16, UINT8, void *);
GKI_API extern void GKI_delete_pool (UINT8);
GKI_API extern void *GKI_find_buf_start (void *);
GKI_API extern void GKI_freebuf (void *);
GKI_API extern void *GKI_getbuf (UINT16);
GKI_API extern UINT16 GKI_get_buf_size (void *);
GKI_API extern void *GKI_getpoolbuf (UINT8);
GKI_API extern UINT16 GKI_poolcount (UINT8);
GKI_API extern UINT16 GKI_poolfreecount (UINT8);
GKI_API extern UINT16 GKI_poolutilization (UINT8);
GKI_API extern void GKI_register_mempool (void *p_mem);
GKI_API extern UINT8 GKI_set_pool_permission(UINT8, UINT8);
/* User buffer queue management
*/
GKI_API extern void *GKI_dequeue (BUFFER_Q *);
GKI_API extern void GKI_enqueue (BUFFER_Q *, void *);
GKI_API extern void GKI_enqueue_head (BUFFER_Q *, void *);
GKI_API extern void *GKI_getfirst (BUFFER_Q *);
GKI_API extern void *GKI_getlast (BUFFER_Q *);
GKI_API extern void *GKI_getnext (void *);
GKI_API extern void GKI_init_q (BUFFER_Q *);
GKI_API extern BOOLEAN GKI_queue_is_empty(BUFFER_Q *);
GKI_API extern void *GKI_remove_from_queue (BUFFER_Q *, void *);
GKI_API extern UINT16 GKI_get_pool_bufsize (UINT8);
/* Timer management
*/
GKI_API extern void GKI_add_to_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT *);
GKI_API extern void GKI_delay(UINT32);
GKI_API extern UINT32 GKI_get_tick_count(void);
GKI_API extern INT8 *GKI_get_time_stamp(INT8 *);
GKI_API extern void GKI_init_timer_list (TIMER_LIST_Q *);
GKI_API extern void GKI_init_timer_list_entry (TIMER_LIST_ENT *);
GKI_API extern INT32 GKI_ready_to_sleep (void);
GKI_API extern void GKI_remove_from_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT *);
GKI_API extern void GKI_start_timer(UINT8, INT32, BOOLEAN);
GKI_API extern void GKI_stop_timer (UINT8);
GKI_API extern void GKI_timer_update(INT32);
GKI_API extern UINT16 GKI_update_timer_list (TIMER_LIST_Q *, INT32);
GKI_API extern UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *, TIMER_LIST_ENT *);
GKI_API extern UINT16 GKI_wait(UINT16, UINT32);
/* Start and Stop system time tick callback
* true for start system tick if time queue is not empty
* false to stop system tick if time queue is empty
*/
typedef void (SYSTEM_TICK_CBACK)(BOOLEAN);
/* Time queue management for system ticks
*/
GKI_API extern BOOLEAN GKI_timer_queue_empty (void);
GKI_API extern void GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK *);
/* Disable Interrupts, Enable Interrupts
*/
GKI_API extern void GKI_enable(void);
GKI_API extern void GKI_disable(void);
GKI_API extern void GKI_sched_lock(void);
GKI_API extern void GKI_sched_unlock(void);
/* Allocate (Free) memory from an OS
*/
GKI_API extern void *GKI_os_malloc (UINT32);
GKI_API extern void GKI_os_free (void *);
/* os timer operation */
GKI_API extern UINT32 GKI_get_os_tick_count(void);
/* Exception handling
*/
GKI_API extern void GKI_exception (UINT16, char *);
#if GKI_DEBUG == TRUE
GKI_API extern void GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used);
GKI_API extern void GKI_PrintBuffer(void);
GKI_API extern void GKI_print_task(void);
#else
#undef GKI_PrintBufferUsage
#define GKI_PrintBuffer() NULL
#endif
/* Mutex APIs
*/
GKI_API extern BOOLEAN GKI_mutex_create(GKI_MUTEX *p_mutex);
GKI_API extern void GKI_mutex_delete(GKI_MUTEX *p_mutex);
GKI_API extern BOOLEAN GKI_mutex_lock(GKI_MUTEX *p_mutex);
GKI_API extern BOOLEAN GKI_mutex_unlock(GKI_MUTEX *p_mutex);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,364 @@
/*******************************************************************************
** Name: ucodec.h
**
** Description:
**
** This file contains codec definitions from Widcomm's Universal Embedded
** Drivers API.
**
*******************************************************************************/
#ifndef UCODEC_H
#define UCODEC_H
#include "bt_target.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
** Codec APIs
*******************************************************************************/
/**** Codec IDs ****/
#define UCODEC_ID_1 0
#define UCODEC_ID_2 1
#define UCODEC_ID_3 2
#define UCODEC_ID_4 3
#define UCODEC_NUMBER 4
typedef UINT8 tUCODEC_ID;
/**** Status ****/
#define UCODEC_SUCCESS 0x00
#define UCODEC_TX_DONE 0x01
#define UCODEC_RX_READY 0x02
#define UCODEC_FLOW_CTRL_ON 0x03
#define UCODEC_FLOW_CTRL_OFF 0x04
#define UCODEC_OVERFLOW 0x05
#define UCODEC_UNSUPORTED_CNF 0x06
#define UCODEC_WRONG_PARAM 0x07
#define UCODEC_NOT_CONFIGURED 0x08
#define UCODEC_OUT_OF_MEMORY 0x09
#define UCODEC_GENERIC_ERROR 0x0a
#define UCODEC_RECOVERABLE_ERROR 0x0b
#define UCODEC_UNRECOVERABLE_ERROR 0x0c
#define UCODEC_LOW_LEVEL_DRIVER_ERROR (0x0d)
typedef UINT8 tUCODEC_STATUS;
/**** Media type ****/
#define UCODEC_MEDIA_TYPE_AUDIO 0
#define UCODEC_MEDIA_TYPE_VIDEO 1
#define UCODEC_MEDIA_TYPE_MULTI 2
typedef UINT8 tUCODEC_MEDIA_TYPE;
/**** Audio Codec type ****/
#define UCODEC_AUDIO_SBC 0
#define UCODEC_AUDIO_M12_LAYER1 1 /* layer1 (mp1) */
#define UCODEC_AUDIO_M12_LAYER2 2 /* layer2 (mp2) */
#define UCODEC_AUDIO_M12_LAYER3 3 /* layer3 (mp3) */
#define UCODEC_AUDIO_M24_2LC 4 /* MPEG-2 AAC LC */
#define UCODEC_AUDIO_M24_4LC 5 /* MPEG-4 AAC LC */
#define UCODEC_AUDIO_M24_4LTP 6 /* MPEG-4 AAC LTP */
#define UCODEC_AUDIO_M24_4S 7 /* MPEG-4 AAC scalable */
#define UCODEC_AUDIO_VOLUME 8 /* Volume settings */
#define UCODEC_AUDIO_BALANCE 9 /* Balance settings */
typedef UINT8 tUCODEC_AUDIO_FEAT_TYPE;
/**** Video Codec type -> TODO ****/
/*TBD*/
typedef UINT8 tUCODEC_VIDEO_FEAT_TYPE;
/**** SBC sample frequency ****/
#define UCODEC_SBC_SMP_FREQ_16 0 /* 16 */
#define UCODEC_SBC_SMP_FREQ_32 1 /* 23 */
#define UCODEC_SBC_SMP_FREQ_44 2 /* 44.1 */
#define UCODEC_SBC_SMP_FREQ_48 3 /* 48 */
typedef UINT8 tUCODEC_SBC_SMP_FREQ;
/**** SBC sample frequency ****/
#define UCODEC_SBC_SUBBAND_4 4
#define UCODEC_SBC_SUBBAND_8 8
typedef UINT8 tUCODEC_SBC_SUBBAND;
/**** Allocation method ****/
#define UCODEC_SBC_ALLOC_MD_S 0 /* SNR */
#define UCODEC_SBC_ALLOC_MD_L 1 /* loundess */
typedef UINT8 tUCODEC_SBC_ALLOC_MD;
/**** MPEG sample frequency ****/
#define UCODEC_M12_SMP_FREQ_16 0 /* 16 */
#define UCODEC_M12_SMP_FREQ_22 1 /* 22 */
#define UCODEC_M12_SMP_FREQ_24 2 /* 24 */
#define UCODEC_M12_SMP_FREQ_32 3 /* 32 */
#define UCODEC_M12_SMP_FREQ_44 4 /* 44 */
#define UCODEC_M12_SMP_FREQ_48 5 /* 48 */
typedef UINT8 tUCODEC_M12_SMP_FREQ;
/**** Channel mode ****/
#define UCODEC_CHN_MONO 0
#define UCODEC_CHN_DUAL 1
#define UCODEC_CHN_STEREO 2
#define UCODEC_CHN_JOINT_STEREO 3
typedef UINT8 tUCODEC_CH_MODE;
/**** Audio Codec type ****/
#define UCODEC_M24_SMP_FREQ_8 0 /* 8 */
#define UCODEC_M24_SMP_FREQ_11 1 /* 11 */
#define UCODEC_M24_SMP_FREQ_12 2 /* 12 */
#define UCODEC_M24_SMP_FREQ_16 3 /* 16 */
#define UCODEC_M24_SMP_FREQ_22 4 /* 22.05 */
#define UCODEC_M24_SMP_FREQ_24 5 /* 24 */
#define UCODEC_M24_SMP_FREQ_32 6 /* 32 */
#define UCODEC_M24_SMP_FREQ_44 7 /* 44.1 */
#define UCODEC_M24_SMP_FREQ_48 8 /* 48 */
#define UCODEC_M24_SMP_FREQ_64 9 /* 64 */
#define UCODEC_M24_SMP_FREQ_88 10 /* 88 */
#define UCODEC_M24_SMP_FREQ_96 11 /* 96 */
typedef UINT8 tUCODEC_M24_SMP_FREQ;
/**** Codec configuration structure ****/
typedef struct tUCODEC_CNF_SBC_TAG {
tUCODEC_SBC_SMP_FREQ SampleFreq;
tUCODEC_CH_MODE ChannelMode;
UINT16 Offset; /* GKI buffer based offset for UCODEC_ReadBuf */
UINT16 MtuSize; /* Max buffer len for UCODEC_ReadBuf*/
UINT8 PoolId; /* GKI pool ID for UCODEC_ReadBuf */
UINT8
NumBlock; /* Number of block in block unit : 4 blocks 8 blocks 12 blocks 16 blocks are the possible value */
UINT8 Subband;
tUCODEC_SBC_ALLOC_MD AllocMthd;
UINT8 MinBitPool;
UINT8 MaxBitPool;
} tUCODEC_CNF_SBC;
typedef struct tUCODEC_CNF_M12_TAG {
tUCODEC_CH_MODE ChannelMode; /* Mono, Dual, stereo, joint stereo */
tUCODEC_M12_SMP_FREQ SampleFreq; /* Sample freq: 16, 22, 24, 32, 44, 48 */
UINT16 BitRate; /* Bit rate in bit per sec */
UINT16 Offset; /* GKI buffer based offset for UCODEC_ReadBuf */
UINT16 MtuSize; /* Max buffer len for UCODEC_ReadBuf*/
UINT8 PoolId; /* GKI pool ID for UCODEC_ReadBuf */
BOOLEAN VBR; /* Variable Bit Rate */
BOOLEAN CRC_On; /* CRC error detection */
BOOLEAN MPF; /* Media payload format */
} tUCODEC_CNF_M12;
typedef struct tUCODEC_CNF_M24_TAG {
tUCODEC_M24_SMP_FREQ SampleFreq; /* Sample freq: 8, 11, 12, 16, 22.05, 24, 32, 44.1, 48, 64, 88, 96 */
UINT32 BitRate; /* Bit rate */
UINT16 Offset; /* GKI buffer based offset for UCODEC_ReadBuf */
UINT16 MtuSize; /* Max buffer len for UCODEC_ReadBuf*/
UINT8 PoolId; /* GKI pool ID for UCODEC_ReadBuf */
UINT8 Chanels; /* 1 or 2 chanels */
} tUCODEC_CNF_M24;
typedef union tUCODEC_CODEC_TYPE_TAG {
tUCODEC_AUDIO_FEAT_TYPE AudioType;
tUCODEC_VIDEO_FEAT_TYPE VideoType;
} tUCODEC_CODEC_TYPE;
typedef union tUCODEC_FEATURE_TAG {
/* Add here the audio feature structure */
tUCODEC_CNF_SBC SBCConfig;
tUCODEC_CNF_M12 M12Config;
tUCODEC_CNF_M24 M24Config;
UINT8 Volume; /* 0 to mute. 0xFF for the max volume */
UINT8 Balance; /* 0->100% right, 255->100% left */
/* Add here the video feature structure */
/* TBD */
} tUCODEC_FEATURE;
typedef struct tUCODEC_CNF_TAG {
tUCODEC_MEDIA_TYPE MediaType;
tUCODEC_CODEC_TYPE Type;
tUCODEC_FEATURE Feature;
} tUCODEC_CNF;
typedef struct tUCODEC_BUF_INFO_TAG {
UINT8 NumOfFrames;
UINT32 TimesStamp;
} tUCODEC_BUF_INFO;
/******************************************************************************
**
** Function tUCODEC_CBACK_PTR
**
** Description This call back report CODEC indication.
** It report codec error as well as flow onfrol indication.
**
** Input : CodecId: Id of the codec that calls this call back.
** Status: ->UCODEC_FLOW_CTRL_OFF if the Tx Q just
** went below the low watermark
** ->UCODEC_RX_READY if data are ready to be
** read. This olny hapens when the Rx Q was
** empty before receiving data.
** ->UCODEC_INTERNAL_ERROR if something went
** wrong with the driver
**
** Output Parameters : None
**
** Returns None.
**
******************************************************************************/
typedef void (* tUCODEC_CBACK_PTR)(tUCODEC_ID, tUCODEC_STATUS);
/*******************************************************************************
** Function Prototypes
*******************************************************************************/
/******************************************************************************
**
** Function UCODEC_Init
**
** Description Startup initialisation function. This function is called
** before any orther function of UCODEC it initialize UCODEC
** internal structure an the external codec.
**
** Input : CodecId: Id of the codec to perform the operation on.
**
** Output Parameters : None
**
** Returns UCODEC_SUCCESS if The action was performed with sucess.
** Error code else.
**
******************************************************************************/
BT_API extern tUCODEC_STATUS UCODEC_Init (void *);
/******************************************************************************
**
** Function UCODEC_Configure
**
** Description Initialise the CODEC for a particular stream.
**
**
** Input : CodecId: Id of the codec to perform the operation on.
** CbackPrt: Call back pointer for codec feedback.
** pConfig: Pointer on a codec configuration structure.
**
** Output Parameters : None
**
** Returns UCODEC_SUCCESS if The action was performed with sucess.
**
******************************************************************************/
BT_API extern tUCODEC_STATUS UCODEC_Configure (tUCODEC_ID, tUCODEC_CBACK_PTR, tUCODEC_CNF *);
/******************************************************************************
**
** Function UCODEC_FlushTx
**
** Description Fluch Tx buffer Q.
**
** Input : CodecId: Id of the codec to perform the operation on.
**
** Output Parameters : None
**
** Returns UCODEC_SUCCESS if The action was performed with sucess.
** Error code else.
**
******************************************************************************/
BT_API extern tUCODEC_STATUS UCODEC_FlushTx (tUCODEC_ID);
/******************************************************************************
**
** Function UCODEC_FlushRx
**
** Description Fluch Rx buffer Q.
**
** Input : CodecId: Id of the codec to perform the operation on.
**
** Output Parameters : None
**
** Returns UCODEC_SUCCESS if The action was performed with sucess.
** Error code else.
**
******************************************************************************/
BT_API extern tUCODEC_STATUS UCODEC_FlushRx (tUCODEC_ID);
/******************************************************************************
**
** Function UCODEC_WriteBuf
**
** Description Send a buffer to the codec.
**
** Input : CodecId: Id of the codec to perform the operation on.
** pBuf: Pointer onto the GKI buffer to be send to the CODEC.
**
** Output Parameters : None
**
** Returns UCODEC_SUCCESS if The action was performed with sucess.
** UCODEC_FLOW_CTRL_ON if The codec buffer Q had reach a UCODEC_HIGH_WM
** watermark. The buffer is queued
** UCODEC_OVERFLOW if The codec buffer Q had reach a critical
** watermark. The buffer is dropped.
**
******************************************************************************/
BT_API extern tUCODEC_STATUS UCODEC_WriteBuf (tUCODEC_ID, BT_HDR *);
/******************************************************************************
**
** Function UCODEC_ReadBuf
**
** Description Get a buffer from the codec.
**
** Input : CodecId: Id of the codec to perform the operation on.
**
** Output Parameters : None
**
** Returns Pointer on the GKI buffer. NULL if the Rx Q is empty
**
******************************************************************************/
BT_API extern tUCODEC_STATUS UCODEC_ReadBuf (tUCODEC_ID, BT_HDR **, tUCODEC_BUF_INFO *);
/******************************************************************************
**
** Function UCODEC_Close
**
** Description This function is called to put the codec in low power mode
**
**
** Input : CodecId: Id of the codec to perform the operation on.
**
** Output Parameters : None
**
** Returns UCODEC_SUCCESS : The action was performed with sucess.
** Error code else.
**
******************************************************************************/
BT_API extern tUCODEC_STATUS UCODEC_Close (tUCODEC_ID);
/******************************************************************************
**
** Function UCODEC_Open
**
** Description This function is called to resume the codec from low power
** mode after UCODEC_Close had been called. It will put the
** codec in the state it was before UCODEC_Close being called.
**
** Input : CodecId: Id of the codec to perform the operation on.
**
** Output Parameters : None
**
** Returns UCODEC_SUCCESS : The action was performed with sucess.
** Error code else.
**
******************************************************************************/
BT_API extern tUCODEC_STATUS UCODEC_Open (tUCODEC_ID);
#ifdef __cplusplus
};
#endif
#endif /* UCODEC_H */

View file

@ -0,0 +1,78 @@
/*****************************************************************************
**
** Name udac.h
**
** Description
** Definitions for UDAC driver
**
*****************************************************************************/
#ifndef UDAC_H
#define UDAC_H
#define UDAC_GAIN_MAX 0x00FFF
typedef UINT16 tUDAC_GAIN;
/* API functions for DAC driver */
/*****************************************************************************
**
** Function DAC_Init
**
** Description
** Initialize the DAC subsystem
**
** Input parameters
** Nothing
**
** Output parameters
** Nothing
**
** Returns
** Nothing
**
*****************************************************************************/
void UDAC_Init(void *p_cfg);
/*****************************************************************************
**
** Function DAC_Read
**
** Description
** Read current DAC gain
**
** Input parameters
** Nothing
**
** Output parameters
** Nothing
**
** Returns
** Current gain setting
**
*****************************************************************************/
tUDAC_GAIN UDAC_Read(void);
/*****************************************************************************
**
** Function DAC_Set
**
** Description
** Set the DAC gain
**
** Input parameters
** gain Gain setting
**
** Output parameters
** Nothing
**
** Returns
** Nothing
**
*****************************************************************************/
void UDAC_Set(tUDAC_GAIN gain);
#endif /* #ifndef UDAC_H */

View file

@ -0,0 +1,156 @@
/********************************************************************************
** *
** Name uipc.h *
** *
** Function UIPC wrapper interface *
** * *
** *
*********************************************************************************/
#ifndef UIPC_H
#define UIPC_H
#ifndef UDRV_API
#define UDRV_API
#endif
#define UIPC_CH_ID_ALL 0 /* used to address all the ch id at once */
#define UIPC_CH_ID_0 1 /* shared mem interface */
#define UIPC_CH_ID_1 2 /* TCP socket (GPS) */
#define UIPC_CH_ID_2 3 /* BSA control socket */
#define UIPC_CH_ID_3 4 /* BSA HH */
#define UIPC_CH_ID_4 5 /* Future usage */
#define UIPC_CH_ID_5 6 /* Future usage */
#define UIPC_CH_ID_6 7 /* Future usage */
#define UIPC_CH_ID_7 8 /* Future usage */
#define UIPC_CH_ID_8 9 /* Future usage */
#define UIPC_CH_ID_9 10 /* Future usage */
#define UIPC_CH_ID_10 11 /* Future usage */
#define UIPC_CH_ID_11 12 /* Future usage */
#define UIPC_CH_ID_12 13 /* Future usage */
#define UIPC_CH_ID_13 14 /* Future usage */
#define UIPC_CH_ID_14 15 /* Future usage */
#define UIPC_CH_ID_15 16 /* Future usage */
#define UIPC_CH_ID_16 17 /* Future usage */
#define UIPC_CH_ID_17 18 /* Future usage */
#define UIPC_CH_ID_18 19 /* Future usage */
#define UIPC_CH_ID_19 20 /* Future usage */
#define UIPC_CH_ID_20 21 /* Future usage */
#define UIPC_CH_ID_21 22 /* Future usage */
#define UIPC_CH_ID_22 23 /* Future usage */
#define UIPC_CH_ID_23 24 /* Future usage */
#define UIPC_CH_ID_24 25 /* Future usage */
#define UIPC_CH_ID_25 26 /* Future usage */
#define UIPC_CH_ID_26 27 /* Future usage */
#define UIPC_CH_ID_27 28 /* Future usage */
#define UIPC_CH_ID_28 29 /* Future usage */
#define UIPC_CH_ID_29 30 /* Future usage */
#define UIPC_CH_ID_30 31 /* Future usage */
#define UIPC_CH_ID_31 32 /* Future usage */
#define UIPC_CH_ID_32 33 /* Future usage */
#define UIPC_CH_ID_33 34 /* Future usage */
#define UIPC_CH_ID_34 35 /* Future usage */
#define UIPC_CH_NUM 35
typedef UINT8 tUIPC_CH_ID;
/* points to BT_HDR which describes event type and length of data;
** len contains the number of bytes of entire message
** (sizeof(BT_HDR) + offset + size of data)
*/
typedef void (tUIPC_RCV_CBACK)(BT_HDR *p_msg);
#ifdef __cplusplus
extern "C"
{
#endif
/*******************************************************************************
**
** Function UIPC_Init
**
** Description Initialize UIPC module
**
** Returns void
**
*******************************************************************************/
UDRV_API extern void UIPC_Init(void *);
/*******************************************************************************
**
** Function UIPC_Open
**
** Description Open UIPC interface
**
** Returns void
**
*******************************************************************************/
UDRV_API extern BOOLEAN UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK *p_cback);
/*******************************************************************************
**
** Function UIPC_Close
**
** Description Close UIPC interface
**
** Returns void
**
*******************************************************************************/
UDRV_API extern void UIPC_Close(tUIPC_CH_ID ch_id);
/*******************************************************************************
**
** Function UIPC_SendBuf
**
** Description Called to transmit a message over UIPC.
** Message buffer will be freed by UIPC_SendBuf.
**
** Returns void
**
*******************************************************************************/
UDRV_API extern BOOLEAN UIPC_SendBuf(tUIPC_CH_ID ch_id, BT_HDR *p_msg);
/*******************************************************************************
**
** Function UIPC_Send
**
** Description Called to transmit a message over UIPC.
**
** Returns void
**
*******************************************************************************/
UDRV_API extern BOOLEAN UIPC_Send(tUIPC_CH_ID ch_id, UINT16 msg_evt, UINT8 *p_buf,
UINT16 msglen);
/*******************************************************************************
**
** Function UIPC_Read
**
** Description Called to read a message from UIPC.
**
** Returns void
**
*******************************************************************************/
UDRV_API extern UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf,
UINT32 len);
/*******************************************************************************
**
** Function UIPC_Ioctl
**
** Description Called to control UIPC.
**
** Returns void
**
*******************************************************************************/
UDRV_API extern BOOLEAN UIPC_Ioctl(tUIPC_CH_ID ch_id, UINT32 request, void *param);
#ifdef __cplusplus
}
#endif
#endif /* UIPC_H */

View file

@ -0,0 +1,70 @@
/*******************************************************************************
** Name: unv.h
**
** Description:
**
** This file contains NV definitions from WIDCOMM's Universal Embedded
** Drivers API.
**
*******************************************************************************/
#ifndef UNV_H
#define UNV_H
#include "data_types.h"
/*******************************************************************************
** NV APIs
*******************************************************************************/
/**** Storage preferences ****/
#define UNV_BLOCK 1
#define UNV_BYTE 2
#define UNV_NOPREF 3
typedef UINT8 tUNV_STORAGE_PREF;
/**** Status ****/
#define UNV_REINIT (-1)
#define UNV_WRITELOCKED (-2)
#define UNV_ERROR (-3)
typedef INT16 tUNV_STATUS;
/* Prototype for function to restore defaults to a block */
typedef void (tUNV_DEFAULT_FUNC)(void);
/*******************************************************************************
** Function Prototypes
*******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef UDRV_API
#define UDRV_API
#endif
UDRV_API extern void UNV_Init(void *);
UDRV_API extern BOOLEAN UNV_MapBlock(UINT16, tUNV_STORAGE_PREF, UINT16,
UINT16, UINT16 *, void *);
UDRV_API extern BOOLEAN UNV_ReadMap(UINT16, tUNV_STORAGE_PREF *, UINT16 *,
UINT16 *, UINT16 *);
UDRV_API extern BOOLEAN UNV_EraseBlock(UINT16);
UDRV_API extern void UNV_Default(UINT16);
UDRV_API extern tUNV_STATUS UNV_Read(UINT16, UINT16, UINT16, UINT16, void *);
UDRV_API extern tUNV_STATUS UNV_Write(UINT16, UINT16, UINT16, UINT16, void *);
UDRV_API extern tUNV_STATUS UNV_ReadBlock(UINT16, UINT16, void *);
UDRV_API extern tUNV_STATUS UNV_WriteBlock(UINT16, void *);
UDRV_API extern UINT32 UNV_BytesRemaining(void);
UDRV_API extern void UNV_Consolidate(void);
UDRV_API extern tUNV_STATUS UNV_ReadPtr(UINT16, UINT16, UINT8 **);
UDRV_API extern tUNV_STATUS UNV_FreePtr(UINT16, UINT16);
#ifdef __cplusplus
}
#endif
#endif /* UNV_H */

View file

@ -0,0 +1,358 @@
/*****************************************************************************
**
** Name upio.h
**
** Description
** Definitions for UPIO driver
**
*****************************************************************************/
#ifndef UPIO_H
#define UPIO_H
#define UDRV_API
/* Enumeration of UPIO features */
/* Not all features enumerated here are supported by the hardware. */
/* Use UPIO_Feature() to determine support of a particular feature. */
enum {
/* LEDs */
UPIO_FEAT_LED1,
UPIO_FEAT_LED2,
UPIO_FEAT_LED3,
UPIO_FEAT_LED4,
UPIO_FEAT_LED5,
UPIO_FEAT_LED6,
UPIO_FEAT_LED7,
UPIO_FEAT_LED8,
/* Switches */
UPIO_FEAT_SWITCH1,
UPIO_FEAT_SWITCH2,
UPIO_FEAT_SWITCH3,
UPIO_FEAT_SWITCH4,
UPIO_FEAT_SWITCH5,
UPIO_FEAT_SWITCH6,
UPIO_FEAT_SWITCH7,
UPIO_FEAT_SWITCH8,
UPIO_FEAT_SWITCH9,
UPIO_FEAT_SWITCH10,
UPIO_FEAT_SWITCH11,
UPIO_FEAT_SWITCH12,
UPIO_FEAT_SWITCH13,
UPIO_FEAT_SWITCH14,
UPIO_FEAT_SWITCH15,
UPIO_FEAT_SWITCH16,
/* Jumpers */
UPIO_FEAT_JUMPER1,
UPIO_FEAT_JUMPER2,
UPIO_FEAT_JUMPER3,
UPIO_FEAT_JUMPER4,
UPIO_FEAT_JUMPER5,
UPIO_FEAT_JUMPER6,
UPIO_FEAT_JUMPER7,
UPIO_FEAT_JUMPER8,
/* Push buttons */
UPIO_FEAT_BUTTON1,
UPIO_FEAT_BUTTON2,
UPIO_FEAT_BUTTON3,
UPIO_FEAT_BUTTON4,
UPIO_FEAT_BUTTON5,
UPIO_FEAT_BUTTON6,
UPIO_FEAT_BUTTON7,
UPIO_FEAT_BUTTON8,
/* General purpose */
UPIO_FEAT_GENERAL1,
UPIO_FEAT_GENERAL2,
UPIO_FEAT_GENERAL3,
UPIO_FEAT_GENERAL4,
UPIO_FEAT_GENERAL5,
UPIO_FEAT_GENERAL6,
UPIO_FEAT_GENERAL7,
UPIO_FEAT_GENERAL8,
UPIO_FEAT_GENERAL9,
UPIO_FEAT_GENERAL10,
UPIO_FEAT_GENERAL11,
UPIO_FEAT_GENERAL12,
UPIO_FEAT_GENERAL13,
UPIO_FEAT_GENERAL14,
UPIO_FEAT_GENERAL15,
UPIO_FEAT_GENERAL16,
UPIO_FEAT_GENERAL17,
UPIO_FEAT_GENERAL18,
UPIO_FEAT_GENERAL19,
UPIO_FEAT_GENERAL20,
UPIO_FEAT_GENERAL21,
UPIO_FEAT_GENERAL22,
UPIO_FEAT_GENERAL23,
UPIO_FEAT_GENERAL24,
UPIO_FEAT_GENERAL25,
UPIO_FEAT_GENERAL26,
UPIO_FEAT_GENERAL27,
UPIO_FEAT_GENERAL28,
UPIO_FEAT_GENERAL29,
UPIO_FEAT_GENERAL30,
UPIO_FEAT_GENERAL31,
UPIO_FEAT_GENERAL32,
UPIO_FEAT_IN_HIGH, /* Support for input with interrupt on high signal level. */
UPIO_FEAT_IN_LOW, /* Support for input with interrupt on low signal level. */
UPIO_FEAT_IN_RISE, /* Support for input with interrupt on rising edge. */
UPIO_FEAT_IN_FALL /* Support for input with interrupt on falling. */
};
typedef UINT8 tUPIO_FEATURE;
/* Enumeration of UPIO configurations */
enum {
UPIO_OUT,
UPIO_IN,
UPIO_IN_EDGE,
UPIO_IN_LEVEL,
UPIO_NONE
};
typedef UINT8 tUPIO_CONFIG;
/* Enumeration of UPIO types */
enum {
UPIO_LED, /* LED */
UPIO_SWITCH, /* Switch */
UPIO_JUMPER, /* Jumper */
UPIO_BUTTON, /* Push-button switch */
UPIO_GENERAL, /* General purpose I/O */
UPIO_NUMBER_OF_TYPES
};
typedef UINT8 tUPIO_TYPE;
/* Enumeration of UPIO states */
enum {
UPIO_OFF,
UPIO_ON,
UPIO_TOGGLE
};
typedef UINT8 tUPIO_STATE;
enum {
UPIO_SW_BANK2,
UPIO_SW_BANK3
};
typedef UINT8 tUPIO_SW_BANK;
/* Jumper masks */
#define UPIO_JUMPER1 0x00000001
#define UPIO_JUMPER2 0x00000002
#define UPIO_JUMPER3 0x00000004
#define UPIO_JUMPER4 0x00000008
#define UPIO_JUMPER5 0x00000010
#define UPIO_JUMPER6 0x00000020
#define UPIO_JUMPER7 0x00000040
#define UPIO_JUMPER8 0x00000080
#define UPIO_JUMPER9 0x00000100
#define UPIO_JUMPER10 0x00000200
#define UPIO_JUMPER11 0x00000400
#define UPIO_JUMPER12 0x00000800
/* General purpose i/o masks */
#define UPIO_GENERAL1 0x00000001
#define UPIO_GENERAL2 0x00000002
#define UPIO_GENERAL3 0x00000004
#define UPIO_GENERAL4 0x00000008
#define UPIO_GENERAL5 0x00000010
#define UPIO_GENERAL6 0x00000020
#define UPIO_GENERAL7 0x00000040
#define UPIO_GENERAL8 0x00000080
#define UPIO_GENERAL9 0x00000100
#define UPIO_GENERAL10 0x00000200
#define UPIO_GENERAL11 0x00000400
#define UPIO_GENERAL12 0x00000800
#define UPIO_GENERAL13 0x00001000
#define UPIO_GENERAL14 0x00002000
#define UPIO_GENERAL15 0x00004000
#define UPIO_GENERAL16 0x00008000
#define UPIO_GENERAL17 0x00010000
#define UPIO_GENERAL18 0x00020000
#define UPIO_GENERAL19 0x00040000
#define UPIO_GENERAL20 0x00080000
#define UPIO_GENERAL21 0x00100000
#define UPIO_GENERAL22 0x00200000
#define UPIO_GENERAL23 0x00400000
#define UPIO_GENERAL24 0x00800000
#define UPIO_GENERAL25 0x01000000
#define UPIO_GENERAL26 0x02000000
#define UPIO_GENERAL27 0x04000000
#define UPIO_GENERAL28 0x08000000
#define UPIO_GENERAL29 0x10000000
#define UPIO_GENERAL30 0x20000000
#define UPIO_GENERAL31 0x40000000
#define UPIO_GENERAL32 0x80000000
typedef UINT32 tUPIO;
/* LED masks */
#define UPIO_LED1 0x00000001
#define UPIO_LED2 0x00000002
#define UPIO_LED3 0x00000004
#define UPIO_LED4 0x00000008
#define UPIO_LED5 0x00000010
#define UPIO_LED6 0x00000020
#define UPIO_LED7 0x00000040
#define UPIO_LED8 0x00000080
#define UPIO_LED_ALL (UPIO_LED1 | UPIO_LED2 | UPIO_LED3 | UPIO_LED4 | \
UPIO_LED5 | UPIO_LED6 | UPIO_LED7 | UPIO_LED8)
/* Switch masks */
#define UPIO_SWITCH1 0x00000001
#define UPIO_SWITCH2 0x00000002
#define UPIO_SWITCH3 0x00000004
#define UPIO_SWITCH4 0x00000008
#define UPIO_SWITCH5 0x00000010
#define UPIO_SWITCH6 0x00000020
#define UPIO_SWITCH7 0x00000040
#define UPIO_SWITCH8 0x00000080
#define UPIO_SWITCH9 0x00000100
#define UPIO_SWITCH10 0x00000200
#define UPIO_SWITCH11 0x00000400
#define UPIO_SWITCH12 0x00000800
#define UPIO_SWITCH13 0x00001000
#define UPIO_SWITCH14 0x00002000
#define UPIO_SWITCH15 0x00004000
#define UPIO_SWITCH16 0x00008000
/* Push button masks */
#define UPIO_BUTTON1 0x00000001
#define UPIO_BUTTON2 0x00000002
#define UPIO_BUTTON3 0x00000004
#define UPIO_BUTTON4 0x00000008
#define UPIO_BUTTON5 0x00000010
#define UPIO_BUTTON6 0x00000020
#define UPIO_BUTTON7 0x00000040
#define UPIO_BUTTON8 0x00000080
typedef void (tUPIO_CBACK)(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
#ifdef __cplusplus
extern "C" {
#endif
/* API functions for UPIO driver */
/*****************************************************************************
**
** Function UPIO_Init
**
** Description
** Initialize the GPIO service.
** This function is typically called once upon system startup.
**
** Returns nothing
**
*****************************************************************************/
UDRV_API void UPIO_Init(void *p_cfg);
/*****************************************************************************
**
** Function UPIO_Set
**
** Description
** This function sets one or more GPIO devices to the given state.
** Multiple GPIOs of the same type can be masked together to set more
** than one GPIO. This function can only be used on types UPIO_LED and
** UPIO_GENERAL.
**
** Input Parameters:
** type The type of device.
** pio Indicates the particular GPIOs.
** state The desired state.
**
** Output Parameter:
** None.
**
** Returns:
** None.
**
*****************************************************************************/
UDRV_API void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
/*****************************************************************************
**
** Function UPIO_Read
**
** Description
** Read the state of a GPIO. This function can be used for any type of
** device. Parameter pio can only indicate a single GPIO; multiple GPIOs
** cannot be masked together.
**
** Input Parameters:
** Type: The type of device.
** pio: Indicates the particular GUPIO.
**
** Output Parameter:
** None.
**
** Returns:
** State of GPIO (UPIO_ON or UPIO_OFF).
**
*****************************************************************************/
UDRV_API tUPIO_STATE UPIO_Read(tUPIO_TYPE type, tUPIO pio);
/*****************************************************************************
**
** Function UPIO_Config
**
** Description - Configure GPIOs of type UPIO_GENERAL as inputs or outputs
** - Configure GPIOs to be polled or interrupt driven
**
** Currently only support polled GPIOs.
**
** Input Parameters:
** type The type of device.
** pio Indicates the particular GPIOs.
** config
** cback
**
** Output Parameter:
** None.
**
** Returns:
** None.
**
*****************************************************************************/
UDRV_API void UPIO_Config(tUPIO_TYPE type, tUPIO pio, tUPIO_CONFIG config, tUPIO_CBACK *cback);
/*****************************************************************************
**
** Function UPIO_Feature
**
** Description
** Checks whether a feature of the pio API is supported
**
** Input Parameter:
** feature The feature to check
**
** Output Parameter:
** None.
**
** Returns:
** TRUE if feature is supported, FALSE if it is not.
**
*****************************************************************************/
UDRV_API BOOLEAN UPIO_Feature(tUPIO_FEATURE feature);
#ifdef __cplusplus
}
#endif
#endif /* ifdef UPIO_H */

View file

@ -0,0 +1,214 @@
/*******************************************************************************
** Name: usb.h
**
** Description:
**
** This file contains serial definitions from WIDCOMM's Universal Embedded
** Drivers API.
**
*******************************************************************************/
#ifndef USB_H
#define USB_H
/*******************************************************************************
** Serial APIs
*******************************************************************************/
/**** port IDs ****/
#define USB_PORT_1 0
#define USB_PORT_2 1
#define USB_PORT_3 2
#define USB_PORT_4 3
typedef UINT8 tUSB_PORT;
/**** baud rates ****/
#define USB_BAUD_300 0
#define USB_BAUD_600 1
#define USB_BAUD_1200 2
#define USB_BAUD_2400 3
#define USB_BAUD_9600 4
#define USB_BAUD_19200 5
#define USB_BAUD_57600 6
#define USB_BAUD_115200 7
#define USB_BAUD_230400 8
#define USB_BAUD_460800 9
#define USB_BAUD_921600 10
#define USB_BAUD_AUTO 11
/**** Data Format ****/
/* Stop Bits */
#define USB_STOPBITS_1 1
#define USB_STOPBITS_1_5 (1<<1)
#define USB_STOPBITS_2 (1<<2)
/* Parity Bits */
#define USB_PARITY_NONE (1<<3)
#define USB_PARITY_EVEN (1<<4)
#define USB_PARITY_ODD (1<<5)
/* Data Bits */
#define USB_DATABITS_5 (1<<6)
#define USB_DATABITS_6 (1<<7)
#define USB_DATABITS_7 (1<<8)
#define USB_DATABITS_8 (1<<9)
/**** Flow Control ****/
#define USB_FC_NONE 0
#define USB_FC_HW 1
#define USB_FC_SW 2
/**** Data Buffering Mechanism ****/
#define USB_BUF_BYTE 0
#define USB_BUF_GKI 1
/**** Signals ****/
#define USB_SIG_RTSCTS 1
#define USB_SIG_DSRDTR (1<<1)
#define USB_SIG_RI (1<<2)
#define USB_SIG_CD (1<<3)
#define USB_SIG_DTE_DEVICE (1<<4)
/**** Errors *****/
#define USB_ERR_OVERRUN 1
#define USB_ERR_PARITY (1<<1)
#define USB_ERR_FRAMING (1<<2)
#define USB_ERR_BREAK (1<<3)
/**** Serial Operations ****/
#define USB_OP_FLUSH 0
#define USB_OP_FLUSH_RX 1
#define USB_OP_FLUSH_TX 2
#define USB_OP_BREAK_OFF 3
#define USB_OP_BREAK_ON 4
#define USB_OP_BAUD_RD 5
#define USB_OP_BAUD_WR 6
#define USB_OP_FMT_RD 7
#define USB_OP_FMT_WR 8
#define USB_OP_SIG_RD 9
#define USB_OP_SIG_WR 10
#define USB_OP_FC_RD 11
#define USB_OP_FC_WR 12
typedef UINT8 tUSB_OP;
/**** Serial feature types ****/
#define USB_FEAT_PORT_1 0
#define USB_FEAT_PORT_2 1
#define USB_FEAT_PORT_3 2
#define USB_FEAT_PORT_4 3
#define USB_FEAT_BAUD_AUTO 4
#define USB_FEAT_BAUD_300 5
#define USB_FEAT_BAUD_600 6
#define USB_FEAT_BAUD_1200 7
#define USB_FEAT_BAUD_2400 8
#define USB_FEAT_BAUD_9600 9
#define USB_FEAT_BAUD_19200 10
#define USB_FEAT_BAUD_57600 11
#define USB_FEAT_BAUD_115200 12
#define USB_FEAT_BAUD_230400 13
#define USB_FEAT_BAUD_460800 14
#define USB_FEAT_BAUD_921600 15
#define USB_FEAT_STOPBITS_1 16
#define USB_FEAT_STOPBITS_1_5 17
#define USB_FEAT_STOPBITS_2 18
#define USB_FEAT_PARITY_NONE 19
#define USB_FEAT_PARITY_EVEN 20
#define USB_FEAT_PARITY_ODD 21
#define USB_FEAT_DATABITS_5 22
#define USB_FEAT_DATABITS_6 23
#define USB_FEAT_DATABITS_7 24
#define USB_FEAT_DATABITS_8 25
#define USB_FEAT_FC_NONE 26
#define USB_FEAT_FC_HW 27
#define USB_FEAT_FC_SW 28
#define USB_FEAT_BUF_BYTE 29
#define USB_FEAT_BUF_GKI 30
#define USB_FEAT_SIG_RTS 31
#define USB_FEAT_SIG_CTS 32
#define USB_FEAT_SIG_DSR 33
#define USB_FEAT_SIG_DTR 34
#define USB_FEAT_SIG_RI 35
#define USB_FEAT_SIG_CD 36
#define USB_FEAT_OP_FLUSH 37
#define USB_FEAT_OP_FLUSH_RX 38
#define USB_FEAT_OP_FLUSH_TX 39
#define USB_FEAT_OP_BREAK 40
#define USB_FEAT_OP_BAUD_RD 41
#define USB_FEAT_OP_BAUD_WR 42
#define USB_FEAT_OP_FMT_RD 43
#define USB_FEAT_OP_FMT_WR 44
#define USB_FEAT_OP_SIG_RD 45
#define USB_FEAT_OP_SIG_WR 46
#define USB_FEAT_OP_FC_RD 47
#define USB_FEAT_OP_FC_WR 48
typedef UINT8 tUSB_FEATURE;
/**** Event types ****/
#define USB_RX_READY_EVT 0
#define USB_TX_DONE_EVT 1
#define USB_SIG_EVT 2
#define USB_ERR_EVT 3
typedef UINT8 tUSB_EVT;
/* Structure used to configure serial port during open */
typedef struct {
UINT16 fmt; /* Data format */
UINT8 baud; /* Baud rate */
UINT8 fc; /* Flow control */
UINT8 buf; /* Data buffering mechanism */
UINT8 pool; /* GKI buffer pool for received data */
UINT16 size; /* Size of GKI buffer pool */
UINT16 offset; /* Offset in GKI buffer pool */
} tUSB_OPEN_CFG;
/* Union used to pass ioctl arguments */
typedef union {
UINT16 fmt;
UINT8 baud;
UINT8 fc;
UINT8 sigs;
} tUSB_IOCTL_DATA;
/* Union to pass event data */
typedef union {
UINT8 sigs;
UINT8 error;
} tUSB_EVT_DATA;
/* callback for events */
typedef void (tUSB_CBACK)(tUSB_PORT, tUSB_EVT, tUSB_EVT_DATA *);
/*******************************************************************************
** Function Prototypes
*******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
UDRV_API extern void USB_Init(void *);
UDRV_API extern void USB_Open(tUSB_PORT, tUSB_OPEN_CFG *, tUSB_CBACK *);
UDRV_API extern void USB_ReadBuf(tUSB_PORT, BT_HDR **);
UDRV_API extern UINT16 USB_Read(tUSB_PORT, UINT8 *, UINT16);
UDRV_API extern BOOLEAN USB_WriteBuf(tUSB_PORT, BT_HDR *);
UDRV_API extern UINT16 USB_Write(tUSB_PORT, UINT8 *, UINT16);
UDRV_API extern void USB_Ioctl(tUSB_PORT, tUSB_OP, tUSB_IOCTL_DATA *);
UDRV_API extern void USB_Close(tUSB_PORT);
UDRV_API extern BOOLEAN USB_Feature(tUSB_FEATURE);
#ifdef __cplusplus
}
#endif
#endif /* USB_H */

View file

@ -0,0 +1,268 @@
/*******************************************************************************
** Name: userial.h
**
** Description:
**
** This file contains serial definitions from WIDCOMM's Universal Embedded
** Drivers API.
**
*******************************************************************************/
#ifndef USERIAL_H
#define USERIAL_H
/*******************************************************************************
** Serial APIs
*******************************************************************************/
/**** port IDs ****/
#define USERIAL_PORT_1 0
#define USERIAL_PORT_2 1
#define USERIAL_PORT_3 2
#define USERIAL_PORT_4 3
#define USERIAL_PORT_5 4
#define USERIAL_PORT_6 5
#define USERIAL_PORT_7 6
#define USERIAL_PORT_8 7
#define USERIAL_PORT_9 8
#define USERIAL_PORT_10 9
#define USERIAL_PORT_11 10
#define USERIAL_PORT_12 11
#define USERIAL_PORT_13 12
#define USERIAL_PORT_14 13
#define USERIAL_PORT_15 14
#define USERIAL_PORT_16 15
#define USERIAL_PORT_17 16
#define USERIAL_PORT_18 17
typedef UINT8 tUSERIAL_PORT;
/**** baud rates ****/
#define USERIAL_BAUD_300 0
#define USERIAL_BAUD_600 1
#define USERIAL_BAUD_1200 2
#define USERIAL_BAUD_2400 3
#define USERIAL_BAUD_9600 4
#define USERIAL_BAUD_19200 5
#define USERIAL_BAUD_57600 6
#define USERIAL_BAUD_115200 7
#define USERIAL_BAUD_230400 8
#define USERIAL_BAUD_460800 9
#define USERIAL_BAUD_921600 10
#define USERIAL_BAUD_1M 11
#define USERIAL_BAUD_1_5M 12
#define USERIAL_BAUD_2M 13
#define USERIAL_BAUD_3M 14
#define USERIAL_BAUD_4M 15
#define USERIAL_BAUD_AUTO 16
/**** Data Format ****/
/* Stop Bits */
#define USERIAL_STOPBITS_1 1
#define USERIAL_STOPBITS_1_5 (1<<1)
#define USERIAL_STOPBITS_2 (1<<2)
/* Parity Bits */
#define USERIAL_PARITY_NONE (1<<3)
#define USERIAL_PARITY_EVEN (1<<4)
#define USERIAL_PARITY_ODD (1<<5)
/* Data Bits */
#define USERIAL_DATABITS_5 (1<<6)
#define USERIAL_DATABITS_6 (1<<7)
#define USERIAL_DATABITS_7 (1<<8)
#define USERIAL_DATABITS_8 (1<<9)
/**** Flow Control ****/
#define USERIAL_FC_NONE 0
#define USERIAL_FC_HW 1
#define USERIAL_FC_SW 2
/**** Data Buffering Mechanism ****/
#define USERIAL_BUF_BYTE 0
#define USERIAL_BUF_GKI 1
/**** Signals ****/
#define USERIAL_SIG_RTSCTS 1
#define USERIAL_SIG_DSRDTR (1<<1)
#define USERIAL_SIG_RI (1<<2)
#define USERIAL_SIG_CD (1<<3)
#define USERIAL_SIG_DTE_DEVICE (1<<4)
/**** Errors *****/
#define USERIAL_ERR_OVERRUN 1
#define USERIAL_ERR_PARITY (1<<1)
#define USERIAL_ERR_FRAMING (1<<2)
#define USERIAL_ERR_BREAK (1<<3)
/**** Serial Operations ****/
#define USERIAL_OP_FLUSH 0
#define USERIAL_OP_FLUSH_RX 1
#define USERIAL_OP_FLUSH_TX 2
#define USERIAL_OP_BREAK_OFF 3
#define USERIAL_OP_BREAK_ON 4
#define USERIAL_OP_BAUD_RD 5
#define USERIAL_OP_BAUD_WR 6
#define USERIAL_OP_FMT_RD 7
#define USERIAL_OP_FMT_WR 8
#define USERIAL_OP_SIG_RD 9
#define USERIAL_OP_SIG_WR 10
#define USERIAL_OP_FC_RD 11
#define USERIAL_OP_FC_WR 12
#define USERIAL_OP_CTS_AS_WAKEUP 13 /* H4IBSS */
#define USERIAL_OP_CTS_AS_FC 14 /* H4IBSS */
#if (defined LINUX_OS) && (LINUX_OS == TRUE)
#define USERIAL_OP_SCO_UP 20 /* LINUX SCO */
#define USERIAL_OP_SCO_DOWN 21 /* LINUX SCO */
#endif
typedef UINT8 tUSERIAL_OP;
/**** Serial feature types ****/
#define USERIAL_FEAT_PORT_1 0
#define USERIAL_FEAT_PORT_2 1
#define USERIAL_FEAT_PORT_3 2
#define USERIAL_FEAT_PORT_4 3
#define USERIAL_FEAT_BAUD_AUTO 4
#define USERIAL_FEAT_BAUD_300 5
#define USERIAL_FEAT_BAUD_600 6
#define USERIAL_FEAT_BAUD_1200 7
#define USERIAL_FEAT_BAUD_2400 8
#define USERIAL_FEAT_BAUD_9600 9
#define USERIAL_FEAT_BAUD_19200 10
#define USERIAL_FEAT_BAUD_57600 11
#define USERIAL_FEAT_BAUD_115200 12
#define USERIAL_FEAT_BAUD_230400 13
#define USERIAL_FEAT_BAUD_460800 14
#define USERIAL_FEAT_BAUD_921600 15
#define USERIAL_FEAT_STOPBITS_1 16
#define USERIAL_FEAT_STOPBITS_1_5 17
#define USERIAL_FEAT_STOPBITS_2 18
#define USERIAL_FEAT_PARITY_NONE 19
#define USERIAL_FEAT_PARITY_EVEN 20
#define USERIAL_FEAT_PARITY_ODD 21
#define USERIAL_FEAT_DATABITS_5 22
#define USERIAL_FEAT_DATABITS_6 23
#define USERIAL_FEAT_DATABITS_7 24
#define USERIAL_FEAT_DATABITS_8 25
#define USERIAL_FEAT_FC_NONE 26
#define USERIAL_FEAT_FC_HW 27
#define USERIAL_FEAT_FC_SW 28
#define USERIAL_FEAT_BUF_BYTE 29
#define USERIAL_FEAT_BUF_GKI 30
#define USERIAL_FEAT_SIG_RTS 31
#define USERIAL_FEAT_SIG_CTS 32
#define USERIAL_FEAT_SIG_DSR 33
#define USERIAL_FEAT_SIG_DTR 34
#define USERIAL_FEAT_SIG_RI 35
#define USERIAL_FEAT_SIG_CD 36
#define USERIAL_FEAT_OP_FLUSH 37
#define USERIAL_FEAT_OP_FLUSH_RX 38
#define USERIAL_FEAT_OP_FLUSH_TX 39
#define USERIAL_FEAT_OP_BREAK 40
#define USERIAL_FEAT_OP_BAUD_RD 41
#define USERIAL_FEAT_OP_BAUD_WR 42
#define USERIAL_FEAT_OP_FMT_RD 43
#define USERIAL_FEAT_OP_FMT_WR 44
#define USERIAL_FEAT_OP_SIG_RD 45
#define USERIAL_FEAT_OP_SIG_WR 46
#define USERIAL_FEAT_OP_FC_RD 47
#define USERIAL_FEAT_OP_FC_WR 48
typedef UINT8 tUSERIAL_FEATURE;
/**** Event types ****/
#define USERIAL_RX_READY_EVT 0
#define USERIAL_TX_DONE_EVT 1
#define USERIAL_SIG_EVT 2
#define USERIAL_ERR_EVT 3
#define USERIAL_WAKEUP_EVT 4 /* H4IBSS */
typedef UINT8 tUSERIAL_EVT;
/* Structure used to configure serial port during open */
typedef struct {
UINT16 fmt; /* Data format */
UINT8 baud; /* Baud rate */
UINT8 fc; /* Flow control */
UINT8 buf; /* Data buffering mechanism */
UINT8 pool; /* GKI buffer pool for received data */
UINT16 size; /* Size of GKI buffer pool */
UINT16 offset; /* Offset in GKI buffer pool */
} tUSERIAL_OPEN_CFG;
/* Union used to pass ioctl arguments */
typedef union {
UINT16 fmt;
UINT8 baud;
UINT8 fc;
UINT8 sigs;
#if (defined LINUX_OS) && (LINUX_OS == TRUE)
UINT16 sco_handle;
#endif
} tUSERIAL_IOCTL_DATA;
/* Union to pass event data */
typedef union {
UINT8 sigs;
UINT8 error;
} tUSERIAL_EVT_DATA;
/* callback for events */
typedef void (tUSERIAL_CBACK)(tUSERIAL_PORT, tUSERIAL_EVT, tUSERIAL_EVT_DATA *);
/*******************************************************************************
** Function Prototypes
*******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
UDRV_API extern void USERIAL_Init(void *);
UDRV_API extern void USERIAL_Open(tUSERIAL_PORT, tUSERIAL_OPEN_CFG *, tUSERIAL_CBACK *);
UDRV_API extern void USERIAL_ReadBuf(tUSERIAL_PORT, BT_HDR **);
UDRV_API extern UINT16 USERIAL_Read(tUSERIAL_PORT, UINT8 *, UINT16);
UDRV_API extern BOOLEAN USERIAL_WriteBuf(tUSERIAL_PORT, BT_HDR *);
UDRV_API extern UINT16 USERIAL_Write(tUSERIAL_PORT, UINT8 *, UINT16);
UDRV_API extern void USERIAL_Ioctl(tUSERIAL_PORT, tUSERIAL_OP, tUSERIAL_IOCTL_DATA *);
UDRV_API extern void USERIAL_Close(tUSERIAL_PORT);
UDRV_API extern BOOLEAN USERIAL_Feature(tUSERIAL_FEATURE);
/*******************************************************************************
**
** Function USERIAL_GetLineSpeed
**
** Description This function convert USERIAL baud to line speed.
**
** Output Parameter None
**
** Returns line speed
**
*******************************************************************************/
UDRV_API extern UINT32 USERIAL_GetLineSpeed(UINT8 baud);
/*******************************************************************************
**
** Function USERIAL_GetBaud
**
** Description This function convert line speed to USERIAL baud.
**
** Output Parameter None
**
** Returns line speed
**
*******************************************************************************/
UDRV_API extern UINT8 USERIAL_GetBaud(UINT32 line_speed);
#ifdef __cplusplus
}
#endif
#endif /* USERIAL_H */

View file

@ -0,0 +1,82 @@
/*******************************************************************************
** Name: utimer.h
**
** Description:
**
** This file contains timer definitions from WIDCOMM's Universal Embedded
** Drivers API.
**
*******************************************************************************/
#ifndef UTIMER_H
#define UTIMER_H
/*******************************************************************************
** Timer APIs
*******************************************************************************/
/**** Timer IDs ****/
#define UTIMER_ID_1 0
#define UTIMER_ID_2 1
#define UTIMER_ID_3 2
#define UTIMER_ID_4 3
#define UTIMER_NUM_TIMERS 4 /* Number of timers supported */
typedef UINT8 tUTIMER_ID;
/**** Timer types ****/
#define UTIMER_TYPE_PERIODIC 0
#define UTIMER_TYPE_ONESHOT 1
typedef UINT8 tUTIMER_TYPE;
/**** Timer time ****/
typedef UINT32 tUTIMER_TIME;
/**** Timer configuration ****/
typedef struct {
tUTIMER_TIME period;
tUTIMER_TYPE type;
} tUTIMER_CFG;
/**** Timer feature types ****/
#define UTIMER_FEAT_ID_1 0
#define UTIMER_FEAT_ID_2 1
#define UTIMER_FEAT_ID_3 2
#define UTIMER_FEAT_ID_4 3
#define UTIMER_FEAT_TYPE_PERIODIC 4
#define UTIMER_FEAT_TYPE_ONESHOT 5
typedef UINT8 tUTIMER_FEATURE;
/**** Callback for timer expiration ****/
typedef void (tUTIMER_CBACK)(tUTIMER_ID);
/*******************************************************************************
** Function Prototypes
*******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
UDRV_API extern void UTIMER_Init(void *);
UDRV_API extern void UTIMER_Start(tUTIMER_ID, tUTIMER_CFG *, tUTIMER_CBACK *);
UDRV_API extern void UTIMER_Read(tUTIMER_ID, tUTIMER_TIME *);
UDRV_API extern void UTIMER_Stop(tUTIMER_ID);
UDRV_API extern BOOLEAN UTIMER_Feature(tUTIMER_FEATURE);
#ifdef __cplusplus
}
#endif
#endif /* UTIMER_H */

View file

@ -0,0 +1,269 @@
/*******************************************************************************
** Name: uusb.h
**
** Description:
**
** This file contains usb definitions from Widcomm's Universal Embedded
** Drivers API.
**
*******************************************************************************/
#ifndef UUSB_H
#define UUSB_H
#include "bt_target.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
** Codec APIs
*******************************************************************************/
/**** Status ****/
#define UUSB_SUCCESS 0
#define UUSB_DRV_INVALID_PARM 1 // Invalid parameter(s) passed to Driver
#define UUSB_DRV_INVALID_STATE 2 // Driver is not in correct state to accept
#define UUSB_DRV_UNSUPPORTED_SETUP_REQ 3 // Unsupported SETUP request (use with tUSER_EP0_SETUP_CB)
#define UUSB_DRV_NO_BUFFER_AVAILABLE 4 // User cannot provide a Buffer (use with CB functions)
typedef UINT8 tUUSB_STATUS;
#define UUSB_EP1 0
#define UUSB_EP2 1
#define UUSB_EP3 2
#define UUSB_EP4 3
#define UUSB_EP5 4
#define UUSB_EP6 5
#define UUSB_EP7 6
typedef UINT8 tUUSB_EP_ID;
typedef enum {
UUSB_EP_TYPE_CONTROL = 0,
UUSB_EP_TYPE_ISOCHRONOUS,
UUSB_EP_TYPE_BULK,
UUSB_EP_TYPE_INTERRUPT
} tUUSB_EP_TYPE;
typedef enum {
UUSB_DIR_OUT = 0,
UUSB_DIR_IN
} tUUSB_EP_DIRECTION;
typedef struct tUUSB_SETUP_PKTTag {
/* Definition of "USBbmRequestType" */
#define UUSB_DATA_PHASE_DIR 0x80 /* Mask to get data phase transfer direction */
#define UUSB_HOST_TO_DEVICE 0x00 /* Data transfer directions */
#define UUSB_DEVICE_TO_HOST 0x80 /* Data transfer directions */
/* Types of requests */
#define UUSB_REQUEST_TYPE 0x60 /* Mask to get request type */
#define UUSB_STANDARD_REQUEST 0x00 /* Standard request */
#define UUSB_CLASS_REQUEST 0x20 /* Class request */
#define UUSB_VENDOR_REQUEST 0x40 /* Vendor request */
UINT8 bmRequestType;
UINT8 bRequest;
UINT16 wValue;
UINT16 wIndex;
UINT16 wLength;
} tUUSB_SETUP_PKT;
typedef union {
#define UUSB_HEAD_SIZE (8)
UINT8 HeadBytes[UUSB_HEAD_SIZE];
tUUSB_SETUP_PKT Setup;
} tSETUP_OR_HEAD;
typedef struct {
UINT8 BufSize;
UINT8 NumBytesInBuf;
tSETUP_OR_HEAD Buf;
} tUUSB_RX_HEAD;
typedef enum {
UUSB_EP_DISABLE,
UUSB_EP_ENABLE,
UUSB_EP_STALL
} tUUSB_EP_STATE;
typedef UINT8 tEndPoint;
#if 0
#define UUSB_ATTACHED 0
#define UUSB_POWERED 1
#define UUSB_DEFAULT 2
#define UUSB_ADDRESS 3
#define UUSB_CONFIGURED 4
#define UUSB_SUSPENDED 5
typedef UINT8 tUUSB_BUS_STATE;
#else
typedef enum {
UUSB_ATTACHED,
UUSB_POWERED,
UUSB_DEFAULT,
UUSB_ADDRESS,
UUSB_CONFIGURED,
UUSB_SUSPENDED
} tUUSB_BUS_STATE;
#endif
typedef enum _tUUSB_STANDART_REQ {
UUSB_GET_STATUS = 0,
UUSB_CLEAR_FEATURE,
UUSB_RESERVED1,
UUSB_SET_FEATURE,
UUSB_RESERVED2,
UUSB_SET_ADDRESS,
UUSB_GET_DESCRIPTOR,
UUSB_SET_DESCRIPTOR,
UUSB_GET_CONFIGURATION,
UUSB_SET_CONFIGURATION,
UUSB_GET_INTERFACE,
UUSB_SET_INTERFACE,
UUSB_TOTAL_sREQUEST, /* Total number of Standard request */
UUSB_SYNCH_FRAME = 12
} tUUSB_STANDART_REQ;
typedef void (*tUUSB_STATE_CB) (tUUSB_BUS_STATE State);
typedef void (*tUUSB_PROT_COMPLETE_CB ) (UINT8 *pBuf, UINT16 NumBytesInBuf);
typedef tUUSB_STATUS (*tUUSB_PROT_SETUP_CB ) (UINT8 **ppBuf, UINT16 *pBufSize);
typedef void (*tUUSB_RX_START_CB ) (tUUSB_EP_ID EndPoint,
UINT8 **ppBuf,
UINT16 *pBufSize);
typedef void (*tUUSB_RX_COMPLETE_CB ) (tUUSB_EP_ID EndPoint,
UINT8 *pRxBuf,
UINT16 NumBytesInBuf);
typedef void (*tUUSB_TX_COMPLETE_CB ) (tUUSB_EP_ID EndPoint,
UINT8 *pRxBuf);
/*******************************************************************************
** Function Prototypes
*******************************************************************************/
/******************************************************************************
**
** Function UCODEC_Init
**
** Description Startup initialisation function. This function is called
** before any orther function of UUSB it initialize UUSB
** internal structure an the external hw.
**
** Input :
**
** Output Parameters :
**
** Returns UUSB_SUCCESS if The action was performed with sucess.
** Error code else.
**
******************************************************************************/
BT_API extern tUUSB_STATUS UUSB_Init (tUUSB_PROT_SETUP_CB userProtSetupCallBack,
tUUSB_PROT_COMPLETE_CB userProtCompleteCallBack,
tUUSB_RX_START_CB userRxStartCallBack,
tUUSB_STATE_CB userStateCallBack,
tUUSB_TX_COMPLETE_CB userTxCompleteCallBack,
tUUSB_RX_COMPLETE_CB userRxCompleteCallBack);
/******************************************************************************
**
** Function UUSB_Start
**
** Description
**
**
**
**
**
** Returns UUSB_SUCCESS if The action was performed with sucess.
**
******************************************************************************/
BT_API extern tUUSB_STATUS UUSB_Start (void);
/******************************************************************************
**
** Function UUSB_Stop
**
** Description
**
**
**
**
** Returns UUSB_SUCCESS if The action was performed with sucess.
** Error code else.
**
******************************************************************************/
BT_API extern tUUSB_STATUS UUSB_Stop (void);
/******************************************************************************
**
** Function UUSB_SetEndPointCnf
**
** Description
**
**
** Returns
**
******************************************************************************/
BT_API extern tUUSB_STATUS UUSB_SetEndPointCnf ( BOOLEAN IsIN_EndPoint,
tUUSB_EP_ID EndPoint,
UINT8 MaxPacketSize,
tUUSB_EP_TYPE EndPointType,
tUUSB_RX_HEAD *pRxHead,
UINT16 RxTimeOut);
/******************************************************************************
**
** Function UUSB_SetEndPointState
**
** Description
**
**
** Returns
**
******************************************************************************/
BT_API extern tUUSB_STATUS UUSB_SetEndPointState (tUUSB_EP_ID EndPoint,
tUUSB_EP_STATE EndPointState);
/******************************************************************************
**
** Function UUSB_WriteEndPoint
**
** Description
**
**
** Returns
**
******************************************************************************/
BT_API extern tUUSB_STATUS UUSB_WriteEndPoint (tUUSB_EP_ID EndPoint,
UINT16 Length,
UINT8 *pBuf);
/******************************************************************************
**
** Function UUSB_GenerateRemoteWakeUp
**
** Description
**
**
** Returns
**
******************************************************************************/
BT_API extern tUUSB_STATUS UUSB_GenerateRemoteWakeUp (void);
#ifdef __cplusplus
};
#endif
#endif /* UUSB_H */

View file

@ -0,0 +1,233 @@
/*******************************************************************************
** Name: userial_bby.c
**
** Description:
**
** This file contains the universal driver wrapper for the BTE-QC serial
** drivers
*******************************************************************************/
#include "mico.h"
#include "mico_bt_types.h"
#include "platform_bluetooth.h"
#include "platform_config.h"
/* Macro for checking of bus is initialised */
#define IS_BUS_INITIALISED( ) \
do \
{ \
if ( bus_initialised == false ) \
{ \
printf( "bus uninitialised" ); \
return -1; \
} \
}while ( 0 )
/* Macro for checking if bus is ready */
#define BT_BUS_IS_READY( ) \
do \
{ \
if ( bt_bus_is_ready( ) == false ) \
{ \
printf( "bus not ready" ) \
return kGeneralErr; \
} \
}while ( 0 )
/* Macro for waiting until bus is ready */
#define BT_BUS_WAIT_UNTIL_READY( ) \
do \
{ \
while ( bt_bus_is_ready( ) == false ) \
{ \
mico_thread_msleep( 10 ); \
} \
} while ( 0 )
/* TODO: bring in bt_bus code to remove BTE dependency on MiCO bluetooth library */
extern int bt_bus_init( void );
extern int bt_bus_deinit( void );
extern int bt_bus_transmit( const uint8_t *data_out, uint32_t size );
extern int bt_bus_receive( uint8_t *data_in, uint32_t size, uint32_t timeout_ms );
extern int bt_bus_uart_reset( void );
extern int bt_bus_uart_reconifig_baud(uint32_t baud);
extern bool bt_bus_is_ready( void );
extern OSStatus platform_uart_reconfig( platform_uart_driver_t *driver, const platform_uart_config_t *config );
/******************************************************
* Enumerations
******************************************************/
/*****************************************************************************
* Platform UART interface, taken from
* ../Library/bluetooth/internal/bus/UART/bt_bus.c
* (audio/2.4.x-bluetooth branch)
*****************************************************************************/
#ifndef USERIAL_RX_FIFO_SIZE
#define USERIAL_RX_FIFO_SIZE (3000)
#endif
static volatile bool bus_initialised = false;
static volatile bool device_powered = false;
/* RX ring buffer. Bluetooth chip UART receive can be asynchronous, therefore a ring buffer is required */
static ring_buffer_t rx_ring_buffer;
static uint8_t rx_data[USERIAL_RX_FIFO_SIZE];
int bt_bus_init( void )
{
//USART_OverSampling8Cmd(USART1, ENABLE);
if ( bus_initialised == false ) {
if ( mico_bt_control_pins[MICO_BT_PIN_HOST_WAKE] != NULL) {
require_noerr( platform_gpio_init( mico_bt_control_pins[MICO_BT_PIN_HOST_WAKE], INPUT_HIGH_IMPEDANCE ), exit );
}
if ( mico_bt_control_pins[MICO_BT_PIN_DEVICE_WAKE] != NULL) {
require_noerr( platform_gpio_init( mico_bt_control_pins[MICO_BT_PIN_DEVICE_WAKE], OUTPUT_OPEN_DRAIN_PULL_UP ), exit );
require_noerr( platform_gpio_output_high( mico_bt_control_pins[MICO_BT_PIN_DEVICE_WAKE] ), exit );
mico_thread_msleep( 100 );
}
/* Configure Reg Enable pin to output. Set to HIGH */
if ( mico_bt_control_pins[MICO_BT_PIN_POWER] != NULL) {
require_noerr( platform_gpio_init( mico_bt_control_pins[MICO_BT_PIN_POWER], OUTPUT_OPEN_DRAIN_PULL_UP ), exit );
require_noerr( platform_gpio_output_high( mico_bt_control_pins[MICO_BT_PIN_POWER] ), exit );
}
device_powered = true;
if ( mico_bt_uart_config.flow_control == FLOW_CONTROL_DISABLED ) {
/* Configure RTS pin to output. Set to HIGH */
require_noerr( platform_gpio_init( mico_bt_uart_pins[MICO_BT_PIN_UART_RTS], OUTPUT_OPEN_DRAIN_PULL_UP ), exit );
require_noerr( platform_gpio_output_high( mico_bt_uart_pins[MICO_BT_PIN_UART_RTS] ),
exit ); //William, working wrong if set high, so donot use FLOW_CONTROL_DISABLED in 43438A1
/* Configure CTS pin to input pull-up */
require_noerr( platform_gpio_init( mico_bt_uart_pins[MICO_BT_PIN_UART_CTS], INPUT_PULL_UP ), exit );
}
/* Configure Reset pin to output. Set to HIGH */
if ( mico_bt_control_pins[MICO_BT_PIN_RESET] != NULL) {
require_noerr( platform_gpio_init( mico_bt_control_pins[MICO_BT_PIN_RESET], OUTPUT_OPEN_DRAIN_PULL_UP ), exit );
require_noerr( platform_gpio_output_high( mico_bt_control_pins[MICO_BT_PIN_RESET] ), exit );
}
/* Initialise RX ring buffer */
ring_buffer_init( &rx_ring_buffer, (uint8_t *) rx_data, sizeof( rx_data ) );
/* Configure USART comms */
require_noerr( platform_uart_init( mico_bt_uart_driver, mico_bt_uart_peripheral, &mico_bt_uart_config,
&rx_ring_buffer ), exit );
#ifdef MICO_USE_BT_RESET_PIN
/* Reset bluetooth chip. Delay momentarily. */
require_noerr( platform_gpio_output_low( &bt_control_pins[BT_PIN_RESET] ), exit );
mico_thread_msleep( 10 );
require_noerr( platform_gpio_output_high( &bt_control_pins[BT_PIN_RESET] ), exit );
#endif
/* Wait until the Bluetooth chip stabilizes. */
mico_thread_msleep( 100 );
/* Bluetooth chip is ready. Pull host's RTS low */
if ( mico_bt_uart_config.flow_control == FLOW_CONTROL_DISABLED ) {
/* Bluetooth chip is ready. Pull host's RTS low */
require_noerr( platform_gpio_output_low( mico_bt_uart_pins[MICO_BT_PIN_UART_RTS] ), exit );
}
bus_initialised = true;
/* Wait for bluetooth chip to pull its RTS (host's CTS) low. From observation using CRO, it takes the bluetooth chip > 170ms to pull its RTS low after CTS low */
BT_BUS_WAIT_UNTIL_READY();
}
exit:
return kNoErr;
}
int bt_bus_deinit( void )
{
require( bus_initialised, exit);
if ( mico_bt_control_pins[MICO_BT_PIN_RESET] != NULL) {
require_noerr( platform_gpio_output_low( mico_bt_control_pins[MICO_BT_PIN_RESET] ), exit );
}
require_noerr( platform_gpio_output_high( mico_bt_uart_pins[MICO_BT_PIN_UART_RTS] ), exit ); // RTS deasserted
if ( mico_bt_control_pins[MICO_BT_PIN_POWER] != NULL) {
require_noerr( platform_gpio_output_low ( mico_bt_control_pins[MICO_BT_PIN_POWER] ),
exit ); // Bluetooth chip regulator off
}
device_powered = false;
/* Deinitialise UART */
require_noerr( platform_uart_deinit( mico_bt_uart_driver ), exit );
bus_initialised = false;
return kNoErr;
exit:
return kGeneralErr;
}
int bt_bus_transmit( const uint8_t *data_out, uint32_t size )
{
IS_BUS_INITIALISED();
BT_BUS_WAIT_UNTIL_READY();
require_noerr( platform_uart_transmit_bytes( mico_bt_uart_driver, data_out, size ), exit );
exit:
return kNoErr;
}
int bt_bus_receive( uint8_t *data_in, uint32_t size, uint32_t timeout_ms )
{
IS_BUS_INITIALISED();
return platform_uart_receive_bytes( mico_bt_uart_driver, (void *)data_in, size, timeout_ms );
}
bool bt_bus_is_ready( void )
{
return ( bus_initialised == false ) ? false : ( ( platform_gpio_input_get( mico_bt_uart_pins[MICO_BT_PIN_UART_CTS] ) ==
true ) ? false : true );
}
int bt_bus_uart_reconifig_baud(uint32_t newBaudRate)
{
platform_uart_config_t bt_uart_config;
uint32_t last_rx_size = mico_bt_uart_driver->rx_size;
memcpy( &bt_uart_config, &mico_bt_uart_config, sizeof( mico_bt_uart_config ) );
if ( bus_initialised == true ) {
bt_uart_config.baud_rate = newBaudRate;
/* Initialise RX ring buffer */
ring_buffer_init( &rx_ring_buffer, (uint8_t *) rx_data, sizeof( rx_data ) );
/* Configure USART comms */
platform_uart_init( mico_bt_uart_driver, mico_bt_uart_peripheral, &bt_uart_config, &rx_ring_buffer );
/* UART receive function may on the pending, but init will clear the rx size, recover here */
mico_bt_uart_driver->rx_size = last_rx_size;
return kNoErr;
} else {
return kGeneralErr;
}
}

View file

@ -0,0 +1,101 @@
#include "mico.h"
#include "platform.h"
#include "platform_config.h"
#ifdef MICO_USE_BT_PARTITION
static uint32_t image_size = 0x0;
void get_one_command(char *out, int offset)
{
//uint32_t size = 0;
uint16_t len = 0;
//resource_read(&bt_patchram_image, offset + 2, 2, &size, &len);
//len &= 0x0ff;
//resource_read(&bt_patchram_image, offset, len + 3, &size, out);
//uint32_t buffer_size;
volatile uint32_t read_address = offset + 2;
mico_logic_partition_t *driver_partition = MicoFlashGetInfo( MICO_PARTITION_BT_FIRMWARE );
if ( image_size == 0) {
image_size = driver_partition->partition_length;
}
MicoFlashRead( MICO_PARTITION_BT_FIRMWARE, &read_address, (uint8_t *)&len, 1);
len = len & 0x00ff;
read_address = offset;
MicoFlashRead( MICO_PARTITION_BT_FIRMWARE, &read_address, (uint8_t *)out, len + 3);
read_address = offset + 10;
}
uint32_t get_hcd_content_length()
{
#define READ_LEN 2048
if (image_size == 0) {
mico_logic_partition_t *driver_partition = MicoFlashGetInfo( MICO_PARTITION_BT_FIRMWARE );
uint32_t offset = driver_partition->partition_length;
uint32_t *p;
uint32_t *buf = (uint32_t *)malloc(READ_LEN);
uint32_t image_size2 = driver_partition->partition_length;
do {
offset -= READ_LEN; // Next block
MicoFlashRead( MICO_PARTITION_BT_FIRMWARE, &offset, (uint8_t *)buf, READ_LEN);
offset -= READ_LEN; // MicoFlashRead will increase FlashAddress READ_LEN, move back.
p = buf + (READ_LEN - 4) / sizeof(uint32_t);
while (p >= buf) {
if (*p != 0xFFFFFFFF) {
goto EXIT;
}
p--;
image_size2 -= 4;
}
} while (offset > 0);
EXIT:
free(buf);
image_size = image_size2; //35584;//image_size2;
}
return image_size;
}
#else
extern const uint8_t brcm_patchram_buf[];
extern const int brcm_patch_ram_length;
/*******************************************************************************
**
** Function get_one_command
**
** Description Called by an application to get a one complete HCI command
**
** Parameters out - (output) buffer where to put the command.
** offset - position of the HCD file
** Returns none
**
*******************************************************************************/
void get_one_command(char *out, int offset)
{
int len = brcm_patchram_buf[2 + offset] & 0x00ff;
memcpy(out, brcm_patchram_buf + offset, 3 + len);
}
/*******************************************************************************
**
** Function get_hcd_content_length
**
** Description get the total length of the HCD content
**
** Parameters none
**
** Returns none
**
*******************************************************************************/
uint32_t get_hcd_content_length()
{
return brcm_patch_ram_length;
}
#endif

View file

@ -0,0 +1,207 @@
/*****************************************************************************
**
** Name: mico_bt_logmsg.c
**
** Description: Contains the LogMsg wrapper routines for BTE. It routes calls
** the appropriate application's LogMsg equivalent.
**
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "bt_types.h"
#include "buildcfg.h"
#include "data_types.h"
#include "mico_rtos.h"
extern int mico_debug_enabled;
extern mico_mutex_t stdio_tx_mutex;
static void printlog(char *M, char *N)
{
if (mico_debug_enabled == 0) {
return;
}
mico_rtos_lock_mutex( &stdio_tx_mutex );
printf("[%ld][%s] %s\r\n", mico_rtos_get_time(), M, N);
mico_rtos_unlock_mutex( &stdio_tx_mutex );
}
void WPRINT_BT_APP_INFO(const char *info, ...)
{
char buffer[256]; // Save stack space - make global
va_list ap;
va_start(ap, info);
vsprintf(buffer, info, ap);
va_end(ap);
printlog("BTAPP", buffer);
}
#if BT_USE_TRACES == TRUE
//extern mico_mutex_t global_trace_mutex;
UINT8 mico_log_enabled = 1;
void
LogMsg(UINT32 trace_set_mask, const char *fmt_str, ...)
{
char buffer[256]; // Save stack space - make global
// char timeBuf[16];
va_list ap;
if ((!mico_log_enabled) && (TRACE_GET_TYPE(trace_set_mask) != TRACE_TYPE_ERROR)) {
/* If mico logging disabled, then only log errors */
return;
}
va_start(ap, fmt_str);
vsprintf(buffer, fmt_str, ap);
va_end(ap);
printlog("BTLOG", buffer);
//printf("[btlog] %s\r\n", buffer);
}
void
ScrLog(UINT32 trace_set_mask, const char *fmt_str, ...)
{
char buffer[256]; // Save stack space - make global
va_list ap;
if ((!mico_log_enabled) && (TRACE_GET_TYPE(trace_set_mask) != TRACE_TYPE_ERROR)) {
/* If mico logging disabled, then only log errors */
return;
}
va_start(ap, fmt_str);
vsprintf(buffer, fmt_str, ap);
va_end(ap);
printlog("BTLOG", buffer);
}
/********************************************************************************
**
** Function Name: LogMsg_0
**
** Purpose: Encodes a trace message that has no parameter arguments
**
** Input Parameters: trace_set_mask: tester trace type.
** fmt_str: displayable string.
** Returns:
** Nothing.
**
*********************************************************************************/
void LogMsg_0( UINT32 trace_set_mask, const char *fmt_str )
{
LogMsg( trace_set_mask, fmt_str );
}
/********************************************************************************
**
** Function Name: LogMsg_1
**
** Purpose: Encodes a trace message that has one parameter argument
**
** Input Parameters: trace_set_mask: tester trace type.
** fmt_str: displayable string.
** Returns:
** Nothing.
**
*********************************************************************************/
void LogMsg_1( UINT32 trace_set_mask, const char *fmt_str, UINTPTR p1 )
{
LogMsg( trace_set_mask, fmt_str, p1 );
}
/********************************************************************************
**
** Function Name: LogMsg_2
**
** Purpose: Encodes a trace message that has two parameter arguments
**
** Input Parameters: trace_set_mask: tester trace type.
** fmt_str: displayable string.
** Returns:
** Nothing.
**
*********************************************************************************/
void LogMsg_2( UINT32 trace_set_mask, const char *fmt_str, UINTPTR p1, UINTPTR p2 )
{
LogMsg( trace_set_mask, fmt_str, p1, p2 );
}
/********************************************************************************
**
** Function Name: LogMsg_3
**
** Purpose: Encodes a trace message that has three parameter arguments
**
** Input Parameters: trace_set_mask: tester trace type.
** fmt_str: displayable string.
** Returns:
** Nothing.
**
*********************************************************************************/
void LogMsg_3( UINT32 trace_set_mask, const char *fmt_str, UINTPTR p1, UINTPTR p2, UINTPTR p3 )
{
LogMsg( trace_set_mask, fmt_str, p1, p2, p3 );
}
/********************************************************************************
**
** Function Name: LogMsg_4
**
** Purpose: Encodes a trace message that has four parameter arguments
**
** Input Parameters: trace_set_mask: tester trace type.
** fmt_str: displayable string.
** Returns:
** Nothing.
**
*********************************************************************************/
void LogMsg_4( UINT32 trace_set_mask, const char *fmt_str, UINTPTR p1, UINTPTR p2, UINTPTR p3, UINTPTR p4 )
{
LogMsg( trace_set_mask, fmt_str, p1, p2, p3, p4 );
}
/********************************************************************************
**
** Function Name: LogMsg_5
**
** Purpose: Encodes a trace message that has five parameter arguments
**
** Input Parameters: trace_set_mask: tester trace type.
** fmt_str: displayable string.
** Returns:
** Nothing.
**
*********************************************************************************/
void LogMsg_5( UINT32 trace_set_mask, const char *fmt_str, UINTPTR p1, UINTPTR p2, UINTPTR p3, UINTPTR p4, UINTPTR p5 )
{
LogMsg( trace_set_mask, fmt_str, p1, p2, p3, p4, p5 );
}
/********************************************************************************
**
** Function Name: LogMsg_6
**
** Purpose: Encodes a trace message that has six parameter arguments
**
** Input Parameters: trace_set_mask: tester trace type.
** fmt_str: displayable string.
** Returns:
** Nothing.
**
*********************************************************************************/
void LogMsg_6( UINT32 trace_set_mask, const char *fmt_str, UINTPTR p1, UINTPTR p2, UINTPTR p3, UINTPTR p4, UINTPTR p5,
UINTPTR p6 )
{
LogMsg( trace_set_mask, fmt_str, p1, p2, p3, p4, p5, p6 );
}
#endif

View file

@ -0,0 +1,408 @@
/*****************************************************************************
**
** Name: mico_bt_nvram_access.c
**
** Description: general method of store/retrieve informations with searching key
** handling linkkey storage
**
******************************************************************************/
#include "common.h"
#include "mico_system.h"
#include "StringUtils.h"
#define EXPORT_API
#include "buildcfg.h"
#include "bt_types.h" /* This must be defined AFTER buildcfg.h */
#include "bt_trace.h"
#include "mico_bt_dev.h"
#include "mico_bt_nvram_access.h"
/** NVRAM entry for bonded device */
#pragma pack(1)
typedef struct {
mico_bt_device_address_t bd_addr; /**< Device address */
uint8_t addr_type; /**< BLE_ADDR_PUBLIC or BLE_ADDR_RANDOM */
uint8_t device_type; /**< BT_DEVICE_TYPE_BREDR or BT_DEVICE_TYPE_BLE */
uint16_t length; /**< Length of key_blobs (link key information) */
uint8_t key_blobs[1]; /**< Link keys (actual length specified by 'length' field) */
} mico_bt_nvram_access_entry_t;
#pragma pack()
#if defined(BTM_INTERNAL_LINKKEY_STORAGE_INCLUDED) && (BTM_INTERNAL_LINKKEY_STORAGE_INCLUDED == TRUE)
/**
* Function mico_bt_nvram_access_init
*
* initialize nvram control block
*
* @param[in] max_num_bonded_devices : maximum limit of number of bonded devices
*
* @return void
*/
void mico_bt_nvram_access_init()
{
return;
}
/**
* Function mico_bt_nvram_access_get_bonded_devices
*
* get lists of bonded devices stored in nvram
*
* @param[in] paired_device_list : array for getting bd address of bonded devices
* @param[in/out] p_num_devices : list size of paired_device_list/total number of bonded devices stored
*
* @return MICO_BT_SUCCESS or ERROR
*/
mico_bt_result_t mico_bt_nvram_access_get_bonded_devices(mico_bt_dev_bonded_device_info_t bonded_device_list[],
uint16_t *p_num_devices)
{
int index, list_size = 0;
mico_bt_nvram_access_entry_t *p_entry;
char key[32];
int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS;
*p_num_devices = 0;
p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen);
if (p_entry == NULL) {
return -1;
}
for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) {
sprintf(key, "bt_bounded_dev%d", index);
if (aos_kv_get(key, p_entry, buflen) != 0) {
continue;
}
memcpy(bonded_device_list[list_size].bd_addr, p_entry->bd_addr, sizeof(p_entry->bd_addr));
bonded_device_list[list_size].addr_type = p_entry->addr_type;
bonded_device_list[list_size].device_type = p_entry->device_type;
list_size++;
}
*p_num_devices = list_size;
APPL_TRACE_DEBUG2("%s num bonded devices : %d", __FUNCTION__, *p_num_devices );
free(p_entry);
return MICO_BT_SUCCESS;
}
/**
* Function mico_bt_nvram_access_save_bonded_device_key
*
* save link key information of bonded device
*
* @param[in] bd_addr : bd_addr of bonded device
* @param[in] p_keyblobs : key blobs including key header, link keys and key length
* @param[in] key_len : total length of p_keyblobs
*
* @return MICO_BT_SUCCESS or ERROR
*/
mico_bt_result_t mico_bt_nvram_access_save_bonded_device_key(mico_bt_device_address_t bd_addr,
mico_bt_ble_address_type_t addr_type, uint8_t device_type, uint8_t *p_keyblobs, uint16_t key_len)
{
int index, list_size = 0, idle_index = -1, ret = MICO_BT_SUCCESS;
mico_bt_nvram_access_entry_t *p_entry;
char key[32];
int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS;
p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen);
if (p_entry == NULL) {
return -1;
}
for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) {
sprintf(key, "bt_bounded_dev%d", index);
if (aos_kv_get(key, p_entry, buflen) != 0) {
idle_index = index;
continue;
}
if ( !memcmp(p_entry->bd_addr, bd_addr, sizeof(mico_bt_device_address_t) )) { // found
if ( (key_len == p_entry->length) && (memcmp( p_entry->key_blobs, p_keyblobs, key_len ) == 0)) { // same key
APPL_TRACE_DEBUG0( "Same key, write ignore..." );
} else {
p_entry->length = key_len;
memcpy(p_entry->key_blobs, p_keyblobs, key_len);
aos_kv_set(key, p_entry, buflen, 1);
APPL_TRACE_DEBUG0( "Found and update" );
}
goto EXIT;
}
}
if (idle_index > 0) {
sprintf(key, "bt_bounded_dev%d", idle_index);
memcpy(p_entry->bd_addr, bd_addr, MICO_BT_DCT_ADDR_FIELD);
p_entry->addr_type = addr_type;
p_entry->device_type = device_type;
p_entry->length = key_len;
memcpy(p_entry->key_blobs, p_keyblobs, key_len);
aos_kv_set(key, p_entry, p_entry->length + sizeof(mico_bt_nvram_access_entry_t), 1);
APPL_TRACE_DEBUG0( "Create new one" );
} else {
ret = -1;
APPL_TRACE_DEBUG0( "Can't save more" );
goto EXIT;
}
EXIT:
free(p_entry);
return ret;
}
/**
* Function mico_bt_nvram_access_load_bonded_device_keys
*
* loads stored key information for bonded device having @bd_addr
*
* @param[in] bd_addr : bd_addr of bonded device
* @param[out] p_key_entry : key information stored
*
* @return MICO_BT_SUCCESS or ERROR
*/
mico_bt_result_t mico_bt_nvram_access_load_bonded_device_keys(mico_bt_device_address_t bd_addr,
mico_bt_nvram_access_entry_t *p_key_entry, uint8_t entry_max_length)
{
int index, ret = MICO_BT_NO_RESOURCES;
mico_bt_nvram_access_entry_t *p_entry;
char key[32];
int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS;
p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen);
if (p_entry == NULL) {
return -1;
}
for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) {
sprintf(key, "bt_bounded_dev%d", index);
if (aos_kv_get(key, p_entry, buflen) != 0) {
continue;
}
if ( !memcmp(p_entry->bd_addr, bd_addr, sizeof(mico_bt_device_address_t) )) { // found
if (entry_max_length < p_entry->length) {
ret = MICO_BT_ILLEGAL_VALUE;
} else {
p_key_entry->addr_type = p_entry->addr_type;
p_key_entry->device_type = p_entry->device_type;
p_key_entry->length = p_entry->length;
memcpy(p_key_entry->key_blobs, p_entry->key_blobs, p_entry->length);
ret = MICO_BT_SUCCESS;
}
}
}
EXIT:
free(p_entry);
return ret;
}
/**
* Function mico_bt_nvram_access_delete_bonded_device
*
* remove key information from storage by releasing bonding with remote device having @bd_addr
*
* @param[in] bd_addr : bd_addr of bonded device to be removed
* @return MICO_BT_SUCCESS or ERROR
*/
mico_bt_result_t mico_bt_nvram_access_delete_bonded_device(mico_bt_device_address_t bd_addr)
{
int index, ret = MICO_BT_NO_RESOURCES;
mico_bt_nvram_access_entry_t *p_entry;
char key[32];
int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS;
p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen);
if (p_entry == NULL) {
return -1;
}
for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) {
sprintf(key, "bt_bounded_dev%d", index);
if (aos_kv_get(key, p_entry, buflen) != 0) {
continue;
}
if ( !memcmp(p_entry->bd_addr, bd_addr, sizeof(mico_bt_device_address_t) )) { // found
aos_kv_del(key);
ret = MICO_BT_SUCCESS;
goto EXIT;
}
}
EXIT:
free(p_entry);
return ret;
}
/**
* Function mico_bt_nvram_access_load_local_identity_keys
*
* load local identity keys including ir/irk/dhk stored in nvram
*
* @param[out] p_lkeys: local identity key information
*
* @return MICO_BT_SUCCESS or ERROR
*/
mico_bt_result_t mico_bt_nvram_access_load_local_identity_keys(mico_bt_local_identity_keys_t *p_lkeys)
{
int ret;
ret = aos_kv_get("bt_local_key", p_lkeys, sizeof(mico_bt_local_identity_keys_t));
if (ret != 0) {
return MICO_BT_NO_RESOURCES;
} else {
return MICO_BT_SUCCESS;
}
}
/**
* Function mico_bt_nvram_access_save_local_identity_keys
*
* save local identity keys including ir/irk/dhk to nvram
*
* @param[in] p_lkeys : local identity key information
*
* @return MICO_BT_SUCCESS or ERROR
*/
mico_bt_result_t mico_bt_nvram_access_save_local_identity_keys(mico_bt_local_identity_keys_t *p_lkeys)
{
int ret;
ret = aos_kv_set("bt_local_key", p_lkeys, sizeof(mico_bt_local_identity_keys_t), 1);
if (ret != 0) {
return MICO_BT_NO_RESOURCES;
} else {
return MICO_BT_SUCCESS;
}
}
/**
* Function mico_bt_nvram_access_key_storage_available
*
* query if there are available spaces for storing key information
* for device with @bd_addr with requested @req_size
*
* @param[in] bd_addr : bd_addr of bonded device
* @param[in] req_size : requested size to be stored
*
* @return TRUE if there is available space or FALSE
*/
BOOLEAN mico_bt_nvram_access_key_storage_available(mico_bt_device_address_t bd_addr, int req_size)
{
int index, found = 0;
mico_bt_nvram_access_entry_t *p_entry;
char key[32];
int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS;
p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen);
if (p_entry == NULL) {
return -1;
}
for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) {
sprintf(key, "bt_bounded_dev%d", index);
if (aos_kv_get(key, p_entry, buflen) != 0) {
found = 1;
}
}
free(p_entry);
if (found == 0) {
return FALSE;
} else {
return TRUE;
}
}
/**
* Function mico_bt_nvram_access_enum_bonded_device_keys
*
* load stored key information by enumeration
*
* @param[out] p_index : index of stored key
* @param[out] p_key_entry : key information stored
*
* @return MICO_BT_SUCCESS or ERROR
*/
mico_bt_result_t mico_bt_nvram_access_enum_bonded_device_keys(int8_t *p_index,
mico_bt_nvram_access_entry_t *p_key_entry, uint8_t entry_max_length)
{
static int8_t enum_index = 0;
char key[32];
*p_index = enum_index;
sprintf(key, "bt_bounded_dev%d", enum_index);
enum_index++;
if (enum_index == MICO_BT_DCT_MAX_KEYBLOBS) {
enum_index = 0;
}
if (aos_kv_get(key, p_key_entry, entry_max_length + sizeof(*p_key_entry)) != 0) {
return -1;
}
return MICO_BT_SUCCESS;
}
/**
* Function mico_bt_nvram_access_find_offset
*
*
* @param[in] *key_bdaddr : bd_addr of bonded device
* @param[in] start_offset : start offset where to start searching
* @param[out] p_offset : stored offset of bonded device of bd_addr
*
* @return TRUE if found or FALSE
*/
mico_bool_t mico_bt_nvram_access_find_device( mico_bt_device_address_t key_bdaddr )
{
int index, list_size = 0;
mico_bt_nvram_access_entry_t *p_entry;
char key[32];
int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS;
mico_bool_t found_keyblobs = FALSE;
p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen);
if (p_entry == NULL) {
return -1;
}
for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) {
sprintf(key, "bt_bounded_dev%d", index);
if (aos_kv_get(key, p_entry, buflen) != 0) {
continue;
}
if ( !memcmp(p_entry->bd_addr, key_bdaddr, sizeof(mico_bt_device_address_t) )) { // found
found_keyblobs = TRUE;
break;
}
}
free(p_entry);
return found_keyblobs;
}
#endif /* #if defined(BTM_INTERNAL_LINKKEY_STORAGE_INCLUDED) && (BTM_INTERNAL_LINKKEY_STORAGE_INCLUDED == TRUE) */

View file

@ -0,0 +1,134 @@
/*****************************************************************************
**
** Name upio_bby.c
**
** Description
** This file contains the universal driver wrapper for the BTE-QC pio
** drivers
**
*****************************************************************************/
#include "buildcfg.h"
#include "mico_bt_dev.h"
#include "include/upio.h"
#include "platform_bluetooth.h"
/******************************************************
* Variables Definitions
******************************************************/
//static volatile mico_bool_t bus_initialised = MICO_FALSE;
//static volatile mico_bool_t device_powered = MICO_FALSE;
/*******************************************************************************
** UPIO Driver functions
*******************************************************************************/
/*****************************************************************************
**
** Function UPIO_Init
**
** Description
** Initialize the GPIO service.
** This function is typically called once upon system startup.
**
** Returns nothing
**
*****************************************************************************/
UDRV_API void UPIO_Init( void *p_cfg )
{
//DRV_TRACE_DEBUG0("UPIO_Init");
}
/*****************************************************************************
**
** Function UPIO_Set
**
** Description
** This function sets one or more GPIO devices to the given state.
** Multiple GPIOs of the same type can be masked together to set more
** than one GPIO. This function can only be used on types UPIO_LED and
** UPIO_GENERAL.
**
** Input Parameters:
** type The type of device.
** pio Indicates the particular GPIOs.
** state The desired state.
**
** Output Parameter:
** None.
**
** Returns:
** None.
**
*****************************************************************************/
UDRV_API void UPIO_Set( tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state )
{
//DRV_TRACE_DEBUG2("UPIO_Set %d, %s", pio, UPIO_OFF == state ? "UPIO_OFF" : "UPIO_ON");
#if HCILP_INCLUDED
if (UPIO_OFF == state) {
platform_gpio_output_low( mico_bt_control_pins[MICO_BT_PIN_DEVICE_WAKE] );
} else {
platform_gpio_output_high( mico_bt_control_pins[MICO_BT_PIN_DEVICE_WAKE] );
}
#endif
}
/*****************************************************************************
**
** Function UPIO_Read
**
** Description
** Read the state of a GPIO. This function can be used for any type of
** device. Parameter pio can only indicate a single GPIO; multiple GPIOs
** cannot be masked together.
**
** Input Parameters:
** Type: The type of device.
** pio: Indicates the particular GUPIO.
**
** Output Parameter:
** None.
**
** Returns:
** State of GPIO (UPIO_ON or UPIO_OFF).
**
*****************************************************************************/
UDRV_API tUPIO_STATE UPIO_Read( tUPIO_TYPE type, tUPIO pio )
{
#if HCILP_INCLUDED
//DRV_TRACE_DEBUG1("UPIO_Read %d", pio);
return platform_gpio_input_get(mico_bt_control_pins[MICO_BT_PIN_HOST_WAKE]) ? UPIO_ON : UPIO_OFF;
#else
return UPIO_OFF;
#endif
}
/*****************************************************************************
**
** Function UPIO_Config
**
** Description - Configure GPIOs of type UPIO_GENERAL as inputs or outputs
** - Configure GPIOs to be polled or interrupt driven
**
**
** Output Parameter:
** None.
**
** Returns:
** None.
**
*****************************************************************************/
#if 0
UDRV_API void UPIO_Config( tUPIO_TYPE type, tUPIO pio, tUPIO_CONFIG config, tUPIO_CBACK *cback )
{
}
#endif
#if 0
mico_bool_t bt_bus_is_ready( void )
{
return ( bus_initialised == MICO_FALSE ) ? MICO_FALSE : ( ( mico_gpio_input_get( BLUETOOTH_GPIO_CTS_PIN ) == MICO_TRUE )
? MICO_FALSE : MICO_TRUE );
}
#endif

View file

@ -0,0 +1,9 @@
NAME := Lib_Ble_Access_Core_Framework
GLOBAL_INCLUDES += .
$(NAME)_SOURCES := ble_access_core.c \
ble_access_core_i.c
$(NAME)_COMPONENTS := framework/bluetooth/bt_smart \
framework/bluetooth/low_energy

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,443 @@
#ifndef __BLE_ACCESS_CORE_H__
#define __BLE_ACCESS_CORE_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
*-------------------------------------------------------------------------------------------------
*
* Configurations & Constants
*
*-------------------------------------------------------------------------------------------------
*/
/* The prefix of device address of peripheral device. */
#define BLE_ACCESS_PREFIX_LEN 3
#define BLE_ACCESS_PREFIX_D0BAE4 "\xD0\xBA\xE4"
#define BLE_ACCESS_PREFIX_C89346 "\xC8\x93\x46"
/* The maximum length of a Bluetooth Device Name */
#define BLE_ACCESS_DEVICE_NAME_MAX_LEN 16
/* Advertisement PACKET type */
#define BLE_ACCESS_ADV_TYPE_INIT 0x01
#define BLE_ACCESS_ADV_TYPE_RECONN 0x02
/*
*-------------------------------------------------------------------------------------------------
* Host Request Command
*-------------------------------------------------------------------------------------------------
*/
#define BLE_ACCESS_STATUS_SUCCESS 0x00
#define BLE_ACCESS_STATUS_FAILED 0x01
#define BLE_ACCESS_STATUS_AUTH_FAILED 0x02
#define BLE_ACCESS_STATUS_ADD_FAILED 0x03
#define BLE_ACCESS_STATUS_SLAVE_REJECT 0x04
#define BLE_ACCESS_STATUS_RECONN_FAILED 0x05
#define BLE_ACCESS_STATUS_NO_RESOURCES 0x06
#define BLE_ACCESS_STATUS_BUSY 0x07
#define BLE_ACCESS_STATUS_TIMEOUT 0x08
#define BLE_ACCESS_STATUS_SLAVE_REQ_DISC 0x09
#define BLE_ACCESS_STATUS_INVALID_PARMS 0x0A
#define BLE_ACCESS_STATUS_NO_CONNECTION 0x0B
/*
* input: none
* output: device_id,name,RSSI (BLE_ACCESS_EVENT_DEV_NEW)
*/
#define BLE_ACCESS_REQ_DEV_SCAN 0x01
/*
* input: device_id
* output: device_id, status (BLE_ACCESS_EVENT_DEV_ADD)
*/
#define BLE_ACCESS_REQ_DEV_ADD 0x02
/*
* input: device_id, timeout
* output: device_id, status (BLE_ACCESS_EVENT_DEV_DISC)
*/
#define BLE_ACCESS_REQ_DEV_DISC 0x03
/*
* input: device_id
* output: device_id, status (BLE_ACCESS_EVENT_DEV_REMOVE)
*/
#define BLE_ACCESS_REQ_DEV_REMOVE 0x04
/*
* input: none
* output: none
*/
#define BLE_ACCESS_REQ_DEV_START_AUTO 0x05 /* Request to start auto connection procedure */
/*
* input: none
* output: none
*/
#define BLE_ACCESS_REQ_DEV_STOP_AUTO 0x06 /* Request to stop auto connection procedure */
/*
* Request command parameters
*/
typedef struct {
uint32_t device_id;
union {
/* used by BLE_ACCESS_REQ_DEV_SCAN */
mico_bool_t start;
/* used by BLE_ACCESS_REQ_DEV_DISC */
uint32_t timeout;
} p;
} ble_access_cmd_parms_t;
/*
* UUID type
*/
typedef struct {
uint16_t len; /* UUID length */
union {
uint16_t uuid16; /* 16-bit UUID */
uint32_t uuid32; /* 32-bit UUID */
uint8_t uuid128[16]; /* 128-bit UUID */
} uu;
} ble_access_uuid_t;
#pragma pack(1)
/*
* 3.1 Attribute Value of Service Definition
*/
typedef struct {
uint16_t start_handle; /* Starting handle */
uint16_t end_handle; /* Ending handle */
ble_access_uuid_t uuid; /* UUID */
} ble_access_attr_val_serv_t;
/*
* 3.2 Attribute Value of Include Definition
*/
typedef struct {
uint16_t included_service_handle; /* Included service handle */
uint16_t end_group_handle; /* End group handle */
ble_access_uuid_t uuid; /* UUID */
} ble_access_attr_val_inc_t;
/*
* 3.3.1 Attribute Value of Characteristic Declaration
*/
typedef struct {
uint8_t properties; /* Properties */
uint16_t value_handle; /* Value handle */
ble_access_uuid_t uuid; /* UUID */
uint16_t descriptor_start_handle; /* Descriptor start handle. Additional field. Not in spec */
uint16_t descriptor_end_handle; /* Descriptor end handle. Additional field. Not in spec */
} ble_access_attr_val_char_t;
/*
* 3.3.2 Attribute Value of Characteristic Value Declaration
*/
typedef struct {
uint8_t value[1]; /* Start of value */
} ble_access_attr_val_char_val_t;
/*
* 3.3.3.1 Attribute Value of Characteristic Extended Properties
*/
typedef struct {
uint8_t properties; /* Properties */
} ble_access_attr_val_ext_prop_t;
/*
* 3.3.3.2 Attribute Value of Characteristic User Description
*/
typedef struct {
char string[1]; /* User description string */
} ble_access_attr_val_usr_desc_t;
/*
* 3.3.3.3 Attribute Value of Client Characteristic Configuration
*/
typedef struct {
uint16_t config_bits; /* Configuration bits */
} ble_access_attr_val_cli_cfg_t;
/*
* 3.3.3.4 Attribute Value of Server Characteristic Configuration
*/
typedef struct {
uint16_t config_bits; /* Configuration bits */
} ble_access_attr_val_srv_cfg_t;
/*
* 3.3.3.5 Attribute Value of Characteristic Presentation Format
*/
typedef struct {
uint8_t format; /* Format */
uint8_t exponent; /* Exponent */
uint16_t unit; /* Unit */
uint8_t name_space; /* Namespace */
uint16_t description; /* Description */
} ble_access_attr_val_pres_format_t;
/*
* 3.3.3.6 Attribute Value of Characteristic Aggregate Format
*/
typedef struct {
uint16_t handle_list[1]; /* Handle list */
} ble_access_attr_val_aggre_format_t;
/*
* Vol 3 Part C 12.1 Attribute Value of Device Name Characteristic
*/
typedef struct {
char device_name[1]; /* Maximum length is 248 bytes */
} ble_access_attr_val_dev_name_t;
/*
* Vol 3 Part C 12.2 Attribute Value of Appearance Characteristic
*/
typedef struct {
uint16_t appearance; /* Enumerated value defined in "Assigned Numbers" */
} ble_access_attr_val_appear_t;
/*
* Vol 3 Part C 12.3 Attribute Value of Peripheral Privacy Flag Characteristic
*/
typedef struct {
uint8_t periph_privacy_flag; /* Peripheral privacy flag: 0 if disabled; 1 if enabled */
} ble_access_attr_val_privacy_flag_t;
/*
* Vol 3 Part C 12.4 Attribute Value of Reconnection Address Characteristic
*/
typedef struct {
uint8_t reconn_address[6]; /* Network-order reconnection address */
} ble_access_attr_val_reconn_addr_t;
/*
* Vol 3 Part C 12.5 Attribute Value of Peripheral Preferred Connection Parameters Characteristic
*/
typedef struct {
uint16_t min_conn_interval; /* Minimum connection interval */
uint16_t max_conn_interval; /* Maximum connection interval */
uint16_t slave_latency; /* Slave latency */
uint16_t conn_supervision_timeout_multiplier; /* Connection supervision timeout multiplier */
} ble_access_attr_val_conn_parms_t;
/*
* Attribute Structure
*/
typedef struct {
void *next; // Not used.
uint16_t handle; // attribute handle
ble_access_uuid_t type; // attribute type
uint8_t permission; // attribute permissions
uint32_t value_length; // length of the attribute value. If no value, this equals 0
uint32_t value_struct_size; // size of the value structure
/* Union of attribute values. Use the right format based on Attribute Type */
union {
/* Not support Long Value */
uint8_t value[512];
/* Attribute Value for Service */
ble_access_attr_val_serv_t service;
/* Attribute Value for Include */
ble_access_attr_val_inc_t include;
/* Attribute Value for Characteristic */
ble_access_attr_val_char_t characteristic;
/* Attribute Value for Characteristic Value */
ble_access_attr_val_char_val_t characteristic_value;
/* Attribute Value for Descriptor: Characteristic Extended Properties */
ble_access_attr_val_ext_prop_t extended_properties;
/* Attribute Value for Descriptor: Characteristic User_Description */
ble_access_attr_val_usr_desc_t user_description;
/* Attribute Value for Descriptor: Client Characteristic Configuration */
ble_access_attr_val_cli_cfg_t client_config;
/* Attribute Value for Descriptor: Server Characteristic Configuration */
ble_access_attr_val_srv_cfg_t server_config;
/* Attribute Value for Descriptor: Characteristic Presentation Format */
ble_access_attr_val_pres_format_t presentation_format;
/* Attribute Value for Descriptor: Characteristic Aggregate Format */
ble_access_attr_val_aggre_format_t aggregate_format;
/* Attribute Value for Characteristic Type: Device Name */
ble_access_attr_val_dev_name_t device_name;
/* Attribute Value for Characteristic Type: Appearance */
ble_access_attr_val_appear_t appearance;
/* Attribute Value for Characteristic Type: Peripheral Privacy Flag */
ble_access_attr_val_privacy_flag_t periph_privacy_flag;
/* Attribute Value for Characteristic Type: Reconnection Address */
ble_access_attr_val_reconn_addr_t reconn_address;
/* Attribute Value for Characteristic Type: Peripheral Preferred Connection Parameters */
ble_access_attr_val_conn_parms_t periph_preferred_conn_params;
} value;
} ble_access_attribute_t;
#pragma pack()
/*
*-------------------------------------------------------------------------------------------------
* Controller Command Response
*-------------------------------------------------------------------------------------------------
*/
#define BLE_ACCESS_EVENT_DEV_NEW 0x01 /* A new device is scanned. */
#define BLE_ACCESS_EVENT_DEV_NEW_CMPL 0x02 /* The new device discovery procedure has completed. */
#define BLE_ACCESS_EVENT_DEV_AUTHING 0x03 /* A new device is authing. */
#define BLE_ACCESS_EVENT_DEV_ADD 0x04 /* A new device is or isn't added. */
#define BLE_ACCESS_EVENT_DEV_CONN 0x05 /* A old device is re-connection */
#define BLE_ACCESS_EVENT_DEV_DISC 0x06 /* A device request to disconnect */
#define BLE_ACCESS_EVENT_GATT_CHAR 0x07 /* A characteristic event for ble_access_get_characteristics */
#define BLE_ACCESS_EVENT_GATT_CHAR_CMPL 0x08 /* All characteristics event finished. */
#define BLE_ACCESS_EVENT_GATT_NOTIFY 0x09 /* A notification from peer server */
/*
* Used to descript a GATT Service Handle range and its type.
*/
typedef struct {
uint16_t start_handle;
uint16_t end_handle;
ble_access_uuid_t type;
} ble_access_serv_t;
/*
* Event Handle Parameters
*/
typedef struct {
/* Always valid */
uint32_t device_id;
uint8_t status;
union {
/* BLE_ACCESS_BT_EVENT_DEV_ADD and BLE_ACCESS_BT_EVENT_DEV_CONN */
struct {
uint8_t serv_count;
ble_access_serv_t *serv;
} add;
/* BLE_ACCESS_EVENT_CHAR and BLE_ACCESS_EVENT_GATT_NOTIFY */
struct {
ble_access_attribute_t *attr;
} gatt;
/* BLE_ACCESS_EVENT_DEV_NEW */
struct {
char *name;
int8_t RSSI;
} scan;
/* BLE_ACCESS_EVENT_DEV_STATE */
uint8_t state;
} p;
} ble_access_evt_parms_t;
/*
* Event handle
*/
typedef void (*ble_access_event_callback_t)(uint8_t event, const ble_access_evt_parms_t *params);
/* Initialize Bluetooth Interface */
extern OSStatus ble_access_bluetooth_init(void);
/* Start BLE Auto Connection Procedure */
extern OSStatus ble_access_bluetooth_start(ble_access_event_callback_t callback);
/* Stop BLE Auto Connection Procedure */
extern OSStatus ble_access_bluetooth_stop(void);
/* Send a command to Bluetooth Interface. */
extern OSStatus ble_access_bluetooth_request(uint8_t request,
const ble_access_cmd_parms_t *parms);
/*
* Get an attribute of Characteristic with the UUID provided from the local attribute database.
*
* @param dev_id[in] The Peer Device ID.
* @param serv[in] The GATT Service Handle Structure. (used start_handle & end_handle)
* @param uuid[in] The Characteristic UUID.
* @param attr[inout] This function calling result in attr->characteristic.
*/
extern OSStatus ble_access_get_characteritic_by_uuid(uint32_t dev_id,
const ble_access_serv_t *serv,
const ble_access_uuid_t *uuid,
ble_access_attribute_t *attr);
/*
* Find all characteristics for 'serv' from the local attribute database and generate
* several EVENT 'BLE_ACCESS_EVENT_CHAR' and 'BLE_ACCESS_EVENT_CHAR_CMPL' to user application.
*
* @param dev_id[in] The Peer Device ID.
* @param serv[in] The GATT Service Handle Structure. (used start_handle & end_handle)
*/
extern OSStatus ble_access_get_characteristics(uint32_t dev_id,
const ble_access_serv_t *serv);
/*
* Find and read attribute with the Handle provided from the Attribute Cache
*
* @param dev_id[in] The Peer Device ID.
* @param handle[in] The Attribute Handle Value
* @param attr[out] This function calling result. And user should make sure its is a valid pointer.
* @param size[in] The 'attr' buffer size in bytes.
*/
extern OSStatus ble_access_get_attribute_by_handle(uint32_t dev_id,
uint16_t handle,
ble_access_attribute_t *attr);
/*
* Update Characteristic Value in the Attribute To the server
*
* @param dev_id[in] The Peer device ID
* @param handle[in] The characteristic value handle.
* @param length[in] The lenght of Data to update characteristic value.
* @param data[in] Point to the data to update characteristic value.
*/
extern OSStatus ble_access_update_characteristic_value(uint32_t dev_id, uint16_t handle, uint8_t length, uint8_t *data);
/*
* Enable Characteristic Client Configuration Indication or Notification with the
* attribute provided from the Attribute Cache
*
* @param dev_id[in] The Peer Device ID.
* @param attr[int] This function calling result. And user should make sure its is a valid pointer.
* @param notify[in] Notification(YES) or Indication(FALSE)
*/
extern OSStatus ble_access_enable_notification(uint32_t dev_id,
const ble_access_attribute_t *attr,
mico_bool_t notify);
/*
* Compare two UUID type.
*
* @param uuid1[in]
* @param uuid2[in]
*
* @return 0 if they are equal, otherwise non-zero.
*/
extern mico_bool_t ble_access_uuid_compare(const ble_access_uuid_t *uuid1, const ble_access_uuid_t *uuid2);
/*
* Calculate device ID by Device Address
*
* @param addr[in] device address
*
* @return device ID or zero
*/
extern uint32_t ble_access_calculate_device_id(const mico_bt_device_address_t addr);
/*
* Generate a device address by device ID
*
* @param addr[out] device address
* @param device_id[in] device ID
*
* @return kNoErr if successful.
*/
extern OSStatus ble_access_generate_device_address(mico_bt_device_address_t addr, uint32_t device_id);
#ifdef __cplusplus
}
#endif
#endif /* __BLE_ACCESS_CORE_H__ */

View file

@ -0,0 +1,624 @@
#include <string.h>
#include <stdio.h>
#include "mico.h"
#include "mico_bt.h"
#include "mico_bt_cfg.h"
#include "mico_bt_smart_interface.h"
#include "mico_bt_smartbridge.h"
#include "mico_bt_smartbridge_gatt.h"
#include "sdpdefs.h"
#include "gattdefs.h"
#include "StringUtils.h"
#include "LinkListUtils.h"
#include "ble_access_core.h"
#include "ble_access_core_i.h"
/*
*-------------------------------------------------------------------------------------------------
*
* Configurations & Constants
*
*-------------------------------------------------------------------------------------------------
*/
/*
*-------------------------------------------------------------------------------------------------
*
* Predefine Type
*
*-------------------------------------------------------------------------------------------------
*/
/*
*-------------------------------------------------------------------------------------------------
*
* Local Function Prototype
*
*-------------------------------------------------------------------------------------------------
*/
/*
*-------------------------------------------------------------------------------------------------
*
* Local Variables
*
*-------------------------------------------------------------------------------------------------
*/
static ble_access_device_t ble_access_devices[MAX_CONCURRENT_CONNECTIONS];
static mico_mutex_t ble_access_dev_mutex;
static linked_list_t ble_access_connecting_device_list;
static mico_mutex_t ble_access_conn_dev_list_mutex;
static mico_worker_thread_t ble_access_worker_thread;
static event_handler_t ble_access_timer_evt;
/* Prefix Address for valid device MAC Address */
static uint8_t prefix_addr[][BLE_ACCESS_PREFIX_LEN] = {
[0] = {
BLE_ACCESS_PREFIX_D0BAE4
},
[1] = {
BLE_ACCESS_PREFIX_C89346
},
};
/*
*-------------------------------------------------------------------------------------------------
*
* Global Function Definition
*
*-------------------------------------------------------------------------------------------------
*/
/*
* Worker thread
*/
OSStatus ble_access_create_worker_thread(void)
{
return mico_rtos_create_worker_thread(&ble_access_worker_thread,
MICO_DEFAULT_WORKER_PRIORITY,
2048,
20);
}
OSStatus ble_access_send_aync_event(event_handler_t event_handle, void *arg)
{
return mico_rtos_send_asynchronous_event(&ble_access_worker_thread, event_handle, arg);
}
/*
* Timer Management
*/
static void ble_access_timer_callback(void *arg)
{
if (ble_access_timer_evt) {
ble_access_send_aync_event(ble_access_timer_evt, arg);
}
}
OSStatus ble_access_start_timer(ble_access_device_t *dev, event_handler_t timer_event_handle, void *arg)
{
OSStatus err = kNoErr;
require_action(dev != NULL && timer_event_handle != NULL, exit, err = kParamErr);
err = mico_rtos_init_timer(&dev->timer, 10000, ble_access_timer_callback, arg);
require_noerr_string(err, exit, "Initialize a timer failed");
err = mico_rtos_start_timer(&dev->timer);
require_noerr_action_string(err, exit, mico_rtos_deinit_timer(&dev->timer), "Start a timer failed");
ble_access_timer_evt = timer_event_handle;
exit:
return err;
}
OSStatus ble_access_stop_timer(ble_access_device_t *dev)
{
OSStatus err = kNoErr;
require_action(dev != NULL, exit, err = kParamErr);
if (mico_rtos_is_timer_running(&dev->timer)) {
mico_rtos_stop_timer(&dev->timer);
}
err = mico_rtos_deinit_timer(&dev->timer);
exit:
return err;
}
/*
* Local Device Pool Management
*/
/* Initialize a devices pool */
void ble_access_initialize_devices(void)
{
OSStatus err = kNoErr;
uint8_t idx = 0;
for (idx = 0; idx < ble_access_array_size(ble_access_devices); idx++) {
ble_access_devices[idx].used = FALSE;
ble_access_devices[idx].device_id = 0;
err = mico_bt_smartbridge_create_socket(&ble_access_devices[idx].socket);
require_noerr_string(err, exit, "Create Sockets failed");
}
mico_rtos_init_mutex(&ble_access_dev_mutex);
exit:
return;
}
/* De-initialize a devices pool */
void ble_access_deinit_devices(void)
{
uint8_t idx = 0;
for (idx = 0; idx < ble_access_array_size(ble_access_devices); idx++) {
mico_bt_smartbridge_delete_socket(&ble_access_devices[idx].socket);
}
mico_rtos_deinit_mutex(&ble_access_dev_mutex);
}
ble_access_device_t *ble_access_find_device_by_address(const mico_bt_device_address_t address)
{
uint8_t idx = 0;
ble_access_device_t *dev = NULL;
uint32_t device_id = ble_access_calculate_device_id(address);
mico_rtos_lock_mutex(&ble_access_dev_mutex);
for (idx = 0; idx < ble_access_array_size(ble_access_devices); idx++) {
if (ble_access_devices[idx].used && device_id == ble_access_devices[idx].device_id) {
break;
}
}
if (idx < ble_access_array_size(ble_access_devices)) {
dev = &ble_access_devices[idx];
}
mico_rtos_unlock_mutex(&ble_access_dev_mutex);
return dev;
}
/* Get a free socket from 'sockets' */
ble_access_device_t *ble_access_get_free_device(void)
{
uint8_t idx = 0;
mico_rtos_lock_mutex(&ble_access_dev_mutex);
for (idx = 0; idx < ble_access_array_size(ble_access_devices); idx++) {
if (!ble_access_devices[idx].used) {
ble_access_devices[idx].used = TRUE;
mico_rtos_unlock_mutex(&ble_access_dev_mutex);
return &ble_access_devices[idx];
}
}
mico_rtos_unlock_mutex(&ble_access_dev_mutex);
return NULL;
}
void ble_access_release_device(mico_bool_t free, const ble_access_device_t *device)
{
uint8_t idx = 0;
mico_rtos_lock_mutex(&ble_access_dev_mutex);
if (device != NULL) {
for (idx = 0;
idx < ble_access_array_size(ble_access_devices) && device != &ble_access_devices[idx];
idx++);
if (idx < ble_access_array_size(ble_access_devices) && free) {
ble_access_devices[idx].device_id = 0;
ble_access_devices[idx].used = FALSE;
}
}
mico_rtos_unlock_mutex(&ble_access_dev_mutex);
}
/*
* Generate a BT device address by device_id and prefix.
*
* @param[output] addr - device address
* @param[input] prefix_addr - a prefix address array.
* @param[input] device_id - a device id.
*
* addr[0 - 2] = prefix_addr[0 - 2]
* addr[3] = device_id[bit23:bit16]
* addr[4] = device_id[bit15:bit8]
* addr[5] = device_id[bit7:bit0]
*
* example:
* prefix - { 0x20, 0x73, 0x6a }, device_id = 0x12112233,
* ---->
* addr = { 0x20, 0x73, 0x6a, 0x11, 0x22, 0x33 }
*/
OSStatus ble_access_generate_device_address(mico_bt_device_address_t addr, uint32_t device_id)
{
uint8_t idx_addr_type = 0;
/* Check Parameters */
if (addr == NULL) {
return kParamErr;
}
idx_addr_type = (uint8_t)((device_id & 0xff000000) >> 24);
if (idx_addr_type >= ble_access_array_size(prefix_addr)) {
return kParamErr;
}
/* Fill prefix address part */
memcpy(addr, prefix_addr[idx_addr_type], 3);
/* Fill the device id part (little endian) */
addr[3] = (uint8_t)((device_id & 0x00ffffff) >> 16);
addr[4] = (uint8_t)((device_id & 0x00ffffff) >> 8);
addr[5] = (uint8_t)((device_id & 0x00ffffff));
return kNoErr;
}
/*
* Calculate the device ID according device address.
*
* @param[input] addr - the device address
*
* return device ID.
*
* example:
* addr = { 0x20, 0x73, 0x6a, 0x11, 0x22, 0x33 };
* so, device_id = 0x112233.
*/
uint32_t ble_access_calculate_device_id(const mico_bt_device_address_t addr)
{
uint32_t id = 0x00000000;
uint8_t idx;
/* check parameters */
if (addr == NULL) {
/* No allow device address. */
goto exit;
}
for (idx = 0; idx < ble_access_array_size(prefix_addr); idx++) {
if (memcmp(&addr[0], prefix_addr[idx], 3) == 0) {
break;
}
}
if (idx >= ble_access_array_size(prefix_addr)) {
goto exit;
}
/* Calculate Device ID. */
id |= (((uint32_t)idx) << 24);
id |= (((uint32_t)addr[3]) << 16);
id |= (((uint32_t)addr[4]) << 8);
id |= (((uint32_t)addr[5]));
exit:
return id;
}
/*
* Get and parse manufacturer data from the Peer Device Advertisement data.
*/
OSStatus ble_access_get_manufactor_adv_data(uint8_t *eir_data,
uint8_t eir_data_length,
ble_access_manufactor_data_t *manufactor_data)
{
if (eir_data == NULL || eir_data_length < 14 || manufactor_data == NULL) {
return kParamErr;
}
/* Manufacture data
*
* ------------------------------------------------------------------------------------
* | MXCHIP (6 bytes) | advType (1 byte) | directAddr (6 bytes) | alertState (1 byte) |
* ------------------------------------------------------------------------------------
*
* advType: MXCHIP_ADV_TYPE_INIT or MXCHIP_ADV_TYPE_RECONN
* directAddr: Directing device address. (used in MXCHIP_ADV_TYPE_RECONN)
* alertState: Alert state. 00 or 01
*
*/
memcpy(manufactor_data->mxchip, &eir_data[0], 6);
manufactor_data->adv_type = eir_data[6];
manufactor_data->alert_state = eir_data[13];
memcpy(manufactor_data->direct_addr, &eir_data[7], 6);
return kNoErr;
}
/* Check wheter a ADV packet is valid type */
OSStatus ble_access_check_adv_type(const uint8_t *adv_data,
uint8_t length,
uint8_t adv_type,
ble_access_manufactor_data_t *manu_data)
{
OSStatus err = kNoErr;
uint8_t *packet = NULL;
uint8_t data_length = 0;
ble_access_manufactor_data_t manufactor_data;
if (adv_data == NULL
|| length == 0
|| (adv_type != BLE_ACCESS_ADV_TYPE_INIT && adv_type != BLE_ACCESS_ADV_TYPE_RECONN)) {
return MICO_FALSE;
}
packet = mico_bt_ble_check_advertising_data((uint8_t *)adv_data,
BTM_BLE_ADVERT_TYPE_MANUFACTURER,
&data_length);
if (packet == NULL || data_length == 0) {
err = kUnknownErr;
goto exit;
}
err = ble_access_get_manufactor_adv_data(packet,
data_length,
&manufactor_data);
if (err != kNoErr) {
goto exit;
}
if (memcmp(manufactor_data.mxchip, BLE_ACCESS_MXCHIP_FLAG, 6) == 0) {
if (manufactor_data.adv_type != adv_type) {
err = kParamErr;
} else {
if (manu_data != NULL) {
memcpy(manu_data, &manufactor_data, sizeof(ble_access_manufactor_data_t));
}
}
} else {
err = kGeneralErr;
}
exit:
return err;
}
void ble_access_set_scan_cfg(mico_bt_smart_scan_settings_t *scan_cfg, mico_bool_t is_auto_scanning)
{
require_string(scan_cfg != NULL, exit, "invalid parameters");
if (is_auto_scanning) {
scan_cfg->interval = 2048;
scan_cfg->window = 48;
scan_cfg->duration_second = 0xffff;
scan_cfg->type = BT_SMART_PASSIVE_SCAN;
scan_cfg->filter_policy = FILTER_POLICY_WHITE_LIST;
scan_cfg->filter_duplicates = DUPLICATES_FILTER_DISABLED;
} else {
scan_cfg->interval = 256;
scan_cfg->window = 48;
scan_cfg->duration_second = 30;
scan_cfg->type = BT_SMART_ACTIVE_SCAN;
scan_cfg->filter_policy = FILTER_POLICY_NONE;
scan_cfg->filter_duplicates = DUPLICATES_FILTER_DISABLED;
}
exit:
return;
}
mico_bool_t ble_access_uuid_compare(const ble_access_uuid_t *uuid1, const ble_access_uuid_t *uuid2)
{
if (!uuid1 || !uuid2) {
return MICO_FALSE;
}
if (uuid1->len == uuid2->len
&& memcmp(&uuid1->uu, &uuid2->uu, uuid1->len) == 0) {
return MICO_TRUE;
}
return MICO_FALSE;
}
OSStatus ble_access_connect_list_init( void )
{
mico_rtos_init_mutex(&ble_access_conn_dev_list_mutex);
return linked_list_init(&ble_access_connecting_device_list);
}
OSStatus ble_access_connect_list_deinit(void)
{
OSStatus err = kNoErr;
mico_bt_smart_device_t *dev = NULL;
for (; ;) {
err = ble_access_connect_list_get(&dev, NULL);
if (err == kNoErr) {
ble_access_connect_list_remove(dev);
} else {
break;
}
}
return mico_rtos_deinit_mutex(&ble_access_conn_dev_list_mutex);
}
mico_bool_t compare_device_by_address(linked_list_node_t *node_to_compare, void *user_data)
{
ble_access_connecting_device_t *device = (ble_access_connecting_device_t * )node_to_compare;
mico_bt_device_address_t *device_address = (mico_bt_device_address_t *)user_data;
if (memcmp(device->device.address, device_address, BD_ADDR_LEN) == 0) {
return TRUE;
} else {
return FALSE;
}
}
OSStatus ble_access_connect_list_add(const mico_bt_smart_device_t *remote_device, mico_bool_t is_reported)
{
OSStatus err = kNoErr;
ble_access_connecting_device_t *device_found, *new_device;
require_action(remote_device != NULL, exit, err = kParamErr);
mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex);
err = linked_list_find_node(&ble_access_connecting_device_list,
(linked_list_compare_callback_t)compare_device_by_address,
(void *)remote_device->address,
(linked_list_node_t **)&device_found);
mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex);
if (err != kNotFoundErr) {
err = kAlreadyInUseErr;
goto exit;
}
new_device = malloc(sizeof(ble_access_device_t));
if (!new_device) {
err = kNoMemoryErr;
goto exit;
}
new_device->reported = is_reported;
memcpy(&new_device->device, remote_device, sizeof(mico_bt_smart_device_t));
mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex);
err = linked_list_insert_node_at_rear(&ble_access_connecting_device_list, &new_device->this_node);
mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex);
exit:
return err;
}
OSStatus ble_access_connect_list_set_report(const mico_bt_smart_device_t *device, mico_bool_t is_reported)
{
OSStatus err = kNoErr;
ble_access_connecting_device_t *device_found;
require_action(device != NULL, exit, err = kParamErr);
mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex);
err = linked_list_find_node(&ble_access_connecting_device_list,
(linked_list_compare_callback_t)compare_device_by_address,
(void *)device->address,
(linked_list_node_t **)&device_found);
if (err == kNoErr) {
device_found->reported = is_reported;
}
mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex);
exit:
return err;
}
OSStatus ble_access_connect_list_get(mico_bt_smart_device_t **device, mico_bool_t *reported)
{
OSStatus err = kNoErr;
ble_access_connecting_device_t *current_device;
require_action(device != NULL, exit, err = kParamErr);
mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex);
err = linked_list_get_front_node(&ble_access_connecting_device_list, (linked_list_node_t **)&current_device);
mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex);
if (err != kNoErr) {
goto exit;
}
*device = &current_device->device;
if (reported) {
*reported = current_device->reported;
}
exit:
return err;
}
OSStatus ble_access_connect_list_get_by_address(mico_bt_smart_device_t **device, mico_bool_t *reported,
const mico_bt_device_address_t address)
{
OSStatus err = kNoErr;
ble_access_connecting_device_t *current_device;
require_action(device != NULL && address != NULL, exit, err = kParamErr);
mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex);
err = linked_list_find_node(&ble_access_connecting_device_list,
(linked_list_compare_callback_t)compare_device_by_address,
(void *)address,
(linked_list_node_t **)&current_device);
mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex);
if (err != kNoErr) {
goto exit;
}
*device = &current_device->device;
if (reported) {
*reported = current_device->reported;
}
exit:
return err;
}
OSStatus ble_access_connect_list_find_by_address(const mico_bt_device_address_t address)
{
OSStatus err = kNoErr;
ble_access_connecting_device_t *current_device;
mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex);
err = linked_list_find_node(&ble_access_connecting_device_list,
(linked_list_compare_callback_t)compare_device_by_address,
(void *)address,
(linked_list_node_t **)&current_device);
mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex);
return err;
}
OSStatus ble_access_connect_list_remove(mico_bt_smart_device_t *device)
{
OSStatus err = kNoErr;
ble_access_connecting_device_t *current_device;
mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex);
err = linked_list_find_node(&ble_access_connecting_device_list,
(linked_list_compare_callback_t)compare_device_by_address,
device->address,
(linked_list_node_t **)&current_device);
if (err != kNoErr) {
goto exit;
}
err = linked_list_remove_node(&ble_access_connecting_device_list, &current_device->this_node);
if (err != kNoErr) {
goto exit;
}
free(current_device);
exit:
mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex);
return err;
}
const char *print_request_str(uint8_t request)
{
switch (request) {
case BLE_ACCESS_REQ_DEV_SCAN:
return "SCAN_REQ";
case BLE_ACCESS_REQ_DEV_ADD:
return "ADD_REQ";
case BLE_ACCESS_REQ_DEV_DISC:
return "DISC_REQ";
case BLE_ACCESS_REQ_DEV_REMOVE:
return "REMOVE_REQ";
case BLE_ACCESS_REQ_DEV_START_AUTO:
return "START_AUTO_REQ";
case BLE_ACCESS_REQ_DEV_STOP_AUTO:
return "STOP_AUTO_REQ";
default:
return "Unknown request";
}
}

View file

@ -0,0 +1,199 @@
#ifndef __BLE_ACCESS_CORE_I_H__
#define __BLE_ACCESS_CORE_I_H__
#include "mico.h"
#include "mico_bt.h"
/*
*-------------------------------------------------------------------------------------------------
*
* Configurations & Constants
*
*-------------------------------------------------------------------------------------------------
*/
/* Debug Logout */
#define BLE_ACCESS_DEBUG 0
/* The maximum number of remote connections */
#define MAX_CONCURRENT_CONNECTIONS 10
/* Protocal Flags */
#define BLE_ACCESS_MXCHIP_FLAG "MXCHIP"
/*
* Array index of Command Packet
*
* ----------------------------------------
* | code | count | length | len1 | data1 |
* ----------------------------------------
*
*/
#define BLE_ACCESS_AUTH_IDX_CODE 0x00
#define BLE_ACCESS_AUTH_IDX_COUNT 0x01
#define BLE_ACCESS_AUTH_IDX_LENGTH 0x02
#define BLE_ACCESS_AUTH_IDX_PARM1_LEN 0x04
#define BLE_ACCESS_AUTH_IDX_PARM1_DAT 0x05
/*
* Code Value
*/
#define BLE_ACCESS_CODE_START_AUTH 0x11
#define BLE_ACCESS_CODE_AUTH_DATA 0x12
#define BLE_ACCESS_CODE_AUTH_RESULT 0x13
/*
* Res Value
*/
#define BLE_ACCESS_RES_START 0x21
#define BLE_ACCESS_RES_AUTH 0x22
#define BLE_ACCESS_CODE_DISC 0x31
#define BLE_ACCESS_RES_DISC 0x41
/* Response to Peer */
//#define BLE_ACCESS_RSP_ALLOW_CONNECT 0x01
//#define BLE_ACCESS_RSP_NOT_ALLOW_CONNECT 0x02
/* Alert code to peer */
#define BLE_ACCESS_RSP_ALERTING 0x03
/* Slave command to authentication */
#define BLE_ACCESS_SLAVE_CMD_AUTH_START 0x11
#define BLE_ACCESS_SLAVE_CMD_AUTH_DATA 0x12
#define BLE_ACCESS_SLAVE_CMD_AUTH_RESULT 0x13
/* Master response to authentication */
#define BLE_ACCESS_MASTER_RSP_AUTH_ACK 0x21
#define BLE_ACCESS_MASTER_RSP_AUTH_DATA 0x22
/* EVENT Error Code */
#define BLE_ACCESS_ERR_NO_ERR 0x00
#define BLE_ACCESS_ERR_ENCRY_FAILED 0x01
#define BLE_ACCESS_ERR_BUSY 0x02
#define BLE_ACCESS_ERR_AUTH_FAILED 0x03
#define BLE_ACCESS_ERR_TIMEOUT 0x04
#define BLE_ACCESS_ERR_REJECT 0x05
#define BLE_ACCESS_ERR_ALERTING 0x10
#define BLE_ACCESS_ERR_NO_ALERT 0x11
/* Control Point Service */
// {7A414C35-605A-4319-AB3C-E945A9A42A70}
#define UUID_MXCHIP_CONTROL_POINT_SERVICE 0x70,0x2a,0xa4,0xa9,0x45,0xe9,0x3c,0xab,0x19,0x43,0x5a,0x60,0x35,0x4c,0x41,0x7a
// {B1CADCA2-9E80-4D24-9313-A45125A5F846}
#define UUID_MXCHIP_CONTROL_POINT_CMD_CHAR 0x46,0xf8,0xa5,0x25,0x51,0xa4,0x13,0x93,0x24,0x4d,0x80,0x9e,0xa2,0xdc,0xca,0xb1
// {E36945B5-30EE-4ABD-9445-4122CB40D175}
#define UUID_MXCHIP_CONTROL_POINT_EVT_CHAR 0x75,0xd1,0x40,0xcb,0x22,0x41,0x45,0x94,0xbd,0x4a,0xee,0x30,0xb5,0x45,0x69,0xe3
/*
*-------------------------------------------------------------------------------------------------
*
* Predefine Type
*
*-------------------------------------------------------------------------------------------------
*/
/* Device info ready to connect */
typedef struct {
linked_list_node_t this_node; /* Linked-list node of this device */
mico_bt_smart_device_t device; /* Remote BT device */
mico_bool_t reported; /* Is reported? */
} ble_access_connecting_device_t;
/* The Peer device Advertisement data */
typedef struct {
uint8_t mxchip[6];
uint8_t adv_type;
uint8_t alert_state;
mico_bt_device_address_t direct_addr;
} ble_access_manufactor_data_t;
/*
* A BLE Access Core BLE Device
*/
typedef struct {
// Device ID
uint32_t device_id;
// BT Socket for Every BLE Connection
mico_bt_smartbridge_socket_t socket;
// A timer for Authentication Process
mico_timer_t timer;
// Authentication State
uint8_t auth_state;
// Is used ?
mico_bool_t used;
// Some handles for a service of a BLE Connection.
struct {
// Notify Characteristic Value handle in MXCHIP Service
uint16_t notify_char_value_handle;
// Control Point Characteristic Value handle in MXCHIP Service.
uint16_t ctrl_evt_char_value_handle;
} service;
} ble_access_device_t;
/*
*-------------------------------------------------------------------------------------------------
*
* Local Function Prototype
*
*-------------------------------------------------------------------------------------------------
*/
/* Log output */
#define ble_access_log(M, ...) custom_log("BLE_ACCESS", M, ##__VA_ARGS__)
/* Calculate An array size */
#define ble_access_array_size(array) (sizeof(array)/sizeof(array[0]))
/*
* Remote device list management
*/
extern OSStatus ble_access_connect_list_init (void);
extern OSStatus ble_access_connect_list_deinit (void);
extern OSStatus ble_access_connect_list_add (const mico_bt_smart_device_t *remote_device,
mico_bool_t is_reported);
extern OSStatus ble_access_connect_list_get (mico_bt_smart_device_t **address, mico_bool_t *reported);
extern OSStatus ble_access_connect_list_get_by_address (mico_bt_smart_device_t **device, mico_bool_t *reported,
const mico_bt_device_address_t address);
extern OSStatus ble_access_connect_list_find_by_address(const mico_bt_device_address_t address);
extern OSStatus ble_access_connect_list_remove (mico_bt_smart_device_t *device);
extern OSStatus ble_access_connect_list_set_report (const mico_bt_smart_device_t *device, mico_bool_t is_reported);
/*
* Utils function
*/
const char *print_request_str(uint8_t request);
extern OSStatus ble_access_get_manufactor_adv_data(uint8_t *eir_data,
uint8_t eir_data_length,
ble_access_manufactor_data_t *manufactor_data);
extern OSStatus ble_access_check_adv_type (const uint8_t *adv_data,
uint8_t length,
uint8_t adv_type,
ble_access_manufactor_data_t *manu_data);
extern void ble_access_set_scan_cfg (mico_bt_smart_scan_settings_t *scan_cfg,
mico_bool_t is_auto_scanning);
extern OSStatus ble_access_start_timer (ble_access_device_t *dev, event_handler_t timer_event_handle,
void *arg);
extern OSStatus ble_access_stop_timer (ble_access_device_t *dev);
/*
* Local Devices Pool
*/
extern void ble_access_initialize_devices (void);
extern void ble_access_deinit_devices (void);
extern ble_access_device_t *ble_access_get_free_device (void);
extern void ble_access_release_device (mico_bool_t free, const ble_access_device_t *device);
//extern ble_access_device_t *ble_access_find_device_by_socket (const mico_bt_smartbridge_socket_t *socket);
extern ble_access_device_t *ble_access_find_device_by_address (const mico_bt_device_address_t address);
extern OSStatus ble_access_create_worker_thread(void);
extern OSStatus ble_access_send_aync_event(event_handler_t event_handle, void *arg);
#endif /* __BLE_ACCESS_CORE_I_H__ */

View file

@ -0,0 +1,15 @@
src =Split('''
ble_access_core.c
ble_access_core_i.c
''')
component =aos_component('Lib_Ble_Access_Core_Framework', src)
global_includes =Split('''
.
''')
for i in global_includes:
component.add_global_includes(i)

View file

@ -0,0 +1,143 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "internal/ble_helper_internal.h"
/* Peripheral auto advertising settings */
static mico_bt_smart_advertising_settings_t advertising_settings = {
.type = BT_SMART_UNDIRECTED_ADVERTISING, /**< Advertising type */
.use_high_duty = MICO_TRUE, /**< Using high duty to start advertising */
.high_duty_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL, /**< High duty advertising interval */
.high_duty_duration = 5, /**< High duty advertising duration in seconds (0 for infinite) */
.low_duty_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL, /**< Low duty advertising interval */
.low_duty_duration = 60, /**< Low duty advertising duration in seconds (0 for infinite) */
/* Used Directed Advertisement */
.directed_advertisement_addr_type = BT_SMART_ADDR_TYPE_PUBLIC,
.directed_advertisement_addr = { 11, 22, 33, 44, 55, 66 },
};
/* Set advertisement data and scanning response data */
static OSStatus set_advertisement_data(const char *manufacture)
{
OSStatus err = kNoErr;
uint16_t uuid[1] = { UUID_SERVCLASS_DEVICE_INFO };
mico_bt_ble_advert_data_t adv_data;
mico_bt_ble_service_t advert_services_16 = {
.num_service = 1,
.list_cmpl = true,
.p_uuid = uuid,
};
mico_bt_ble_manu_t advert_manufacture = {
.len = strlen(manufacture),
.p_val = (uint8_t *)manufacture,
};
adv_data.flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED;
adv_data.p_services = &advert_services_16;
adv_data.p_manu = &advert_manufacture;
mico_bt_ble_set_advertisement_data(
BTM_BLE_ADVERT_BIT_DEV_NAME | BTM_BLE_ADVERT_BIT_SERVICE | BTM_BLE_ADVERT_BIT_FLAGS,
&adv_data );
mico_bt_ble_set_scan_response_data( BTM_BLE_ADVERT_BIT_MANUFACTURER, &adv_data );
return err;
}
/* Display Advertisement Arguments */
static void start_advertisements(peripheral_hdl_t hdl,
mico_bt_smart_advertising_complete_callback_t advertisement_complete_handle)
{
mico_bt_dev_status_t status;
mico_bt_peripheral_socket_status_t socket_status = PERIPHERAL_SOCKET_CONNECTED;
peripheral_socket_t *p = g_skt_head;
printf("%d, hdl (%d) to operate\r\n", __LINE__, hdl);
for (; p; p = p->next) {
printf("%d iterate on hdl (%d)\r\n", __LINE__, p->hdl);
if (p->hdl == hdl) {
break;
}
}
if (!p) {
printf("%s %d no hdl found\r\n", __func__, __LINE__);
return;
}
/* Check current connection state. */
mico_bt_peripheral_get_socket_status(&p->skt, &socket_status );
if ( socket_status != PERIPHERAL_SOCKET_DISCONNECTED ) {
printf( "Advertisements Started unsuccessfully! Existed connection" );
printf( "" );
return;
}
/* Start advertisements */
status = mico_bt_peripheral_start_advertisements( &advertising_settings,
advertisement_complete_handle );
/* LOG */
printf("");
if ( status == MICO_BT_SUCCESS ) {
printf( "Advertisements Started successfully! Arguments: " );
} else if ( status == MICO_BT_ILLEGAL_VALUE ) {
printf( "Advertisements Started unsuccessfully! Illegal value: " );
} else {
printf( "Advertisements Started unsuccessfully! Unknown error: " );
}
printf( "" );
//printf( "\t\t type : %s", pBT_AdvertStr( advertising_settings.type ) );
printf( "\t\t duty : %s",
advertising_settings.use_high_duty == MICO_TRUE ? "High duty" : "Low duty" );
printf( "\t\t high_duty_interval: %-4d (slots, 0.625ms)",
advertising_settings.high_duty_interval );
printf( "\t\t high_duty_duration: %-4d (seconds)",
advertising_settings.high_duty_duration );
printf( "\t\t low_duty_interval : %-4d (slots, 0.625ms)",
advertising_settings.low_duty_interval );
printf( "\t\t low_duty_duration : %-4d (seconds)",
advertising_settings.low_duty_duration );
printf( "" );
}
void ble_adv_start(mico_bt_smart_advertising_complete_callback_t adv_handler,
const char *manufacture, peripheral_hdl_t hdl)
{
/* Set the advertising parameters and make the device discoverable */
set_advertisement_data(manufacture);
/* Start advertising */
start_advertisements(hdl, adv_handler);
}
void ble_adv_stop()
{
}
void ble_set_ad_data
(
peripheral_hdl_t hdl,
const struct adv_data *ad,
size_t ad_siz
)
{
}
void ble_set_sd_data
(
peripheral_hdl_t hdl,
const struct adv_data *sd,
size_t sd_siz
)
{
}

View file

@ -0,0 +1,5 @@
NAME := ble_app_helper_impl
$(NAME)_SOURCES := adv_helper.c init_helper.c gatt_attr_helper.c
$(NAME)_COMPONENTS := bluetooth.mk3239.bt_smart bluetooth.ble_app_framework bluetooth.mk3239.low_energy

View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "internal/ble_helper_internal.h"
ble_gatt_attr_t *ble_attr_add(uint16_t hdl, uint16_t val_len, const uint8_t *val)
{
return mico_bt_peripheral_ext_attribute_add(hdl, val_len, val, NULL);
}
void ble_attr_indicate(ble_gatt_attr_t *attr, peripheral_hdl_t hdl,
uint16_t len, const uint8_t *data)
{
peripheral_socket_t *p = g_skt_head;
for (; p; p = p->next)
if (p->hdl == hdl) {
break;
}
if (!p) {
return;
}
mico_bt_peripheral_ext_attribute_value_write(attr, len, 0, data);
mico_bt_peripheral_gatt_indicate_attribute_value(&p->skt, attr);
}
void ble_attr_notify(ble_gatt_attr_t *attr, peripheral_hdl_t hdl,
uint16_t len, const uint8_t *data)
{
peripheral_socket_t *p = g_skt_head;
for (; p; p = p->next)
if (p->hdl == hdl) {
break;
}
if (!p) {
return;
}
mico_bt_peripheral_ext_attribute_value_write(attr, len, 0, data);
mico_bt_peripheral_gatt_notify_attribute_value(&p->skt, attr);
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "internal/ble_helper_internal.h"
/* Peripheral security settings */
static const mico_bt_smart_security_settings_t security_settings = {
.timeout_second = 15,
.io_capabilities = BT_SMART_IO_DISPLAY_ONLY,
.authentication_requirements = BT_SMART_AUTH_REQ_BONDING,
.oob_authentication = BT_SMART_OOB_AUTH_NONE,
.max_encryption_key_size = 16,
.master_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS,
.slave_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS,
};
peripheral_socket_t *g_skt_head = NULL;
static uint32_t g_ble_hdl = 0;
peripheral_hdl_t ble_peripheral_init(peripheral_init_t *p,
ble_peripheral_conn_cb_t c,
ble_peripheral_disconn_cb_t disc,
const uint8_t *db, int db_len)
{
peripheral_socket_t *s = (peripheral_socket_t *)aos_malloc((sizeof(peripheral_socket_t)));
// mutex? <TODO>
s->hdl = g_ble_hdl++;
s->next = g_skt_head;
g_skt_head = s;
printf("%d, hdl (%d) inserted\r\n", __LINE__, s->hdl);
/* Initialize MICO bluetooth Framework */
mico_bt_init(MICO_BT_HCI_MODE, p->dev_name, p->client_links, p->server_links);
/* Initialize MICO bluetooth peripheral */
mico_bt_peripheral_init(&s->skt, &security_settings, c, disc, NULL);
/* Build BT Stack layer GATT database */
mico_bt_gatt_db_init(db, db_len);
return s->hdl;
}
// Mutex? <TODO>
void ble_peripheral_deinit(peripheral_hdl_t hdl)
{
peripheral_socket_t *p, *q;
for (p = g_skt_head; p; q = p, p = p->next)
if (p->hdl == hdl) {
break;
}
if (!p) {
printf("%s %d no hdl found\r\n", __func__, __LINE__);
return;
}
if (p == g_skt_head) {
g_skt_head = p->next;
mico_free(p);
} else {
q->next = p->next;
mico_free(p);
}
mico_bt_peripheral_deinit();
mico_bt_deinit();
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _BLE_HELPER_INTERNAL_H_
#define _BLE_HELPER_INTERNAL_H_
#include "ble_app_framework.h"
#include <stdio.h>
#include "sdpdefs.h"
#include "mico_bt_cfg.h"
#include "mico_bt.h"
#include "mico_bt_peripheral.h"
typedef struct peripheral_socket_s {
peripheral_hdl_t hdl;
mico_bt_peripheral_socket_t skt;
struct peripheral_socket_s *next;
} peripheral_socket_t;
extern peripheral_socket_t *g_skt_head;
#endif

View file

@ -0,0 +1,19 @@
src =Split('''
adv_helper.c
init_helper.c
gatt_attr_helper.c
''')
component =aos_component('ble_app_helper_impl', src)
dependencis =Split('''
device/bluetooth/mk3239/bt_smart
framework/bluetooth/ble_app_framework
device/bluetooth/mk3239/low_energy
''')
for i in dependencis:
component.add_comp_deps(i)

View file

@ -0,0 +1,309 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "LinkListUtils.h"
#include "debug.h"
OSStatus linked_list_init( linked_list_t *list )
{
OSStatus err = kNoErr;
require_action( list, exit, err = kParamErr);
memset( list, 0, sizeof( *list ) );
exit:
return err;
}
OSStatus linked_list_deinit( linked_list_t *list )
{
OSStatus err = kNoErr;
linked_list_node_t *current;
require_action( list, exit, err = kParamErr);
/* Traverse through all nodes and detach them */
current = list->front;
while ( current != NULL ) {
linked_list_node_t *next = current->next;
/* Detach node from the list */
current->prev = NULL;
current->next = NULL;
/* Move to the next node */
current = next;
}
memset( list, 0, sizeof( *list ) );
exit:
return err;
}
OSStatus linked_list_get_count( linked_list_t *list, uint32_t *count )
{
OSStatus err = kNoErr;
require_action( list, exit, err = kParamErr);
*count = list->count;
exit:
return err;
}
OSStatus linked_list_set_node_data( linked_list_node_t *node, const void *data )
{
OSStatus err = kNoErr;
require_action( node, exit, err = kParamErr);
node->data = (void *)data;
exit:
return err;
}
OSStatus linked_list_get_front_node( linked_list_t *list, linked_list_node_t **front_node )
{
OSStatus err = kNoErr;
require_action( list, exit, err = kParamErr);
*front_node = NULL;
require_action_quiet( list->count, exit, err = kNotFoundErr);
*front_node = list->front;
exit:
return err;
}
OSStatus linked_list_get_rear_node( linked_list_t *list, linked_list_node_t **rear_node )
{
OSStatus err = kNoErr;
require_action( list, exit, err = kParamErr);
*rear_node = NULL;
require_action( list->count, exit, err = kNotFoundErr);
*rear_node = list->rear;
exit:
return err;
}
OSStatus linked_list_find_node( linked_list_t *list, linked_list_compare_callback_t callback, void *user_data,
linked_list_node_t **node_found )
{
OSStatus err = kNotFoundErr;
linked_list_node_t *current;
require_action( list && callback && node_found, exit, err = kParamErr);
require_action_quiet(list->count, exit, err = kNotFoundErr);
current = list->front;
while ( current != NULL ) {
if ( callback( current, user_data ) ) {
*node_found = current;
err = kNoErr;
goto exit;
}
current = current->next;
}
exit:
return err;
}
OSStatus linked_list_insert_node_at_front( linked_list_t *list, linked_list_node_t *node )
{
OSStatus err = kNoErr;
require_action( list && node, exit, err = kParamErr);
if ( list->count == 0 ) {
list->front = node;
list->rear = node;
node->prev = NULL;
node->next = NULL;
} else {
node->prev = NULL;
node->next = list->front;
list->front->prev = node;
list->front = node;
}
list->count++;
exit:
return err;
}
OSStatus linked_list_insert_node_at_rear( linked_list_t *list, linked_list_node_t *node )
{
OSStatus err = kNoErr;
require_action( list && node, exit, err = kParamErr);
if ( list->count == 0 ) {
list->front = node;
list->rear = node;
node->prev = NULL;
node->next = NULL;
} else {
node->next = NULL;
node->prev = list->rear;
list->rear->next = node;
list->rear = node;
}
list->count++;
exit:
return err;
}
OSStatus linked_list_insert_node_before( linked_list_t *list, linked_list_node_t *reference_node,
linked_list_node_t *node_to_insert )
{
/* WARNING: User must make sure that reference_node is in the list */
OSStatus err = kNoErr;
require_action( list && reference_node && node_to_insert, exit, err = kParamErr);
require_action_quiet( list->count, exit, err = kNotFoundErr);
if ( reference_node == list->front ) {
err = linked_list_insert_node_at_front( list, node_to_insert );
} else {
node_to_insert->prev = reference_node->prev;
node_to_insert->prev->next = node_to_insert;
node_to_insert->next = reference_node;
reference_node->prev = node_to_insert;
list->count++;
}
exit:
return err;
}
OSStatus linked_list_insert_node_after( linked_list_t *list, linked_list_node_t *reference_node,
linked_list_node_t *node_to_insert )
{
/* WARNING: User must make sure that reference_node is in the list */
OSStatus err = kNoErr;
require_action( list && reference_node && node_to_insert, exit, err = kParamErr);
require_action_quiet( list->count, exit, err = kNotFoundErr);
if ( reference_node == list->rear ) {
err = linked_list_insert_node_at_rear( list, node_to_insert );
} else {
node_to_insert->prev = reference_node;
node_to_insert->next = reference_node->next;
reference_node->next->prev = node_to_insert;
reference_node->next = node_to_insert;
list->count++;
}
exit:
return err;
}
OSStatus linked_list_remove_node( linked_list_t *list, linked_list_node_t *node )
{
/* WARNING: User must make sure that node to remove is in the list */
OSStatus err = kNoErr;
require_action( list && node, exit, err = kParamErr);
require_action_quiet( list->count, exit, err = kNotFoundErr);
if ( list->count == 1 ) {
list->front = NULL;
list->rear = NULL;
} else if ( node == list->front ) {
linked_list_node_t *removed_node;
return linked_list_remove_node_from_front( list, &removed_node );
} else if ( node == list->rear ) {
linked_list_node_t *removed_node;
return linked_list_remove_node_from_rear( list, &removed_node );
} else {
node->prev->next = node->next;
node->next->prev = node->prev;
}
/* Make sure that detach node does not point to some arbitrary memory location */
node->prev = NULL;
node->next = NULL;
list->count--;
exit:
return err;
}
OSStatus linked_list_remove_node_from_front( linked_list_t *list, linked_list_node_t **removed_node )
{
OSStatus err = kNoErr;
require_action( list && removed_node, exit, err = kParamErr);
require_action_quiet( list->count, exit, err = kNotFoundErr);
*removed_node = list->front;
if ( list->count == 1 ) {
list->front = NULL;
list->rear = NULL;
} else {
list->front = list->front->next;
list->front->prev = NULL;
}
/* Make sure node does not point to some arbitrary memory location */
(*removed_node)->prev = NULL;
(*removed_node)->next = NULL;
list->count--;
exit:
return err;
}
OSStatus linked_list_remove_node_from_rear( linked_list_t *list, linked_list_node_t **removed_node )
{
OSStatus err = kNoErr;
require_action( list && removed_node, exit, err = kParamErr);
require_action_quiet( list->count, exit, err = kNotFoundErr);
*removed_node = list->rear;
if ( list->count == 1 ) {
list->front = NULL;
list->rear = NULL;
} else {
list->rear = list->rear->prev;
list->rear->next = NULL;
}
/* Make sure node does not point to some arbitrary memory location */
(*removed_node)->prev = NULL;
(*removed_node)->next = NULL;
list->count--;
exit:
return err;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
NAME := bt_smart
GLOBAL_INCLUDES += include
$(NAME)_INCLUDES += internal
$(NAME)_SOURCES := mico_bt_management.c \
mico_bt_peripheral.c \
mico_bt_smartbridge_gatt.c \
mico_bt_smartbridge.c \
mico_bt_smartbridge_cfg.c \
internal/bt_peripheral_stack_interface.c \
internal/bt_smart_attribute.c \
internal/bt_smartbridge_att_cache_manager.c \
internal/bt_smartbridge_socket_manager.c \
internal/bt_smartbridge_helper.c \
internal/bt_smartbridge_stack_interface.c \
LinkListUtils.c StringUtils.c

View file

@ -0,0 +1,80 @@
#pragma once
#include "common.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Type Definitions
******************************************************/
typedef struct linked_list_node linked_list_node_t;
/******************************************************
* Structures
******************************************************/
#pragma pack(1)
struct linked_list_node {
void *data;
linked_list_node_t *next;
linked_list_node_t *prev;
};
typedef struct {
uint32_t count;
linked_list_node_t *front;
linked_list_node_t *rear;
} linked_list_t;
#pragma pack()
typedef bool (*linked_list_compare_callback_t)( linked_list_node_t *node_to_compare, void *user_data );
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
OSStatus linked_list_init( linked_list_t *list );
OSStatus linked_list_deinit( linked_list_t *list );
OSStatus linked_list_get_count( linked_list_t *list, uint32_t *count );
OSStatus linked_list_set_node_data( linked_list_node_t *node, const void *data );
OSStatus linked_list_get_front_node( linked_list_t *list, linked_list_node_t **front_node );
OSStatus linked_list_get_rear_node( linked_list_t *list, linked_list_node_t **rear_node );
OSStatus linked_list_find_node( linked_list_t *list, linked_list_compare_callback_t callback, void *user_data,
linked_list_node_t **node_found );
OSStatus linked_list_insert_node_at_front( linked_list_t *list, linked_list_node_t *node );
OSStatus linked_list_insert_node_at_rear( linked_list_t *list, linked_list_node_t *node );
OSStatus linked_list_insert_node_before( linked_list_t *list, linked_list_node_t *reference_node,
linked_list_node_t *node_to_insert );
OSStatus linked_list_insert_node_after( linked_list_t *list, linked_list_node_t *reference_node,
linked_list_node_t *node_to_insert );
OSStatus linked_list_remove_node( linked_list_t *list, linked_list_node_t *node );
OSStatus linked_list_remove_node_from_front( linked_list_t *list, linked_list_node_t **removed_node );
OSStatus linked_list_remove_node_from_rear( linked_list_t *list, linked_list_node_t **removed_node );
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,278 @@
#ifndef __StringUtils_h__
#define __StringUtils_h__
#include <stdarg.h>
#include "common.h"
/** @addtogroup MICO_Middleware_Interface
* @{
*/
/** @defgroup MICO_String_Utils MiCO String Utils
* @brief Provide String operations APIs.
* @{
*/
// ==== STRING SIZE UTILS ====
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined sizeof_string
@abstract Determines the size of a constant C string, excluding the null terminator.
*/
#define sizeof_string( X ) ( sizeof( ( X ) ) - 1 )
//---------------------------------------------------------------------------------------------------------------------------
/*! @defined kSizeCString
@abstract Constant for describing the size of a null terminated string
*/
#define kSizeCString ( (size_t) -1 )
// ==== MAC String Tools ====
void formatMACAddr(char *destAddr, char *srcAddr);
/* @brief transform src string to hex mode
* Example: "aabbccddee" => 0xaabbccddee
* each char in the string must 0~9 a~f A~F, otherwise return 0
* return the real obuf length
*
* @param ibuf:?
* @param obuf:?
* @param olen:?
*
* @retval ?
*/
unsigned int str2hex(unsigned char *ibuf, unsigned char *obuf, unsigned int olen);
/**
* @brief Convert an Integer to a string
*
* @param str: The string
* @param intnum: The integer to be converted
*
* @retval None
*/
void Int2Str(uint8_t *str, int32_t intnum);
/**
* @brief Convert a string to an integer
*
* @param inputstr: The string to be converted
* @param intnum: The integer value
*
* @retval 1: Correct
* 0: Error
*/
uint32_t Str2Int(uint8_t *inputstr, int32_t *intnum);
/**
* @brief Allocate a memory to store the string
*
* @param src: ?
*
* @retval ?
*/
char *__strdup(const char *src);
/**
* @brief Allocate a memory to store the string, and transfer '.' to '\.'
*
* @param src: ?
*
* @retval ?
*/
char *__strdup_trans_dot(char *src);
// ==== NETWORKING STRING UTILS ====
#define TextToMACAddress( TEXT, SIZE, ADDR ) TextToHardwareAddress( TEXT, SIZE, 6, ADDR )
/**
* @brief ?
*
* @param inText : ?
* @param inTextSize: ?
* @param inAddrSize: ?
* @param outAddr : ?
*
* @retval ?
*/
int TextToHardwareAddress( const void *inText, size_t inTextSize, size_t inAddrSize, void *outAddr );
unsigned int str2hex(unsigned char *ibuf, unsigned char *obuf, unsigned int olen);
// ==== BYTE BUFFER TO STRING CONVERSION UTILS ====
/**
* @brief
*
* @param inBuf :?
* @param inBufLen:?
*
* @retval ?
*/
char *DataToCString( const uint8_t *inBuf, size_t inBufLen );
/**
* @brief ?
*
* @param inBuf :?
* @param inBufLen:?
*
* @retval ?
*/
char *DataToHexString( const uint8_t *inBuf, size_t inBufLen );
/**
* @brief ?
*
* @param inBuf :?
* @param inBufLen:?
*
* @retval ?
*/
char *DataToHexStringWithSpaces( const uint8_t *inBuf, size_t inBufLen );
/**
* @brief ?
*
* @param inBuf :?
* @param inBufLen:?
*
* @retval ?
*/
char *DataToHexStringWithColons( const uint8_t *inBuf, size_t inBufLen );
// ==== STRING COMPARE UTILS ====
/**
* @brief ?
*
* @param inStr :?
* @param inMaxLen:?
* @param inSuffix:?
*
* @retval ?
*/
int strnicmp_suffix( const void *inStr, size_t inMaxLen, const char *inSuffix );
/**
* @brief ?
*
* @param inS1 :?
* @param inS2 :?
* @param inMax :?
*
* @retval ?
*/
int strnicmp( const char *inS1, const char *inS2, size_t inMax );
/**
* @brief ?
*
* @param inS1 :?
* @param inN :?
* @param inS2 :?
*
* @retval ?
*/
int strnicmpx( const void *inS1, size_t inN, const char *inS2 );
/**
* @brief ?
*
* @param inStr :?
* @param inMaxLen:?
* @param inSuffix:?
*
* @retval ?
*/
char *strnstr_suffix( const char *inStr, size_t inMaxLen, const char *inSuffix);
/**
* @brief ?
*
* @param inStr : ?
* @param inMaxLen: ?
* @param inSuffix: ?
*
* @retval ?
*/
int VSNScanF( const void *inString, size_t inSize, const char *inFormat, va_list inArgs );
/**
* @brief ?
*
* @param value : ?
* @param output: ?
* @param min_length: ?
* @param max_length: ?
*
* @retval ?
*/
uint8_t unsigned_to_hex_string( uint32_t value, char *output, uint8_t min_length, uint8_t max_length );
/**
* @brief ?
*
* @param string : ?
* @param str_length: ?
* @param value_out: ?
* @param is_hex: ?
*
* @retval ?
*/
uint8_t string_to_unsigned( const char *string, uint8_t str_length, uint32_t *value_out, uint8_t is_hex );
/**
* @brief ?
*
* @param start :?
* @param s_len :?
* @param find :?
* @param f_len :?
*
* @retval none
*/
void *memmem(void *start, unsigned int s_len, void *find, unsigned int f_len);
uint8_t unsigned_to_decimal_string( uint32_t value, char *output, uint8_t min_length, uint8_t max_length );
#if defined (__CC_ARM)
#define strdup __strdup
/**
* @brief ?
*
* @param s :
* @param count :
*
* @retval ?
*/
size_t strnlen(const char *s, size_t count);
#endif
/**
* @}
*/
/**
* @}
*/
#endif // __StringUtils_h__

View file

@ -0,0 +1,341 @@
/** @file
* Defines functions for using the MICO Bluetooth Framework
*/
#pragma once
#include "mico.h"
#include "mico_bt_types.h"
#include "mico_bt_dev.h"
#include "mico_bt_smart_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/** MICO Bluetooth Framework mode of operation
*/
typedef enum {
MICO_BT_MPAF_MODE, /**< The framework uses Multi-Profile Application Framework (MPAF). The entire Bluetooth stack runs on the controller. The host controls the controller using remote procedure calls (RPC) */
MICO_BT_HCI_MODE, /**< The framework uses standard Host Controller Interface (HCI). The upper stack runs on the host and the lower stack runs on the controller */
} mico_bt_mode_t;
/******************************************************
* Type Definitions
******************************************************/
/** MICO Bluetooth packet.
* An opaque data type representing a generic, zero-copy packet used for transporting data to/from the Bluetooth controller.
*/
typedef struct bt_packet mico_bt_packet_t;
typedef platform_uart_config_t mico_uart_config_t;
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
extern mico_worker_thread_t mico_bt_worker_thread;
extern mico_worker_thread_t mico_bt_evt_worker_thread;
#define MICO_BT_WORKER_THREAD ((mico_worker_thread_t *)&mico_bt_worker_thread)
#define MICO_BT_EVT_WORKER_THREAD ((mico_worker_thread_t *)&mico_bt_evt_worker_thread)
/******************************************************
* Function Declarations
******************************************************/
/*****************************************************************************/
/** @defgroup micobt Bluetooth
*
* MICO Bluetooth Framework Functions
*/
/*****************************************************************************/
/*****************************************************************************/
/** @addtogroup btfwmgmt Framework
* @ingroup micobt
*
* Bluetooth Framework Management Functions
*
*
* @{
*/
/*****************************************************************************/
/** Initialise the MICO Bluetooth Framework
*
* This function initialises the local Bluetooth device and the framework core
* components to operate in the mode specified. Upon return, the device is
* powered.
*
* @note To switch mode, invoke @ref mico_bt_deinit to tear down the current
* operating mode, and call this function with the desired mode.
*
* @param mode : The framework mode of operation, only MICO_BT_HCI_MODE is
* supported now
* @param device_name : A user-friendly name of the local Bluetooth device. A
* name longer than 21 characters will be truncated.
* @param client_links : Max cocurrent connections as a BLE client
* @param server_links :
*
* @return MICO_SUCCESS : on success;
* MICO_ERROR : if an error occurred
*/
OSStatus mico_bt_init( mico_bt_mode_t mode, const char *device_name, uint8_t client_links, uint8_t server_links );
/** Deinitialise the MICO Bluetooth Framework
*
* This function tears down all active framework components. Depending on the
* hardware platform used, it may also power down the Bluetooth device.
*
* @return MICO_SUCCESS : on success;
* MICO_ERROR : if an error occurred
*/
OSStatus mico_bt_deinit( void );
/** Initialise the device address of the local Bluetooth device
*
* This function provides users with a option to overwrite the default address of
* the local Bluetooth device with the address provided. Once called, @ref mico_bt_init()
* overwrites the default address with the address provided. Users can selectively
* overwrite bits of the default address by setting the correspondping bits in the
* 'mask' argument to 1.
*
* @warning When used, this function *MUST* be called before mico_bt_init()
*
* @param[in] address : new address
* @param[in] mask : masking bits
*
* @return MICO_SUCCESS : on success;
* MICO_ERROR : if an error occurred
*/
OSStatus mico_bt_init_address( const mico_bt_device_address_t *address, const mico_bt_device_address_t *mask );
/** Start manufacturing test mode
*
* @param[in] config : Configuration of the UART peripheral that connects to the host PC
*
* @return MICO_SUCCESS : on success;
* MICO_ERROR : if an error occurred
*/
OSStatus mico_bt_start_mfgtest_mode( const mico_uart_config_t *config );
/** @} */
/*****************************************************************************/
/** @addtogroup btdevmgmt Device
* @ingroup micobt
*
* Bluetooth Device Management Functions
*
*
* @{
*/
/*****************************************************************************/
/** Retrieve the device address of the local Bluetooth device
*
* @param[out] address : device address
*
* @return MICO_TRUE : is device address successfully retrieved;
* MICO_FALSE : if not or if an error occurred
*/
OSStatus mico_bt_device_get_address( mico_bt_device_address_t *address );
/** Retrieve the user-friendly name of the local Bluetooth device
*
* @return pointer to the device name string
*/
const char *mico_bt_device_get_name( void );
/** Check if the local Bluetooth device is powered
*
* @return MICO_TRUE : if powered on;
* MICO_FALSE : if not powered or if an error occurred
*/
mico_bool_t mico_bt_device_is_on( void );
/** Check if the local Bluetooth device is connectable state
*
* @return MICO_TRUE : is in connectable state;
* MICO_FALSE : if not or if an error occurred
*/
mico_bool_t mico_bt_device_is_connectable( void );
/** Check if the local Bluetooth device is discoverable state
*
* @return MICO_TRUE : is in discoverable state;
* MICO_FALSE : if not or if an error occurred
*/
mico_bool_t mico_bt_device_is_discoverable( void );
/** @} */
/*****************************************************************************/
/** @addtogroup btdevmgmt Device
* @ingroup micobt
*
* Bluetooth Pairing Management Functions
*
*
* @{
*/
/*****************************************************************************/
/** Start a MiCO bluetooth LE pairing procedure
*
*
* @param address : The remote device address
* @param type : The remote device address type
* @param settings : Security settings used in pairing procedure
*
* @return MICO_BT_PENDING if successfully initiated,
* MICO_BT_SUCCESS if already paired to the device, else
* error code
*/
OSStatus mico_bt_start_pairing( mico_bt_device_address_t address, mico_bt_smart_address_type_t type,
const mico_bt_smart_security_settings_t *settings );
/** Stop a MiCO bluetooth LE pairing procedure
*
* @param address : The remote device address
*
* @return MICO_BT_PENDING if cancel initiated,
* MICO_BT_SUCCESS if cancel has completed already, else error code.
*/
OSStatus mico_bt_stop_pairing( mico_bt_device_address_t address );
/** Satrt a MiCO bluetooth LE encryption procedure
*
* @param address : The remote device address
*
* @return MICO_BT_SUCCESS : already encrypted
* MICO_BT_PENDING : command will be returned in the callback
* MICO_BT_WRONG_MODE : connection not up.
* MICO_BT_BUSY : security procedures are currently active
*/
OSStatus mico_bt_start_encryption( mico_bt_device_address_t *address );
/** @} */
/*****************************************************************************/
/** @addtogroup btpktmgmt Packet
* @ingroup micobt
*
* Bluetooth Packet Management Functions
*
*
* @{
*/
/*****************************************************************************/
/** Delete a MICO Bluetooth packet
*
* This function returns the packet's memory space back to the source, allowing
* for reuse.
*
* @param packet : The pointer to the packet to delete
* @return MICO_SUCCESS : on success;
* MICO_BADARG : if bad argument(s) are inserted;
* MICO_ERROR : if an error occurred.
*/
OSStatus mico_bt_packet_delete( mico_bt_packet_t *packet );
/** Get a pointer to the packet data
*
* This function retrieves a pointer to the start of the data section in the
* packet. It also returns the current data size and the remaining data space
* in the packet.
*
* @param packet : The pointer to the packet
* @param data : A pointer that will receive the pointer to the
* start of the data section in the packet
* @param current_data_size : A pointer that will receive the size of the data
* in the packet in bytes
* @param available_space : A pointer that will receive the available data
* space in the packet in bytes
*
* @return MICO_SUCCESS : on success;
* MICO_BADARG : if bad argument(s) are inserted;
* MICO_ERROR : if an error occurred.
*/
OSStatus mico_bt_packet_get_data( const mico_bt_packet_t *packet, uint8_t **data, uint32_t *current_data_size,
uint32_t *available_space );
/** Set the end of the packet data
*
* This function updates the end of the data section and the data size in the
* packet.
*
* @param packet : The pointer to the packet
* @param data_end : The pointer to the end of the data section in the packet
* @return MICO_SUCCESS : on success;
* MICO_BADARG : if bad argument(s) are inserted;
* MICO_ERROR : if an error occurred
*/
OSStatus mico_bt_packet_set_data_end( mico_bt_packet_t *packet, const uint8_t *data_end );
/** @} */
/*****************************************************************************/
/** @addtogroup sbwhitelist SmartBridge Whitelist Filter
* @ingroup smartbridge
*
* SmartBridge Whitelist Filter Functions
*
*
* @{
*/
/*****************************************************************************/
/** Get the maximum number of devices supported by the whitelist
*
* @note
* This function retrieves the maximum number of Bluetooth Smart devices which can
* be added to the whitelist.
*
* @param[out] size : device count
*
* @return @ref OSStatus
*/
OSStatus mico_bt_get_whitelist_capability( uint8_t *size );
/** Clear the whitelist
*
* @note
* This function instructs the Bluetooth Controller to remove all devices from the
* whitelist
*
* @return @ref OSStatus
*/
OSStatus mico_bt_clear_whitelist( void );
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,399 @@
#pragma once
#include "mico_bt_smart_interface.h"
#include "LinkListUtils.h"
#include "mico_bt_gatt.h"
/** @file
* Defines functions for bridging Bluetooth Smart with Wi-Fi
*/
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/**
* BT smart peripheral socket status
*/
typedef enum {
PERIPHERAL_SOCKET_DISCONNECTED, /**< Socket is disconnected */
PERIPHERAL_SOCKET_CONNECTING, /**< Socket is in connecting state */
PERIPHERAL_SOCKET_CONNECTED, /**< Socket is connected with a remote device */
} mico_bt_peripheral_socket_status_t;
/**
* Advertising filter policy
*/
typedef enum {
PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ = 0x00, /**< Process scan and connection requests from all devices (i.e., the White List is not in use) (default) */
PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x01, /**< Process connection requests from all devices and only scan requests from devices that are in the White List. */
PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ = 0x02, /**< Process scan requests from all devices and only connection requests from devices that are in the White List */
PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x03, /**< Process scan and connection requests only from devices in the White List. */
PERIPHERAL_ADVERT_FILTER_MAX
} mico_bt_peripheral_adv_filter_policy_t;
/******************************************************
* Type Definitions
******************************************************/
typedef struct _bt_ext_attribute_value_t mico_bt_ext_attribute_value_t;
/**
* Socket to create a BT smart peripheral connection
*/
typedef struct mico_bt_peripheral_socket mico_bt_peripheral_socket_t;
/**
* Socket connection callback
*/
typedef OSStatus (* mico_bt_peripheral_connection_callback_t) ( mico_bt_peripheral_socket_t *socket );
/**
* Socket disconnection callback
*/
typedef OSStatus (* mico_bt_peripheral_disconnection_callback_t) ( mico_bt_peripheral_socket_t *socket );
/**
* Attrubute request callback
*/
typedef mico_bt_gatt_status_t (* mico_bt_peripheral_attribute_handler)( mico_bt_ext_attribute_value_t *attribute,
mico_bt_gatt_request_type_t op );
/******************************************************
* Structures
******************************************************/
#define BT_SMART_S_NONE ( 0x0 )
#define BT_SMART_S_INDICATE ( 0x1 << 0 )
#define BT_SMART_S_NOTIFICATION ( 0x1 << 1 )
typedef uint8_t bt_smart_server_send_type_t;
struct _bt_ext_attribute_value_t {
linked_list_node_t this_node; /* Linked-list node of this characteristic */
uint16_t handle; /* Attribute handle */
uint16_t value_length; /* Attribute value length */
uint16_t value_buffer_length; /* Attribute value buffer length */
uint8_t *p_value; /* Pointer to characteristic value */
mico_bt_peripheral_attribute_handler attribute_handler;
};
/**
* Socket to create a Smart Peripheral connection
* @warning The content of the socket structure is for INTERNAL USE only. Modifying
* the content of this structure is prohibited. Please use the Bluetooth SmartBridge
* API to retrieve socket information.
*/
struct mico_bt_peripheral_socket {
mico_bt_smart_device_t
remote_device; /**< Remote Bluetooth device MiCO is connected with (BLE server) */
uint16_t
connection_handle; /**< Connection handle */
uint8_t
state; /**< Internal state */
uint8_t
actions; /**< Internal socket actions */
mico_bt_peripheral_connection_callback_t
connection_callback; /**< Callback for handling connection event by remote device */
mico_bt_peripheral_disconnection_callback_t
disconnection_callback; /**< Callback for handling disconnection event by remote device */
mico_bt_smart_bonding_callback_t
bonding_callback; /**< Callback for handling bonding evnet by remote device */
mico_bt_smart_security_settings_t
security_settings; /**< Security settings */
mico_bt_smart_bond_request_t
bond_req; /**< Bond Request Structure */
mico_semaphore_t
semaphore; /**< Semaphore */
linked_list_t
attribute_database; /**< Attribute database */
uint16_t mtu;
};
/******************************************************
* Function declarations
******************************************************/
/*****************************************************************************/
/** @addtogroup smartbridge SmartBridge
* @ingroup micobt
*
* Bluetooth SmartBridge Functions
*
*
* @{
*/
/*****************************************************************************/
/*****************************************************************************/
/** @addtogroup sbmgmt SmartBridge Management
* @ingroup smartbridge
*
* SmartBridge Management Functions
*
*
* @{
*/
/*****************************************************************************/
/** Initialise the MiCO BT peripheral
*
* @note
* This function initialises:
* \li Generic Attribute Profile (GATT) Server
* \li Generic Access Profile (GAP) Peripheral Role
* \li Security settings used when conneted by BT client
* \li Initialises the socket internals to make it ready to connect to
* a Bluetooth Smart Central
*
*
* @return MICO_BT_SUCCESS: success , else @ref OSStatus
*/
OSStatus mico_bt_peripheral_init( mico_bt_peripheral_socket_t *socket,
const mico_bt_smart_security_settings_t *settings,
mico_bt_peripheral_connection_callback_t connection_callback,
mico_bt_peripheral_disconnection_callback_t disconnection_callback,
mico_bt_smart_bonding_callback_t bonding_callback );
/** Deinitialise the MiCO BT peripheral
*
* @note
* This function deinitialises:
* \li Generic Attribute Profile (GATT) Server
* \li Generic Access Profile (GAP) Peripheral Role
* \li Create BT peripheral Socket ready to be connected
*
* @return MICO_BT_SUCCESS: success
*/
OSStatus mico_bt_peripheral_deinit( void );
/** @} */
/*****************************************************************************/
/** @addtogroup sbsock BT peripheral Socket and Connection Management
* @ingroup SmartPeripheral
*
* BT peripheral Socket and Connection Functions
*
*
* @{
*/
/*****************************************************************************/
/** Get BT peripheral socket status
*
* @param[in] socket : pointer to the socket to get the status
* @param[out] status : socket status
*
* @return MICO_BT_SUCCESS: success
* MICO_BT_SMART_APPL_UNINITIALISED: Smart peripheral framework is uninitialized
*/
OSStatus mico_bt_peripheral_get_socket_status( mico_bt_peripheral_socket_t *socket,
mico_bt_peripheral_socket_status_t *status );
/** Disconnect BT peripheral connection
*
* @note
* This function disconnects a connection with remote client.
*
* @return MICO_BT_SUCCESS: success
* MICO_BT_SMART_APPL_UNINITIALISED: Smart peripheral framework is uninitialized
*/
OSStatus mico_bt_peripheral_disconnect( void );
/** @} */
/*****************************************************************************/
/** @addtogroup sbscan Smart Peripheral Advert
* @ingroup SmartPeripheral
*
* Smart Peripheral Advertising Functions
*
*
* @{
*/
/*****************************************************************************/
/** Start advertising local Bluetooth Smart devices
*
* @note
* This function instructs the Bluetooth controller to start advertising. Advertising data
* sould be set first use mico_bt_ble_set_advertisement_data().
*
* @warning
* \li complete_callback is an intermediate report callback.
*
* @param[in] settings : advertising settings
* @param[in] complete_callback : callback function which is called when advertising is
* completerunning under MICO_BT_EVT_WORKER_THREAD
*
* @return MICO_BG_SUCCESS, else @ref OSStatus
*/
OSStatus mico_bt_peripheral_start_advertisements( mico_bt_smart_advertising_settings_t *settings,
mico_bt_smart_advertising_complete_callback_t complete_callback);
/** Stop the ongoing advertising process
*
* This function instructs the Bluetooth controller to advertising local
* Bluetooth Smart devices.
*
* @return MICO_BG_SUCCESS, else @ref OSStatus
*/
OSStatus mico_bt_peripheral_stop_advertisements( void );
/** @} */
/*****************************************************************************/
/** @addtogroup sbwhitelist SmartBridge Whitelist Filter
* @ingroup smartbridge
*
* SmartBridge Whitelist Filter Functions
*
*
* @{
*/
/*****************************************************************************/
/** Update the devices in white list.
*
* @param[in] add : Add or remove this device specified by device_address.
* @param[in] device_address : Bluetooth address of the device to add to the whitelist
*
* @return @ref OSStatus
*/
OSStatus mico_bt_peripheral_update_advertisements_white_list( mico_bool_t add,
mico_bt_device_address_t device_address );
/** Get the number of devices in white list
*
* @param[out] size : The number of devices in white list.
*
* @return @ref OSStatus
*/
OSStatus mico_bt_peripheral_get_advertisements_white_list_size( uint8_t *size );
/** Set Advertisements Filter Policy
*
* @param[in] policy : Advertisements filter policy
*
* @return @ref OSStatus
*/
OSStatus mico_bt_peripheral_set_advertisements_filter_policy( mico_bt_peripheral_adv_filter_policy_t policy );
/** @} */
/*****************************************************************************/
/** @addtogroup sbattr Smart peripheral Attribute Value database
* @ingroup SmartPeripheral
*
* Smart Peripheral External Attribute Value Database Functions
*
*
* @{
*/
/*****************************************************************************/
/** Add an external attribute vale to BT peripheral
*
* @param handle[in] : Handle of an attribution
* @param length[in] : Attribute value length (0, if value is not existed)
* @param value[in] : Point to the Attribute value (NULL, if value is not existed)
* @param handler[in] : Attribute request handler is synchronized triggerd
* after an attribute write by remote GATT write operation
* or before anattribute read by remote GATT read operation
*
* @return The address of the external attrbute value object, NULL if failed
*/
mico_bt_ext_attribute_value_t *mico_bt_peripheral_ext_attribute_add( uint16_t handle, uint16_t length,
const uint8_t *value, mico_bt_peripheral_attribute_handler handler );
/** Remove an external attribute vale from BT peripheral
*
* @param attribute[in] : The address of the external attrbute value object
*
* @return @ref OSStatus
*/
OSStatus mico_bt_peripheral_ext_attribute_remove( mico_bt_ext_attribute_value_t *attribute );
/** Find an external attribute value from BT peripheral using handle
*
* @param handle[in] : Handle of an attribute
* @param attribute_found[in,out] : Pointer to the external attribute address find by handle
*
* @return @ref OSStatus
*/
OSStatus mico_bt_peripheral_ext_attribute_find_by_handle( uint16_t handle,
mico_bt_ext_attribute_value_t **attribute_found );
/** Write or update data to the external attribute value object
*
* @note
* The value will copy to attrubute object, free after write
*
* @param handle[in] : Handle of an attribute
* @param length[in] : Data length
* @param length[in] : Attrubute value offset where data is written to
* @param value[in] : Point to the data
*
* @return @ref OSStatus
*/
OSStatus mico_bt_peripheral_ext_attribute_value_write( mico_bt_ext_attribute_value_t *attribute, uint16_t length,
uint16_t value_offset, const uint8_t *value );
/** Remove all external attribute vale from BT peripheral
*
* @return @ref OSStatus
*/
OSStatus mico_bt_peripheral_ext_attribute_remove_all( void );
/** Send external attribute value to BT client using indicate
*
*
* @param socket[in] : Pointer to the socket to send attribute value
* @param attribute[in] : Pointer to the external attribute that hold the value to be sent
*
* @return @ref OSStatus
*/
OSStatus mico_bt_peripheral_gatt_indicate_attribute_value ( mico_bt_peripheral_socket_t *socket,
const mico_bt_ext_attribute_value_t *attribute );
/** Send external attribute value to BT client using notify
*
*
* @param socket[in] : Pointer to the socket to send attribute value
* @param attribute[in] : Pointer to the external attribute that hold the value to be sent
*
* @return @ref OSStatus
*/
OSStatus mico_bt_peripheral_gatt_notify_attribute_value( mico_bt_peripheral_socket_t *socket,
const mico_bt_ext_attribute_value_t *attribute );
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,416 @@
/** @file
* Defines structures and functions for Bluetooth Smart Attribute abstraction
*/
#pragma once
#include "mico.h"
#include "mico_bt_smartbridge_constants.h"
#include "mico_bt_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/** @cond !ADDTHIS*/
/* Attribute structure fixed length */
#define ATTR_COMMON_FIELDS_SIZE ( sizeof(mico_bt_smart_attribute_t*) + sizeof(uint16_t) + sizeof(mico_bt_uuid_t) + sizeof(uint8_t) + sizeof(uint32_t) + + sizeof(uint32_t))
#define ATTR_NO_VALUE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(uint8_t) )
#define ATTR_LONG_VALUE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(uint8_t) * MAX_CHARACTERISTIC_VALUE_LENGTH )
#define ATTR_SERVICE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_service_t) )
#define ATTR_INCLUDE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_include_t) )
#define ATTR_CHARACTERISTIC_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_characteristic_t) )
#define ATTR_CHARACTERISTIC_VALUE_SIZE( value_length ) ( ATTR_COMMON_FIELDS_SIZE + (sizeof(uint8_t) * value_length) )
#define ATTR_EXTENDED_PROPERTIES_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_extended_properties_t) )
#define ATTR_USER_DESCRIPTION_SIZE( string_length ) ( ATTR_COMMON_FIELDS_SIZE + (sizeof(char) * string_length) )
#define ATTR_CLIENT_CONFIG_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_client_config_t) )
#define ATTR_SERVER_CONFIG_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_server_config_t) )
#define ATTR_PRESENTATION_FORMAT_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_presentation_format_t) )
#define ATTR_AGGREGATE_FORMAT_SIZE( handle_count ) ( ATTR_COMMON_FIELDS_SIZE + (sizeof(uint16_t) * handle_count) )
/* Maximum characteristic value length */
#define MAX_CHARACTERISTIC_VALUE_LENGTH 512
/** @endcond */
/******************************************************
* Enumerations
******************************************************/
/**
* Bluetooth Smart Attribute type
*/
typedef enum {
MICO_ATTRIBUTE_TYPE_NO_VALUE, /**< Attribute with no value */
MICO_ATTRIBUTE_TYPE_LONG_VALUE, /**< Attribute with long value */
MICO_ATTRIBUTE_TYPE_PRIMARY_SERVICE, /**< Primary service */
MICO_ATTRIBUTE_TYPE_INCLUDE, /**< Included Service */
MICO_ATTRIBUTE_TYPE_CHARACTERISTIC, /**< Characteristic */
MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, /**< Characteristic Value */
MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_EXTENDED_PROPERTIES, /**< Characteristic Descriptor: Extended Properties */
MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION, /**< Characteristic Descriptor: User Description */
MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_CLIENT_CONFIGURATION, /**< Characteristic Descriptor: Client Configuration */
MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_SERVER_CONFIGURATION, /**< Characteristic Descriptor: Server Configuration */
MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_PRESENTATION_FORMAT, /**< Characteristic Descriptor: Presentation Format */
MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT /**< Characteristic Descriptor: Aggregate Format */
} mico_bt_smart_attribute_type_t;
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
#pragma pack(1)
/* @note: The following Attribute Values follow the Bluetooth Core Spec v4.0
* Volume 3 Part G Section 3 closely. This allows for direct memcpy from
* the ATT response PDU to the Attribute Value structure. Also note that
* any additional fields follow the fields in the specification.
*/
/**
* 3.1 Attribute Value of Service Definition
*/
typedef struct {
uint16_t start_handle; /**< Starting handle */
uint16_t end_handle; /**< Ending handle */
mico_bt_uuid_t uuid; /**< UUID */
} attr_val_service_t;
/**
* 3.2 Attribute Value of Include Definition
*/
typedef struct {
uint16_t included_service_handle; /**< Included service handle */
uint16_t end_group_handle; /**< End group handle */
mico_bt_uuid_t uuid; /**< UUID */
} attr_val_include_t;
/**
* 3.3.1 Attribute Value of Characteristic Declaration
*/
typedef struct {
uint8_t properties; /**< Properties */
uint16_t value_handle; /**< Value handle */
mico_bt_uuid_t uuid; /**< UUID */
uint16_t descriptor_start_handle; /**< Descriptor start handle. Additional field. Not in spec */
uint16_t descriptor_end_handle; /**< Descriptor end handle. Additional field. Not in spec */
} attr_val_characteristic_t;
/**
* 3.3.2 Attribute Value of Characteristic Value Declaration
*/
typedef struct {
uint8_t value[1]; /**< Start of value */
} attr_val_characteristic_value_t;
/**
* 3.3.3.1 Attribute Value of Characteristic Extended Properties
*/
typedef struct {
uint8_t properties; /**< Properties */
} attr_val_extended_properties_t;
/**
* 3.3.3.2 Attribute Value of Characteristic User Description
*/
typedef struct {
char string[1]; /**< User description string */
} attr_val_user_description_t;
/**
* 3.3.3.3 Attribute Value of Client Characteristic Configuration
*/
typedef struct {
uint16_t config_bits; /**< Configuration bits */
} attr_val_client_config_t;
/**
* 3.3.3.4 Attribute Value of Server Characteristic Configuration
*/
typedef struct {
uint16_t config_bits; /**< Configuration bits */
} attr_val_server_config_t;
/**
* 3.3.3.5 Attribute Value of Characteristic Presentation Format
*/
typedef struct {
uint8_t format; /**< Format */
uint8_t exponent; /**< Exponent */
uint16_t unit; /**< Unit */
uint8_t name_space; /**< Namespace */
uint16_t description; /**< Description */
} attr_val_presentation_format_t;
/**
* 3.3.3.6 Attribute Value of Characteristic Aggregate Format
*/
typedef struct {
uint16_t handle_list[1]; /**< Handle list */
} attr_val_aggregate_format_t;
/**
* Vol 3 Part C 12.1 Attribute Value of Device Name Characteristic
*/
typedef struct {
char device_name[1]; /**< Maximum length is 248 bytes */
} attr_val_device_name_t;
/**
* Vol 3 Part C 12.2 Attribute Value of Appearance Characteristic
*/
typedef struct {
uint16_t appearance; /**< Enumerated value defined in "Assigned Numbers" */
} attr_val_appearance_t;
/**
* Vol 3 Part C 12.3 Attribute Value of Peripheral Privacy Flag Characteristic
*/
typedef struct {
uint8_t periph_privacy_flag; /**< Peripheral privacy flag: 0 if disabled; 1 if enabled */
} attr_val_periph_privacy_flag_t;
/**
* Vol 3 Part C 12.4 Attribute Value of Reconnection Address Characteristic
*/
typedef struct {
uint8_t reconn_address[6]; /**< Network-order reconnection address */
} attr_val_reconnection_address_t;
/**
* Vol 3 Part C 12.5 Attribute Value of Peripheral Preferred Connection Parameters Characteristic
*/
typedef struct {
uint16_t min_conn_interval; /**< Minimum connection interval */
uint16_t max_conn_interval; /**< Maximum connection interval */
uint16_t slave_latency; /**< Slave latency */
uint16_t conn_supervision_timeout_multiplier; /**< Connection supervision timeout multiplier */
} attr_val_periph_preferred_conn_params_t;
/**
* Attribute Structure
*/
typedef struct mico_bt_attribute {
struct mico_bt_attribute
*next; /**< Pointer to the next attribute in the list. NULL if not a list */
uint16_t
handle; /**< Attribute Handle */
mico_bt_uuid_t
type; /**< Attribute Type (UUID) */
uint8_t
permission; /**< Attribute Permission(s). Unused in GATT client */
uint32_t
value_length; /**< Length of the Attribute Value. If no value, this equals 0 */
uint32_t
value_struct_size; /**< Size of the value structure */
/* Union of Attribute Values. Use the right format based on Attribute Type */
union {
uint8_t
value[MAX_CHARACTERISTIC_VALUE_LENGTH]; /**< Long Value */
attr_val_service_t
service; /**< Attribute Value for Service */
attr_val_include_t
include; /**< Attribute Value for Include */
attr_val_characteristic_t
characteristic; /**< Attribute Value for Characteristic */
attr_val_characteristic_value_t
characteristic_value; /**< Attribute Value for Characteristic Value */
attr_val_extended_properties_t
extended_properties; /**< Attribute Value for Descriptor: Characteristic Extended Properties */
attr_val_user_description_t
user_description; /**< Attribute Value for Descriptor: Characteristic User_Description */
attr_val_client_config_t
client_config; /**< Attribute Value for Descriptor: Client Characteristic Configuration */
attr_val_server_config_t
server_config; /**< Attribute Value for Descriptor: Server Characteristic Configuration */
attr_val_presentation_format_t
presentation_format; /**< Attribute Value for Descriptor: Characteristic Presentation Format */
attr_val_aggregate_format_t
aggregate_format; /**< Attribute Value for Descriptor: Characteristic Aggregate Format */
attr_val_device_name_t
device_name; /**< Attribute Value for Characteristic Type: Device Name */
attr_val_appearance_t
appearance; /**< Attribute Value for Characteristic Type: Appearance */
attr_val_periph_privacy_flag_t
periph_privacy_flag; /**< Attribute Value for Characteristic Type: Peripheral Privacy Flag */
attr_val_reconnection_address_t
reconn_address; /**< Attribute Value for Characteristic Type: Reconnection Address */
attr_val_periph_preferred_conn_params_t
periph_preferred_conn_params; /**< Attribute Value for Characteristic Type: Peripheral Preferred Connection Parameters */
} value; /**< Union of Attribute Values. Use the right format based on Attribute Type */
} mico_bt_smart_attribute_t;
/**
* Attribute List Structure
*/
typedef struct {
uint32_t count; /**< Attribute count */
mico_bt_smart_attribute_t *list; /**< Pointer to attribute linked-list */
} mico_bt_smart_attribute_list_t;
#pragma pack()
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
/*****************************************************************************/
/** @addtogroup btattr Attribute
* @ingroup micobt
*
* Bluetooth Smart Attribute Abstraction
*
*
* @{
*/
/*****************************************************************************/
/** Create a Bluetooth Smart Attribute structure
*
* @param[out] attribute : pointer that will receive the attribute structure
* @param[in] type : attribute type
* @param[in] variable_length : length of the variable part of the attribute.
* For some attribute types, this argument is not
* used.
*
* @return MICO_BT_SUCCESSsuccessMICO_BT_BADARGinput argument error
*/
OSStatus mico_bt_smart_attribute_create( mico_bt_smart_attribute_t **attribute, mico_bt_smart_attribute_type_t type,
uint16_t variable_length );
/** Delete a Bluetooth Smart Attribute structure
*
* @param[in,out] attribute : attribute structure to delete
*
* @return MICO_BT_SUCCESSsuccessMICO_BT_BADARGinput argument error
*/
OSStatus mico_bt_smart_attribute_delete( mico_bt_smart_attribute_t *attribute );
/** Initialise a list of Bluetooth Smart Attributes
*
* @param[out] list : list to initialise
*
* @return MICO_BT_SUCCESSsuccessMICO_BT_BADARGinput argument error
*/
OSStatus mico_bt_smart_attribute_create_list( mico_bt_smart_attribute_list_t *list );
/** Deinitialise a list of Bluetooth Smart Attributes
*
* @param[out] list : list to deinitialise
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_delete_list( mico_bt_smart_attribute_list_t *list );
/** Add a Bluetooth Smart Attribute to a list
*
* @param[in,out] list : list to add attribute to
* @param[in] attribute : attribute to add to the list
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_add_to_list( mico_bt_smart_attribute_list_t *list,
mico_bt_smart_attribute_t *attribute );
/** Remove a Bluetooth Smart Attribute with the given handle from a list
*
* @param[in,out] list : list to remote attribute from
* @param[in] handle : handle of the attribute to remove
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_remove_from_list( mico_bt_smart_attribute_list_t *list, uint16_t handle );
/** Find a Bluetooth Smart Attribute with the given handle from a list
*
* @param[in,out] list : list to find attribute in
* @param[in] handle : handle of the attribute to find
* @param[out] attribute : pointer that will receive the attribute
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_search_list_by_handle( const mico_bt_smart_attribute_list_t *list, uint16_t handle,
mico_bt_smart_attribute_t **attribute );
/** Find a Bluetooth Smart Attribute with the given handle from a list
*
* @param[in,out] list : list to find attribute in
* @param[in] uuid : UUID of the attribute to find
* @param[in] starting_handle : handle to start the search
* @param[in] ending_handle : handle to end the search
* @param[out] attribute : pointer that will receive the attribute
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_search_list_by_uuid( const mico_bt_smart_attribute_list_t *list,
const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t **attribute );
/** Merge two Bluetooth Smart Attribute lists
*
* @param[in,out] trunk_list : list that will receive all of the attributes from the branch list
* @param[in,out] branch_list : list whose attributes will be removed and inserted into the trunk list
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_merge_lists( mico_bt_smart_attribute_list_t *trunk_list,
mico_bt_smart_attribute_list_t *branch_list );
/** Print attribute contents
*
* @param[in] attribute : attribute to print
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_print( const mico_bt_smart_attribute_t *attribute );
/** Print the contents of all attributes in a list
*
* @param[in] list : list whose attributes to print
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_print_list( const mico_bt_smart_attribute_list_t *list );
/** Get attribute list head
*
* @param[in] list : attribute list
* @param[out] head : pointer that will receive the list head
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_get_list_head( const mico_bt_smart_attribute_list_t *list,
mico_bt_smart_attribute_t **head );
/** Get attribute list count
*
* @param[in] list : attribute list
* @param[out] count : variable that will receive the count
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smart_attribute_get_list_count( const mico_bt_smart_attribute_list_t *list, uint32_t *count );
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,427 @@
/** @file
* Defines common constants and types for MiCO support for Bluetooth Smart
*/
#pragma once
#include "mico_bt_smartbridge_constants.h"
#include "mico_bt_smart_attribute.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/** @cond !ADDTHIS*/
/* Limits and Default Value for Scan Interval */
#define DEFAULT_SCAN_INTERVAL 0x0010
#define MIN_SCAN_INTERVAL 0x0004
#define MAX_SCAN_INTERVAL 0x4000
/* Limits and Default Value for Scan Window */
#define DEFAULT_SCAN_WINDOW 0x0010
#define MIN_SCAN_WINDOW 0x0004
#define MAX_SCAN_WINDOW 0x4000
#define BONDING_DISABLED 0x00
#define BONDING_ENABLED 0x01
#define PASSKEY_ENTRY_ENABLED 0x04
#define SECURE_CONNECTION_ENABLE 0x08
#define DISTRIBUTE_ENCRYPTION_KEY 0x01
#define DISTRIBUTE_ID_KEY 0x02
#define DISTRIBUTE_SIGN_KEY 0x04
/** @endcond */
/******************************************************
* Enumerations
******************************************************/
/**
* Bluetooth Smart filter policy
*/
typedef enum {
FILTER_POLICY_NONE = 0x00, /**< No filter policy */
FILTER_POLICY_WHITE_LIST = 0x01, /**< White list filter policy */
} mico_bt_smart_filter_policy_t;
/**
* Bluetooth Smart scan duplicates filter
*/
typedef enum {
DUPLICATES_FILTER_DISABLED = 0x00, /**< Duplicates filter is disabled */
DUPLICATES_FILTER_ENABLED = 0x01, /**< Duplicates filter is enabled */
} mico_bt_smart_filter_duplicated_t;
/**
* Bluetooth Smart address type
*/
typedef enum {
BT_SMART_ADDR_TYPE_PUBLIC = 0x00, /**< Public address */
BT_SMART_ADDR_TYPE_RANDOM = 0x01 /**< Random address */
} mico_bt_smart_address_type_t;
/**
* Bluetooth Smart link role
*/
typedef enum {
BT_SMART_LINK_ROLE_MASTER = 0x00, /**< Public address */
BT_SMART_LINK_ROLE_SLAVE = 0x01 /**< Random address */
} mico_bt_smart_link_role_t;
/**
* Bluetooth Smart scan type
*/
typedef enum {
BT_SMART_PASSIVE_SCAN = 0x00, /**< Passive scan. Controller does not send SCAN_REQ and listens for Advertising from remote devices */
BT_SMART_ACTIVE_SCAN = 0x01, /**< Active scan. Controller sends SCAN_REQ. Controller listens for Advertising from remote devices and may receive SCAN_RSP from remote devices */
} mico_bt_smart_scan_type_t;
/**
* Bluetooth Smart advertising event
*/
typedef enum {
BT_SMART_CONNECTABLE_UNDIRECTED_ADVERTISING_EVENT = 0x00, /**< ADV_IND : Connectable undirected advertising event */
BT_SMART_CONNECTABLE_DIRECTED_ADVERTISING_EVENT = 0x01, /**< ADV_DIRECT_IND : Connectable directed advertising event */
BT_SMART_SCANNABLE_UNDIRECTED_ADVERTISING_EVENT = 0x02, /**< ADV_SCAN_IND : Scannable undirected advertising event */
BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING_EVENT = 0x03, /**< ADV_NONCONN_IND : Non-connectable undirected advertising event */
BT_SMART_SCAN_RESPONSE_EVENT = 0x04, /**< SCAN_RSP : Scan response event */
} mico_bt_smart_advertising_event_t;
/**
* Bluetooth Smart advertising event
*/
typedef enum {
BT_SMART_UNDIRECTED_ADVERTISING = 0x00, /**< General undirected advertising */
BT_SMART_DISCOVERABLE_ADVERTISING = 0x01, /**< Discoverable advertising */
BT_SMART_DIRECTED_ADVERTISING = 0x02, /**< Directed advertising */
BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING = 0x03, /**< Non-connectable undirected advertising */
} mico_bt_smart_advertising_type_t;
/**
* Bluetooth Smart device input/output (IO) capabilities
*/
typedef enum {
BT_SMART_IO_DISPLAY_ONLY = 0x00,
BT_SMART_IO_DISPLAY_YES_NO_BUTTONS = 0x01,
BT_SMART_IO_KEYBOARD_ONLY = 0x02,
BT_SMART_IO_NO_INPUT_NO_OUTPUT = 0x03,
BT_SMART_IO_KEYBOARD_DISPLAY = 0x04,
} mico_bt_io_capabilities_t;
/**
* Bluetooth Smart device Authentication Requirements (AuthReq)
*/
typedef enum {
BT_SMART_AUTH_REQ_NONE = 0,
BT_SMART_AUTH_REQ_BONDING = ( BONDING_ENABLED ),
BT_SMART_AUTH_REQ_PASSKEY_ENTRY = ( PASSKEY_ENTRY_ENABLED ),
BT_SMART_AUTH_REQ_BONDING_AND_PASSKEY_ENTRY = ( BONDING_ENABLED | PASSKEY_ENTRY_ENABLED ),
} mico_bt_smart_auth_req_t;
/**
* Bluetooth Smart device bonding request type
*/
typedef enum {
/* Bonding event -- user should reply it with #mico_bt_smart_bond_reply() */
MICO_BT_SMART_BOND_PASS_KEY_REQ = 0x01,
/* Bonding event -- user should reply it with #mico_bt_smart_bond_reply() */
MICO_BT_SMART_BOND_USR_CONFIRM_REQ = 0x02,
/* Bonding event -- user should reply it with #mico_bt_smart_bond_reply() */
MICO_BT_SMART_BOND_OOB_DATA_REQ = 0x03,
/* Bonding event -- user should not reply it */
MICO_BT_SMART_BOND_PASS_KEY_NOTIFY = 0x04,
} mico_bt_smart_bond_request_type_t;
/**
* Bluetooth Smart device key distribution types
*/
typedef enum {
BT_SMART_DISTRIBUTE_NONE = 0,
BT_SMART_DISTRIBUTE_ENCRYPTION_KEY = ( DISTRIBUTE_ENCRYPTION_KEY ),
BT_SMART_DISTRIBUTE_ID_KEY = ( DISTRIBUTE_ID_KEY ),
BT_SMART_DISTRIBUTE_ENCRYPTION_AND_ID_KEYS = ( DISTRIBUTE_ID_KEY | DISTRIBUTE_ENCRYPTION_KEY ),
BT_SMART_DISTRIBUTE_SIGN_KEY = ( DISTRIBUTE_SIGN_KEY ),
BT_SMART_DISTRIBUTE_ENCRYPTION_AND_SIGN_KEYS = ( DISTRIBUTE_SIGN_KEY | DISTRIBUTE_ENCRYPTION_KEY ),
BT_SMART_DISTRIBUTE_ID_AND_SIGN_KEYS = ( DISTRIBUTE_SIGN_KEY | DISTRIBUTE_ID_KEY ),
BT_SMART_DISTRIBUTE_ALL_KEYS = ( DISTRIBUTE_SIGN_KEY | DISTRIBUTE_ID_KEY | DISTRIBUTE_ENCRYPTION_KEY ),
} mico_bt_smart_key_distribution_t;
/**
* Bluetooth Smart Out-of-Band (OOB) authentication data
*/
typedef enum {
BT_SMART_OOB_AUTH_NONE, /**< OOB authentication data is not available */
BT_SMART_OOB_AUTH_AVAILABLE, /**< OOB authentication data is available */
} mico_bt_smart_oob_auth_t;
/******************************************************
* Structures
******************************************************/
#pragma pack(1)
/**
* Bluetooth Smart device
*/
typedef struct {
mico_bt_device_address_t address; /**< Bluetooth device address */
mico_bt_smart_address_type_t address_type; /**< Address Type */
char name[31]; /**< User-friendly name */
} mico_bt_smart_device_t;
/**
* Bluetooth Smart scan settings
*/
typedef struct {
mico_bt_smart_scan_type_t
type; /**< Scan type */
mico_bt_smart_filter_policy_t
filter_policy; /**< Scan filter policy */
mico_bt_smart_filter_duplicated_t
filter_duplicates; /**< Scan duplicates filter */
uint16_t
interval; /**< Interval between scans. Unit: 0.625ms. Range: 0x0004 - 0x4000 (2.5ms - 10.24s) */
uint16_t
window; /**< Scan window. Must be <= scan interval. Unit: 0.625ms. Range: 0x0004 - 0x4000 (2.5ms - 10.24s) */
uint16_t
duration_second; /**< Scan duration in seconds */
} mico_bt_smart_scan_settings_t;
/**
* Bluetooth Smart advertising report
*/
typedef struct {
mico_bt_smart_device_t remote_device; /**< Remote device */
int8_t signal_strength; /**< RSSI in dBm */
mico_bt_smart_advertising_event_t event; /**< Advertising event received */
uint8_t eir_data_length; /**< Length of EIR data received with advertising event */
uint8_t eir_data[31]; /**< EIR data of advertising event */
} mico_bt_smart_advertising_report_t;
/**
* Bluetooth Smart scan result
*/
typedef struct mico_bt_smart_scan_result {
mico_bt_smart_device_t remote_device; /**< Remote device */
int8_t signal_strength; /**< RSSI in dBm */
mico_bt_smart_advertising_report_t last_scan_response_received; /**< Last scan response event received */
mico_bt_smart_advertising_report_t last_advertising_event_received; /**< Last advertising event received */
struct mico_bt_smart_scan_result *next; /**< Pointer to the next scan result */
/* Additional flag to help application filter scan results */
mico_bool_t filter_display; /**< Set to MICO_TRUE if filter display */
} mico_bt_smart_scan_result_t;
/**
* Bluetooth Smart advertise settings
*/
typedef struct {
mico_bt_smart_advertising_type_t
type; /**< Advertising type */
mico_bool_t
use_high_duty; /**< Start advertising use high duty cycle interval */
uint16_t
high_duty_interval; /**< High duty advertising interval */
uint16_t
high_duty_duration; /**< High duty advertising duration in seconds (0 for infinite) */
uint16_t
low_duty_interval; /**< Low duty advertising interval */
uint16_t
low_duty_duration; /**< Low duty advertising duration in seconds (0 for infinite) */
mico_bt_smart_address_type_t
directed_advertisement_addr_type; /**< Target device address type for directed advertising */
mico_bt_device_address_t
directed_advertisement_addr; /**< Target device address for directed advertising */
} mico_bt_smart_advertising_settings_t;
/**
* Bluetooth Smart connection settings
*/
typedef struct {
uint16_t
timeout_second; /**< Connection timeout in seconds */
mico_bt_smart_filter_policy_t
filter_policy; /**< Connection initiator filter policy: No filter or using white list */
uint16_t
interval_min; /**< Connection Interval Min. Unit: 1.25ms. Range: 0x000A - 0x0C80 (7.5ms - 4s) */
uint16_t
interval_max; /**< Connection Interval Max. Unit: 1.25ms. Range: 0x000A - 0x0C80 (7.5ms - 4s) */
uint16_t
latency; /**< Connection Latency. Unit: Connection Events. Range: 0x0000 - 0x01F4 */
uint16_t
supervision_timeout; /**< Supervision Timeout. Unit: 10ms. Range: 0x000A - 0x0C80 (100ms - 32s)*/
uint16_t
ce_length_min; /**< Connection Event Length Min. Unit: Connection Events. Range: 0x0000 - 0xFFFF */
uint16_t
ce_length_max; /**< Connection Event Length Max. Unit: Connection Events. Range: 0x0000 - 0xFFFF */
uint32_t
attribute_protocol_timeout_ms; /**< Attribute protocol timeout in milliseconds */
} mico_bt_smart_connection_settings_t;
/**
* Bluetooth Smart Extended Inquiry Response (EIR) data structure
*/
typedef struct {
uint8_t length; /**< Length */
uint8_t type; /**< Type */
uint8_t data[1]; /**< Start of data */
} mico_bt_smart_eir_data_structure_t;
/**
* Bluetooth Smart security settings
*/
typedef struct {
uint16_t timeout_second; /**< Timeout in second. Default is 30 seconds */
mico_bt_io_capabilities_t io_capabilities; /**< Device I/O capability */
mico_bt_smart_auth_req_t authentication_requirements; /**< Authentication requirements */
mico_bt_smart_oob_auth_t oob_authentication; /**< OOB authentication data */
uint8_t max_encryption_key_size; /**< Encryption key size (7 to 16 bytes) */
mico_bt_smart_key_distribution_t master_key_distribution; /**< Bit mask of master/initiator key distribution */
mico_bt_smart_key_distribution_t slave_key_distribution; /**< Bit mask of slave/responder key distribution */
} mico_bt_smart_security_settings_t;
/**
* Bluetooth Smart Peer Device Bond Info
*/
typedef struct {
mico_bt_device_address_t
peer_address; /**< Bonded peer device address */
mico_bt_smart_address_type_t
address_type; /**< Peer device's address type */
uint8_t
irk [16]; /**< Peer device's Identity Resolving Key (IRK). Used for random address generation and resolution */
uint8_t
csrk[16]; /**< Peer device's Connection Signature Resolving Key (CSRK). Used for signing data and verifying messages */
uint8_t
ltk [16]; /**< Peer device's Long Term Key (LTK). Used for encryption */
uint8_t
rand[8]; /**< Peer device's Random Number (Rand). Used for identifying LTK */
uint16_t
ediv; /**< Peer device's Encrypted Diversifier (EDIV). Used for identifying LTK */
} mico_bt_smart_bond_info_t;
/**
* Bluetooth Smart Device Bond Request Event Parameters.
*/
typedef struct {
/* Type of the request */
mico_bt_smart_bond_request_type_t type;
union {
/* MICO_BT_SMART_BOND_PASS_KEY_REQ */
struct {
mico_bt_device_address_t addr;
} passkey;
/* MICO_BT_SMART_BOND_USR_CONFIRM_REQ */
struct {
mico_bt_device_address_t addr;
/* An up to six-digit number (from 0 to 999999) to display or
* request remote entry
*/
uint32_t passkey;
} confirm;
/* MICO_BT_SMART_BOND_OOB_DATA_REQ */
struct {
mico_bt_device_address_t addr;
} oob_data;
/* MICO_BT_SMART_BOND_PASS_KEY_NOTIFY */
struct {
mico_bt_device_address_t addr;
uint32_t passkey;
} notify;
} u;
} mico_bt_smart_bond_request_t;
/*
* Bluetooth Smart Device Bond Replay information.
*/
typedef struct {
/* Type of the request */
mico_bt_smart_bond_request_type_t type;
/* reply status */
mico_bt_result_t res;
/* reply data -- only valid when 'res' is MICO_BT_SUCCESS */
union {
/* Used for MICO_BT_SMART_BOND_USER_CONFIRM */
struct {
mico_bt_device_address_t addr;
} confirm;
/* Used for MICO_BT_SMART_BOND_PASS_KEY_REQ */
struct {
mico_bt_device_address_t addr;
uint32_t passkey;
} passkey;
/* Used for MICO_BT_SMART_BOND_OOB_DATA_REQ */
struct {
mico_bt_device_address_t addr;
uint8_t *data;
uint8_t len;
} oob_data;
} u;
} mico_bt_smart_bond_reply_t;
#pragma pack()
/******************************************************
* Type Definitions
******************************************************/
/**
* Bluetooth Smart scan complete callback
*/
typedef event_handler_t mico_bt_smart_scan_complete_callback_t;
/**
* Bluetooth Smart advertising report callback
*/
typedef OSStatus (*mico_bt_smart_advertising_report_callback_t) ( const mico_bt_smart_advertising_report_t *result );
/**
* Bluetooth Smart Device Bond Callback.
*/
typedef OSStatus (*mico_bt_smart_bonding_callback_t)(const mico_bt_smart_bond_request_t *request);
/**
* Bluetooth Smart advertising complete callback
*/
typedef event_handler_t mico_bt_smart_advertising_complete_callback_t;
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
/** mico_bt_smart_bond_reply
*
* This function is called to reply BLE Bond Event posted by #mico_bt_smart_bonding_callback_t.
* You should fill a strcutre #mico_bt_smart_bond_reply_t to complete this bonding procedure.
*
* @param[in] response the response to current bonding event.
*
* @return OSStatus
*/
extern OSStatus mico_bt_smart_bond_reply(const mico_bt_smart_bond_reply_t *response);
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,731 @@
#pragma once
#include "mico_bt_smart_interface.h"
#include "LinkListUtils.h"
/** @file
* Defines functions for bridging Bluetooth Smart with Wi-Fi
*/
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/**
* SmartBridge socket status
*/
typedef enum {
SMARTBRIDGE_SOCKET_DISCONNECTED, /**< Socket is disconnected */
SMARTBRIDGE_SOCKET_CONNECTING, /**< Socket is in connecting state */
SMARTBRIDGE_SOCKET_CONNECTED, /**< Socket is connected with a remote device */
} mico_bt_smartbridge_socket_status_t;
/******************************************************
* Type Definitions
******************************************************/
/**
* Socket to create a SmartBridge connection
*/
typedef struct mico_bt_smartbridge_socket mico_bt_smartbridge_socket_t;
/**
* Auto connection callback parameters
*/
typedef struct mico_bt_smartbridge_auto_conn_cback_parm mico_bt_smartbridge_auto_conn_cback_parms_t;
/**
* Socket disconnection callback
*/
typedef OSStatus (*mico_bt_smartbridge_disconnection_callback_t) ( mico_bt_smartbridge_socket_t *socket );
/**
* Socket GATT notification callback
*/
typedef OSStatus (*mico_bt_smartbridge_notification_callback_t) ( mico_bt_smartbridge_socket_t *socket,
uint16_t attribute_handle );
/**
* BLE Auto connection callback
*/
typedef OSStatus (*mico_bt_smartbridge_auto_connection_callback_t) ( mico_bt_smartbridge_socket_t *socket );
/**
* BLE Auto connection parameters callback -- auto connection procedure callback
*/
typedef OSStatus (*mico_bt_smartbridge_auto_connection_parms_cback_t) ( const mico_bt_device_address_t random_bda,
const char *name, const uint8_t *p_data, uint8_t len, mico_bt_smartbridge_auto_conn_cback_parms_t *parm );
/******************************************************
* Structures
******************************************************/
/**
* Socket to create a SmartBridge connection
* @warning The content of the socket structure is for INTERNAL USE only. Modifying
* the content of this structure is prohibited. Please use the Bluetooth SmartBridge
* API to retrieve socket information.
*/
struct mico_bt_smartbridge_socket {
linked_list_node_t
node; /**< Socket list node */
mico_bt_smart_device_t
remote_device; /**< Remote Bluetooth device MICO is connected with (bridging) */
uint16_t
connection_handle; /**< Connection handle */
uint16_t
last_notified_attribute_handle; /**< Last notified attribute handle */
uint8_t
state; /**< Internal state */
uint8_t
actions; /**< Internal socket actions */
mico_bt_smartbridge_auto_connection_callback_t
auto_connection_callback; /**< Callback for handing connection event by Auto Connection */
mico_bt_smartbridge_disconnection_callback_t
disconnection_callback; /**< Callback for handling disconnection event by remote device */
mico_bt_smart_bonding_callback_t
bonding_callback; /**< Callback for handling pairing/bonding successful event */
mico_bt_smartbridge_notification_callback_t
notification_callback; /**< Callback for handling GATT notification from remote device */
mico_bt_smart_connection_settings_t
connection_settings; /**< Connection settings */
mico_bt_smart_security_settings_t
security_settings; /**< Security settings */
mico_bt_smart_bond_info_t
bond_info; /**< Bond Info */
mico_bt_smart_bond_request_t
bond_req; /**< Bond Request Structure */
void
*att_cache; /**< Pointer to Attribute Cache */
mico_semaphore_t
semaphore; /**< Semaphore */
};
struct mico_bt_smartbridge_auto_conn_cback_parm {
mico_bt_smartbridge_socket_t
*socket; /**< A socket associated with the auto connection */
mico_bt_smart_connection_settings_t
conn_settings; /**< The connection settings associated with a socket */
mico_bt_smart_security_settings_t
security_settings; /**< Security settings */
mico_bt_smartbridge_auto_connection_callback_t
auto_connection_callback; /**< Callback for handing connection event by Auto connection */
mico_bt_smartbridge_disconnection_callback_t
auto_disconn_callback; /**< Callback for handing disconnection event */
mico_bt_smartbridge_notification_callback_t
notification_callback; /**< Callback for handing GATT notification from a remote device */
};
/******************************************************
* Function declarations
******************************************************/
/*****************************************************************************/
/** @addtogroup smartbridge SmartBridge
* @ingroup micobt
*
* Bluetooth SmartBridge Functions
*
*
* @{
*/
/*****************************************************************************/
/*****************************************************************************/
/** @addtogroup sbmgmt SmartBridge Management
* @ingroup smartbridge
*
* SmartBridge Management Functions
*
*
* @{
*/
/*****************************************************************************/
/** Initialise the MICO SmartBridge
*
* @note
* This function initialises:
* \li Generic Attribute Profile (GATT) Client
* \li Generic Access Profile (GAP) Central Role
* \li SmartBridge Socket Manager
* \li Set the number of concurrent connections
*
* After calling @ref mico_bt_smartbridge_init, you may call:
* \li @ref mico_bt_smartbridge_enable_attribute_cache() to enable Attribute Cache
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_init( uint8_t count );
/** Deinitialise the MICO SmartBridge
*
* @note
* This function deinitialises:
* \li GATT Client
* \li GAP Central Role
* \li SmartBridge Socket Manager
* \li SmartBridge Attribute Cache Manager (if enabled)
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_deinit( void );
/** Enable Attribute Cache
*
* @note
* This function enables the attribute caching feature as specified in the Bluetooth
* Specification version 4.0 Volume 3 Part G Section 2.5.2. Attribute Cache allows
* SmartBridge to discover server's Attribute information once and use cached information
* across reconnections without rediscovery, thus saving time and reducing the amount
* of packet exhange required between MICO SmartBridge and the server.
*
* On a reconnection, SmartBridge searches for matching Attribute information in
* the cache. If not found, SmartBridge discovers server's Attribute
* information and adds the information to the cache when completed. If SmartBridge
* runs out of cache space, the first non-active cache in the list is replaced.
*
* Specified services can be used in ATT cache generation, it makes MICO SmartBridge
* only cache the services that application can support and operate.
*
* @param[in] cache_count : the number of caches that will be supported by MICO SmartBridge
* @param[in] cache_services : define service list to generate caches
* @param[in] service_count : the number of services to generate caches, pass 0 to generate
* all primary services
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_enable_attribute_cache( uint32_t cache_count, mico_bt_uuid_t cache_services[],
uint32_t service_count );
/** Disable Attribute Cache
*
* @note
* This function disables the attribute caching feature
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_disable_attribute_cache( void );
/** @} */
/*****************************************************************************/
/** @addtogroup sbscan SmartBridge Scan
* @ingroup smartbridge
*
* SmartBridge Scan Functions
*
*
* @{
*/
/*****************************************************************************/
/** Check if the MICO SmartBridge is currently scanning for Bluetooth Smart devices
*
* @note
* This function checks if the Bluetooth Controller is currently scanning for Bluetooth
* Smart devices
*
* @return @ref mico_bool_t
*/
mico_bool_t mico_bt_smartbridge_is_scanning( void );
/** Start scanning for remote Bluetooth Smart devices
*
* @note
* This function instructs the Bluetooth controller to start scanning for remote
* Bluetooth Smart devices within proximity with the settings specified.
* Scan results are reported via the given callback handlers.
*
* @warning
* \li result_callback is an intermediate report callback. The complete scan results
* are retrieved using @ref mico_bt_smartbridge_get_scan_result_list once scan
* is complete
* \li advertising_report_callback runs on the context of Bluetooth transport thread. Please refrain
* from executing a long task in the callback
* \li complete_callback runs on the context of MICO_BT_EVT_WORKER_THREAD
* \li If the whitelist filter is enabled in the scan settings, only devices
* in the whitelist appear in the scan results. Call @ref mico_bt_smartbridge_add_device_to_whitelist()
* to add a device to the whitelist
*
* @param[in] settings : scan settings
* @param[in] complete_callback : callback function which is called when scan is
* complete
* @param[in] advertising_report_callback : callback function which is called when an advertising
* report is received
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_start_scan( const mico_bt_smart_scan_settings_t *settings,
mico_bt_smart_scan_complete_callback_t complete_callback,
mico_bt_smart_advertising_report_callback_t advertising_report_callback );
/** Stop the ongoing scan process
*
* This function instructs the Bluetooth controller to stop scanning for remote
* Bluetooth Smart devices.
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_stop_scan( void );
/** Retrieve the most recent scan results
*
* @note
* This function returns a linked-list of the most recent scan results
*
* @warning:
* Application must not modify the list
*
* @param[out] result_list : pointer that will receive the result linked-list
* @param[out] count : variable that will receive the result count
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_get_scan_result_list( mico_bt_smart_scan_result_t **result_list, uint32_t *count );
/** @} */
/*****************************************************************************/
/** @addtogroup sbwhitelist SmartBridge Whitelist Filter
* @ingroup smartbridge
*
* SmartBridge Whitelist Filter Functions
*
*
* @{
*/
/*****************************************************************************/
/** Get the number of devices specified by type in the whitelist
*
* @note
* This function retrieves the number of Bluetooth Smart devices which can
* be used to auto connection procedure in the whitelist.
*
* @param[out] size : device count
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_get_background_connection_devices_size( uint8_t *size );
/** Set auto connection action - start or stop.
*
* @param[in] start_stop : Start or stop auto connection establishment procedure by
* the White List.
* @param[in] scan_settings : Used to set up Scanning Parameters during Auto Connection
* Procedure when the 'start_stop' is BT_TRUE.
* And 'scan_settings.interval', 'scan_settings.window'
* and 'scan_settings.duration_second' are only used.
* If 'duration_second' is 0xFFFF, it will be forever until recalling
* this function by "start_stop = FALSE".
* @param[in] p_auto_conn_cback : Callback function called when a auto connection
* will be established. It is used to query
* user some information and configuration by lower
* stack. Users should fill a socket entity,
* connection settings and callback function.
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_set_auto_connection_action( mico_bool_t start_stop,
const mico_bt_smart_scan_settings_t *scan_settings,
mico_bt_smartbridge_auto_connection_parms_cback_t p_auto_conn_cback );
/** @} */
/*****************************************************************************/
/** @addtogroup sbsock SmartBridge Socket and Connection Management
* @ingroup smartbridge
*
* SmartBridge Socket and Connection Functions
*
*
* @{
*/
/*****************************************************************************/
/** Check if the Bluetooth SmartBridge is ready to connect
*
* @note
* This function checks if the Bluetooth SmartBridge is ready to make a connection
* to a Bluetooth Smart device. The Bluetooth Controller does not support concurrent
* connection requests.
*
* @return @ref mico_bool_t
*/
mico_bool_t mico_bt_smartbridge_is_ready_to_connect( void );
/** Get SmartBridge socket status
*
* @param[in] socket : pointer to the socket to get the status
* @param[out] status : socket status
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_get_socket_status( mico_bt_smartbridge_socket_t *socket,
mico_bt_smartbridge_socket_status_t *status );
/** Create a SmartBridge socket
*
* @note
* \li This function initialises the socket internals to make it ready to connect to
* a Bluetooth Smart device
* \li Socket reconnections are allowed without re-creations
*
* @param[out] socket : pointer to the socket to initialise
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_create_socket( mico_bt_smartbridge_socket_t *socket );
/** Delete a SmartBridge socket
*
* @note
* This function deinitialises the socket internals.
*
* @param[in,out] socket : pointer to the socket to deinitialise
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_delete_socket( mico_bt_smartbridge_socket_t *socket );
/** Initiate a SmartBridge connection with a remote Bluetooth Smart device
*
* @note
* This function creates a connection with the specified remote device.
*
* \li If Bond Information is loaded, the socket uses the Long-Term Key (LTK), Random
* Number (RAND), and Encryption Diversifier (EDIV) of the Bond Information to
* encrypt the connection. Call @ref mico_bt_smartbridge_set_bond_info() before
* connecting to load Bond information.
* \li If Pairing is enforced, the socket initiates Pairing Request and a new Bond
* is created. Call @ref mico_bt_smartbridge_enable_pairing() before connecting
* to initiate Pairing Request.
* \li If Attribute Cache is enabled, the socket starts a discovery of the server's
* Attribute information.
*
* @warning
* \li Callback functions run on the context of MICO_BT_EVT_WORKER_THREAD.
* \li If Pairing and Attribute Cache are enabled, this function may block for a
* few seconds.
*
* @param[in,out] socket : pointer to the socket to create the
* connection
* @param[in] remote_device : remote device to connect
* @param[in] settings : connection settings
* @param[in] disconnection_callback : callback function that is called when
* the connection is disconnected by
* remote device
* @param[in] notification_callback : callback function that is called when
* a GATT notification or indication is
* received from the remote device
*
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_connect( mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_device_t *remote_device,
const mico_bt_smart_connection_settings_t *settings,
mico_bt_smartbridge_disconnection_callback_t disconnection_callback,
mico_bt_smartbridge_notification_callback_t notification_callback );
/** Disconnect a SmartBridge connection
*
* @note
* This function disconnects a connection with a remote device.
*
* @param[in,out] socket : pointer to the socket of the connection to disconnect
* @param[in] remove_it_from_whitelist: this device is remove from the white list if TRUE.
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_disconnect( mico_bt_smartbridge_socket_t *socket, mico_bool_t remove_it_from_whitelist );
/** Set transmit power during connection
*
* @note
* This function set the transmit power of the connection
*
* @param[in] socket : pointer to the socket of the connection
* @param[in] transmit_power_dbm : transmit power in dBm
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_set_transmit_power( mico_bt_smartbridge_socket_t *socket, int8_t transmit_power_dbm );
/** @} */
/*****************************************************************************/
/** @addtogroup sbsec SmartBridge Security
* @ingroup smartbridge
*
* SmartBridge Security Functions
*
*
* @{
*/
/*****************************************************************************/
/** Set a peer device's bond information
*
* @note
* This function loads Bond (security) information to the socket which will be used
* to reestablish an encrypted link with the peer device without having to perform
* the complete handshake procedure (pairing)
*
* @warning
* This function must be called before calling @ref mico_bt_smartbridge_connect
*
* @param[in,out] socket : socket to load the Bond information into
* @param[in] settings : security settings
* @param[in] bond_info : Bond information
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_set_bond_info( mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_security_settings_t *settings,
const mico_bt_smart_bond_info_t *bond_info );
/** Reset the bond information stored in the socket
*
* @warning
* This function must be called before calling @ref mico_bt_smartbridge_connect
*
* @param[in,out] socket : pointer to the socket of the connection to disconnect
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_clear_bond_info( mico_bt_smartbridge_socket_t *socket );
/** Force a SmartBridge socket to initiate Pairing Request with a Bluetooth Smart device
*
* @note
* This function prepares the socket to initiate Pairing Request with the device.
* Previously loaded bond information is deleted and is replaced with a new bond
* if the pairing process succeeds.
*
* @warning
* \li This function must be called before calling @ref mico_bt_smartbridge_connect
* \li Callback functions run on the context of MICO_BT_EVT_WORKER_THREAD
*
* @param[in,out] socket : pointer to the socket to enable pairing
* @param[in] settings : security settings
* @param[in] numeric_passkey : NUL-terminated string of numeric passkey. Maximum is 6 digits.
* @param[in] bonding callback : callback that is called when bonding with remote device occurs
*
* @note:
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_enable_pairing( mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_security_settings_t *settings,
mico_bt_smart_bonding_callback_t bonding_callback );
/** Set a SmartBridge socket to disable pairing with a remote device
*
* @warning
* This function must be called before calling @ref mico_bt_smartbridge_connect
*
* @param[in,out] socket : pointer to the socket to disable pairing
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_disable_pairing( mico_bt_smartbridge_socket_t *socket );
/** @} */
/*****************************************************************************/
/** @addtogroup sbattr SmartBridge Attribute Cache
* @ingroup smartbridge
*
* SmartBridge Attribute Cache Functions
*
*
* @{
*/
/*****************************************************************************/
/** Enable all GATT notifications supported by the server
*
* @note
* This function searches for client configuration Attribute in the cache and enables
* all notifications from the server.
*
* @warning This function returns error if Attribute Cache is not enabled
*
* @param[in] socket : socket to enable notifications
* @param[in] is_notification_or_indication: Enable Notification or Indication
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_enable_attribute_cache_notification( mico_bt_smartbridge_socket_t *socket,
mico_bool_t is_notification_or_indication );
/** Disable all GATT notifications supported by the server
*
* @note
* This function searches for client configuration Attribute in the cache and disables
* all notifications from the server.
*
* @warning This function returns error if Attribute Cache is not enabled
*
* @param[in] socket : socket to disable notifications
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_disable_attribute_cache_notification( mico_bt_smartbridge_socket_t *socket );
/** Release attribute cache data
*
* @note
* This function release all data in the cache and put attribute cache to free list.
*
* @warning This function returns error if Attribute Cache is not enabled
*
* @param[in] socket : socket to delete attribute cache
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_remove_attribute_cache( mico_bt_smartbridge_socket_t *socket );
/** Retrieve the list of cached Attributes
*
* @note
* This function retrieves the list of cached Attributes of the socket
*
* @warning This function returns error if Attribute Cache is not enabled
*
* @param[in] socket : socket to get the Attribute list from
* @param[out] att_cache_list : pointer that will receive the Attribute list
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_get_attribute_cache_list( mico_bt_smartbridge_socket_t *socket,
mico_bt_smart_attribute_list_t **att_cache_list );
/** Find and read attribute with the handle provided from the Attribute Cache
*
* @note
* This function searches for an attribute with the given handle in the cache and
* copies the content to the attribute buffer provided.
*
* @warning This function returns error if Attribute Cache is not enabled
*
* @param[in] socket : pointer to the socket to search the attribute
* @param[in] handle : handle of the attribute to find
* @param[in,out] attribute : pointer to the buffer which will contain the attribute
* @param[in] size : buffer size in bytes
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_get_attribute_cache_by_handle( mico_bt_smartbridge_socket_t *socket, uint16_t handle,
mico_bt_smart_attribute_t *attribute, uint16_t size );
/** Find and read attribute with the UUID provided from the local attribute database
*
* @note
* This function searches for an attribute with the given UUID in the local
* attribute database and copies the content to the attribute buffer provided.
*
* @warning This function returns error if Attribute Cache is not enabled
*
* @param[in] socket : pointer to the socket to search the attribute from
* @param[in] uuid : UUID of the attribute to find
* @param[in] starting_handle : the search starting handle
* @param[in] ending_handle : the search ending handle
* @param[in,out] attribute : pointer to the buffer which will contain the attribute content
* @param[in] size : buffer size in bytes
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_get_attribute_cache_by_uuid( mico_bt_smartbridge_socket_t *socket,
const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t *attribute,
uint32_t size );
OSStatus mico_bt_smartbridge_get_service_from_attribute_cache_by_uuid( mico_bt_smartbridge_socket_t *socket,
const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t *attribute,
uint32_t size );
OSStatus mico_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( mico_bt_smartbridge_socket_t *socket,
const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t *attribute,
uint32_t size );
/** Find and refresh Characteristic Value with the given handle in the Attribute Cache
*
* @note
* This function reads the Characteristic Value from the server and updates the
* cache.
*
* @warning This function returns error if Attribute Cache is not enabled
*
* @param[in] socket : socket with the Characteristic Value to refresh
* @param[in] handle : handle of the Characteritic Value to refresh
*
* @return OSStatus
*/
OSStatus mico_bt_smartbridge_refresh_attribute_cache_characteristic_value( mico_bt_smartbridge_socket_t *socket,
uint16_t handle );
/** Write Characteristic Value in the Attribute Cache to the server
*
* @note
* This function writes the given Characteristic Value to the server and updates the
* cache.
*
* @warning This function returns error if Attribute Cache is not enabled
*
* @param[in] socket : socket with the Characteristic Value to write to the server
* @param[in] characteristic_value : Characteritic Value to write to the server
*
* @return OSStatus
*/
OSStatus mico_bt_smartbridge_write_attribute_cache_characteristic_value( mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *characteristic_value );
/** @} */
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,84 @@
/** @file
* Defines common constants and types for the MICO Bluetooth Framework
*/
#pragma once
#include "mico_bt_constants.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/** @cond !ADDTHIS*/
#define MICO_BT_ADDRESS_BYTE_SIZE 6
/** @endcond */
/******************************************************
* Enumerations
******************************************************/
/**
* UUID size
*/
typedef enum {
UUID_16BIT = 0x02, /**< 16-bit */
UUID_32BIT = 0x04, /**< 32-bit */
UUID_128BIT = 0x10 /**< 128-bit */
} mico_bt_uuid_size_t;
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
#if 0
/**
* Bluetooth Device Address (BD_ADDR)
* A 48-bit address that uniquely identifies a Bluetooth device
*/
typedef struct {
uint8_t address[MICO_BT_ADDRESS_BYTE_SIZE]; /**< Address. 48-bit Bluetooth device address in a little-endian format */
} mico_bt_device_address_t;
/**
* Universally Unique Identifier (UUID)
* A standardised format of string ID that uniquely identifies a Bluetooth service
*/
typedef struct {
union {
uint16_t value_16_bit; /**< 16-bit UUID value. */
uint16_t value_128_bit[UUID_128BIT / 2]; /**< 128-bit UUID value. */
} value; /**< A union of UUID values */
mico_bt_uuid_size_t size; /**< UUID size */
} mico_bt_uuid_t;
#endif
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,272 @@
#pragma once
/** @file
* Defines SmartBridge Generic Attribute Profile (GATT) Functions
*/
#include "mico_bt_smartbridge.h"
#include "mico_bt_smart_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
/*****************************************************************************/
/** @addtogroup sbgatt SmartBridge GATT Procedures
* @ingroup smartbridge
*
* SmartBridge Raw GATT Functions
*
*
* @{
*/
/*****************************************************************************/
/** Discover All Primary Services
*
* @param[in] socket : socket that is connected to the server to discover
* Primary Services from
* @param[out] service_list : pointer that will receive the list of Primary Services
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_discover_all_primary_services( const mico_bt_smartbridge_socket_t *socket,
mico_bt_smart_attribute_list_t *service_list );
/** Discover Primary Services by the given UUID
*
* @param[in] socket : socket that is connected to the server to discover
* Primary Services from
* @param[in] uuid : unique identifier of the Primary Services to discover
* @param[out] service_list : pointer that will receive the list of Primary Services
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_discover_primary_services_by_uuid( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *service_list );
/** Find Included Services
*
* @param[in] socket : socket that is connected to the server to discover
* Included Services from
* @param[in] start_handle : starting Attribute handle of the Primary Service to
* find the Included Services from
* @param[in] end_handle : ending Attribute handle of the Primary Service to
* find the Included Services from
* @param[out] include_list : pointer that will receive the list of Included Services
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_find_included_services( const mico_bt_smartbridge_socket_t *socket,
uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *include_list );
/** Discover All Characterisitics in a Service
*
* @param[in] socket : socket that is connected to the server to discover
* Characteristics from
* @param[in] start_handle : starting Attribute handle of the Primary Service to
* discover Characteristics from
* @param[in] end_handle : ending Attribute handle of the Primary Service to
* discover Characteristics from
* @param[out] characteristic_list : pointer that will receive the list of Characteristics
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_discover_all_characteristics_in_a_service( const mico_bt_smartbridge_socket_t *socket,
uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *characteristic_list );
/** Discover Characterisitics by the given UUID
*
* @param[in] socket : socket that is connected to the server to discover
* Characteristics from
* @param[in] uuid : unique identifier of the Characteristics to discover
* @param[in] start_handle : starting Attribute handle of the Primary Service to
* discover Characteristics from
* @param[in] end_handle : ending Attribute handle of the Primary Service to
* discover Characteristics from
* @param[out] characteristic_list : pointer that will receive the list of Characteristics
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_discover_characteristic_by_uuid( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle,
mico_bt_smart_attribute_list_t *characteristic_list );
/** Discover Attribute Handle and Type of all Characteristic Descriptors
*
* @note
* Additional information of the Descriptors can be read using @ref mico_bt_smartbridge_gatt_read_characteristic_descriptor()
* and @ref mico_bt_smartbridge_gatt_read_long_characteristic_descriptor()
*
* @param[in] socket : socket that is connected to the server to discover
* Characteristic Descriptors from
* @param[in] start_handle : starting Attribute handle of the Characteristic to
* discover Characteristic Descriptors from
* @param[in] end_handle : ending Attribute handle of the Characteristic to
* discover Characteristic Descriptors from
* @param[out] descriptor_list : pointer that will receive the list of Descriptors
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_discover_handle_and_type_of_all_characteristic_descriptors(
const mico_bt_smartbridge_socket_t *socket, uint16_t start_handle, uint16_t end_handle,
mico_bt_smart_attribute_list_t *descriptor_list );
/** Read Characteristic Descriptor
*
* @param[in] socket : socket that is connected to the server to read
* Characteristic Descriptor from
* @param[in] handle : Attribute handle of the Characteristic Descriptor to read
* @param[in] uuid : unique identifier of the Characteristic Descriptor to read
* @param[out] descriptor : pointer that will receive the Descriptors
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_read_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket,
uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor );
/** Read Long Characteristic Descriptor
*
* @param[in] socket : socket that is connected to the server to read
* Characteristic Descriptor from
* @param[in] handle : Attribute handle of the Characteristic Descriptor to read
* @param[in] uuid : unique identifier of the Characteristic Descriptor to read
* @param[out] descriptor : pointer that will receive the Descriptors
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_read_long_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket,
uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor );
/** Write Characteristic Descriptor
*
* @param[in] socket : socket that is connected to the server to write
* Characteristic Descriptor to
* @param[in] descriptor : Characteristic Descriptor to write
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_write_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *descriptor );
/** Write Long Characteristic Descriptor
*
* @param[in] socket : socket that is connected to the server to write
* Characteristic Descriptor to
* @param[in] descriptor : Characteristic Descriptor to write
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_write_long_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *descriptor );
/** Read Characteristic Value
*
* @param[in] socket : socket that is connected to the server to read
* Characteristic Value from
* @param[in] handle : Attribute handle of the Characteristic Value to read
* @param[in] uuid : unique identifier of the Characteristic Value to read
* @param[out] characteristic_value : pointer that will receive the Characteristic Value
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_read_characteristic_value( const mico_bt_smartbridge_socket_t *socket,
uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **characteristic_value );
/** Read Characteristic Value
*
* @param[in] socket : socket that is connected to the server to read
* Characteristic Value from
* @param[in] uuid : unique identifier of the Characteristic Values to read
* @param[out] characteristic_value_list : pointer that will receive the Characteristic Value list
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_read_characteristic_values_using_uuid( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *characteristic_value_list );
/** Read Long Characteristic Value
*
* @param[in] socket : socket that is connected to the server to read
* Characteristic Value from
* @param[in] handle : Attribute handle of the Characteristic Value to read
* @param[in] uuid : unique identifier of the Characteristic Value to read
* @param[out] characteristic_value : pointer that will receive the Characteristic Value
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_read_long_characteristic_value( const mico_bt_smartbridge_socket_t *socket,
uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **characteristic_value );
/** Write Characteristic Value
*
* @param[in] socket : socket that is connected to the server to write
* Characteristic Value to
* @param[in] characteristic_value : Characteristic Value to write
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_write_characteristic_value( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *characteristic_value );
/** Write Long Characteristic Value
*
* @param[in] socket : socket that is connected to the server to write
* Characteristic Value to
* @param[in] characteristic_value : Characteristic Value to write
*
* @return @ref OSStatus
*/
OSStatus mico_bt_smartbridge_gatt_write_long_characteristic_value( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *characteristic_value );
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,367 @@
/** @file
*
*/
#include "mico.h"
#include "mico_bt_smartbridge.h"
#include "mico_bt.h"
#include "mico_bt_gatt.h"
#include "mico_bt_ble.h"
#include "mico_bt_cfg.h"
#include "bt_smartbridge_socket_manager.h"
#include "bt_smartbridge_att_cache_manager.h"
#include "bt_smartbridge_helper.h"
#include "bt_smartbridge_stack_interface.h"
#include "StringUtils.h"
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
#define INTERNAL_SECURITY_LEVEL ( 1 ) /* Encryption enabled, no pairing requested because device is already paired */
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Static Function Declarations
******************************************************/
/******************************************************
* Variable Definitions
******************************************************/
gatt_subprocedure_t peripheral_subprocedure;
extern mico_bt_cfg_settings_t mico_bt_cfg_settings;
extern mico_bt_dev_ble_io_caps_req_t default_io_caps_ble;
extern mico_bt_gatt_status_t bt_peripheral_gatt_callback( mico_bt_gatt_evt_t event,
mico_bt_gatt_event_data_t *p_event_data );
mico_bt_smart_advertising_complete_callback_t app_advertising_complete_callback;
/******************************************************
* Function Definitions
******************************************************/
OSStatus peripheral_bt_interface_initialize( void )
{
OSStatus result;
bt_peripheral_log( "Initializing Bluetooth Interface..." );
result = mico_rtos_init_mutex( &peripheral_subprocedure.mutex );
if ( result != MICO_BT_SUCCESS ) {
bt_peripheral_log( "Error creating mutex" );
return result;
}
result = mico_rtos_init_semaphore( &peripheral_subprocedure.done_semaphore, 1 );
if ( result != MICO_BT_SUCCESS ) {
bt_peripheral_log( "Error creating semaphore" );
return result;
}
subprocedure_reset( &peripheral_subprocedure );
mico_bt_gatt_register( GATT_IF_FIXED_DB_APP, bt_peripheral_gatt_callback );
return MICO_BT_SUCCESS;
}
OSStatus peripheral_bt_interface_deinitialize( void )
{
bt_peripheral_log( "Deinitializing Bluetooth Interface..." );
subprocedure_reset( &peripheral_subprocedure );
mico_rtos_deinit_mutex( &peripheral_subprocedure.mutex );
mico_rtos_deinit_semaphore( &peripheral_subprocedure.done_semaphore );
return MICO_BT_SUCCESS;
}
OSStatus peripheral_bt_interface_cancel_last_connect( mico_bt_device_address_t address )
{
return mico_bt_gatt_cancel_connect( address, MICO_TRUE );
}
OSStatus peripheral_bt_interface_disconnect( uint16_t connection_handle )
{
return mico_bt_gatt_disconnect( connection_handle );
}
OSStatus peripheral_bt_interface_set_security_settings( const mico_bt_smart_security_settings_t *settings )
{
/* update the security settings as per passed by the application */
default_io_caps_ble.local_io_cap = settings->io_capabilities;
default_io_caps_ble.auth_req = settings->authentication_requirements;
default_io_caps_ble.oob_data = settings->oob_authentication;
default_io_caps_ble.max_key_size = settings->max_encryption_key_size;
default_io_caps_ble.init_keys = settings->master_key_distribution;
default_io_caps_ble.resp_keys = settings->slave_key_distribution;
return MICO_BT_SUCCESS;
}
OSStatus peripheral_bt_interface_start_advertisements( mico_bt_smart_advertising_settings_t *settings,
mico_bt_smart_advertising_complete_callback_t complete_callback )
{
mico_bt_smart_advertising_type_t advertising_type = settings->type;
mico_bool_t high_duty = settings->use_high_duty;
mico_bt_ble_advert_mode_t mode;
app_advertising_complete_callback = complete_callback;
switch ( advertising_type ) {
case BT_SMART_UNDIRECTED_ADVERTISING: {
mico_bt_cfg_settings.ble_advert_cfg.high_duty_min_interval = settings->high_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.high_duty_max_interval = settings->high_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.high_duty_duration = settings->high_duty_duration;
mico_bt_cfg_settings.ble_advert_cfg.low_duty_min_interval = settings->low_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.low_duty_max_interval = settings->low_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.low_duty_duration = settings->low_duty_duration;
mode = high_duty ? BTM_BLE_ADVERT_UNDIRECTED_HIGH : BTM_BLE_ADVERT_UNDIRECTED_LOW;
return mico_bt_start_advertisements( mode, 0, NULL );
}
case BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING:
case BT_SMART_DISCOVERABLE_ADVERTISING: {
mico_bt_cfg_settings.ble_advert_cfg.high_duty_nonconn_min_interval = settings->high_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.high_duty_nonconn_max_interval = settings->high_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.high_duty_nonconn_duration = settings->high_duty_duration;
mico_bt_cfg_settings.ble_advert_cfg.low_duty_nonconn_min_interval = settings->low_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.low_duty_nonconn_max_interval = settings->low_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.low_duty_nonconn_duration = settings->low_duty_duration;
if ( advertising_type == BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING ) {
mode = high_duty ? BTM_BLE_ADVERT_NONCONN_HIGH : BTM_BLE_ADVERT_NONCONN_LOW;
} else {
mode = high_duty ? BTM_BLE_ADVERT_DISCOVERABLE_HIGH : BTM_BLE_ADVERT_DISCOVERABLE_LOW;
}
return mico_bt_start_advertisements( mode, 0, NULL );
}
case BT_SMART_DIRECTED_ADVERTISING: {
mico_bt_cfg_settings.ble_advert_cfg.low_duty_directed_min_interval = settings->low_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.low_duty_directed_max_interval = settings->low_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.low_duty_directed_duration = settings->low_duty_duration;
mico_bt_cfg_settings.ble_advert_cfg.high_duty_directed_min_interval = settings->high_duty_interval;
mico_bt_cfg_settings.ble_advert_cfg.high_duty_directed_max_interval = settings->high_duty_interval;
mode = high_duty ? BTM_BLE_ADVERT_DIRECTED_HIGH : BTM_BLE_ADVERT_DIRECTED_LOW;
return mico_bt_start_advertisements( BTM_BLE_ADVERT_DIRECTED_HIGH, settings->directed_advertisement_addr_type,
settings->directed_advertisement_addr );
}
default:
return kUnknownErr;
}
}
OSStatus peripheral_bt_interface_stop_advertisements( void )
{
app_advertising_complete_callback = NULL;
return mico_bt_start_advertisements( BTM_BLE_ADVERT_OFF, 0, NULL );
}
void peripheral_bt_interface_advertisements_state_change_callback( mico_bt_ble_advert_mode_t state )
{
if ( state == BTM_BLE_ADVERT_OFF && app_advertising_complete_callback != NULL ) {
mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, app_advertising_complete_callback, NULL );
}
}
OSStatus peripheral_bt_interface_indicate_attribute_value ( uint16_t connection_handle,
const mico_bt_ext_attribute_value_t *attribute )
{
uint16_t val_len = 0;
uint16_t offset = 0;
subprocedure_lock( &peripheral_subprocedure );
subprocedure_reset( &peripheral_subprocedure );
val_len = attribute->value_length;
while ( mico_bt_gatt_send_indication( connection_handle, attribute->handle, &val_len,
attribute->p_value + offset ) == MICO_BT_GATT_SUCCESS ) {
subprocedure_wait_for_completion( &peripheral_subprocedure );
if ( peripheral_subprocedure.result != MICO_BT_SUCCESS ) {
break;
}
offset += val_len;
val_len = attribute->value_length - offset;
if ( offset >= attribute->value_length ) {
break;
}
}
subprocedure_unlock( &peripheral_subprocedure );
return peripheral_subprocedure.result;
}
OSStatus peripheral_bt_interface_notify_attribute_value( uint16_t connection_handle,
const mico_bt_ext_attribute_value_t *attribute )
{
uint16_t val_len = 0;
uint16_t offset = 0;
subprocedure_lock( &peripheral_subprocedure );
subprocedure_reset( &peripheral_subprocedure );
val_len = attribute->value_length;
while ( mico_bt_gatt_send_notification( connection_handle, attribute->handle, &val_len,
attribute->p_value + offset ) == MICO_BT_GATT_SUCCESS ) {
offset += val_len;
val_len = attribute->value_length - offset;
if ( offset >= attribute->value_length ) {
break;
}
}
subprocedure_unlock( &peripheral_subprocedure );
return kNoErr;
}
#if 0
OSStatus smartbridge_bt_interface_start_advertise( const mico_bt_smart_advertise_settings_t *settings,
mico_bt_smart_advertise_mode_changed_callback_t advertise_mode_changed_callback )
{
mico_bool_t duplicate_filter_enabled = MICO_FALSE;
/* fill with the settings provided by the smartserver-application */
mico_bt_cfg_settings.ble_advert_cfg.
mico_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_duration = settings->duration_second;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval;
duplicate_filter_enabled = settings->filter_duplicates;
app_scan_complete_callback = complete_callback;
app_scan_report_callback = advertising_report_callback;
return mico_bt_start_advertisements( BTM_BLE_ADVERT_UNDIRECTED_LOW, 0, NULL );
return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_HIGH_DUTY, duplicate_filter_enabled, smartbridge_scan_result_callback );
}
OSStatus smartbridge_bt_interface_stop_scan( )
{
app_scan_complete_callback = NULL;
app_scan_report_callback = NULL;
return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_NONE, MICO_TRUE, smartbridge_scan_result_callback );
}
OSStatus smartbridge_bt_interface_start_scan( const mico_bt_smart_scan_settings_t *settings,
mico_bt_smart_scan_complete_callback_t complete_callback,
mico_bt_smart_advertising_report_callback_t advertising_report_callback )
{
mico_bool_t duplicate_filter_enabled = MICO_FALSE;
/* First delete the previous scan result list */
smartbridge_helper_delete_scan_result_list();
/* fill with the settings provided by the smartbridge-application */
mico_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_duration = settings->duration_second;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval;
duplicate_filter_enabled = settings->filter_duplicates;
app_scan_complete_callback = complete_callback;
app_scan_report_callback = advertising_report_callback;
return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_HIGH_DUTY, duplicate_filter_enabled, smartbridge_scan_result_callback );
}
#endif
OSStatus peripheral_bt_interface_update_advertisements_white_list( mico_bool_t add,
mico_bt_device_address_t device_address )
{
if ( device_address == 0 ) {
return kParamErr;
}
if ( add ) {
if ( TRUE != mico_bt_ble_update_advertising_white_list( MICO_TRUE, device_address ) ) {
return kGeneralErr;
}
} else {
if ( TRUE != mico_bt_ble_update_advertising_white_list( MICO_FALSE, device_address ) ) {
return kGeneralErr;
}
}
return kNoErr;
}
OSStatus peripheral_bt_interface_get_advertisements_white_list_size( uint8_t *size )
{
if ( TRUE != mico_bt_ble_get_advertisement_white_list_size(size) ) {
return kGeneralErr;
}
return kNoErr;
}
OSStatus peripheral_bt_interface_set_advertisements_filter_policy(mico_bt_peripheral_adv_filter_policy_t type)
{
OSStatus status = kNoErr;
mico_bt_ble_advert_filter_policy_t policy;
switch (type) {
case PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ:
policy = BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ;
break;
case PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ:
policy = BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ;
break;
case PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ:
policy = BTM_BLE_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ;
break;
case PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ:
policy = BTM_BLE_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ;
break;
default:
return kParamErr;
}
if (!mico_bt_ble_update_advertisement_filter_policy(policy)) {
status = kUnknownErr;
}
return status;
}

View file

@ -0,0 +1,77 @@
#pragma once
/** @file
* Peripheral's Interface Header with Bluetooth Stack
*/
//#include "mico_utilities.h"
#include "mico_bt_peripheral.h"
#include "mico_bt_smart_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
#define ATT_DEFAULT_MTU (23)
#define ATT_STANDARD_VALUE_LENGTH (ATT_DEFAULT_MTU - 3)
#define ATT_STANDARD_TIMEOUT (500)
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
OSStatus peripheral_bt_interface_initialize( void );
OSStatus peripheral_bt_interface_deinitialize( void );
OSStatus peripheral_bt_interface_cancel_last_connect( mico_bt_device_address_t address );
OSStatus peripheral_bt_interface_disconnect( uint16_t connection_handle );
OSStatus peripheral_bt_interface_set_security_settings( const mico_bt_smart_security_settings_t *settings );
OSStatus peripheral_bt_interface_start_advertisements( mico_bt_smart_advertising_settings_t *settings,
mico_bt_smart_advertising_complete_callback_t complete_callback );
OSStatus peripheral_bt_interface_stop_advertisements( void );
OSStatus peripheral_bt_interface_indicate_attribute_value ( uint16_t connection_handle,
const mico_bt_ext_attribute_value_t *attribute );
OSStatus peripheral_bt_interface_notify_attribute_value( uint16_t connection_handle,
const mico_bt_ext_attribute_value_t *attribute );
OSStatus peripheral_bt_interface_update_advertisements_white_list( mico_bool_t add,
mico_bt_device_address_t device_address );
OSStatus peripheral_bt_interface_get_advertisements_white_list_size( uint8_t *size );
OSStatus peripheral_bt_interface_set_advertisements_filter_policy(mico_bt_peripheral_adv_filter_policy_t type);
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,623 @@
/** @file
*
*/
#include "mico_rtos.h"
#include "mico_bt_constants.h"
#include "string.h"
#include "bt_smartbridge_helper.h"
#include "bt_smartbridge_stack_interface.h"
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Static Function Declarations
******************************************************/
/******************************************************
* Variable Definitions
******************************************************/
static const uint16_t fixed_attribute_size_list[] = {
[MICO_ATTRIBUTE_TYPE_NO_VALUE ] = ATTR_NO_VALUE_SIZE,
[MICO_ATTRIBUTE_TYPE_LONG_VALUE ] = ATTR_LONG_VALUE_SIZE,
[MICO_ATTRIBUTE_TYPE_PRIMARY_SERVICE ] = ATTR_SERVICE_SIZE,
[MICO_ATTRIBUTE_TYPE_INCLUDE ] = ATTR_INCLUDE_SIZE,
[MICO_ATTRIBUTE_TYPE_CHARACTERISTIC ] = ATTR_CHARACTERISTIC_SIZE,
[MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE ] = 0, // Variable length
[MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_EXTENDED_PROPERTIES ] = ATTR_EXTENDED_PROPERTIES_SIZE,
[MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION ] = 0, // Variable length
[MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_CLIENT_CONFIGURATION] = ATTR_CLIENT_CONFIG_SIZE,
[MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_SERVER_CONFIGURATION] = ATTR_SERVER_CONFIG_SIZE,
[MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_PRESENTATION_FORMAT ] = ATTR_PRESENTATION_FORMAT_SIZE,
[MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT ] = 0, // Variable length
};
static uint32_t attributes_created = 0;
static uint32_t attributes_deleted = 0;
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Static Function Declarations
******************************************************/
static OSStatus print_uuid( const mico_bt_uuid_t *uuid );
static OSStatus print_type( const mico_bt_uuid_t *uuid );
/******************************************************
* Variable Definitions
******************************************************/
/******************************************************
* Function Definitions
******************************************************/
OSStatus mico_bt_smart_attribute_create( mico_bt_smart_attribute_t **attribute, mico_bt_smart_attribute_type_t type,
uint16_t variable_length )
{
uint16_t size;
if ( attribute == NULL ) {
return MICO_BT_BADARG;
}
switch ( type ) {
case MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE: {
size = ATTR_CHARACTERISTIC_VALUE_SIZE( variable_length );
break;
}
case MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION: {
size = ATTR_USER_DESCRIPTION_SIZE( variable_length );
break;
}
case MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT: {
size = ATTR_AGGREGATE_FORMAT_SIZE( variable_length );
break;
}
default: {
size = fixed_attribute_size_list[type];
break;
}
}
*attribute = (mico_bt_smart_attribute_t *)malloc_named("attribute", size );
if ( *attribute == NULL ) {
return MICO_BT_OUT_OF_HEAP_SPACE;
}
memset( *attribute, 0, size );
(*attribute)->value_struct_size = size - ATTR_COMMON_FIELDS_SIZE;
attributes_created++;
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_smart_attribute_delete( mico_bt_smart_attribute_t *attribute )
{
if ( attribute == NULL ) {
return MICO_BT_BADARG;
}
/* Set to NULL to make sure this doesn't point to any used attribute */
attribute->next = NULL;
/* For malloc debugging */
malloc_transfer_to_curr_thread( attribute );
free( attribute );
attributes_deleted++;
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_smart_attribute_create_list( mico_bt_smart_attribute_list_t *list )
{
if ( list == NULL ) {
return MICO_BT_BADARG;
}
memset( list, 0, sizeof( *list ) );
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_smart_attribute_add_to_list( mico_bt_smart_attribute_list_t *list,
mico_bt_smart_attribute_t *attribute )
{
if ( list == NULL || attribute == NULL ) {
return MICO_BT_BADARG;
}
if ( list->count == 0 ) {
/* List is empty. Point list to the attribute */
attribute->next = NULL;
list->list = attribute;
} else {
mico_bt_smart_attribute_t *curr = list->list;
mico_bt_smart_attribute_t *prev = NULL;
/* Traverse the list and compare handle */
while ( curr != NULL ) {
if ( curr->handle > attribute->handle ) {
if ( prev == NULL ) {
/* Insert attribute at first position */
attribute->next = curr;
list->list = attribute;
break;
} else {
/* Insert attribute in between prev and curr */
prev->next = attribute;
attribute->next = curr;
break;
}
} else if ( curr->next == NULL ) {
/* Insert attribute at the end of the list */
curr->next = attribute;
attribute->next = NULL;
break;
}
/* Update previous and current attribute pointers */
prev = curr;
curr = curr->next;
}
}
/* Increment count */
list->count++;
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_smart_attribute_remove_from_list( mico_bt_smart_attribute_list_t *list, uint16_t handle )
{
if ( list == NULL ) {
return MICO_BT_BADARG;
}
if ( list->count == 0 ) {
return MICO_BT_LIST_EMPTY;
} else {
mico_bt_smart_attribute_t *curr = list->list;
mico_bt_smart_attribute_t *prev = NULL;
/* Traverse the list and compare handle */
while ( curr != NULL ) {
if ( curr->handle == handle ) {
if ( prev == NULL ) {
/* Remove attribute at first position */
list->list = curr->next;
} else {
/* Remove curr */
prev->next = curr->next;
}
mico_bt_smart_attribute_delete( curr );
/* Decrement count */
list->count--;
return MICO_BT_SUCCESS;
}
/* Update previous and current attribute pointers */
prev = curr;
curr = curr->next;
}
}
return MICO_BT_ITEM_NOT_IN_LIST;
}
OSStatus mico_bt_smart_attribute_delete_list( mico_bt_smart_attribute_list_t *list )
{
mico_bt_smart_attribute_t *curr;
if ( list == NULL ) {
return MICO_BT_BADARG;
}
curr = list->list;
/* Traverse through the list and delete all attributes */
while ( curr != NULL ) {
/* Store pointer to next because curr is about to be deleted */
mico_bt_smart_attribute_t *next = curr->next;
mico_bt_smart_attribute_delete( curr );
/* Update curr */
curr = next;
}
memset( list, 0, sizeof( *list ) );
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_smart_attribute_search_list_by_handle( const mico_bt_smart_attribute_list_t *list, uint16_t handle,
mico_bt_smart_attribute_t **attribute )
{
if ( list == NULL || attribute == NULL ) {
return MICO_BT_BADARG;
}
if ( list->count == 0 ) {
return MICO_BT_LIST_EMPTY;
} else {
mico_bt_smart_attribute_t *curr = list->list;
/* Traverse the list and compare handle */
while ( curr != NULL ) {
if ( curr->handle == handle ) {
*attribute = curr;
return MICO_BT_SUCCESS;
}
/* Update current attribute pointers */
curr = curr->next;
}
}
return MICO_BT_ITEM_NOT_IN_LIST;
}
OSStatus mico_bt_smart_attribute_search_list_by_uuid( const mico_bt_smart_attribute_list_t *list,
const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t **attribute )
{
if ( list == NULL || uuid == NULL || attribute == NULL ) {
return MICO_BT_BADARG;
}
if ( list->count == 0 ) {
return MICO_BT_LIST_EMPTY;
} else {
mico_bt_smart_attribute_t *curr = list->list;
/* Traverse the list until it's larger or equal the starting handle provided */
while ( curr != NULL && curr->handle <= ending_handle ) {
if ( curr->handle >= starting_handle ) {
break;
}
curr = curr->next;
}
/* Return if reaches the end of the list */
if ( curr == NULL || curr->handle > ending_handle ) {
return MICO_BT_ITEM_NOT_IN_LIST;
}
/* Traverse the list and compare handle */
while ( curr != NULL && curr->handle <= ending_handle ) {
/* Check if UUID is found */
if ( memcmp( (void *)&curr->type.uu, &uuid->uu, uuid->len ) == 0 ) {
*attribute = curr;
return MICO_BT_SUCCESS;
}
/* Update current attribute pointers */
curr = curr->next;
}
}
return MICO_BT_ITEM_NOT_IN_LIST;
}
OSStatus mico_bt_smart_attribute_merge_lists( mico_bt_smart_attribute_list_t *trunk_list,
mico_bt_smart_attribute_list_t *branch_list )
{
mico_bt_smart_attribute_t *curr;
if ( trunk_list == NULL || branch_list == NULL ) {
return MICO_BT_BADARG;
}
curr = branch_list->list;
/* Traverse through the branch list */
while ( curr != NULL ) {
mico_bt_smart_attribute_t *prev = curr;
/* Increment curr and take prev of the branch list */
curr = curr->next;
prev->next = NULL;
/* Add prev to the trunk list */
mico_bt_smart_attribute_add_to_list( trunk_list, prev );
}
memset( branch_list, 0, sizeof( *branch_list ) );
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_smart_attribute_print( const mico_bt_smart_attribute_t *attribute )
{
mico_bt_smart_attribute_t *curr_attr = (mico_bt_smart_attribute_t *)attribute;
if ( attribute == NULL ) {
return MICO_BT_BADARG;
}
WPRINT_LIB_INFO( ( "----------------------------------------------------\n" ) );
print_type( &curr_attr->type );
WPRINT_LIB_INFO( ( "\n" ) );
WPRINT_LIB_INFO( ( "Handle : %d\n", (int)curr_attr->handle ) );
WPRINT_LIB_INFO( ( "Type : " ) );
print_uuid( &curr_attr->type );
WPRINT_LIB_INFO( ( "Permission : %d\n", (int)curr_attr->permission ) );
WPRINT_LIB_INFO( ( "Value Length : %d\n", (int)curr_attr->value_length ) );
if ( curr_attr->type.len == UUID_16BIT ) {
switch ( curr_attr->type.uu.uuid16 ) {
case 0x2800: {
WPRINT_LIB_INFO( ( "Start Handle : %d\n", (int)curr_attr->value.service.start_handle ) );
WPRINT_LIB_INFO( ( "End Handle : %d\n", (int)curr_attr->value.service.end_handle ) );
WPRINT_LIB_INFO( ( "Service UUID : ") );
print_uuid( &curr_attr->value.service.uuid );
break;
}
case 0x2802: {
WPRINT_LIB_INFO( ( "Start Handle : %d\n", (int)curr_attr->value.include.included_service_handle ) );
WPRINT_LIB_INFO( ( "End Handle : %d\n", (int)curr_attr->value.include.end_group_handle ) );
WPRINT_LIB_INFO( ( "Service UUID : ") );
print_uuid( &curr_attr->value.include.uuid );
break;
}
case 0x2803: {
WPRINT_LIB_INFO( ( "Properties : %d\n", (int)curr_attr->value.characteristic.properties ) );
WPRINT_LIB_INFO( ( "Value Handle : %d\n", (int)curr_attr->value.characteristic.value_handle ) );
WPRINT_LIB_INFO( ( "Value UUID : ") );
print_uuid( &curr_attr->value.characteristic.uuid );
break;
}
case 0x2900: {
WPRINT_LIB_INFO( ( "Extended Properties : %d\n", (int)curr_attr->value.extended_properties.properties ) );
break;
}
case 0x2901: {
WPRINT_LIB_INFO( ( "Extended Properties : %s\n", curr_attr->value.user_description.string ) );
break;
}
case 0x2902: {
WPRINT_LIB_INFO( ( "Client Configuration : %d\n", (int)curr_attr->value.client_config.config_bits ) );
break;
}
case 0x2903: {
WPRINT_LIB_INFO( ( "Server Configuration : %d\n", (int)curr_attr->value.server_config.config_bits ) );
break;
}
case 0x2904: {
WPRINT_LIB_INFO( ( "Format : %d\n", (int)curr_attr->value.presentation_format.format ) );
WPRINT_LIB_INFO( ( "Exponent : %d\n", (int)curr_attr->value.presentation_format.exponent ) );
WPRINT_LIB_INFO( ( "Unit : %d\n", (int)curr_attr->value.presentation_format.unit ) );
WPRINT_LIB_INFO( ( "Namespace : %d\n", (int)curr_attr->value.presentation_format.name_space ) );
WPRINT_LIB_INFO( ( "Description : %d\n", (int)curr_attr->value.presentation_format.description ) );
break;
}
case 0x2905: {
uint32_t i;
WPRINT_LIB_INFO( ( "List of Handles : \n" ) );
for ( i = 0; i < curr_attr->value_length / 2; i ++ ) {
WPRINT_LIB_INFO( ( "%02d ", (int)curr_attr->value.aggregate_format.handle_list[i] ) );
}
WPRINT_LIB_INFO( ( "\n" ) );
break;
}
case 0x2A00: {
WPRINT_LIB_INFO( ( "Device Name : %s\n", curr_attr->value.device_name.device_name ) );
break;
}
case 0x2A01: {
WPRINT_LIB_INFO( ( "Appearance : %d\n", (int)curr_attr->value.appearance.appearance ) );
break;
}
case 0x2A02: {
WPRINT_LIB_INFO( ( "Peripheral Privacy Flag : %d\n",
(int)curr_attr->value.periph_privacy_flag.periph_privacy_flag ) );
break;
}
case 0x2A03: {
WPRINT_LIB_INFO( ( "Reconnection Address : %02x:%02x:%02x:%02x:%02x:%02x\n",
(int)curr_attr->value.reconn_address.reconn_address[0],
(int)curr_attr->value.reconn_address.reconn_address[1],
(int)curr_attr->value.reconn_address.reconn_address[2],
(int)curr_attr->value.reconn_address.reconn_address[3],
(int)curr_attr->value.reconn_address.reconn_address[4],
(int)curr_attr->value.reconn_address.reconn_address[5] ) );
break;
}
case 0x2A04: {
WPRINT_LIB_INFO( ( "Max Connection Interval : %d\n",
(int)curr_attr->value.periph_preferred_conn_params.max_conn_interval ) );
WPRINT_LIB_INFO( ( "Min Connection Interval : %d\n",
(int)curr_attr->value.periph_preferred_conn_params.min_conn_interval ) );
WPRINT_LIB_INFO( ( "Slave Latency : %d\n",
(int)curr_attr->value.periph_preferred_conn_params.slave_latency ) );
WPRINT_LIB_INFO( ( "Supervision Timeout Multiplier : %d\n",
(int)curr_attr->value.periph_preferred_conn_params.conn_supervision_timeout_multiplier ) );
break;
}
default: {
uint32_t i;
WPRINT_LIB_INFO( ( "Value : \n" ) );
for ( i = 0; i < curr_attr->value_length; i ++ ) {
WPRINT_LIB_INFO( ( "%02x ", (int)curr_attr->value.value[i] ) );
}
WPRINT_LIB_INFO( ( "\n" ) );
break;
}
}
}
WPRINT_LIB_INFO( ( "----------------------------------------------------\n" ) );
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_smart_attribute_print_list( const mico_bt_smart_attribute_list_t *list )
{
mico_bt_smart_attribute_t *curr_attr = (mico_bt_smart_attribute_t *)list->list;
while ( curr_attr != NULL ) {
mico_bt_smart_attribute_print( curr_attr );
curr_attr = curr_attr->next;
}
return MICO_BT_SUCCESS;
}
static OSStatus print_uuid( const mico_bt_uuid_t *uuid )
{
if ( uuid->len == UUID_16BIT ) {
WPRINT_LIB_INFO( ( "%04x\n", (int)uuid->uu.uuid16 ) );
} else {
WPRINT_LIB_INFO( ( "%04x %04x %04x %04x %04x %04x %04x %04x\n",
(int)uuid->uu.uuid128[0],
(int)uuid->uu.uuid128[1],
(int)uuid->uu.uuid128[2],
(int)uuid->uu.uuid128[3],
(int)uuid->uu.uuid128[4],
(int)uuid->uu.uuid128[5],
(int)uuid->uu.uuid128[6],
(int)uuid->uu.uuid128[7] ) );
}
return MICO_BT_SUCCESS;
}
static OSStatus print_type( const mico_bt_uuid_t *uuid )
{
if ( uuid->len != UUID_16BIT ) {
WPRINT_LIB_INFO( ( "Unknown Type" ) );
return MICO_BT_SUCCESS;
}
switch ( uuid->uu.uuid16 ) {
case 0x2800: {
WPRINT_LIB_INFO( ( "Primary Service" ) );
break;
}
case 0x2801: {
WPRINT_LIB_INFO( ( "Secondary Service" ) );
break;
}
case 0x2802: {
WPRINT_LIB_INFO( ( "Include" ) );
break;
}
case 0x2803: {
WPRINT_LIB_INFO( ( "Characteristic" ) );
break;
}
case 0x2900: {
WPRINT_LIB_INFO( ( "Characteristic Descriptor - Extended Characteristic Properties" ) );
break;
}
case 0x2901: {
WPRINT_LIB_INFO( ( "Characteristic Descriptor - User Description" ) );
break;
}
case 0x2902: {
WPRINT_LIB_INFO( ( "Characteristic Descriptor - Client Characteristic Configuration" ) );
break;
}
case 0x2903: {
WPRINT_LIB_INFO( ( "Characteristic Descriptor - Server Characteristic Configuration" ) );
break;
}
case 0x2904: {
WPRINT_LIB_INFO( ( "Characteristic Descriptor - Characteristic Presentation Format" ) );
break;
}
case 0x2905: {
WPRINT_LIB_INFO( ( "Characteristic Descriptor - Characteristic Aggregate Format" ) );
break;
}
case 0x2A00: {
WPRINT_LIB_INFO( ( "Characteristic Type - Device Name" ) );
break;
}
case 0x2A01: {
WPRINT_LIB_INFO( ( "Characteristic Type - Appearance" ) );
break;
}
case 0x2A02: {
WPRINT_LIB_INFO( ( "Characteristic Type - Peripheral Privacy Flags" ) );
break;
}
case 0x2A03: {
WPRINT_LIB_INFO( ( "Characteristic Type - Reconnection Address" ) );
break;
}
case 0x2A04: {
WPRINT_LIB_INFO( ( "Characteristic Type - Peripheral Preferred Connection Parameters" ) );
break;
}
case 0x2A05: {
WPRINT_LIB_INFO( ( "Service Changed" ) );
break;
}
default: {
WPRINT_LIB_INFO( ( "Unknown Type" ) );
break;
}
}
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_smart_attribute_get_list_head( const mico_bt_smart_attribute_list_t *list,
mico_bt_smart_attribute_t **head )
{
if ( list == NULL ) {
return MICO_BT_BADARG;
}
*head = list->list;
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_smart_attribute_get_list_count( const mico_bt_smart_attribute_list_t *list, uint32_t *count )
{
if ( list == NULL ) {
return MICO_BT_BADARG;
}
*count = list->count;
return MICO_BT_SUCCESS;
}

View file

@ -0,0 +1,810 @@
/** @file
*
*/
#include "mico.h"
#include "LinkListUtils.h"
#include "mico_bt_smartbridge.h"
#include "mico_bt_smart_interface.h"
#include "bt_smartbridge_stack_interface.h"
#include "bt_smartbridge_helper.h"
#include "bt_smartbridge_att_cache_manager.h"
/******************************************************
* Macros
******************************************************/
#define CHECK_FOR_ERROR( condition, error_code ) \
do \
{ \
if ( ( condition ) ) \
{ \
bt_smartbridge_log( "[Att Cache] Error: %d", (int)error_code); \
error_code_var = (error_code); \
goto error; \
} \
} \
while (0)
#define CALCULATE_ATT_CACHE_MANAGER_SIZE( cache_count ) \
sizeof( bt_smartbridge_att_cache_manager_t ) + \
sizeof( bt_smartbridge_att_cache_t ) * ( cache_count - 1 )
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
typedef struct bt_smartbridge_att_cache {
linked_list_node_t node;
mico_bool_t is_active;
mico_bool_t is_discovering;
mico_bt_smart_device_t remote_device;
uint16_t connection_handle;
mico_bt_smart_attribute_list_t attribute_list;
mico_mutex_t mutex;
} bt_smartbridge_att_cache_t;
typedef struct {
uint32_t count;
mico_bt_uuid_t *att_cache_services;
uint32_t att_cache_services_count;
linked_list_t free_list;
linked_list_t used_list;
mico_mutex_t mutex;
bt_smartbridge_att_cache_t pool[1];
} bt_smartbridge_att_cache_manager_t;
/******************************************************
* Static Function Declarations
******************************************************/
static OSStatus smartbridge_att_cache_get_free_cache ( bt_smartbridge_att_cache_t **free_cache );
static OSStatus smartbridge_att_cache_insert_to_used_list ( bt_smartbridge_att_cache_t *instance );
static OSStatus smartbridge_att_cache_return_to_free_list ( bt_smartbridge_att_cache_t *instance );
static OSStatus smartbridge_att_cache_discover_all ( bt_smartbridge_att_cache_t *cache,
uint16_t connection_handle );
static bool smartbridge_att_cache_find_by_device_callback ( linked_list_node_t *node_to_compare, void *user_data );
static bool smartbridge_att_cache_get_free_callback ( linked_list_node_t *node_to_compare, void *user_data );
/******************************************************
* Variable Definitions
******************************************************/
/* Attribute Caching Management Globals */
static bt_smartbridge_att_cache_manager_t *att_cache_manager = NULL;
/******************************************************
* Function Definitions
******************************************************/
OSStatus bt_smartbridge_att_cache_enable( uint32_t cache_count, mico_bt_uuid_t cache_services[],
uint32_t service_count )
{
uint32_t a;
OSStatus result;
bt_smartbridge_att_cache_manager_t *manager;
mico_bt_uuid_t *services = NULL;
if ( att_cache_manager != NULL ) {
return MICO_BT_SUCCESS;
}
manager = (bt_smartbridge_att_cache_manager_t *)malloc_named( "att_cache",
CALCULATE_ATT_CACHE_MANAGER_SIZE( cache_count ) );
if ( manager == NULL ) {
return MICO_BT_OUT_OF_HEAP_SPACE;
}
if ( service_count != 0 ) {
services = (mico_bt_uuid_t *)malloc_named( "cache_services", service_count * sizeof(mico_bt_uuid_t) );
if ( services == NULL ) {
return MICO_BT_OUT_OF_HEAP_SPACE;
}
}
memset( manager, 0, CALCULATE_ATT_CACHE_MANAGER_SIZE( cache_count ) );
att_cache_manager = manager;
manager->count = cache_count;
manager->att_cache_services_count = service_count;
if ( service_count != 0 ) {
manager->att_cache_services = services;
memcpy( manager->att_cache_services, cache_services, service_count * sizeof(mico_bt_uuid_t) );
}
result = linked_list_init( &manager->free_list );
if ( result != MICO_BT_SUCCESS ) {
bt_smartbridge_log( "Error creating linked list\n" );
goto error;
}
result = linked_list_init( &manager->used_list );
if ( result != MICO_BT_SUCCESS ) {
bt_smartbridge_log( "Error creating linked list\n" );
goto error;
}
result = mico_rtos_init_mutex( &manager->mutex );
if ( result != MICO_BT_SUCCESS ) {
bt_smartbridge_log( "Error creating mutex\n" );
goto error;
}
/* Initialise mutexes for protecting access to cached attributes */
for ( a = 0; a < manager->count; a++ ) {
result = mico_rtos_init_mutex( &manager->pool[a].mutex );
if ( result != MICO_BT_SUCCESS ) {
goto error;
}
/* Point node data to cached attribute instance */
manager->pool[a].node.data = (void *)&manager->pool[a];
/* Insert cached attribute instance into free list */
result = linked_list_insert_node_at_rear( &manager->free_list, &manager->pool[a].node );
if ( result != MICO_BT_SUCCESS ) {
goto error;
}
}
return MICO_BT_SUCCESS;
error:
bt_smartbridge_att_cache_disable();
return result;
}
OSStatus bt_smartbridge_att_cache_disable( void )
{
uint32_t a;
linked_list_node_t *node = NULL;
bt_smartbridge_att_cache_manager_t *manager = att_cache_manager;
if ( att_cache_manager == NULL ) {
return MICO_BT_SUCCESS;
}
/* Set status at the beginning to prevent cached attributes being used even when deinitialisation failed */
att_cache_manager = NULL;
while ( linked_list_remove_node_from_front( &manager->free_list, &node ) == MICO_BT_SUCCESS ) {
bt_smartbridge_att_cache_t *cache = (bt_smartbridge_att_cache_t *)node->data;
mico_bt_smart_attribute_delete_list( &cache->attribute_list );
}
linked_list_deinit( &manager->free_list );
while ( linked_list_remove_node_from_front( &manager->used_list, &node ) == MICO_BT_SUCCESS ) {
bt_smartbridge_att_cache_t *cache = (bt_smartbridge_att_cache_t *)node->data;
mico_bt_smart_attribute_delete_list( &cache->attribute_list );
}
linked_list_deinit( &manager->used_list );
mico_rtos_deinit_mutex( &manager->mutex );
/* Deinitialise mutexes for protecting access to cached attributes */
for ( a = 0; a < manager->count; a++ ) {
mico_rtos_deinit_mutex( &manager->pool[a].mutex );
}
if ( manager->att_cache_services_count != 0 ) {
free( manager->att_cache_services );
}
memset( manager, 0, CALCULATE_ATT_CACHE_MANAGER_SIZE( manager->count ) );
free( manager );
return MICO_BT_SUCCESS;
}
OSStatus bt_smartbridge_att_cache_get_list( bt_smartbridge_att_cache_t *cache, mico_bt_smart_attribute_list_t **list )
{
if ( cache == NULL || list == NULL ) {
return MICO_BT_BADARG;
}
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
*list = &cache->attribute_list;
return MICO_BT_SUCCESS;
}
mico_bool_t bt_smartbridge_att_cache_is_enabled( void )
{
return ( att_cache_manager == NULL ) ? MICO_FALSE : MICO_TRUE;
}
mico_bool_t bt_smartbridge_att_cache_is_discovering( const bt_smartbridge_att_cache_t *cache )
{
if ( cache == NULL || att_cache_manager == NULL ) {
return MICO_FALSE;
}
return cache->is_discovering;
}
mico_bool_t bt_smartbridge_att_cache_get_active_state( const bt_smartbridge_att_cache_t *cache )
{
if ( cache == NULL || att_cache_manager == NULL ) {
return MICO_FALSE;
}
return cache->is_active;
}
OSStatus bt_smartbridge_att_cache_set_active_state( bt_smartbridge_att_cache_t *cache, mico_bool_t is_active )
{
if ( cache == NULL ) {
return MICO_BT_BADARG;
}
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
cache->is_active = is_active;
return MICO_BT_SUCCESS;
}
OSStatus bt_smartbridge_att_cache_lock( bt_smartbridge_att_cache_t *cache )
{
if ( cache == NULL ) {
return MICO_BT_BADARG;
}
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
return mico_rtos_lock_mutex( &cache->mutex );
}
OSStatus bt_smartbridge_att_cache_unlock( bt_smartbridge_att_cache_t *cache )
{
if ( cache == NULL ) {
return MICO_BT_BADARG;
}
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
return mico_rtos_unlock_mutex( &cache->mutex );
}
OSStatus bt_smartbridge_att_cache_find( const mico_bt_smart_device_t *remote_device,
bt_smartbridge_att_cache_t **cache )
{
OSStatus result;
linked_list_node_t *node_found;
if ( remote_device == NULL || cache == NULL ) {
return MICO_BT_BADARG;
}
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
/* Lock protection */
result = mico_rtos_lock_mutex( &att_cache_manager->mutex );
if ( result != MICO_BT_SUCCESS ) {
return result;
}
result = linked_list_find_node( &att_cache_manager->used_list, smartbridge_att_cache_find_by_device_callback,
(void *)remote_device, &node_found );
if ( result == MICO_BT_SUCCESS ) {
*cache = (bt_smartbridge_att_cache_t *)node_found->data;
}
/* Unlock protection */
mico_rtos_unlock_mutex( &att_cache_manager->mutex );
return result;
}
OSStatus bt_smartbridge_att_cache_generate( const mico_bt_smart_device_t *remote_device, uint16_t connection_handle,
bt_smartbridge_att_cache_t **cache )
{
bt_smartbridge_att_cache_t *new_cache = NULL;
OSStatus result;
if ( cache == NULL ) {
return MICO_BT_BADARG;
}
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
/* Cached attributes not found. Get a free instance and discover services */
result = smartbridge_att_cache_get_free_cache( &new_cache );
if ( result != MICO_BT_SUCCESS ) {
return result;
}
/* Copy remote device to cache */
mico_rtos_lock_mutex( &new_cache->mutex );
memcpy( &new_cache->remote_device, remote_device, sizeof( new_cache->remote_device ) );
new_cache->connection_handle = connection_handle;
new_cache->is_discovering = MICO_TRUE;
mico_rtos_unlock_mutex( &new_cache->mutex );
/* Rediscover services */
result = smartbridge_att_cache_discover_all( new_cache, new_cache->connection_handle );
mico_rtos_lock_mutex( &new_cache->mutex );
new_cache->is_discovering = MICO_FALSE;
mico_rtos_unlock_mutex( &new_cache->mutex );
if ( result == MICO_BT_SUCCESS ) {
result = smartbridge_att_cache_insert_to_used_list( new_cache );
if ( result == MICO_BT_SUCCESS ) {
*cache = new_cache;
}
} else {
smartbridge_att_cache_return_to_free_list( new_cache );
}
return result;
}
OSStatus bt_smartbridge_att_cache_release( bt_smartbridge_att_cache_t *cache )
{
OSStatus result;
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
/* Lock protection */
result = mico_rtos_lock_mutex( &att_cache_manager->mutex );
if ( result != MICO_BT_SUCCESS ) {
return result;
}
result = linked_list_remove_node( &att_cache_manager->used_list, &cache->node );
if ( result == MICO_BT_SUCCESS ) {
/* Delete list and set data to NULL */
mico_bt_smart_attribute_delete_list( &cache->attribute_list );
}
smartbridge_att_cache_return_to_free_list( cache );
/* Unlock protection */
mico_rtos_unlock_mutex( &att_cache_manager->mutex );
return result;
}
static OSStatus smartbridge_att_cache_get_free_cache( bt_smartbridge_att_cache_t **free_cache )
{
OSStatus result;
linked_list_node_t *node;
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
/* Lock protection */
result = mico_rtos_lock_mutex( &att_cache_manager->mutex );
if ( result != kNoErr ) {
return result;
}
/* Remove from front of free list */
result = linked_list_remove_node_from_front( &att_cache_manager->free_list, &node );
/* Free list is empty. Remove the oldest one from used list */
if ( result != MICO_BT_SUCCESS ) {
result = linked_list_find_node( &att_cache_manager->used_list, smartbridge_att_cache_get_free_callback, NULL, &node );
if ( result == MICO_BT_SUCCESS ) {
result = linked_list_remove_node( &att_cache_manager->used_list, node );
if ( result == MICO_BT_SUCCESS ) {
mico_bt_smart_attribute_list_t *list = (mico_bt_smart_attribute_list_t *)node->data;
/* Delete list and set data to NULL */
mico_bt_smart_attribute_delete_list( list );
}
}
}
if ( result == MICO_BT_SUCCESS ) {
*free_cache = (bt_smartbridge_att_cache_t *)node->data;
}
/* Unlock protection */
mico_rtos_unlock_mutex( &att_cache_manager->mutex );
return result;
}
static OSStatus smartbridge_att_cache_insert_to_used_list( bt_smartbridge_att_cache_t *cache )
{
OSStatus result;
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
/* Lock protection */
result = mico_rtos_lock_mutex( &att_cache_manager->mutex );
if ( result != MICO_BT_SUCCESS ) {
return result;
}
result = linked_list_insert_node_at_rear( &att_cache_manager->used_list, &cache->node );
/* Unlock protection */
mico_rtos_unlock_mutex( &att_cache_manager->mutex );
return result;
}
static OSStatus smartbridge_att_cache_return_to_free_list( bt_smartbridge_att_cache_t *cache )
{
OSStatus result;
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
/* Lock protection */
result = mico_rtos_lock_mutex( &att_cache_manager->mutex );
if ( result != MICO_BT_SUCCESS ) {
return result;
}
result = linked_list_insert_node_at_rear( &att_cache_manager->free_list, &cache->node );
/* Unlock protection */
mico_rtos_unlock_mutex( &att_cache_manager->mutex );
return result;
}
static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t *cache, uint16_t connection_handle )
{
/* This function performs the following:
* 1. Primary Services discovery
* 2. Relationship (Included Services) Discovery for every Primary Service
* 3. Characteristic Discovery for every Primary Service
* 4. Characteristic Value Read for every Charactertistic
* 5. Characteristic Descriptor Discovery for every Characteristic
*/
mico_bt_smart_attribute_t **primary_service_array = NULL;
mico_bt_smart_attribute_t **characteristic_array = NULL;
mico_bt_smart_attribute_t *characteristic_value = NULL;
mico_bt_smart_attribute_t *descriptor_with_no_value = NULL;
mico_bt_smart_attribute_t *descriptor_with_value = NULL;
mico_bt_smart_attribute_t *iterator = NULL;
OSStatus result = MICO_BT_SUCCESS;
OSStatus error_code_var = MICO_BT_ERROR;
uint32_t i = 0;
uint32_t j = 0;
uint32_t primary_service_count = 0;
uint32_t characteristic_count = 0;
mico_bt_smart_attribute_list_t primary_service_list;
mico_bt_smart_attribute_list_t branch_primary_service_list;
mico_bt_smart_attribute_list_t included_service_list;
mico_bt_smart_attribute_list_t characteristic_list;
mico_bt_smart_attribute_list_t descriptor_list;
mico_bool_t characteristic_list_merged = MICO_FALSE;
mico_bool_t included_service_list_merged = MICO_FALSE;
if ( att_cache_manager == NULL ) {
return MICO_BT_ATT_CACHE_UNINITIALISED;
}
/* Initialise local variables */
memset( &primary_service_list, 0, sizeof( primary_service_list ) );
memset( &branch_primary_service_list, 0, sizeof( primary_service_list ) );
memset( &included_service_list, 0, sizeof( included_service_list ) );
memset( &characteristic_list, 0, sizeof( characteristic_list ) );
memset( &descriptor_list, 0, sizeof( descriptor_list ) );
mico_rtos_lock_mutex( &cache->mutex );
result = mico_bt_smart_attribute_create_list( &primary_service_list );
mico_rtos_unlock_mutex( &cache->mutex );
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
/**************************************************************************
* Primary Services Discovery
**************************************************************************/
if ( att_cache_manager->att_cache_services_count == 0 ) {
result = smartbridge_bt_interface_discover_all_primary_services( connection_handle, &primary_service_list );
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
} else {
for ( i = 0; i < att_cache_manager->att_cache_services_count; i++ ) {
result = smartbridge_bt_interface_discover_primary_services_by_uuid( connection_handle,
&att_cache_manager->att_cache_services[i], &branch_primary_service_list );
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
result = mico_bt_smart_attribute_merge_lists( &primary_service_list, &branch_primary_service_list );
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
}
}
mico_bt_smart_attribute_get_list_count( &primary_service_list, &primary_service_count );
primary_service_array = (mico_bt_smart_attribute_t **)malloc_named( "svc_array",
primary_service_count * sizeof(mico_bt_smart_attribute_t));
CHECK_FOR_ERROR( primary_service_array == NULL, MICO_BT_OUT_OF_HEAP_SPACE );
/* Keep the original pointers to the primary service list before the list gets merged */
mico_bt_smart_attribute_get_list_head( &primary_service_list, &iterator );
for ( i = 0; i < primary_service_count; i++ ) {
primary_service_array[i] = iterator;
iterator = iterator->next;
}
bt_smartbridge_log( "[Cache] All services discovered. count: %u", (unsigned int) primary_service_count );
/* Check if characteristic is readable. If not readable, create a control-point attribute */
for ( i = 0; i < primary_service_count; i++ ) {
/* Initialise variable for this iteration */
memset( &characteristic_list, 0, sizeof( characteristic_list ) );
memset( &included_service_list, 0, sizeof( included_service_list ) );
characteristic_array = NULL;
/**********************************************************************
* Relationship Discovery
**********************************************************************/
/*result = bt_smart_gatt_find_included_services( connection_handle, primary_service_array[i]->value.service.start_handle, primary_service_array[i]->value.service.start_handle, &included_service_list );
CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT, result );
mico_rtos_lock_mutex( &cache->mutex );
result = mico_bt_smart_attribute_merge_lists( &primary_service_list, &included_service_list );
if( result == MICO_BT_SUCCES )
{
included_service_list_merged = MICO_TRUE;
}
mico_rtos_unlock_mutex( &cache->mutex );
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
*/
/**********************************************************************
* Characteristic Discovery
**********************************************************************/
result = smartbridge_bt_interface_discover_all_characteristics_in_a_service( connection_handle,
primary_service_array[i]->value.service.start_handle, primary_service_array[i]->value.service.end_handle,
&characteristic_list );
CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result );
mico_bt_smart_attribute_get_list_count( &characteristic_list, &characteristic_count );
characteristic_array = (mico_bt_smart_attribute_t **)malloc_named( "char_array",
characteristic_count * sizeof(characteristic_list));
CHECK_FOR_ERROR( characteristic_array == NULL, MICO_BT_OUT_OF_HEAP_SPACE );
/* Keep the original pointers to the characteristic list before the list gets merged. */
mico_bt_smart_attribute_get_list_head( &characteristic_list, &iterator );
for ( j = 0; j < characteristic_count; j++ ) {
characteristic_array[j] = iterator;
iterator = iterator->next;
}
/* Traverse through all characteristics to perform Characteristic Value Read and Descriptors Discovery */
for ( j = 0; j < characteristic_count; j++ ) {
/* Initialise local variables for this iteration */
memset( &descriptor_list, 0, sizeof( descriptor_list ) );
characteristic_value = NULL;
/******************************************************************
* Characteristic Value Read
******************************************************************/
if ( ( characteristic_array[j]->value.characteristic.properties & 0x02 ) != 0 ) {
bt_smartbridge_log( "[Cache] Characteristic Read-Property IS set" );
/* If characteristic is readable. If not readable, create a control-point attribute */
result = smartbridge_bt_interface_read_characteristic_value( connection_handle,
characteristic_array[j]->value.characteristic.value_handle, &characteristic_array[j]->value.characteristic.uuid,
&characteristic_value );
CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result );
} else {
bt_smartbridge_log( "[Cache] Characteristic Read-Properties is NOT set" );
/* Failed to read. Let's enter a control-point attribute (dummy) here so when notification come, UUID is known. */
result = mico_bt_smart_attribute_create( &characteristic_value, MICO_ATTRIBUTE_TYPE_NO_VALUE, 0 );
if ( result == MICO_BT_SUCCESS ) {
characteristic_value->handle = characteristic_array[j]->value.characteristic.value_handle;
characteristic_value->type = characteristic_array[j]->value.characteristic.uuid;
}
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
}
if ( characteristic_value != NULL ) {
/* Add Characteristic Value to main list */
mico_rtos_lock_mutex( &cache->mutex );
/* Add characteristic_value to main list */
result = mico_bt_smart_attribute_add_to_list( &primary_service_list, characteristic_value );
/* Merge success, it will be deleted by primary_service_list when error */
if ( result == MICO_BT_SUCCESS ) {
characteristic_value = NULL;
}
mico_rtos_unlock_mutex( &cache->mutex );
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
}
/******************************************************************
* Characteristic Descriptor Discovery
******************************************************************/
/* Check whether the Descriptor Handle is valid or not. Add by zhj */
if (j < characteristic_count - 1) {
if ((characteristic_array[j]->value.characteristic.descriptor_start_handle <=
characteristic_array[j]->value.characteristic.value_handle)
|| (characteristic_array[j]->value.characteristic.descriptor_end_handle >= characteristic_array[j + 1]->handle)) {
continue;
}
} else {
if ((characteristic_array[j]->value.characteristic.descriptor_start_handle <=
characteristic_array[j]->value.characteristic.value_handle)
|| (characteristic_array[j]->value.characteristic.descriptor_end_handle >
primary_service_array[i]->value.service.end_handle)) {
continue;
}
}
if ( characteristic_array[j]->value.characteristic.descriptor_start_handle <=
characteristic_array[j]->value.characteristic.descriptor_end_handle ) {
result = smartbridge_bt_interface_discover_all_characteristic_descriptors( connection_handle,
characteristic_array[j]->value.characteristic.descriptor_start_handle,
characteristic_array[j]->value.characteristic.descriptor_end_handle, &descriptor_list );
CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result );
mico_bt_smart_attribute_get_list_head( &descriptor_list, &descriptor_with_no_value );
/* Traverse through all descriptors */
while ( descriptor_with_no_value != NULL ) {
/* Initialise variable for this iteration */
descriptor_with_value = NULL;
result = smartbridge_bt_interface_read_characteristic_descriptor( connection_handle, descriptor_with_no_value->handle,
&descriptor_with_no_value->type, &descriptor_with_value );
CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result );
/* Add Descriptor with Value to main list */
result = mico_bt_smart_attribute_add_to_list( &primary_service_list, descriptor_with_value );
/* Merge success, it will be deleted by primary_service_list when error */
if ( result == MICO_BT_SUCCESS ) {
descriptor_with_value = NULL;
}
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
descriptor_with_no_value = descriptor_with_no_value->next;
}
/* Delete the empty descriptor list */
result = mico_bt_smart_attribute_delete_list( &descriptor_list );
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
}
}
/* Merge Characteristics to main list */
mico_rtos_lock_mutex( &cache->mutex );
result = mico_bt_smart_attribute_merge_lists( &primary_service_list, &characteristic_list );
if ( result == MICO_BT_SUCCESS ) {
characteristic_list_merged = MICO_TRUE;
}
mico_rtos_unlock_mutex( &cache->mutex );
CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
/* Free primary service array */
free( characteristic_array );
}
/* Free primary service array */
free( primary_service_array );
/* Successful. Now copy the primary service list to the cached attributes list */
memcpy( &cache->attribute_list, &primary_service_list, sizeof( cache->attribute_list ) );
//mico_bt_smart_attribute_print_list( &(cache->attribute_list) );
return MICO_BT_SUCCESS;
error:
/* Delete all local attributes */
if ( descriptor_with_value != NULL ) {
mico_bt_smart_attribute_delete( descriptor_with_value );
}
if ( characteristic_value != NULL ) {
mico_bt_smart_attribute_delete( characteristic_value );
}
if ( characteristic_array != NULL ) {
free( characteristic_array );
}
if ( primary_service_array != NULL ) {
free( primary_service_array );
}
if ( characteristic_list_merged == MICO_FALSE ) {
mico_bt_smart_attribute_delete_list( &characteristic_list );
}
if ( included_service_list_merged == MICO_FALSE ) {
mico_bt_smart_attribute_delete_list( &included_service_list );
}
mico_bt_smart_attribute_delete_list( &descriptor_list );
mico_bt_smart_attribute_delete_list( &primary_service_list );
/* Return the error code to the caller */
return error_code_var;
}
static bool smartbridge_att_cache_find_by_device_callback( linked_list_node_t *node_to_compare, void *user_data )
{
bt_smartbridge_att_cache_t *cached_attributes = (bt_smartbridge_att_cache_t *)node_to_compare->data;
mico_bt_smart_device_t *remote_device = (mico_bt_smart_device_t *)user_data;
return ( ( memcmp( cached_attributes->remote_device.address, remote_device->address,
sizeof( remote_device->address ) ) == 0 ) &&
( cached_attributes->remote_device.address_type == remote_device->address_type) ) ? true : false;
}
static bool smartbridge_att_cache_get_free_callback( linked_list_node_t *node_to_compare, void *user_data )
{
bt_smartbridge_att_cache_t *cache = (bt_smartbridge_att_cache_t *)node_to_compare->data;
return ( cache->is_active == MICO_FALSE ) ? true : false;
}

View file

@ -0,0 +1,72 @@
#pragma once
//#include "mico_utilities.h"
#include "mico_bt_smart_interface.h"
#include "bt_smartbridge_att_cache_manager.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
#define MAX_CACHED_ATTRIBUTES_INSTANCES ( MAX_BT_SMART_CONNECTIONS )
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
typedef struct bt_smartbridge_att_cache bt_smartbridge_att_cache_t;
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
OSStatus bt_smartbridge_att_cache_enable( uint32_t cache_count, mico_bt_uuid_t cache_services[],
uint32_t service_count );
OSStatus bt_smartbridge_att_cache_disable( void );
mico_bool_t bt_smartbridge_att_cache_is_enabled( void );
mico_bool_t bt_smartbridge_att_cache_is_discovering( const bt_smartbridge_att_cache_t *cache );
mico_bool_t bt_smartbridge_att_cache_get_active_state( const bt_smartbridge_att_cache_t *cache );
OSStatus bt_smartbridge_att_cache_set_active_state( bt_smartbridge_att_cache_t *cache, mico_bool_t is_active );
OSStatus bt_smartbridge_att_cache_find( const mico_bt_smart_device_t *remote_device,
bt_smartbridge_att_cache_t **cache );
OSStatus bt_smartbridge_att_cache_generate( const mico_bt_smart_device_t *remote_device, uint16_t connection_handle,
bt_smartbridge_att_cache_t **cache );
OSStatus bt_smartbridge_att_cache_release( bt_smartbridge_att_cache_t *cache );
OSStatus bt_smartbridge_att_cache_get_list( bt_smartbridge_att_cache_t *cache, mico_bt_smart_attribute_list_t **list );
OSStatus bt_smartbridge_att_cache_lock( bt_smartbridge_att_cache_t *cache );
OSStatus bt_smartbridge_att_cache_unlock( bt_smartbridge_att_cache_t *cache );
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,306 @@
/** @file
*
*/
#include "mico.h"
#include "mico_bt_smartbridge.h"
#include "mico_bt_peripheral.h"
#include "mico_bt_gatt.h"
#include "mico_bt_ble.h"
#include "mico_bt_cfg.h"
#include "bt_smartbridge_socket_manager.h"
#include "bt_smartbridge_att_cache_manager.h"
#include "bt_smartbridge_helper.h"
#include "bt_smartbridge_stack_interface.h"
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Static Function Declarations
******************************************************/
/******************************************************
* Variable Definitions
******************************************************/
static mico_bt_smart_scan_result_t *scan_result_head = NULL;
static mico_bt_smart_scan_result_t *scan_result_tail = NULL;
static uint32_t scan_result_count = 0;
/******************************************************
* Function Definitions
******************************************************/
OSStatus smartbridge_helper_get_scan_results( mico_bt_smart_scan_result_t **result_list, uint32_t *count )
{
if ( smartbridge_bt_interface_is_scanning() == MICO_TRUE ) {
bt_smartbridge_log("Can't Fetch Scan-Results [ Scan in-progress ? ]");
return MICO_BT_SCAN_IN_PROGRESS;
}
*result_list = scan_result_head;
*count = scan_result_count;
return MICO_BT_SUCCESS;
}
OSStatus smartbridge_helper_delete_scan_result_list( void )
{
mico_bt_smart_scan_result_t *curr;
if ( scan_result_count == 0 ) {
return MICO_BT_LIST_EMPTY;
}
curr = scan_result_head;
/* Traverse through the list and delete all attributes */
while ( curr != NULL ) {
/* Store pointer to next because curr is about to be deleted */
mico_bt_smart_scan_result_t *next = curr->next;
/* Detach result from the list and free memory */
curr->next = NULL;
free( curr );
/* Update curr */
curr = next;
}
scan_result_count = 0;
scan_result_head = NULL;
scan_result_tail = NULL;
return MICO_BT_SUCCESS;
}
OSStatus smartbridge_helper_add_scan_result_to_list( mico_bt_smart_scan_result_t *result )
{
if ( scan_result_count == 0 ) {
scan_result_head = result;
scan_result_tail = result;
} else {
scan_result_tail->next = result;
scan_result_tail = result;
}
scan_result_count++;
//bt_smartbridge_log("New scan-result-count:%d", (int)scan_result_count);
result->next = NULL;
return MICO_BT_SUCCESS;
}
OSStatus smartbridge_helper_find_device_in_scan_result_list( mico_bt_device_address_t *address,
mico_bt_smart_address_type_t type, mico_bt_smart_scan_result_t **result )
{
mico_bt_smart_scan_result_t *iterator = scan_result_head;
while ( iterator != NULL ) {
if ( ( memcmp( &iterator->remote_device.address, address, sizeof( *address ) ) == 0 ) &&
( iterator->remote_device.address_type == type ) ) {
*result = iterator;
return MICO_BT_SUCCESS;
}
iterator = iterator->next;
}
return MICO_BT_ITEM_NOT_IN_LIST;
}
/******************************************************
* Socket Action Helper Functions
******************************************************/
mico_bool_t smartbridge_helper_socket_check_actions_enabled( mico_bt_smartbridge_socket_t *socket, uint8_t action_bits )
{
return ( ( socket->actions & action_bits ) == action_bits ) ? MICO_TRUE : MICO_FALSE;
}
mico_bool_t smartbridge_helper_socket_check_actions_disabled( mico_bt_smartbridge_socket_t *socket,
uint8_t action_bits )
{
return ( ( socket->actions | ~action_bits ) == ~action_bits ) ? MICO_TRUE : MICO_FALSE;
}
void smartbridge_helper_socket_set_actions( mico_bt_smartbridge_socket_t *socket, uint8_t action_bits )
{
socket->actions |= action_bits;
}
void smartbridge_helper_socket_clear_actions( mico_bt_smartbridge_socket_t *socket, uint8_t action_bits )
{
socket->actions &= ~action_bits;
}
mico_bool_t peripheral_helper_socket_check_actions_enabled( mico_bt_peripheral_socket_t *socket, uint8_t action_bits )
{
return ( ( socket->actions & action_bits ) == action_bits ) ? MICO_TRUE : MICO_FALSE;
}
mico_bool_t peripheral_helper_socket_check_actions_disabled( mico_bt_peripheral_socket_t *socket, uint8_t action_bits )
{
return ( ( socket->actions | ~action_bits ) == ~action_bits ) ? MICO_TRUE : MICO_FALSE;
}
void peripheral_helper_socket_set_actions( mico_bt_peripheral_socket_t *socket, uint8_t action_bits )
{
socket->actions |= action_bits;
}
void peripheral_helper_socket_clear_actions( mico_bt_peripheral_socket_t *socket, uint8_t action_bits )
{
socket->actions &= ~action_bits;
}
/******************************************************
* GATT/GAP subprocedure Functions
******************************************************/
#define GATT_MAX_PROCEDURE_TIMEOUT (10000)
OSStatus subprocedure_lock( gatt_subprocedure_t *subprocedure )
{
return mico_rtos_lock_mutex( &subprocedure->mutex );
}
OSStatus subprocedure_unlock( gatt_subprocedure_t *subprocedure )
{
return mico_rtos_unlock_mutex( &subprocedure->mutex );
}
OSStatus subprocedure_reset( gatt_subprocedure_t *subprocedure )
{
subprocedure->subprocedure = GATT_SUBPROCEDURE_NONE;
subprocedure->attr_head = NULL;
subprocedure->attr_tail = NULL;
subprocedure->attr_count = 0;
subprocedure->result = MICO_BT_SUCCESS;
subprocedure->start_handle = 0;
subprocedure->end_handle = 0;
//subprocedure.pdu = 0;
subprocedure->length = 0;
subprocedure->offset = 0;
subprocedure->connection_handle = 0;
memset( &subprocedure->uuid, 0, sizeof( subprocedure->uuid ) );
subprocedure_wait_clear_semaphore( subprocedure );
return MICO_BT_SUCCESS;
}
OSStatus subprocedure_wait_for_completion( gatt_subprocedure_t *subprocedure )
{
if ( kNoErr != mico_rtos_get_semaphore( &subprocedure->done_semaphore, GATT_MAX_PROCEDURE_TIMEOUT ) ) {
subprocedure->result = MICO_BT_TIMEOUT;
}
return subprocedure->result;
}
OSStatus subprocedure_wait_clear_semaphore( gatt_subprocedure_t *subprocedure )
{
while ( mico_rtos_get_semaphore( &subprocedure->done_semaphore, MICO_NO_WAIT ) == kNoErr ) {
}
return MICO_BT_SUCCESS;
}
OSStatus subprocedure_notify_complete( gatt_subprocedure_t *subprocedure )
{
return mico_rtos_set_semaphore( &subprocedure->done_semaphore );
}
/******************************************************
* Smartbridge timer Functions
******************************************************/
/* Smartbridge timer handler */
static void smartbridge_helper_timer_handler(void *arg)
{
smartbridge_helper_timer_t *timer = (smartbridge_helper_timer_t *)arg;
bt_smartbridge_log("smartbridge timer expired.");
/* Call user timer handler */
timer->handler(timer->context);
/* Reload if not one-shot timer. */
if (timer->is_started && !timer->one_shot) {
bt_smartbridge_log("smartbridge timer reload");
mico_rtos_reload_timer(&timer->timer);
}
}
/* This function is used to stop a active timer.
* return MICO_TRUE if successful, otherwise, return MICO_FALSE.
*/
mico_bool_t smartbridge_helper_timer_stop(smartbridge_helper_timer_t *timer)
{
if (timer == (void *)0) {
return MICO_FALSE;
}
if (!timer->is_started) {
return MICO_FALSE;
}
if (mico_rtos_is_timer_running(&timer->timer)) {
mico_rtos_stop_timer(&timer->timer);
}
mico_rtos_deinit_timer(&timer->timer);
timer->is_started = MICO_FALSE;
timer->one_shot = MICO_FALSE;
return MICO_TRUE;
}
/* This function is used to start or restart a timer.
* The 'timer' will be restarted if it is active.
*/
mico_bool_t smartbridge_helper_timer_start(smartbridge_helper_timer_t *timer, mico_bool_t one_shot, uint32_t ms,
timer_handler_t handler, void *arg)
{
if (timer == (void *)0) {
return MICO_FALSE;
}
if (timer->is_started) {
smartbridge_helper_timer_stop(timer);
}
if (mico_rtos_init_timer(&timer->timer, ms, smartbridge_helper_timer_handler, (void *)timer) != kNoErr) {
return MICO_FALSE;
}
if (mico_rtos_start_timer(&timer->timer) != kNoErr) {
mico_rtos_deinit_timer(&timer->timer);
return MICO_FALSE;
}
timer->is_started = MICO_TRUE;
timer->one_shot = one_shot;
timer->handler = handler;
timer->context = arg;
return MICO_TRUE;
}

View file

@ -0,0 +1,163 @@
#pragma once
/** @file
* Smartbridge's Helper Function Headers
*/
//#include "mico_utilities.h"
#include "mico_bt_smartbridge.h"
#include "mico_bt_smart_interface.h"
#include "mico_bt_peripheral.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
//#define bt_smartbridge_log(M, ...) custom_log("Smartbridge", M, ##__VA_ARGS__)
#define bt_smartbridge_log(M, ...)
//#define bt_peripheral_log(M, ...) custom_log("Peripheral", M, ##__VA_ARGS__)
#define bt_peripheral_log(M, ...)
//#define bt_manager_log(M, ...) custom_log("Manager", M, ##__VA_ARGS__)
#define bt_manager_log(M, ...)
/******************************************************
* Constants
******************************************************/
#define SOCKET_STATE_DISCONNECTED ( 0 )
#define SOCKET_STATE_LINK_CONNECTED ( 1 )
#define SOCKET_STATE_LINK_ENCRYPTED ( 2 )
#define SOCKET_STATE_LINK_CONNECTING ( 3 )
#define SOCKET_ACTION_HOST_CONNECT ( 1 << 0 )
#define SOCKET_ACTION_HOST_DISCONNECT ( 1 << 2 )
#define SOCKET_ACTION_INITIATE_PAIRING ( 1 << 3 )
#define SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ( 1 << 4 )
/******************************************************
* Enumerations
******************************************************/
/* GATT Feature Sub-Procedures (SPEC v4.0 Part G Section 4) */
typedef enum {
GATT_SUBPROCEDURE_NONE, /* Default Value */
GATT_EXCHANGE_MTU, /* GATT Feature: Server Configuration */
GATT_DISCOVER_ALL_PRIMARY_SERVICES, /* GATT Feature: Primary Service Discovery */
GATT_DISCOVER_PRIMARY_SERVICE_BY_SERVICE_UUID, /* GATT Feature: Primary Service Discovery */
GATT_FIND_INCLUDED_SERVICES, /* GATT Feature: Relationship Discovery */
GATT_DISCOVER_ALL_CHARACTERISTICS_OF_A_SERVICE, /* GATT Feature: Characteristic Discovery */
GATT_DISCOVER_CHARACTERISTIC_BY_UUID, /* GATT Feature: Characteristic Discovery */
GATT_DISCOVER_ALL_CHARACTERISTICS_DESCRIPTORS, /* GATT Feature: Characteristic Descriptor Discovery */
GATT_READ_CHARACTERISTIC_VALUE, /* GATT Feature: Characteristic Value Read */
GATT_READ_USING_CHARACTERISTIC_UUID, /* GATT Feature: Characteristic Value Read */
GATT_READ_LONG_CHARACTERISTIC_VALUES, /* GATT Feature: Characteristic Value Read */
GATT_READ_MULTIPLE_CHARACTERISTIC_VALUES, /* GATT Feature: Characteristic Value Read */
GATT_WRITE_WITHOUT_RESPONSE, /* GATT Feature: Characteristic Value Write */
GATT_SIGNED_WRITE_WITHOUT_RESPONSE, /* GATT Feature: Characteristic Value Write */
GATT_WRITE_CHARACTERISTIC_VALUE, /* GATT Feature: Characteristic Value Write */
GATT_WRITE_LONG_CHARACTERISTIC_VALUE, /* GATT Feature: Characteristic Value Write */
GATT_CHARACTERISTIC_VALUE_RELIABLE_WRITES, /* GATT Feature: Characteristic Value Write */
GATT_NOTIFICATIONS, /* GATT Feature: Characteristic Value Notification */
GATT_INDICATIONS, /* GATT Feature: Characteristic Value Indication */
GATT_READ_CHARACTERISTIC_DESCRIPTORS, /* GATT Feature: Characteristic Descriptor Value Read */
GATT_READ_LONG_CHARACTERISTIC_DESCRIPTORS, /* GATT Feature: Characteristic Descriptor Value Read */
GATT_WRITE_CHARACTERISTIC_DESCRIPTORS, /* GATT Feature: Characteristic Descriptor Value Write */
GATT_WRITE_LONG_CHARACTERISTIC_DESCRIPTORS, /* GATT Feature: Characteristic Descriptor Value Write */
} bt_smart_gatt_subprocedure_t;
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
typedef struct {
bt_smart_gatt_subprocedure_t subprocedure;
mico_mutex_t mutex;
mico_semaphore_t done_semaphore;
OSStatus result;
mico_bt_uuid_t uuid;
mico_bt_smart_attribute_t *attr_head;
mico_bt_smart_attribute_t *attr_tail;
uint32_t attr_count;
uint16_t server_mtu;
uint16_t start_handle;
uint16_t end_handle;
uint16_t length;
uint16_t offset;
//bt_smart_att_pdu_t* pdu;
uint16_t connection_handle;
} gatt_subprocedure_t;
typedef struct {
mico_timer_t timer; // MiCO timer object
mico_bool_t is_started; // is it started?
mico_bool_t one_shot; // one-shot?
timer_handler_t handler; // timer expired handler
void *context; // user context
} smartbridge_helper_timer_t;
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
OSStatus smartbridge_helper_delete_scan_result_list ( void );
OSStatus smartbridge_helper_add_scan_result_to_list ( mico_bt_smart_scan_result_t *result );
OSStatus smartbridge_helper_find_device_in_scan_result_list ( mico_bt_device_address_t *address,
mico_bt_smart_address_type_t type, mico_bt_smart_scan_result_t **result );
OSStatus smartbridge_helper_get_scan_results ( mico_bt_smart_scan_result_t **result_list,
uint32_t *count );
mico_bool_t smartbridge_helper_socket_check_actions_enabled ( mico_bt_smartbridge_socket_t *socket,
uint8_t action_bits );
mico_bool_t smartbridge_helper_socket_check_actions_disabled ( mico_bt_smartbridge_socket_t *socket,
uint8_t action_bits );
void smartbridge_helper_socket_set_actions ( mico_bt_smartbridge_socket_t *socket,
uint8_t action_bits );
void smartbridge_helper_socket_clear_actions ( mico_bt_smartbridge_socket_t *socket,
uint8_t action_bits );
mico_bool_t peripheral_helper_socket_check_actions_enabled ( mico_bt_peripheral_socket_t *socket,
uint8_t action_bits );
mico_bool_t peripheral_helper_socket_check_actions_disabled ( mico_bt_peripheral_socket_t *socket,
uint8_t action_bits );
void peripheral_helper_socket_set_actions ( mico_bt_peripheral_socket_t *socket,
uint8_t action_bits );
void peripheral_helper_socket_clear_actions ( mico_bt_peripheral_socket_t *socket,
uint8_t action_bits );
OSStatus subprocedure_notify_complete ( gatt_subprocedure_t *subprocedure );
OSStatus subprocedure_unlock ( gatt_subprocedure_t *subprocedure );
OSStatus subprocedure_lock ( gatt_subprocedure_t *subprocedure );
OSStatus subprocedure_reset ( gatt_subprocedure_t *subprocedure );
OSStatus subprocedure_wait_for_completion ( gatt_subprocedure_t *subprocedure );
OSStatus subprocedure_wait_clear_semaphore ( gatt_subprocedure_t *subprocedure );
/* This function is used to stop a active timer.
* return MICO_TRUE if successful, otherwise, return MICO_FALSE
*/
mico_bool_t smartbridge_helper_timer_stop(smartbridge_helper_timer_t *timer);
/* This function is used to start or restart a timer.
* The 'timer' will be restarted if it is active.
*/
mico_bool_t smartbridge_helper_timer_start(smartbridge_helper_timer_t *timer, mico_bool_t one_shot, uint32_t ms,
timer_handler_t handler, void *arg);
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,226 @@
/** @file
*
*/
#include "mico.h"
#include "LinkListUtils.h"
#include "bt_smartbridge_socket_manager.h"
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Static Function Declarations
******************************************************/
static bool smartbridge_socket_manager_find_socket_by_handle_callback ( linked_list_node_t *node_to_compare,
void *user_data );
static bool smartbridge_socket_manager_find_socket_by_address_callback ( linked_list_node_t *node_to_compare,
void *user_data );
/******************************************************
* Variable Definitions
******************************************************/
/* Socket Management Globals */
static linked_list_t connected_socket_list;
static mico_mutex_t connected_socket_list_mutex;
static uint8_t max_number_of_connections = 0;
/******************************************************
* Function Definitions
******************************************************/
OSStatus bt_smartbridge_socket_manager_init( void )
{
OSStatus result;
result = linked_list_init( &connected_socket_list );
if ( result != kNoErr ) {
WPRINT_LIB_INFO( ( "Error creating linked list\n" ) );
return result;
}
result = mico_rtos_init_mutex( &connected_socket_list_mutex );
if ( result != kNoErr ) {
WPRINT_LIB_INFO( ( "Error creating mutex\n" ) );
return result;
}
max_number_of_connections = 1;
return MICO_BT_SUCCESS;
}
OSStatus bt_smartbridge_socket_manager_deinit( void )
{
mico_rtos_deinit_mutex( &connected_socket_list_mutex );
linked_list_deinit( &connected_socket_list );
max_number_of_connections = 0;
return MICO_BT_SUCCESS;
}
OSStatus bt_smartbridge_socket_manager_set_max_concurrent_connections( uint8_t count )
{
max_number_of_connections = count;
return MICO_BT_SUCCESS;
}
mico_bool_t bt_smartbridge_socket_manager_is_full( void )
{
uint32_t active_connection_count;
linked_list_get_count( &connected_socket_list, &active_connection_count );
return ( active_connection_count == max_number_of_connections ) ? MICO_TRUE : MICO_FALSE;
}
OSStatus bt_smartbridge_socket_manager_insert_socket( mico_bt_smartbridge_socket_t *socket )
{
OSStatus result;
uint32_t count;
linked_list_get_count( &connected_socket_list, &count );
if ( count == max_number_of_connections ) {
return MICO_BT_MAX_CONNECTIONS_REACHED;
}
/* Lock protection */
mico_rtos_lock_mutex( &connected_socket_list_mutex );
result = linked_list_insert_node_at_rear( &connected_socket_list, &socket->node );
/* Unlock protection */
mico_rtos_unlock_mutex( &connected_socket_list_mutex );
return result;
}
OSStatus bt_smartbridge_socket_manager_remove_socket( uint16_t connection_handle,
mico_bt_smartbridge_socket_t **socket )
{
OSStatus result;
uint32_t count;
linked_list_node_t *node_found;
uint32_t user_data = connection_handle;
linked_list_get_count( &connected_socket_list, &count );
if ( count == 0 ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
/* Lock protection */
mico_rtos_lock_mutex( &connected_socket_list_mutex );
result = linked_list_find_node( &connected_socket_list, smartbridge_socket_manager_find_socket_by_handle_callback,
(void *)user_data, &node_found );
if ( result == MICO_BT_SUCCESS ) {
result = linked_list_remove_node( &connected_socket_list, node_found );
if ( result == MICO_BT_SUCCESS ) {
*socket = (mico_bt_smartbridge_socket_t *)node_found->data;
}
}
/* Unlock protection */
mico_rtos_unlock_mutex( &connected_socket_list_mutex );
return result;
}
OSStatus bt_smartbridge_socket_manager_find_socket_by_handle( uint16_t connection_handle,
mico_bt_smartbridge_socket_t **socket )
{
OSStatus result;
uint32_t count;
linked_list_node_t *node_found;
uint32_t user_data = connection_handle;
linked_list_get_count( &connected_socket_list, &count );
if ( count == 0 ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
/* Lock protection */
mico_rtos_lock_mutex( &connected_socket_list_mutex );
result = linked_list_find_node( &connected_socket_list, smartbridge_socket_manager_find_socket_by_handle_callback,
(void *)user_data, &node_found );
if ( result == MICO_BT_SUCCESS ) {
*socket = (mico_bt_smartbridge_socket_t *)node_found->data;
}
/* Unlock protection */
mico_rtos_unlock_mutex( &connected_socket_list_mutex );
return result;
}
OSStatus bt_smartbridge_socket_manager_find_socket_by_address( const mico_bt_device_address_t *address,
mico_bt_smartbridge_socket_t **socket )
{
OSStatus result;
uint32_t count;
linked_list_node_t *node_found;
linked_list_get_count( &connected_socket_list, &count );
if ( count == 0 ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
/* Lock protection */
mico_rtos_lock_mutex( &connected_socket_list_mutex );
result = linked_list_find_node( &connected_socket_list, smartbridge_socket_manager_find_socket_by_address_callback,
(void *)address, &node_found );
if ( result == MICO_BT_SUCCESS ) {
*socket = (mico_bt_smartbridge_socket_t *)node_found->data;
}
/* Unlock protection */
mico_rtos_unlock_mutex( &connected_socket_list_mutex );
return result;
}
static bool smartbridge_socket_manager_find_socket_by_handle_callback( linked_list_node_t *node_to_compare,
void *user_data )
{
mico_bt_smartbridge_socket_t *socket = (mico_bt_smartbridge_socket_t *)node_to_compare->data;
uint32_t connection_handle = (uint32_t)user_data;
return ( socket->connection_handle == connection_handle ) ? true : false;
}
static bool smartbridge_socket_manager_find_socket_by_address_callback( linked_list_node_t *node_to_compare,
void *user_data )
{
mico_bt_smartbridge_socket_t *socket = (mico_bt_smartbridge_socket_t *)node_to_compare->data;
mico_bt_device_address_t *address = (mico_bt_device_address_t *)user_data;
return ( memcmp( socket->remote_device.address, address, sizeof( *address ) ) == 0 ) ? true : false;
}

View file

@ -0,0 +1,60 @@
#pragma once
//#include "mico_utilities.h"
#include "mico_bt_smartbridge.h"
#include "LinkListUtils.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
OSStatus bt_smartbridge_socket_manager_init( void );
OSStatus bt_smartbridge_socket_manager_deinit( void );
OSStatus bt_smartbridge_socket_manager_set_max_concurrent_connections( uint8_t count );
mico_bool_t bt_smartbridge_socket_manager_is_full( void );
OSStatus bt_smartbridge_socket_manager_insert_socket( mico_bt_smartbridge_socket_t *socket );
OSStatus bt_smartbridge_socket_manager_remove_socket( uint16_t connection_handle,
mico_bt_smartbridge_socket_t **socket );
OSStatus bt_smartbridge_socket_manager_find_socket_by_handle( uint16_t connection_handle,
mico_bt_smartbridge_socket_t **socket );
OSStatus bt_smartbridge_socket_manager_find_socket_by_address( const mico_bt_device_address_t *address,
mico_bt_smartbridge_socket_t **socket );
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,888 @@
/** @file
*
*/
#include "mico.h"
#include "mico_bt_smartbridge.h"
#include "mico_bt.h"
#include "mico_bt_gatt.h"
#include "mico_bt_ble.h"
#include "mico_bt_cfg.h"
#include "bt_smartbridge_socket_manager.h"
#include "bt_smartbridge_att_cache_manager.h"
#include "bt_smartbridge_helper.h"
#include "bt_smartbridge_stack_interface.h"
#include "StringUtils.h"
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Static Function Declarations
******************************************************/
/******************************************************
* Variable Definitions
******************************************************/
gatt_subprocedure_t smartbridge_subprocedure;
extern mico_bt_cfg_settings_t mico_bt_cfg_settings;
mico_bt_smart_scan_complete_callback_t app_scan_complete_callback;
mico_bt_smart_advertising_report_callback_t app_scan_report_callback;
mico_bt_dev_ble_io_caps_req_t default_io_caps_ble = {
.bd_addr = { 0 },
.local_io_cap = BTM_IO_CAPABILITIES_NONE,
.oob_data = 0,
.auth_req = BTM_LE_AUTH_REQ_BOND | BTM_LE_AUTH_REQ_MITM, /* BTM_LE_AUTH_REQ_SC_MITM_BOND */
.max_key_size = 16,
.init_keys = (BTM_LE_KEY_PENC | BTM_LE_KEY_PID | BTM_LE_KEY_PCSRK | BTM_LE_KEY_PLK), // init_keys - Keys to be distributed, bit mask
.resp_keys = (BTM_LE_KEY_PENC | BTM_LE_KEY_PID | BTM_LE_KEY_PCSRK | BTM_LE_KEY_PLK) // resp_keys - Keys to be distributed, bit mask
};
extern mico_bt_gatt_status_t smartbridge_gatt_callback ( mico_bt_gatt_evt_t event,
mico_bt_gatt_event_data_t *p_event_data );
/******************************************************
* Function Definitions
******************************************************/
OSStatus smartbridge_bt_interface_initialize( void )
{
OSStatus result;
bt_smartbridge_log( "Initializing Bluetooth Interface..." );
result = mico_rtos_init_mutex( &smartbridge_subprocedure.mutex );
if ( result != MICO_BT_SUCCESS ) {
bt_smartbridge_log( "Error creating mutex" );
return result;
}
result = mico_rtos_init_semaphore( &smartbridge_subprocedure.done_semaphore, 1 );
if ( result != MICO_BT_SUCCESS ) {
bt_smartbridge_log( "Error creating semaphore" );
return result;
}
subprocedure_reset( &smartbridge_subprocedure );
mico_bt_gatt_register( GATT_IF_CLIENT, smartbridge_gatt_callback );
return MICO_BT_SUCCESS;
}
OSStatus smartbridge_bt_interface_deinitialize( void )
{
bt_smartbridge_log( "Deinitializing Bluetooth Interface..." );
subprocedure_reset( &smartbridge_subprocedure );
mico_rtos_deinit_mutex( &smartbridge_subprocedure.mutex );
mico_rtos_deinit_semaphore( &smartbridge_subprocedure.done_semaphore );
return MICO_BT_SUCCESS;
}
OSStatus smartbridge_bt_interface_discover_all_primary_services( uint16_t connection_handle,
mico_bt_smart_attribute_list_t *service_list )
{
mico_bt_gatt_discovery_param_t parameter;
bt_smartbridge_log( "Discover all Primary Services" );
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
/* FIXME : reset() above is not taking effect. Need to be debugged */
smartbridge_subprocedure.attr_count = 0;
memset( &parameter.uuid, 0, sizeof( parameter.uuid ) );
parameter.s_handle = 1;
parameter.e_handle = 0xffff;
smartbridge_subprocedure.end_handle = 0xffff;
smartbridge_subprocedure.start_handle = 1;
mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_SERVICES_ALL, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
service_list->count = smartbridge_subprocedure.attr_count;
service_list->list = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_list_t list;
list.count = smartbridge_subprocedure.attr_count;
list.list = smartbridge_subprocedure.attr_head;
mico_bt_smart_attribute_delete_list( &list );
}
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_discover_primary_services_by_uuid( uint16_t connection_handle,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *service_list )
{
mico_bt_gatt_discovery_param_t parameter;
bt_smartbridge_log( "Discover all Primary Services(By-UUID)" );
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
/* FIXME : reset() above is not taking effect. Need to be debugged */
smartbridge_subprocedure.attr_count = 0;
memcpy( &parameter.uuid, uuid, sizeof( parameter.uuid ) );
parameter.s_handle = smartbridge_subprocedure.end_handle = 0x0001;
parameter.e_handle = smartbridge_subprocedure.start_handle = 0xffff;
mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_SERVICES_BY_UUID, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
service_list->count = smartbridge_subprocedure.attr_count;
service_list->list = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_list_t list;
list.count = smartbridge_subprocedure.attr_count;
list.list = smartbridge_subprocedure.attr_head;
mico_bt_smart_attribute_delete_list( &list );
}
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_find_included_services( uint16_t connection_handle, uint16_t start_handle,
uint16_t end_handle, mico_bt_smart_attribute_list_t *include_list )
{
mico_bt_gatt_discovery_param_t parameter;
bt_smartbridge_log( "Discover all Included Services" );
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
/* FIXME : reset() above is not taking effect. Need to be debugged */
smartbridge_subprocedure.attr_count = 0;
memset( &parameter.uuid, 0, sizeof( parameter.uuid ) );
parameter.s_handle = smartbridge_subprocedure.end_handle = start_handle;
parameter.e_handle = smartbridge_subprocedure.start_handle = end_handle;
mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_INCLUDED_SERVICES, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
include_list->count = smartbridge_subprocedure.attr_count;
include_list->list = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_list_t list;
list.count = smartbridge_subprocedure.attr_count;
list.list = smartbridge_subprocedure.attr_head;
mico_bt_smart_attribute_delete_list( &list );
}
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_discover_all_characteristics_in_a_service( uint16_t connection_handle,
uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *characteristic_list )
{
mico_bt_gatt_discovery_param_t parameter;
subprocedure_lock( &smartbridge_subprocedure );
bt_smartbridge_log( "Discover Characteristics by Service[%x %x]", start_handle, end_handle );
subprocedure_reset( &smartbridge_subprocedure );
smartbridge_subprocedure.attr_count = 0;
memset( &parameter.uuid, 0, sizeof( parameter.uuid ) );
parameter.s_handle = start_handle;
parameter.e_handle = end_handle;
smartbridge_subprocedure.end_handle = end_handle;
smartbridge_subprocedure.start_handle = start_handle;
mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_CHARACTERISTICS, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
characteristic_list->count = smartbridge_subprocedure.attr_count;
characteristic_list->list = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_list_t list;
list.count = smartbridge_subprocedure.attr_count;
list.list = smartbridge_subprocedure.attr_head;
mico_bt_smart_attribute_delete_list( &list );
}
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_discover_characteristic_by_uuid( uint16_t connection_handle,
const mico_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle,
mico_bt_smart_attribute_list_t *characteristic_list )
{
UNUSED_PARAMETER(characteristic_list);
mico_bt_gatt_discovery_param_t parameter;
subprocedure_lock( &smartbridge_subprocedure );
bt_smartbridge_log( "Discover Characteristics by UUID [%x %x]", start_handle, end_handle );
subprocedure_reset( &smartbridge_subprocedure );
smartbridge_subprocedure.attr_count = 0;
memcpy( &parameter.uuid, uuid, sizeof( parameter.uuid ) );
parameter.s_handle = smartbridge_subprocedure.start_handle = start_handle;
parameter.e_handle = smartbridge_subprocedure.end_handle = end_handle;
mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_CHARACTERISTICS, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
characteristic_list->count = smartbridge_subprocedure.attr_count;
characteristic_list->list = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_list_t list;
list.count = smartbridge_subprocedure.attr_count;
list.list = smartbridge_subprocedure.attr_head;
mico_bt_smart_attribute_delete_list( &list );
}
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_discover_all_characteristic_descriptors( uint16_t connection_handle,
uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *no_value_descriptor_list )
{
mico_bt_gatt_discovery_param_t parameter;
bt_smartbridge_log( "Discover all Characteristic Descriptors[%x %x]", start_handle, end_handle );
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
smartbridge_subprocedure.attr_count = 0;
memset( &parameter.uuid, 0, sizeof( parameter.uuid ) );
parameter.s_handle = start_handle;
parameter.e_handle = end_handle;
smartbridge_subprocedure.start_handle = start_handle;
smartbridge_subprocedure.end_handle = end_handle;
smartbridge_subprocedure.connection_handle = connection_handle;
mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure);
bt_smartbridge_log( "Discover complete: %d", smartbridge_subprocedure.result );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
no_value_descriptor_list->count = smartbridge_subprocedure.attr_count;
no_value_descriptor_list->list = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_list_t list;
list.count = smartbridge_subprocedure.attr_count;
list.list = smartbridge_subprocedure.attr_head;
mico_bt_smart_attribute_delete_list( &list );
}
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_read_characteristic_descriptor( uint16_t connection_handle, uint16_t handle,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor )
{
mico_bt_gatt_read_param_t parameter;
bt_smartbridge_log( "Read Characteristic Descriptor" );
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
parameter.by_handle.auth_req = GATT_AUTH_REQ_NONE;
parameter.by_handle.handle = handle;
smartbridge_subprocedure.attr_count = 0;
smartbridge_subprocedure.subprocedure = GATT_READ_CHARACTERISTIC_DESCRIPTORS;
smartbridge_subprocedure.start_handle = handle;
smartbridge_subprocedure.uuid.len = uuid->len;
smartbridge_subprocedure.connection_handle = connection_handle;
if ( uuid->len == UUID_16BIT ) {
smartbridge_subprocedure.uuid.uu.uuid16 = uuid->uu.uuid16;
}
else if ( uuid->len == UUID_128BIT ) {
memcpy( smartbridge_subprocedure.uuid.uu.uuid128, uuid->uu.uuid128, UUID_128BIT );
}
mico_bt_gatt_send_read( connection_handle, GATT_READ_BY_HANDLE, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
*descriptor = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head );
}
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_read_characteristic_value( uint16_t connection_handle, uint16_t handle,
const mico_bt_uuid_t *type, mico_bt_smart_attribute_t **characteristic_value )
{
mico_bt_gatt_read_param_t parameter;
bt_smartbridge_log( "Read Characteristic Value" );
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
parameter.by_handle.auth_req = GATT_AUTH_REQ_NONE;
parameter.by_handle.handle = handle;
smartbridge_subprocedure.subprocedure = GATT_READ_CHARACTERISTIC_VALUE;
smartbridge_subprocedure.attr_count = 0;
smartbridge_subprocedure.start_handle = handle;
smartbridge_subprocedure.uuid.len = type->len;
smartbridge_subprocedure.connection_handle = connection_handle;
if ( type->len == UUID_16BIT ) {
smartbridge_subprocedure.uuid.uu.uuid16 = type->uu.uuid16;
} else if ( type->len == UUID_128BIT ) {
memcpy( (uint8_t *)smartbridge_subprocedure.uuid.uu.uuid128, (uint8_t *)type->uu.uuid128, UUID_128BIT );
}
mico_bt_gatt_send_read( connection_handle, GATT_READ_BY_HANDLE, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
*characteristic_value = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head );
}
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_read_characteristic_values_using_uuid( uint16_t connection_handle,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *characteristic_value_list )
{
mico_bt_gatt_read_param_t parameter;
bt_smartbridge_log( "Read Characteristic Value" );
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
parameter.char_type.auth_req = GATT_AUTH_REQ_NONE;
parameter.char_type.s_handle = smartbridge_subprocedure.start_handle = 0x0001;
parameter.char_type.e_handle = smartbridge_subprocedure.end_handle = 0xffff;
memcpy( &parameter.char_type.uuid, uuid, sizeof(mico_bt_uuid_t) );
smartbridge_subprocedure.subprocedure = GATT_READ_USING_CHARACTERISTIC_UUID;
smartbridge_subprocedure.attr_count = 0;
smartbridge_subprocedure.uuid.len = uuid->len;
smartbridge_subprocedure.connection_handle = connection_handle;
if ( uuid->len == UUID_16BIT ) {
smartbridge_subprocedure.uuid.uu.uuid16 = uuid->uu.uuid16;
} else if ( uuid->len == UUID_128BIT ) {
memcpy( smartbridge_subprocedure.uuid.uu.uuid128, uuid->uu.uuid128, UUID_128BIT );
}
mico_bt_gatt_send_read( connection_handle, GATT_READ_CHAR_VALUE, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
characteristic_value_list->count = smartbridge_subprocedure.attr_count;
characteristic_value_list->list = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head );
}
subprocedure_unlock( &smartbridge_subprocedure );
bt_smartbridge_log( "Read Long Characteristic Value result: %d", smartbridge_subprocedure.result );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_read_long_characteristic_value( uint16_t connection_handle, uint16_t handle,
const mico_bt_uuid_t *type, mico_bt_smart_attribute_t **characteristic_value )
{
mico_bt_gatt_read_param_t parameter;
bt_smartbridge_log( "Read Long Characteristic Value" );
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
parameter.partial.auth_req = GATT_AUTH_REQ_NONE;
parameter.partial.handle = handle;
parameter.partial.offset = 0;
smartbridge_subprocedure.subprocedure = GATT_READ_LONG_CHARACTERISTIC_VALUES;
smartbridge_subprocedure.attr_count = 0;
smartbridge_subprocedure.start_handle = handle;
smartbridge_subprocedure.uuid.len = type->len;
smartbridge_subprocedure.connection_handle = connection_handle;
if ( type->len == UUID_16BIT ) {
smartbridge_subprocedure.uuid.uu.uuid16 = type->uu.uuid16;
} else if ( type->len == UUID_128BIT ) {
memcpy( smartbridge_subprocedure.uuid.uu.uuid128, type->uu.uuid128, UUID_128BIT );
}
mico_bt_gatt_send_read( connection_handle, GATT_READ_PARTIAL, &parameter );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) {
*characteristic_value = smartbridge_subprocedure.attr_head;
} else {
/* Clean up */
mico_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head );
}
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_read_long_characteristic_descriptor( uint16_t connection_handle, uint16_t handle,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor )
{
UNUSED_PARAMETER(connection_handle);
UNUSED_PARAMETER(handle);
UNUSED_PARAMETER(uuid);
UNUSED_PARAMETER(descriptor);
return MICO_BT_UNSUPPORTED;
}
OSStatus smartbridge_bt_interface_write_characteristic_descriptor( uint16_t connection_handle,
mico_bt_smart_attribute_t *attribute )
{
uint8_t buffer[100] = { 0 };
mico_bt_gatt_value_t *write_value = (mico_bt_gatt_value_t *)buffer;
bt_smartbridge_log( "Write Characteristic Descriptor" );
#if 0
if ( attribute->value_length > LEATT_ATT_MTU - sizeof(LEATT_PDU_WRITE_HDR) ) {
BT_DEBUG_PRINT( ( "[GATT] Write Characteristic Value: value too long\n" ) );
return MICO_BT_ATTRIBUTE_VALUE_TOO_LONG;
}
#endif
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
smartbridge_subprocedure.subprocedure = GATT_WRITE_CHARACTERISTIC_DESCRIPTORS;
smartbridge_subprocedure.connection_handle = connection_handle;
write_value->auth_req = GATT_AUTH_REQ_NONE;
write_value->handle = attribute->handle;
write_value->len = attribute->value_length;
write_value->offset = 0;
memcpy( write_value->value, attribute->value.value, attribute->value_length );
mico_bt_gatt_send_write( connection_handle, GATT_WRITE, write_value );
subprocedure_wait_for_completion( &smartbridge_subprocedure );
subprocedure_unlock( &smartbridge_subprocedure );
return smartbridge_subprocedure.result;
}
OSStatus smartbridge_bt_interface_write_characteristic_value( uint16_t connection_handle,
mico_bt_smart_attribute_t *attribute )
{
OSStatus err = kNoErr;
uint8_t buffer[100] = { 0 };
mico_bt_gatt_value_t *write_value = (mico_bt_gatt_value_t *)buffer;
bt_smartbridge_log( "Write Characteristic value" );
subprocedure_lock( &smartbridge_subprocedure );
subprocedure_reset( &smartbridge_subprocedure );
write_value->auth_req = GATT_AUTH_REQ_NONE;
write_value->handle = attribute->handle;
write_value->len = attribute->value_length;
write_value->offset = 0;
memcpy( write_value->value, attribute->value.value, attribute->value_length );
err = mico_bt_gatt_send_write( connection_handle, GATT_WRITE, write_value );
require_noerr(err, exit);
subprocedure_wait_for_completion( &smartbridge_subprocedure );
err = smartbridge_subprocedure.result;
exit:
subprocedure_unlock( &smartbridge_subprocedure );
return err;
}
OSStatus smartbridge_bt_interface_write_long_characteristic_value( uint16_t connection_handle,
mico_bt_smart_attribute_t *attribute )
{
UNUSED_PARAMETER(connection_handle);
UNUSED_PARAMETER(attribute);
return MICO_BT_UNSUPPORTED;
}
OSStatus smartbridge_bt_interface_write_long_characteristic_descriptor( uint16_t connection_handle,
const mico_bt_smart_attribute_t *descriptor )
{
UNUSED_PARAMETER( connection_handle );
UNUSED_PARAMETER( descriptor );
return MICO_BT_UNSUPPORTED;
}
static void smartbridge_scan_result_callback( mico_bt_ble_scan_results_t *p_scan_result, uint8_t *p_adv_data )
{
if ( p_scan_result ) {
mico_bt_smart_advertising_report_t advertising_report;
mico_bt_smart_scan_result_t *current_scan_result = NULL;
uint8_t adv_data_length;
uint8_t *p = p_adv_data;
uint8_t adv_type;
uint8_t i;
memset( &advertising_report, 0x0, sizeof(mico_bt_smart_advertising_report_t) );
advertising_report.remote_device.address[0] = p_scan_result->remote_bd_addr[0];
advertising_report.remote_device.address[1] = p_scan_result->remote_bd_addr[1];
advertising_report.remote_device.address[2] = p_scan_result->remote_bd_addr[2];
advertising_report.remote_device.address[3] = p_scan_result->remote_bd_addr[3];
advertising_report.remote_device.address[4] = p_scan_result->remote_bd_addr[4];
advertising_report.remote_device.address[5] = p_scan_result->remote_bd_addr[5];
advertising_report.remote_device.address_type = (mico_bt_smart_address_type_t)p_scan_result->ble_addr_type;
advertising_report.signal_strength = p_scan_result->rssi;
advertising_report.event = (mico_bt_smart_advertising_event_t)p_scan_result->ble_evt_type;
advertising_report.eir_data_length = 0;
bt_smartbridge_log( "address:%x %x %x %x %x %x rssi:%d bdaddrtype:%d event_type:%x length:%u",
p_scan_result->remote_bd_addr[0], p_scan_result->remote_bd_addr[1], p_scan_result->remote_bd_addr[2],
p_scan_result->remote_bd_addr[3], p_scan_result->remote_bd_addr[4], p_scan_result->remote_bd_addr[5],
p_scan_result->rssi, p_scan_result->ble_addr_type, p_scan_result->ble_evt_type, p_scan_result->length );
if (p_scan_result->ble_evt_type > 4) {
return;
}
if ( smartbridge_helper_find_device_in_scan_result_list( &advertising_report.remote_device.address,
advertising_report.remote_device.address_type, &current_scan_result ) == MICO_BT_ITEM_NOT_IN_LIST ) {
/* This is a new result. Create new result object and add to the list */
current_scan_result = (mico_bt_smart_scan_result_t *)malloc_named( "scanres", sizeof( *current_scan_result ) );
if ( !current_scan_result ) {
bt_smartbridge_log( "Failed to alloc memory for scan-list" );
return;
}
memset( current_scan_result, 0, sizeof( *current_scan_result ) );
current_scan_result->remote_device.address[0] = p_scan_result->remote_bd_addr[0];
current_scan_result->remote_device.address[1] = p_scan_result->remote_bd_addr[1];
current_scan_result->remote_device.address[2] = p_scan_result->remote_bd_addr[2];
current_scan_result->remote_device.address[3] = p_scan_result->remote_bd_addr[3];
current_scan_result->remote_device.address[4] = p_scan_result->remote_bd_addr[4];
current_scan_result->remote_device.address[5] = p_scan_result->remote_bd_addr[5];
current_scan_result->remote_device.address_type = (mico_bt_smart_address_type_t)p_scan_result->ble_addr_type;
smartbridge_helper_add_scan_result_to_list( current_scan_result );
}
current_scan_result->signal_strength = p_scan_result->rssi;
if ( p_scan_result->length > 0 ) {
STREAM_TO_UINT8( adv_data_length, p );
while ( adv_data_length && (p - p_adv_data <= p_scan_result->length ) ) {
advertising_report.eir_data_length += ( adv_data_length + 1 );
STREAM_TO_UINT8( adv_type, p );
if ( adv_type == 0x09 || adv_type == 0x08 ) {
uint8_t j;
for ( i = 0, j = 0; i < ( adv_data_length - 1 ) && j <= p_scan_result->length; i++, j++ ) {
advertising_report.remote_device.name[j] = p[i];
current_scan_result->remote_device.name[j] = p[i];
}
bt_smartbridge_log( "Name of Device: %s", advertising_report.remote_device.name );
}
p += adv_data_length - 1; /* skip the type of data */
STREAM_TO_UINT8( adv_data_length, p );
}
}
memcpy(advertising_report.eir_data, p_adv_data, advertising_report.eir_data_length);
if ( p_scan_result->ble_evt_type == BT_SMART_SCAN_RESPONSE_EVENT ) {
bt_smartbridge_log( "Received SCAN_RSP\r\n" );
memcpy( &current_scan_result->last_scan_response_received, &advertising_report,
sizeof(mico_bt_smart_advertising_report_t) );
if ( app_scan_report_callback != NULL ) {
bt_smartbridge_log( "advertising callback reported" );
mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)app_scan_report_callback,
&current_scan_result->last_scan_response_received );
}
} else {
bt_smartbridge_log( "Received ADV[%lu], %d\r\n", (uint32_t)p_scan_result->ble_evt_type,
advertising_report.eir_data_length );
memcpy( &current_scan_result->last_advertising_event_received, &advertising_report,
sizeof(mico_bt_smart_advertising_report_t) );
if ( app_scan_report_callback != NULL ) {
bt_smartbridge_log( "advertising callback reported" );
mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)app_scan_report_callback,
&current_scan_result->last_advertising_event_received );
}
}
}
else {
bt_smartbridge_log( "LE scan completed." );
if ( app_scan_complete_callback != NULL ) {
mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, app_scan_complete_callback, NULL );
}
}
}
OSStatus smartbridge_bt_interface_set_attribute_timeout( uint32_t timeout_seconds )
{
UNUSED_PARAMETER(timeout_seconds);
return MICO_BT_UNSUPPORTED;
}
OSStatus smartbridge_bt_interface_update_background_connection_device( mico_bool_t add,
mico_bt_device_address_t device_address )
{
if ( device_address == 0 ) {
return kParamErr;
}
if ( add ) {
if ( mico_bt_ble_update_background_connection_device( MICO_TRUE, device_address ) != TRUE ) {
return kGeneralErr;
}
} else {
if ( mico_bt_ble_update_background_connection_device( MICO_FALSE, device_address ) != TRUE ) {
return kGeneralErr;
}
}
return kNoErr;
}
OSStatus smartbridge_bt_interface_get_background_connection_device_size( uint8_t *size )
{
OSStatus status = kNoErr;
if (TRUE != mico_bt_ble_get_background_connection_device_size(size)) {
status = kGeneralErr;
}
return status;
}
OSStatus smartbridge_bt_interface_set_background_connection_type(mico_bt_smartbridge_auto_connection_type_t type,
const mico_bt_smart_scan_settings_t *settings, mico_bt_smartbridge_auto_connection_parms_cback_t p_select_cback)
{
OSStatus status = kNoErr;
mico_bt_ble_conn_type_t conn_type;
switch (type) {
case SMARTBRIDGE_CONN_AUTO:
conn_type = BTM_BLE_CONN_AUTO;
break;
case SMARTBRIDGE_CONN_SELECTIVE:
conn_type = BTM_BLE_CONN_SELECTIVE;
break;
case SMARTBRIDGE_CONN_NONE:
conn_type = BTM_BLE_CONN_NONE;
break;
default:
return kParamErr;
}
/* fill with the settings provided by the smartbridge-application */
if (settings != NULL) {
mico_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval;
} else {
/* Used the default. */
}
if (!mico_bt_ble_set_background_connection_type(conn_type, *(mico_bt_ble_selective_conn_cback_t *)p_select_cback)) {
status = kGeneralErr;
}
return status;
}
OSStatus smartbridge_bt_interface_cancel_last_connect( mico_bt_device_address_t address )
{
return mico_bt_gatt_cancel_connect( address, MICO_TRUE );
}
OSStatus smartbridge_bt_interface_set_connection_tx_power( uint16_t connection_handle, int8_t transmit_power_dbm )
{
return MICO_BT_UNSUPPORTED;
}
mico_bool_t smartbridge_bt_interface_is_scanning( void )
{
mico_bt_ble_scan_type_t scan_type;
scan_type = mico_bt_ble_get_current_scan_state();
if ( scan_type != BTM_BLE_SCAN_TYPE_NONE ) {
return MICO_TRUE;
}
return MICO_FALSE;
}
OSStatus smartbridge_bt_interface_set_max_concurrent_connections( uint8_t count )
{
/* Just update the Stack's configuration settings */
mico_bt_cfg_settings.max_simultaneous_links = count;
mico_bt_cfg_settings.gatt_cfg.client_max_links = count;
return MICO_BT_SUCCESS;
}
OSStatus smartbridge_bt_interface_stop_scan( )
{
app_scan_complete_callback = NULL;
app_scan_report_callback = NULL;
return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_NONE, MICO_TRUE, smartbridge_scan_result_callback );
}
OSStatus smartbridge_bt_interface_start_scan( const mico_bt_smart_scan_settings_t *settings,
mico_bt_smart_scan_complete_callback_t complete_callback,
mico_bt_smart_advertising_report_callback_t advertising_report_callback )
{
mico_bool_t duplicate_filter_enabled = MICO_FALSE;
/* First delete the previous scan result list */
smartbridge_helper_delete_scan_result_list();
/* fill with the settings provided by the smartbridge-application */
mico_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_duration = settings->duration_second;
mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval;
mico_bt_cfg_settings.ble_scan_cfg.scan_filter_policy = settings->filter_policy;
duplicate_filter_enabled = settings->filter_duplicates;
app_scan_complete_callback = complete_callback;
app_scan_report_callback = advertising_report_callback;
return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_HIGH_DUTY, duplicate_filter_enabled, smartbridge_scan_result_callback );
}
OSStatus smartbridge_bt_interface_connect( const mico_bt_smart_device_t *remote_device,
const mico_bt_smart_connection_settings_t *settings,
mico_bt_smartbridge_disconnection_callback_t disconnection_callback,
mico_bt_smartbridge_notification_callback_t notification_callback )
{
mico_bool_t gatt_connect_result;
UNUSED_PARAMETER(disconnection_callback);
UNUSED_PARAMETER(notification_callback);
/* Update the Stack's configuration */
mico_bt_cfg_settings.ble_scan_cfg.conn_min_interval = settings->interval_min;
mico_bt_cfg_settings.ble_scan_cfg.conn_max_interval = settings->interval_max;
mico_bt_cfg_settings.ble_scan_cfg.conn_latency = settings->latency;
mico_bt_cfg_settings.ble_scan_cfg.conn_supervision_timeout = settings->supervision_timeout;
/* Send connection request */
gatt_connect_result = mico_bt_gatt_le_connect( (uint8_t *)remote_device->address, remote_device->address_type,
BLE_CONN_MODE_HIGH_DUTY, MICO_TRUE);
bt_smartbridge_log( "LE-connect, result:%d", gatt_connect_result );
return gatt_connect_result;
}
OSStatus smartbridge_bt_interface_disconnect( uint16_t connection_handle )
{
/* First delete the previous scan result list */
smartbridge_helper_delete_scan_result_list();
return mico_bt_gatt_disconnect( connection_handle );
}

View file

@ -0,0 +1,127 @@
#pragma once
/** @file
* Smartbridge's Interface Header with Bluetooth Stack
*/
//#include "mico_utilities.h"
#include "mico_bt_smartbridge.h"
#include "mico_bt_smart_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
#define ATT_DEFAULT_MTU (23)
#define ATT_STANDARD_VALUE_LENGTH (ATT_DEFAULT_MTU - 3)
#define ATT_STANDARD_TIMEOUT (500)
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/**
* SmartBridge background connection type
*/
typedef enum {
SMARTBRIDGE_CONN_NONE, /**< No background connection */
SMARTBRIDGE_CONN_AUTO, /**< Auto connection */
SMARTBRIDGE_CONN_SELECTIVE /**< Selective connection */
} mico_bt_smartbridge_auto_connection_type_t;
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
OSStatus smartbridge_bt_interface_initialize( void );
OSStatus smartbridge_bt_interface_deinitialize( void );
OSStatus smartbridge_bt_interface_stop_scan( void );
OSStatus smartbridge_bt_interface_start_scan( const mico_bt_smart_scan_settings_t *setting,
mico_bt_smart_scan_complete_callback_t complete_callback,
mico_bt_smart_advertising_report_callback_t advertising_report_callback );
mico_bool_t smartbridge_bt_interface_is_scanning( void );
OSStatus smartbridge_bt_interface_connect( const mico_bt_smart_device_t *remote_device,
const mico_bt_smart_connection_settings_t *settings,
mico_bt_smartbridge_disconnection_callback_t disconnection_callback,
mico_bt_smartbridge_notification_callback_t notification_callback );
OSStatus smartbridge_bt_interface_cancel_last_connect( mico_bt_device_address_t address );
OSStatus smartbridge_bt_interface_disconnect( uint16_t connection_handle );
OSStatus smartbridge_bt_interface_update_background_connection_device( mico_bool_t add,
mico_bt_device_address_t device_address );
OSStatus smartbridge_bt_interface_get_background_connection_device_size( uint8_t *size );
OSStatus smartbridge_bt_interface_set_background_connection_type(mico_bt_smartbridge_auto_connection_type_t type,
const mico_bt_smart_scan_settings_t *settings, mico_bt_smartbridge_auto_connection_parms_cback_t );
OSStatus smartbridge_bt_interface_set_attribute_timeout( uint32_t timeout_seconds );
OSStatus smartbridge_bt_interface_set_connection_tx_power( uint16_t connection_handle, int8_t transmit_power_dbm );
OSStatus smartbridge_bt_interface_set_max_concurrent_connections( uint8_t count );
OSStatus smartbridge_bt_interface_discover_all_primary_services( uint16_t connection_handle,
mico_bt_smart_attribute_list_t *service_list );
OSStatus smartbridge_bt_interface_discover_all_characteristics_in_a_service( uint16_t connection_handle,
uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *characteristic_list );
OSStatus smartbridge_bt_interface_discover_all_characteristic_descriptors( uint16_t connection_handle,
uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *no_value_descriptor_list );
OSStatus smartbridge_bt_interface_discover_primary_services_by_uuid( uint16_t connection_handle,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *service_list );
OSStatus smartbridge_bt_interface_find_included_services( uint16_t connection_handle, uint16_t start_handle,
uint16_t end_handle, mico_bt_smart_attribute_list_t *include_list );
OSStatus smartbridge_bt_interface_discover_characteristic_by_uuid( uint16_t connection_handle,
const mico_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle,
mico_bt_smart_attribute_list_t *characteristic_list );
OSStatus smartbridge_bt_interface_read_characteristic_value( uint16_t connection_handle, uint16_t handle,
const mico_bt_uuid_t *type, mico_bt_smart_attribute_t **characteristic_value );
OSStatus smartbridge_bt_interface_read_long_characteristic_value( uint16_t connection_handle, uint16_t handle,
const mico_bt_uuid_t *type, mico_bt_smart_attribute_t **characteristic_value );
OSStatus smartbridge_bt_interface_read_characteristic_descriptor( uint16_t connection_handle, uint16_t handle,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor );
OSStatus smartbridge_bt_interface_read_long_characteristic_descriptor( uint16_t connection_handle, uint16_t handle,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor );
OSStatus smartbridge_bt_interface_read_characteristic_values_using_uuid( uint16_t connection_handle,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *characteristic_value_list );
OSStatus smartbridge_bt_interface_write_characteristic_value( uint16_t connection_handle,
mico_bt_smart_attribute_t *attribute );
OSStatus smartbridge_bt_interface_write_long_characteristic_value( uint16_t connection_handle,
mico_bt_smart_attribute_t *attribute );
OSStatus smartbridge_bt_interface_write_long_characteristic_descriptor( uint16_t connection_handle,
const mico_bt_smart_attribute_t *descriptor );
OSStatus smartbridge_bt_interface_write_characteristic_descriptor( uint16_t connection_handle,
mico_bt_smart_attribute_t *attribute );
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,675 @@
/** @file
*
*/
#include "mico.h"
#include "mico_bt.h"
#include "mico_bt_smartbridge_constants.h"
#include "mico_bt_smartbridge.h"
#include "mico_bt_types.h"
#include "mico_bt_stack.h"
#ifdef BT_MFGTEST_MODE
#include "bt_mfgtest.h"
#endif
#include "bt_smartbridge_helper.h"
#include "bt_smartbridge_stack_interface.h"
#include "bt_smartbridge_socket_manager.h"
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/* Stack size and Queue size for BT Worker Thread */
#define MICO_BT_WORKER_THREAD_STACK_SIZE (3 * 1024)
#define MICO_BT_WORKER_THREAD_QUEUE_SIZE 15
/* Stack size and Queue size for BT Event Worker thread */
#define MICO_BT_EVT_WORKER_THREAD_STACK_SIZE (3 * 1024)
#define MICO_BT_EVT_WORKER_THREAD_QUEUE_SIZE 15
#define BT_DEVICE_NAME_MAX_LENGTH 21
/* Encryption enabled, no pairing requested because device is already paired */
#define INTERNAL_SECURITY_LEVEL ( 1 )
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Static Function Declarations
******************************************************/
static mico_bt_dev_status_t smartbridge_bt_stack_management_callback ( mico_bt_management_evt_t event,
mico_bt_management_evt_data_t *p_event_data );
/******************************************************
* Variable Definitions
******************************************************/
mico_worker_thread_t mico_bt_worker_thread;
mico_worker_thread_t mico_bt_evt_worker_thread;
mico_bt_local_identity_keys_t local_identity_keys;
mico_bt_device_sec_keys_t device_link_keys;
mico_bool_t device_link_key_updated = MICO_FALSE;
extern mico_bt_cfg_settings_t mico_bt_cfg_settings;
extern mico_bt_dev_ble_io_caps_req_t default_io_caps_ble;
extern mico_bt_smartbridge_socket_t *connecting_socket;
extern mico_bt_peripheral_socket_t *connecting_peripheral_socket;
extern const mico_bt_cfg_buf_pool_t mico_bt_cfg_buf_pools[];
static char bt_device_name[BT_DEVICE_NAME_MAX_LENGTH + 1] = { 0 };
mico_bool_t bt_initialised = MICO_FALSE;
static mico_semaphore_t wait_bt_initialised_sem = NULL;
static mico_bt_device_address_t bt_address = { 0 };
extern void peripheral_bt_interface_advertisements_state_change_callback( mico_bt_ble_advert_mode_t state );
extern void smartbridge_auto_connection_encryption_check(const mico_bt_dev_pairing_cplt_t *p_event_data);
/******************************************************
* Function Definitions
******************************************************/
OSStatus mico_bt_init( mico_bt_mode_t mode, const char *device_name, uint8_t client_links, uint8_t server_links )
{
OSStatus result = MICO_BT_SUCCESS;
if ( bt_initialised == MICO_TRUE ) {
return MICO_BT_SUCCESS;
}
bt_manager_log( "Initializing Bluetooth" );
if ( mode == MICO_BT_MPAF_MODE ) {
bt_manager_log( "Error. MPAF-mode is not supported" );
return MICO_BT_UNSUPPORTED;
}
/* Create the BT Woker thread */
result = mico_rtos_create_worker_thread(MICO_BT_WORKER_THREAD,
MICO_APPLICATION_PRIORITY,
MICO_BT_WORKER_THREAD_STACK_SIZE,
MICO_BT_WORKER_THREAD_QUEUE_SIZE);
if (result != kNoErr) {
bt_smartbridge_log("Error creating BT WORKER THREAD");
goto exit;
}
/* Create the BT Event Woker thread */
result = mico_rtos_create_worker_thread(MICO_BT_EVT_WORKER_THREAD,
MICO_APPLICATION_PRIORITY,
MICO_BT_EVT_WORKER_THREAD_STACK_SIZE,
MICO_BT_EVT_WORKER_THREAD_QUEUE_SIZE);
if (result != kNoErr) {
bt_smartbridge_log("Error create BT EVT WORKER THREAD");
goto err1;
}
/* Initialise Bluetooth Stack */
wait_bt_initialised_sem = NULL;
mico_rtos_init_semaphore( &wait_bt_initialised_sem, 1 );
mico_bt_cfg_settings.device_name = (uint8_t *)device_name;
mico_bt_cfg_settings.max_simultaneous_links = client_links + server_links;
mico_bt_cfg_settings.gatt_cfg.client_max_links = client_links;
mico_bt_cfg_settings.gatt_cfg.server_max_links = server_links;
result = mico_bt_stack_init( smartbridge_bt_stack_management_callback, &mico_bt_cfg_settings, mico_bt_cfg_buf_pools );
if ( result != MICO_BT_SUCCESS ) {
bt_smartbridge_log( "Error initialising Bluetooth stack" );
goto err2;
}
mico_rtos_get_semaphore( &wait_bt_initialised_sem, MICO_NEVER_TIMEOUT );
mico_rtos_deinit_semaphore( &wait_bt_initialised_sem );
mico_bt_dev_read_local_addr( bt_address );
memset( bt_device_name, 0, sizeof( bt_device_name ) );
memcpy( bt_device_name, device_name, strnlen( device_name, BT_DEVICE_NAME_MAX_LENGTH ) );
mico_rtos_delay_milliseconds(10);
result = MICO_BT_SUCCESS;
goto exit;
err2:
mico_rtos_deinit_semaphore( &wait_bt_initialised_sem );
mico_rtos_delete_worker_thread(MICO_BT_EVT_WORKER_THREAD);
err1:
mico_rtos_delete_worker_thread(MICO_BT_WORKER_THREAD);
exit:
return result;
}
OSStatus mico_bt_deinit( void )
{
OSStatus result;
if ( bt_initialised == MICO_FALSE ) {
return MICO_BT_SUCCESS;
}
result = mico_bt_stack_deinit( );
if ( result != MICO_BT_SUCCESS ) {
bt_manager_log( "Error de-initialising Bluetooth stack" );
return result;
}
mico_rtos_delete_worker_thread(MICO_BT_WORKER_THREAD);
mico_rtos_delete_worker_thread(MICO_BT_EVT_WORKER_THREAD);
memset( bt_device_name, 0, sizeof( bt_device_name ) );
bt_initialised = MICO_FALSE;
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_init_address( const mico_bt_device_address_t *address, const mico_bt_device_address_t *mask )
{
UNUSED_PARAMETER(address);
UNUSED_PARAMETER(mask);
return MICO_BT_UNSUPPORTED;
}
OSStatus mico_bt_start_mfgtest_mode( const mico_uart_config_t *config )
{
#ifdef BT_MFGTEST_MODE
OSStatus result = bt_bus_init();
if ( result != MICO_BT_SUCCESS ) {
bt_manager_log( "Error initialising Bluetooth transport bus" );
return result;
}
return bt_mfgtest_start( config );
#else
return MICO_BT_UNSUPPORTED;
#endif
}
OSStatus mico_bt_device_get_address( mico_bt_device_address_t *address )
{
if ( bt_initialised == MICO_FALSE ) {
return MICO_BT_ERROR;
}
memcpy( address, &bt_address, sizeof( *address ) );
return MICO_BT_SUCCESS;
}
const char *mico_bt_device_get_name( void )
{
/* TODO: bt_device_name is not provided to Stack/Controller. Once it is provided to the Stack
* correctly, we should rather read the name of the device from the Stack */
return (const char *)bt_device_name;
}
mico_bool_t mico_bt_device_is_on( void )
{
/* TODO: Need to be implemented again as per the new Stack */
return MICO_FALSE;
}
mico_bool_t mico_bt_device_is_connectable( void )
{
/* TODO : Need to be implemented for the new-stack */
return MICO_FALSE;
}
mico_bool_t mico_bt_device_is_discoverable( void )
{
/* TODO : Need to be implemented for the new-stack */
return MICO_FALSE;
}
OSStatus mico_bt_start_pairing( mico_bt_device_address_t address, mico_bt_smart_address_type_t type,
const mico_bt_smart_security_settings_t *settings )
{
OSStatus err = kNoErr;
uint8_t integer_passkey[4] = { 0 };
/* update the security settings as per passed by the application */
default_io_caps_ble.local_io_cap = settings->io_capabilities;
default_io_caps_ble.auth_req = settings->authentication_requirements;
default_io_caps_ble.oob_data = settings->oob_authentication;
default_io_caps_ble.max_key_size = settings->max_encryption_key_size;
default_io_caps_ble.init_keys = settings->master_key_distribution;
default_io_caps_ble.resp_keys = settings->slave_key_distribution;
err = mico_bt_dev_sec_bond( address, type, BT_TRANSPORT_LE, 4, integer_passkey );
bt_manager_log( "mico_bt_start_pairing, ret = %d", err );
return err;
}
OSStatus mico_bt_stop_pairing( mico_bt_device_address_t address )
{
OSStatus err = kNoErr;
err = mico_bt_dev_sec_bond_cancel( address );
bt_manager_log( "mico_bt_stop_pairing, ret = %d", err );
return err;
}
OSStatus mico_bt_start_encryption( mico_bt_device_address_t *address )
{
OSStatus err = kNoErr;
uint32_t security_level = INTERNAL_SECURITY_LEVEL;
err = mico_bt_dev_set_encryption( *address, BT_TRANSPORT_LE, &security_level );
bt_manager_log( "mico_bt_start_encryption, ret = %d", err );
return err;
}
OSStatus mico_bt_clear_whitelist( void )
{
if ( TRUE != mico_bt_ble_clear_white_list( ) ) {
return kGeneralErr;
}
return kNoErr;
}
OSStatus mico_bt_get_whitelist_capability( uint8_t *size )
{
if ( size == (uint8_t *)0 ) {
return kGeneralErr;
}
if ( TRUE != mico_bt_ble_get_white_list_capability( size ) ) {
return kGeneralErr;
}
return kNoErr;
}
static mico_bt_dev_status_t smartbridge_bt_stack_management_callback( mico_bt_management_evt_t event,
mico_bt_management_evt_data_t *p_event_data )
{
mico_bt_dev_status_t status = MICO_BT_SUCCESS;
BD_ADDR address;
switch (event) {
case BTM_ENABLED_EVT: {
/* Initialize GATT REST API Server once Bluetooth controller and host stack is enabled */
if ( ( status = p_event_data->enabled.status ) == MICO_BT_SUCCESS ) {
mico_bt_dev_read_local_addr(address);
bt_manager_log( "Local Bluetooth Address: [%02X:%02X:%02X:%02X:%02X:%02X]", address[0], address[1], address[2],
address[3], address[4], address[5] );
/* Register for GATT event notifications */
bt_initialised = MICO_TRUE;
if ( wait_bt_initialised_sem ) {
mico_rtos_set_semaphore( &wait_bt_initialised_sem );
}
}
break;
}
case BTM_SECURITY_REQUEST_EVT: {
bt_manager_log( "Security grant request" );
mico_bt_ble_security_grant( p_event_data->security_request.bd_addr, MICO_BT_SUCCESS );
break;
}
case BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT: {
memcpy(&local_identity_keys, &p_event_data->local_identity_keys_update, sizeof( mico_bt_local_identity_keys_t ) );
bt_manager_log( "Local Identity Keys Update type:%u", local_identity_keys.local_key_data[0] );
break;
}
case BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT: {
memcpy( &p_event_data->local_identity_keys_request , &local_identity_keys, sizeof(mico_bt_local_identity_keys_t) );
bt_manager_log( "Local Identity Keys Request Event" );
break;
}
case BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT: {
bt_manager_log( "Paired Device Link Keys Update Event" );
memcpy(&device_link_keys, &p_event_data->paired_device_link_keys_request.key_data, sizeof(mico_bt_device_sec_keys_t));
device_link_key_updated = MICO_TRUE;
break;
}
case BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT: {
bt_manager_log( "Paired Device Link Keys Request Event" );
if ( device_link_key_updated == MICO_TRUE ) {
memcpy( &p_event_data->paired_device_link_keys_request.key_data, &device_link_keys, sizeof(mico_bt_device_sec_keys_t));
return MICO_BT_SUCCESS;
}
status = MICO_BT_ERROR;
break;
}
case BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT: {
bt_manager_log( "Pairing IO capabilities Request Event" );
/* Peer requested for I/O capabilities. Copy local I/O caps to stack */
bt_smartbridge_log( "Getting local I/O capabilities" );
p_event_data->pairing_io_capabilities_ble_request.local_io_cap = default_io_caps_ble.local_io_cap;
p_event_data->pairing_io_capabilities_ble_request.oob_data = default_io_caps_ble.oob_data;
p_event_data->pairing_io_capabilities_ble_request.auth_req = default_io_caps_ble.auth_req;
p_event_data->pairing_io_capabilities_ble_request.max_key_size = default_io_caps_ble.max_key_size;
p_event_data->pairing_io_capabilities_ble_request.init_keys = default_io_caps_ble.init_keys;
p_event_data->pairing_io_capabilities_ble_request.resp_keys = default_io_caps_ble.resp_keys;
break;
}
case BTM_PAIRING_COMPLETE_EVT: {
bt_manager_log( "Pairing complete status=%i, reason=0x%x.",
p_event_data->pairing_complete.pairing_complete_info.ble.status,
p_event_data->pairing_complete.pairing_complete_info.ble.reason );
if ( p_event_data->pairing_complete.pairing_complete_info.ble.status == MICO_BT_SUCCESS ) {
}
/* Notify app thread that pairing is complete, regardless of */
if ( connecting_socket &&
memcmp( p_event_data->pairing_complete.bd_addr, connecting_socket->remote_device.address, BD_ADDR_LEN ) == 0 ) {
if ( smartbridge_helper_socket_check_actions_enabled( connecting_socket,
SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ) {
if ( connecting_socket->semaphore ) {
mico_rtos_set_semaphore( &connecting_socket->semaphore );
}
}
}
if ( connecting_peripheral_socket &&
memcmp( p_event_data->pairing_complete.bd_addr, connecting_peripheral_socket->remote_device.address,
BD_ADDR_LEN ) == 0 ) {
if ( peripheral_helper_socket_check_actions_enabled( connecting_peripheral_socket,
SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ) {
if ( connecting_peripheral_socket->semaphore ) {
mico_rtos_set_semaphore( &connecting_peripheral_socket->semaphore );
}
}
}
break;
}
case BTM_ENCRYPTION_STATUS_EVT: {
bt_manager_log( "encryption status = %i", p_event_data->encryption_status.result );
if ( p_event_data->encryption_status.result == MICO_BT_SUCCESS ) {
/* Update state of the socket to encrypted */
if ( connecting_socket ) {
connecting_socket->state = SOCKET_STATE_LINK_ENCRYPTED;
}
if ( connecting_peripheral_socket ) {
connecting_peripheral_socket->state = SOCKET_STATE_LINK_ENCRYPTED;
}
}
/* Notify app thread that pairing is complete, regardless of */
if ( connecting_socket &&
memcmp( p_event_data->pairing_complete.bd_addr, connecting_socket->remote_device.address, BD_ADDR_LEN ) == 0 ) {
if ( smartbridge_helper_socket_check_actions_enabled( connecting_socket,
SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ||
smartbridge_helper_socket_check_actions_enabled( connecting_socket,
SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ) == MICO_TRUE ) {
if ( connecting_socket->semaphore ) {
mico_rtos_set_semaphore( &connecting_socket->semaphore );
}
}
}
if ( connecting_peripheral_socket &&
memcmp( p_event_data->pairing_complete.bd_addr, connecting_peripheral_socket->remote_device.address,
BD_ADDR_LEN ) == 0 ) {
if ( peripheral_helper_socket_check_actions_enabled( connecting_peripheral_socket,
SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ||
peripheral_helper_socket_check_actions_enabled( connecting_peripheral_socket,
SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ) == MICO_TRUE ) {
if ( connecting_peripheral_socket->semaphore ) {
mico_rtos_set_semaphore( &connecting_peripheral_socket->semaphore );
}
}
break;
}
/* Auto connection encryption completed. */
smartbridge_auto_connection_encryption_check(&p_event_data->pairing_complete);
break;
}
case BTM_BLE_SCAN_STATE_CHANGED_EVT: {
bt_manager_log( "Scan state changed: %d", p_event_data->ble_scan_state_changed );
break;
}
case BTM_BLE_ADVERT_STATE_CHANGED_EVT: {
bt_manager_log( "Advertisement state changed: %d", p_event_data->ble_advert_state_changed );
peripheral_bt_interface_advertisements_state_change_callback( p_event_data->ble_advert_state_changed );
break;
}
case BTM_PASSKEY_NOTIFICATION_EVT: {
bt_manager_log("Passkey Notification event( PassKey generated is: %u )",
(unsigned int)p_event_data->user_passkey_notification.passkey );
/* Smartbridge socket */
if (connecting_socket
&& memcmp(p_event_data->user_passkey_notification.bd_addr,
connecting_socket->remote_device.address,
BD_ADDR_LEN) == 0) {
if (connecting_socket->bonding_callback
&& smartbridge_helper_socket_check_actions_enabled(connecting_socket, SOCKET_ACTION_INITIATE_PAIRING)) {
connecting_socket->bond_req.type = MICO_BT_SMART_BOND_PASS_KEY_NOTIFY;
connecting_socket->bond_req.u.notify.passkey = p_event_data->user_passkey_notification.passkey;
memcpy(connecting_socket->bond_req.u.notify.addr, p_event_data->user_passkey_notification.bd_addr, 6);
mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)connecting_socket->bonding_callback,
(void *)&connecting_socket->bond_req);
}
}
/* Smart Peripheral Socket */
if (connecting_peripheral_socket
&& memcmp(p_event_data->user_passkey_notification.bd_addr,
connecting_peripheral_socket->remote_device.address,
BD_ADDR_LEN) == 0) {
if (connecting_peripheral_socket->bonding_callback
&& peripheral_helper_socket_check_actions_enabled(connecting_peripheral_socket, SOCKET_ACTION_INITIATE_PAIRING)) {
connecting_peripheral_socket->bond_req.type = MICO_BT_SMART_BOND_PASS_KEY_NOTIFY;
connecting_peripheral_socket->bond_req.u.notify.passkey = p_event_data->user_passkey_notification.passkey;
memcpy(connecting_peripheral_socket->bond_req.u.notify.addr, p_event_data->user_passkey_notification.bd_addr, 6);
mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)connecting_peripheral_socket->bonding_callback,
(void *)&connecting_peripheral_socket->bond_req);
}
}
break;
}
case BTM_PASSKEY_REQUEST_EVT: {
bt_manager_log("Passkey Request event: dev[%02x:%02x:%02x:%02x:%02x:%02x]" ,
p_event_data->user_passkey_request.bd_addr[0],
p_event_data->user_passkey_request.bd_addr[1],
p_event_data->user_passkey_request.bd_addr[2],
p_event_data->user_passkey_request.bd_addr[3],
p_event_data->user_passkey_request.bd_addr[4],
p_event_data->user_passkey_request.bd_addr[5]);
if (connecting_socket
&& memcmp(p_event_data->user_passkey_request.bd_addr,
connecting_socket->remote_device.address,
BD_ADDR_LEN) == 0) {
if (connecting_socket->bonding_callback
&& smartbridge_helper_socket_check_actions_enabled(connecting_socket, SOCKET_ACTION_INITIATE_PAIRING)) {
connecting_socket->bond_req.type = MICO_BT_SMART_BOND_PASS_KEY_REQ;
memcpy(connecting_socket->bond_req.u.passkey.addr, p_event_data->user_passkey_request.bd_addr, 6);
mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)connecting_socket->bonding_callback,
(void *)&connecting_socket->bond_req);
} else {
mico_bt_dev_pass_key_req_reply(MICO_BT_ERROR, p_event_data->user_passkey_request.bd_addr, 0);
}
}
if (connecting_peripheral_socket
&& memcmp(p_event_data->user_passkey_request.bd_addr,
connecting_peripheral_socket->remote_device.address,
BD_ADDR_LEN) == 0) {
if (connecting_peripheral_socket->bonding_callback
&& peripheral_helper_socket_check_actions_enabled(connecting_peripheral_socket, SOCKET_ACTION_INITIATE_PAIRING)) {
connecting_peripheral_socket->bond_req.type = MICO_BT_SMART_BOND_PASS_KEY_REQ;
memcpy(connecting_peripheral_socket->bond_req.u.passkey.addr, p_event_data->user_passkey_request.bd_addr, 6);
mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)connecting_peripheral_socket->bonding_callback,
(void *)&connecting_peripheral_socket->bond_req);
} else {
mico_bt_dev_pass_key_req_reply(MICO_BT_ERROR, p_event_data->user_passkey_request.bd_addr, 0);
}
}
break;
}
case BTM_USER_CONFIRMATION_REQUEST_EVT: {
bt_manager_log("User Confirm Request Event: dev[%02x:%02x:%02x:%02x:%02x:%02x], numeric_value[%lu], %s",
p_event_data->user_confirmation_request.bd_addr[0],
p_event_data->user_confirmation_request.bd_addr[1],
p_event_data->user_confirmation_request.bd_addr[2],
p_event_data->user_confirmation_request.bd_addr[3],
p_event_data->user_confirmation_request.bd_addr[4],
p_event_data->user_confirmation_request.bd_addr[5],
p_event_data->user_confirmation_request.numeric_value,
p_event_data->user_confirmation_request.just_works ? "Just works" : "Not Just works");
if (connecting_socket
&& memcmp(p_event_data->user_confirmation_request.bd_addr,
connecting_socket->remote_device.address,
BD_ADDR_LEN) == 0) {
if (connecting_socket->bonding_callback
&& smartbridge_helper_socket_check_actions_enabled(connecting_socket, SOCKET_ACTION_INITIATE_PAIRING)) {
connecting_socket->bond_req.type = MICO_BT_SMART_BOND_USR_CONFIRM_REQ;
connecting_socket->bond_req.u.confirm.passkey = p_event_data->user_confirmation_request.numeric_value;
memcpy(connecting_socket->bond_req.u.confirm.addr, p_event_data->user_confirmation_request.bd_addr, 6);
mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)connecting_socket->bonding_callback,
(void *)&connecting_socket->bond_req);
} else {
mico_bt_dev_confirm_req_reply(MICO_BT_ERROR, p_event_data->user_confirmation_request.bd_addr);
}
}
if (connecting_peripheral_socket
&& memcmp(p_event_data->user_confirmation_request.bd_addr,
connecting_peripheral_socket->remote_device.address,
BD_ADDR_LEN) == 0) {
if (connecting_peripheral_socket->bonding_callback
&& peripheral_helper_socket_check_actions_enabled(connecting_peripheral_socket, SOCKET_ACTION_INITIATE_PAIRING)) {
connecting_peripheral_socket->bond_req.type = MICO_BT_SMART_BOND_USR_CONFIRM_REQ;
connecting_peripheral_socket->bond_req.u.confirm.passkey = p_event_data->user_confirmation_request.numeric_value;
memcpy(connecting_peripheral_socket->bond_req.u.confirm.addr, p_event_data->user_confirmation_request.bd_addr, 6);
mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)connecting_peripheral_socket->bonding_callback,
(void *)&connecting_peripheral_socket->bond_req);
} else {
mico_bt_dev_confirm_req_reply(MICO_BT_ERROR, p_event_data->user_confirmation_request.bd_addr);
}
}
break;
}
#if (BTM_OOB_INCLUDED == TRUE)
case BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT: {
bt_manager_log( "OOB DATA Request event: dev[%02x:%02x:%02x:%02x:%02x:%02x]",
p_event_data->smp_remote_oob_data_request.bd_addr[0],
p_event_data->smp_remote_oob_data_request.bd_addr[1],
p_event_data->smp_remote_oob_data_request.bd_addr[2],
p_event_data->smp_remote_oob_data_request.bd_addr[3],
p_event_data->smp_remote_oob_data_request.bd_addr[4],
p_event_data->smp_remote_oob_data_request.bd_addr[5]);
if (connecting_socket
&& memcmp(p_event_data->smp_remote_oob_data_request.bd_addr,
connecting_socket->remote_device.address,
BD_ADDR_LEN) == 0) {
if (connecting_socket->bonding_callback
&& smartbridge_helper_socket_check_actions_enabled(connecting_socket, SOCKET_ACTION_INITIATE_PAIRING)) {
connecting_socket->bond_req.type = MICO_BT_SMART_BOND_OOB_DATA_REQ;
memcpy(connecting_socket->bond_req.u.oob_data.addr, p_event_data->smp_remote_oob_data_request.bd_addr, 6);
mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)connecting_socket->bonding_callback,
(void *)&connecting_socket->bond_req);
} else {
mico_bt_smp_oob_data_reply(p_event_data->smp_remote_oob_data_request.bd_addr, MICO_BT_ERROR, 0, NULL);
}
}
if (connecting_peripheral_socket
&& memcmp(p_event_data->smp_remote_oob_data_request.bd_addr,
connecting_peripheral_socket->remote_device.address,
BD_ADDR_LEN) == 0) {
if (connecting_peripheral_socket->bonding_callback
&& peripheral_helper_socket_check_actions_enabled(connecting_peripheral_socket, SOCKET_ACTION_INITIATE_PAIRING)) {
connecting_peripheral_socket->bond_req.type = MICO_BT_SMART_BOND_OOB_DATA_REQ;
memcpy(connecting_peripheral_socket->bond_req.u.oob_data.addr, p_event_data->smp_remote_oob_data_request.bd_addr, 6);
mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)connecting_peripheral_socket->bonding_callback,
(void *)&connecting_peripheral_socket->bond_req);
} else {
mico_bt_smp_oob_data_reply(p_event_data->smp_remote_oob_data_request.bd_addr, MICO_BT_ERROR, 0, NULL);
}
}
break;
}
case BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT:
case BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT:
#endif
default:
bt_manager_log( "Unhandled Bluetooth Stack Callback event :%d", event );
break;
}
return status;
}
/** mico_bt_smart_bond_reply
*
* This function is called to reply BLE Bond Event posted by #mico_bt_smart_bonding_callback_t.
* You should fill a strcutre #mico_bt_smart_bond_reply_t to complete this bonding procedure.
*
* @param[in] response the response to current bonding event.
*
* @return OSStatus
*/
OSStatus mico_bt_smart_bond_reply(const mico_bt_smart_bond_reply_t *response)
{
OSStatus err = kNoErr;
if (!response) {
return kParamErr;
}
switch (response->type) {
case MICO_BT_SMART_BOND_PASS_KEY_REQ:
mico_bt_dev_pass_key_req_reply(response->res,
(uint8_t *)response->u.passkey.addr,
response->u.passkey.passkey);
break;
case MICO_BT_SMART_BOND_USR_CONFIRM_REQ:
mico_bt_dev_confirm_req_reply(response->res, (uint8_t *)response->u.confirm.addr);
break;
#if (BTM_OOB_INCLUDED == TRUE)
case MICO_BT_SMART_BOND_OOB_DATA_REQ:
mico_bt_smp_oob_data_reply((uint8_t *)response->u.oob_data.addr,
response->res,
response->u.oob_data.len,
response->u.oob_data.data);
break;
#endif
default:
err = kParamErr;
break;
}
return err;
}

View file

@ -0,0 +1,652 @@
/** @file
*
*/
#include "mico.h"
#include "StringUtils.h"
#include "mico_bt_peripheral.h"
#include "mico_bt_gatt.h"
#include "mico_bt_ble.h"
#include "mico_bt_cfg.h"
#include "mico_bt.h"
#include "bt_smartbridge_socket_manager.h"
#include "bt_smartbridge_helper.h"
#include "bt_peripheral_stack_interface.h"
#include "mico_bt_cfg.h"
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
#define SOCKET_INVALID_CONNECTION_HANDLE ( 0xFFFF )
#define MAX_CONNECTION_TIMEOUT ( 10000 )
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Static Function Declarations
******************************************************/
static OSStatus peripheral_app_connection_handler ( void *arg );
static OSStatus peripheral_app_disconnection_handler ( void *arg );
/******************************************************
* Variable Definitions
******************************************************/
extern gatt_subprocedure_t peripheral_subprocedure;
mico_bt_peripheral_socket_t *peripheral_socket = NULL;
static mico_bool_t initialised = MICO_FALSE;
extern mico_bool_t bt_initialised;
extern mico_bt_dev_ble_io_caps_req_t local_io_caps_ble;
mico_bt_peripheral_socket_t *connecting_peripheral_socket = NULL;
/******************************************************
* Function Definitions
******************************************************/
static void peripheral_gatt_connection_handler( uint16_t connection_handle )
{
bt_peripheral_log( "GATT connection was SUCCESS" );
mico_rtos_send_asynchronous_event( MICO_BT_WORKER_THREAD, peripheral_app_connection_handler,
(void *)peripheral_socket );
}
static void peripheral_gatt_disconnection_handler( uint16_t connection_handle )
{
bt_peripheral_log( "GATT disconnection" );
/* Remove socket from the connected list */
if ( peripheral_socket->connection_handle != SOCKET_INVALID_CONNECTION_HANDLE ) {
/* Reset connection handle to invalid value */
peripheral_socket->connection_handle = SOCKET_INVALID_CONNECTION_HANDLE;
/* Reset socket state */
peripheral_socket->state = SOCKET_STATE_DISCONNECTED;
/* Check if disconnection is from host or remote device */
if ( peripheral_helper_socket_check_actions_enabled( peripheral_socket, SOCKET_ACTION_HOST_DISCONNECT ) == MICO_TRUE ) {
/* Disconnection is originated from the host. Notify app thread that disconnection is complete */
mico_rtos_set_semaphore( &peripheral_socket->semaphore );
} else {
/* Notify app that connection is disconnected by the remote device */
if ( peripheral_socket->disconnection_callback != NULL ) {
mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, peripheral_app_disconnection_handler,
(void *)peripheral_socket );
}
/* If disconnection happens when connection is still being established. Notify app */
if ( connecting_peripheral_socket == peripheral_socket ) {
mico_rtos_set_semaphore( &connecting_peripheral_socket->semaphore );
}
}
} else {
/* If disconnection happens when connection is still being established. Notify app */
if ( connecting_peripheral_socket != NULL ) {
mico_rtos_set_semaphore( &connecting_peripheral_socket->semaphore );
}
}
}
static mico_bt_gatt_status_t peripheral_gatt_read_request_handler( mico_bt_gatt_read_t *request_data )
{
mico_bt_ext_attribute_value_t *attribute;
mico_bt_gatt_status_t status = MICO_BT_GATT_SUCCESS;
// Find characteristic value
if ( mico_bt_peripheral_ext_attribute_find_by_handle( request_data->handle, &attribute ) == kNoErr ) {
/* Invoke attribute_handler before real read request, prepare attribute data if needed */
if ( attribute->attribute_handler != NULL ) {
/* Invock callback only once per attribute read */
if ( request_data->offset == 0 ) { //|| request_data->is_long == MICO_FALSE )
status = ( attribute->attribute_handler )( attribute, GATTS_REQ_TYPE_READ );
}
}
/* Calculate the number of copied bytes */
*(request_data->p_val_len) = MIN( attribute->value_length - request_data->offset, *(request_data->p_val_len) );
/* Copy the attribute value */
if ( *(request_data->p_val_len) ) {
memcpy( request_data->p_val, (void *)((uint8_t *)attribute->p_value + request_data->offset),
*(request_data->p_val_len) );
}
} else {
status = MICO_BT_GATT_READ_NOT_PERMIT;
}
return status;
}
mico_bt_gatt_status_t bt_peripheral_gatt_callback( mico_bt_gatt_evt_t event, mico_bt_gatt_event_data_t *p_event_data )
{
mico_bt_ext_attribute_value_t *attribute;
mico_bt_gatt_status_t status = MICO_BT_GATT_SUCCESS;
switch (event) {
case GATT_CONNECTION_STATUS_EVT: {
if ( p_event_data->connection_status.link_role == BT_SMART_LINK_ROLE_SLAVE ) {
/* Connection */
if ( p_event_data->connection_status.connected == MICO_TRUE ) {
/* Store remote device information */
connecting_peripheral_socket = peripheral_socket;
memcpy( &peripheral_socket->remote_device.address, p_event_data->connection_status.bd_addr, BD_ADDR_LEN );
peripheral_socket->remote_device.address_type = (mico_bt_smart_address_type_t)p_event_data->connection_status.addr_type;
peripheral_socket->connection_handle = p_event_data->connection_status.conn_id;
peripheral_socket->state = SOCKET_STATE_LINK_CONNECTED;
peripheral_gatt_connection_handler( p_event_data->connection_status.conn_id );
} else {
peripheral_gatt_disconnection_handler( p_event_data->connection_status.conn_id );
}
}
break;
}
case GATT_ATTRIBUTE_REQUEST_EVT: {
/* GATT attribute read/write request */
if ( p_event_data->attribute_request.request_type == GATTS_REQ_TYPE_WRITE ) {
if ( p_event_data->attribute_request.data.write_req.is_prep == MICO_TRUE ) {
bt_peripheral_log("Not implement");
break;
}
if ( mico_bt_peripheral_ext_attribute_find_by_handle( p_event_data->attribute_request.data.handle,
&attribute ) == kNoErr ) {
mico_bt_peripheral_ext_attribute_value_write( attribute, p_event_data->attribute_request.data.write_req.val_len,
p_event_data->attribute_request.data.write_req.offset, p_event_data->attribute_request.data.write_req.p_val );
if ( attribute->attribute_handler != NULL ) {
status = (attribute->attribute_handler)( attribute, GATTS_REQ_TYPE_WRITE );
}
} else {
status = MICO_BT_GATT_WRITE_NOT_PERMIT;
}
break;
} else if ( p_event_data->attribute_request.request_type == GATTS_REQ_TYPE_WRITE_EXEC ) {
bt_peripheral_log("Not implement");
break;
} else if ( p_event_data->attribute_request.request_type == GATTS_REQ_TYPE_READ) {
status = peripheral_gatt_read_request_handler( &p_event_data->attribute_request.data.read_req );
break;
} else if ( p_event_data->attribute_request.request_type == GATTS_REQ_TYPE_MTU ) {
bt_peripheral_log("GATT Event: GATTS_REQ_TYPE_MTU, mtu = %d", p_event_data->attribute_request.data.mtu);
\
break;
} else if ( p_event_data->attribute_request.request_type == GATTS_REQ_TYPE_CONF ) {
subprocedure_notify_complete( &peripheral_subprocedure );
break;
}
}
default: {
bt_smartbridge_log( "Gatt callback event:%d", event );
break;
}
}
return status;
}
OSStatus mico_bt_peripheral_init( mico_bt_peripheral_socket_t *socket,
const mico_bt_smart_security_settings_t *settings,
mico_bt_peripheral_connection_callback_t connection_callback,
mico_bt_peripheral_disconnection_callback_t disconnection_callback,
mico_bt_smart_bonding_callback_t bonding_callback )
{
OSStatus result;
if ( initialised == MICO_TRUE ) {
return MICO_BT_SUCCESS;
}
bt_peripheral_log( "Initialising MICO Smart preipheral ..." );
/* Reset socket fields */
memset( socket, 0, sizeof( *socket ) );
socket->connection_handle = SOCKET_INVALID_CONNECTION_HANDLE;
/* Initialise socket semaphore */
result = mico_rtos_init_semaphore( &socket->semaphore, 1 );
require_noerr(result, exit);
/* Initialise callbacks */
socket->connection_callback = connection_callback;
socket->disconnection_callback = disconnection_callback;
socket->bonding_callback = bonding_callback;
/* Reset connection handle to invalid value */
socket->connection_handle = SOCKET_INVALID_CONNECTION_HANDLE;
/* Reset state */
socket->state = SOCKET_STATE_DISCONNECTED;
/* Create service linked-list */
result = linked_list_init( &socket->attribute_database );
require_noerr(result, exit);
/* Set local copies of security settings */
memcpy( &socket->security_settings, settings, sizeof( *settings ) );
peripheral_bt_interface_set_security_settings( settings );
/* Enable security */
if (settings && bonding_callback && settings->authentication_requirements != BT_SMART_AUTH_REQ_NONE) {
peripheral_helper_socket_set_actions(socket, SOCKET_ACTION_INITIATE_PAIRING);
} else {
peripheral_helper_socket_clear_actions(socket, SOCKET_ACTION_INITIATE_PAIRING);
}
peripheral_socket = socket;
/* Initialise bt stack operation interface */
//TODO use a different interface!!!
peripheral_bt_interface_initialize();
initialised = MICO_TRUE;
exit:
return result;
}
OSStatus mico_bt_peripheral_deinit( void )
{
if ( initialised == MICO_FALSE ) {
return MICO_BT_SUCCESS;
}
peripheral_socket = NULL;
/* Uninitialise bt stack operation interface */
//TODO use a different interface!!!
peripheral_bt_interface_deinitialize();
initialised = MICO_FALSE;
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_peripheral_delete_socket( mico_bt_peripheral_socket_t *socket )
{
OSStatus result;
if ( initialised == MICO_FALSE ) {
return MICO_BT_SMART_APPL_UNINITIALISED;
}
result = mico_rtos_deinit_semaphore( &socket->semaphore );
if ( result != MICO_BT_SUCCESS ) {
return result;
}
memset( socket, 0, sizeof( *socket ) );
socket->connection_handle = SOCKET_INVALID_CONNECTION_HANDLE;
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_peripheral_disconnect( void )
{
if ( initialised == MICO_FALSE ) {
return MICO_BT_SMART_APPL_UNINITIALISED;
}
/* Mark disconnection flag that it's coming from the host */
peripheral_helper_socket_set_actions( peripheral_socket, SOCKET_ACTION_HOST_DISCONNECT );
/* Clean-up accidentally set semaphores */
while ( mico_rtos_get_semaphore( &peripheral_socket->semaphore, MICO_NO_WAIT ) == MICO_BT_SUCCESS ) {
}
/* Check if either link is encrypted or connected */
if ( peripheral_socket->state >= SOCKET_STATE_LINK_CONNECTED ) {
peripheral_bt_interface_disconnect( peripheral_socket->connection_handle );
/* Wait for disconnection */
mico_rtos_get_semaphore( &peripheral_socket->semaphore, 5 * 1000 );
} else {
/* Link is not yet connected. Cancel last */
peripheral_bt_interface_cancel_last_connect( peripheral_socket->remote_device.address );
}
/* Clear socket disconnect action */
peripheral_helper_socket_set_actions( peripheral_socket, SOCKET_ACTION_HOST_DISCONNECT );
/* Proper clean-up if socket isn't properly disconnected */
if ( peripheral_socket->state != SOCKET_STATE_DISCONNECTED ) {
/* Reset connection handle to invalid value */
peripheral_socket->connection_handle = SOCKET_INVALID_CONNECTION_HANDLE;
/* Clear socket state */
peripheral_socket->state = SOCKET_STATE_DISCONNECTED;
}
return MICO_BT_SUCCESS;
}
OSStatus mico_bt_peripheral_gatt_indicate_attribute_value ( mico_bt_peripheral_socket_t *socket,
const mico_bt_ext_attribute_value_t *attribute )
{
mico_bt_peripheral_socket_status_t status;
if ( initialised == MICO_FALSE ) {
return MICO_BT_SMART_APPL_UNINITIALISED;
}
if ( socket == NULL || attribute == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_peripheral_get_socket_status( socket, &status );
if ( status != PERIPHERAL_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return peripheral_bt_interface_indicate_attribute_value( socket->connection_handle, attribute );
}
OSStatus mico_bt_peripheral_gatt_notify_attribute_value ( mico_bt_peripheral_socket_t *socket,
const mico_bt_ext_attribute_value_t *attribute )
{
mico_bt_peripheral_socket_status_t status;
if ( initialised == MICO_FALSE ) {
return MICO_BT_SMART_APPL_UNINITIALISED;
}
if ( socket == NULL || attribute == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_peripheral_get_socket_status( socket, &status );
if ( status != PERIPHERAL_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return peripheral_bt_interface_notify_attribute_value( socket->connection_handle, attribute );
}
OSStatus mico_bt_peripheral_start_advertisements( mico_bt_smart_advertising_settings_t *settings,
mico_bt_smart_advertising_complete_callback_t complete_callback)
{
return peripheral_bt_interface_start_advertisements( settings, complete_callback );
}
OSStatus mico_bt_peripheral_stop_advertisements( void )
{
return peripheral_bt_interface_stop_advertisements();
}
OSStatus mico_bt_peripheral_update_advertisements_white_list( mico_bool_t add, mico_bt_device_address_t device_address )
{
if ( initialised == MICO_FALSE ) {
return kNotInitializedErr;
}
return peripheral_bt_interface_update_advertisements_white_list( add, device_address );
}
OSStatus mico_bt_peripheral_get_advertisements_white_list_size( uint8_t *size )
{
if ( initialised == MICO_FALSE ) {
return kNotInitializedErr;
}
if ( size == (uint8_t *)0 ) {
return kParamErr;
}
return peripheral_bt_interface_get_advertisements_white_list_size( size );
}
OSStatus mico_bt_peripheral_set_advertisements_filter_policy( mico_bt_peripheral_adv_filter_policy_t policy )
{
if ( initialised == MICO_FALSE ) {
return kNotInitializedErr;
}
return peripheral_bt_interface_set_advertisements_filter_policy( policy );
}
OSStatus mico_bt_peripheral_get_socket_status( mico_bt_peripheral_socket_t *socket,
mico_bt_peripheral_socket_status_t *status )
{
if ( initialised == MICO_FALSE ) {
return MICO_BT_SMART_APPL_UNINITIALISED;
}
if ( socket->state == SOCKET_STATE_LINK_ENCRYPTED ) {
*status = PERIPHERAL_SOCKET_CONNECTED;
} else if ( socket->state == SOCKET_STATE_LINK_CONNECTED ) {
/* Status is connected if socket does not have loaded bond info and does not initiate pairing */
// if ( smartbridge_helper_socket_check_actions_disabled( server_socket, SOCKET_ACTION_ENCRYPT_USING_BOND_INFO | SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE )
// {
*status = PERIPHERAL_SOCKET_CONNECTED;
// }
// else
// {
// *status = Smart Peripheral_SOCKET_CONNECTING;
// }
} else {
*status = PERIPHERAL_SOCKET_DISCONNECTED;
}
return MICO_BT_SUCCESS;
}
static OSStatus bt_peripheral_get_buffer( void **buffer, uint32_t size )
{
OSStatus err = kNoErr;
require_action( buffer != NULL, exit, err = kParamErr );
/* Allocate buffer object */
*buffer = malloc( size );
require_action( *buffer != NULL, exit, err = kNoMemoryErr);
exit:
return err;
}
static OSStatus bt_peripheral_resize_buffer( void **buffer, uint32_t size )
{
OSStatus err = kNoErr;
require_action( buffer != NULL, exit, err = kParamErr );
/* Allocate buffer object */
*buffer = realloc( *buffer, size );
require_action( *buffer != NULL, exit, err = kNoMemoryErr);
exit:
return err;
}
static OSStatus bt_peripheral_release_buffer( void *buffer )
{
OSStatus err = kNoErr;
require_action( buffer != NULL, exit, err = kParamErr );
free( buffer );
exit:
return err;
}
mico_bt_ext_attribute_value_t *mico_bt_peripheral_ext_attribute_add( uint16_t handle, uint16_t value_length,
const uint8_t *value, mico_bt_peripheral_attribute_handler handler )
{
mico_bt_ext_attribute_value_t *new_attribite = NULL;
OSStatus err = kNoErr;
void *value_buffer;
require_action( initialised == MICO_TRUE, exit, err = kNotInitializedErr );
/* Get buffer */
err = bt_peripheral_get_buffer( (void **)&new_attribite, sizeof( mico_bt_ext_attribute_value_t ) );
require_noerr(err, exit);
/* Copy content to buffer */
new_attribite->handle = handle;
new_attribite->value_length = 0;
new_attribite->value_buffer_length = 0;
new_attribite->p_value = NULL;
new_attribite->attribute_handler = NULL;
/* Allocate buffer for value */
if ( value_length != 0) {
err = bt_peripheral_get_buffer( (void **)&value_buffer, value_length );
require_noerr(err, exit);
memcpy( value_buffer, (void *)value, value_length );
new_attribite->p_value = value_buffer;
new_attribite->value_length = value_length;
new_attribite->value_buffer_length = value_length;
}
if ( handler != NULL ) {
new_attribite->attribute_handler = handler;
}
/* Add to socket */
err = linked_list_insert_node_at_rear( &peripheral_socket->attribute_database, &new_attribite->this_node );
require_noerr_action(err, exit, bt_peripheral_release_buffer( (void *)new_attribite ););
exit:
if ( err != kNoErr && new_attribite ) {
mico_bt_peripheral_ext_attribute_remove( new_attribite );
new_attribite = NULL;
}
return new_attribite;
}
OSStatus mico_bt_peripheral_ext_attribute_remove( mico_bt_ext_attribute_value_t *attribute )
{
OSStatus err = kNoErr;
require_action( initialised == MICO_TRUE, exit, err = kNotInitializedErr );
/* Remove characteristic from service */
err = linked_list_remove_node( &peripheral_socket->attribute_database, &attribute->this_node );
require_noerr( err, exit );
/* Delete value */
if ( attribute->p_value != NULL ) {
err = bt_peripheral_release_buffer( (void *)attribute->p_value );
require_noerr(err, exit);
}
/* Delete characteristic */
err = bt_peripheral_release_buffer( (void *)attribute );
require_noerr(err, exit);
exit:
return err;
}
OSStatus mico_bt_peripheral_ext_attribute_value_write( mico_bt_ext_attribute_value_t *attribute, uint16_t length,
uint16_t offset, const uint8_t *value )
{
OSStatus err = kNoErr;
require_action( initialised == MICO_TRUE, exit, err = kNotInitializedErr );
if ( attribute->p_value == NULL ) {
/* Allocate buffer for value */
err = bt_peripheral_get_buffer( (void **)&attribute->p_value, length + offset );
require_noerr(err, exit);
attribute->value_buffer_length = length + offset;
} else {
if ( ( length + offset ) > attribute->value_buffer_length ) {
err = bt_peripheral_resize_buffer( (void **)&attribute->p_value, length + offset );
require_noerr(err, exit);
attribute->value_buffer_length = length + offset;
}
}
memcpy( attribute->p_value + offset , (void *)value, length );
attribute->value_length = length + offset;
exit:
return err;
}
static bool compare_attribute_by_handle( linked_list_node_t *node_to_compare, void *user_data )
{
mico_bt_ext_attribute_value_t *current_attribute = (mico_bt_ext_attribute_value_t *)node_to_compare;
uint16_t attribute_handle = (uint16_t)( (uint32_t)user_data & 0xffff );
if ( current_attribute->handle == attribute_handle ) {
return true;
} else {
return false;
}
}
OSStatus mico_bt_peripheral_ext_attribute_find_by_handle( uint16_t handle,
mico_bt_ext_attribute_value_t **attribute_found )
{
OSStatus err = kNoErr;
require_action( ( initialised == MICO_TRUE ) && ( attribute_found != NULL ), exit, err = kParamErr );
err = linked_list_find_node( &peripheral_socket->attribute_database, compare_attribute_by_handle,
(void *)( handle & 0xffffffff ), (linked_list_node_t **)attribute_found );
exit:
return err;
}
/******************************************************
* Callback Definitions
******************************************************/
static OSStatus peripheral_app_connection_handler( void *arg )
{
mico_bt_peripheral_socket_t *socket = (mico_bt_peripheral_socket_t *)arg;
/* Performing PAIRING & ENCRYPTION Procedure */
if (peripheral_helper_socket_check_actions_enabled(socket, SOCKET_ACTION_INITIATE_PAIRING)) {
if (mico_bt_dev_find_bonded_device(socket->remote_device.address)) {
mico_bt_start_encryption(&socket->remote_device.address);
} else {
mico_bt_start_pairing(socket->remote_device.address, socket->remote_device.address_type, &socket->security_settings);
mico_rtos_get_semaphore(&socket->semaphore, MICO_NEVER_TIMEOUT);
mico_bt_start_encryption(&socket->remote_device.address);
}
mico_rtos_get_semaphore(&socket->semaphore, MICO_NEVER_TIMEOUT);
}
/* Finished */
connecting_peripheral_socket = NULL;
if ( socket != NULL && socket->connection_callback != NULL ) {
return mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD,
(event_handler_t)socket->connection_callback,
(void *)socket );
}
return MICO_BT_ERROR;
}
static OSStatus peripheral_app_disconnection_handler( void *arg )
{
mico_bt_peripheral_socket_t *socket = (mico_bt_peripheral_socket_t *)arg;
if ( socket != NULL && socket->disconnection_callback != NULL ) {
socket->disconnection_callback( socket );
return MICO_BT_SUCCESS;
}
return MICO_BT_ERROR;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,126 @@
/** @file
*
* Runtime Bluetooth stack configuration parameters
*
*/
#include "mico_bt_cfg.h"
/*****************************************************************************
* BTE stack configuration
****************************************************************************/
mico_bt_cfg_settings_t mico_bt_cfg_settings = {
.device_name = (uint8_t *)"MiCO BT Gateway", /**< Local device name (NULL terminated) */
.device_class = { 0x00, 0x00, 0x00 }, /**< Local device class */
.security_requirement_mask = BTM_SEC_NONE, /**< Security requirements mask (BTM_SEC_NONE, or combination of BTM_SEC_IN_AUTHENTICATE, BTM_SEC_OUT_AUTHENTICATE, BTM_SEC_ENCRYPT (see #mico_bt_sec_level_e)) */
.max_simultaneous_links = 3, /**< Maximum number simultaneous links to different devices */
/* Scan and advertisement configuration */
.br_edr_scan_cfg = /**< BR/EDR scan settings */
{
.inquiry_scan_type = BTM_SCAN_TYPE_STANDARD, /**< Inquiry scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */
.inquiry_scan_interval = MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL, /**< Inquiry scan interval (default: MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL) */
.inquiry_scan_window = MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW, /**< Inquiry scan window (default: MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW) */
.page_scan_type = BTM_SCAN_TYPE_STANDARD, /**< Page scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */
.page_scan_interval = MICO_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL, /**< Page scan interval (default: MICO_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL) */
.page_scan_window = MICO_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW, /**< Page scan window (default: MICO_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW) */
},
.ble_scan_cfg = /**< BLE scan settings */
{
.scan_mode = BTM_BLE_SCAN_MODE_PASSIVE, /**< BLE scan mode (BTM_BLE_SCAN_MODE_PASSIVE, BTM_BLE_SCAN_MODE_ACTIVE) */
.scan_filter_policy = BTM_BLE_SCAN_FILTER_POLICY_NONE,
.high_duty_scan_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL, /**< High duty scan interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL) */
.high_duty_scan_window = MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW, /**< High duty scan window (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW) */
.high_duty_scan_duration = 3, /**< High duty scan duration in seconds (0 for infinite) */
.low_duty_scan_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL, /**< Low duty scan interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL) */
.low_duty_scan_window = MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW, /**< Low duty scan window (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW) */
.low_duty_scan_duration = 3, /**< Low duty scan duration in seconds (0 for infinite) */
.high_duty_conn_scan_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL, /**< High duty cycle connection scan interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL) */
.high_duty_conn_scan_window = MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW, /**< High duty cycle connection scan window (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW) */
.high_duty_conn_duration = 0, /**< High duty cycle connection duration in seconds (0 for infinite) */
.low_duty_conn_scan_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL, /**< Low duty cycle connection scan interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL) */
.low_duty_conn_scan_window = MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW, /**< Low duty cycle connection scan window (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW) */
.low_duty_conn_duration = 0, /**< Low duty cycle connection duration in seconds (0 for infinite) */
.conn_min_interval = MICO_BT_CFG_DEFAULT_CONN_MIN_INTERVAL, /**< Minimum connection interval (default: MICO_BT_CFG_DEFAULT_CONN_MIN_INTERVAL) */
.conn_max_interval = MICO_BT_CFG_DEFAULT_CONN_MAX_INTERVAL, /**< Maximum connection interval (default: MICO_BT_CFG_DEFAULT_CONN_MAX_INTERVAL) */
.conn_latency = MICO_BT_CFG_DEFAULT_CONN_LATENCY, /**< Connection latency (default: MICO_BT_CFG_DEFAULT_CONN_LATENCY) */
.conn_supervision_timeout = MICO_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT, /**< Connection link supervision timeout (default: MICO_BT_CFG_DEFAULT_ CONN_SUPERVISION_TIMEOUT) */
},
.ble_advert_cfg = /**< BLE advertisement settings */
{
.channel_map = ( BTM_BLE_ADVERT_CHNL_37 | BTM_BLE_ADVERT_CHNL_38 | BTM_BLE_ADVERT_CHNL_39 ), /**< Advertising channel map (mask of BTM_BLE_ADVERT_CHNL_37, BTM_BLE_ADVERT_CHNL_38, BTM_BLE_ADVERT_CHNL_39) */
.high_duty_min_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL, /**< High duty undirected connectable advert minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL) */
.high_duty_max_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL, /**< High duty undirected connectable advert maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL) */
.high_duty_duration = 30, /**< High duty advertising duration in seconds (0 for infinite) */
.low_duty_min_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL, /**< Low duty undirected connectable advert minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL) */
.low_duty_max_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL, /**< Low duty undirected connectable advert maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL) */
.low_duty_duration = 30, /**< Low duty advertising duration in seconds (0 for infinite) */
.high_duty_directed_min_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL, /**< high duty directed adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL) */
.high_duty_directed_max_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL, /**< high duty directed adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL) */
.low_duty_directed_min_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL, /**< Low duty directed adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL) */
.low_duty_directed_max_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL, /**< Low duty directed adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL) */
.low_duty_directed_duration = 30, /**< Low duty directed advertising duration in seconds (0 for infinite) */
.high_duty_nonconn_min_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL, /**< High duty non-connectable adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL) */
.high_duty_nonconn_max_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL, /**< High duty non-connectable adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL) */
.high_duty_nonconn_duration = 30, /**< High duty non-connectable advertising duration in seconds (0 for infinite) */
.low_duty_nonconn_min_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL, /**< Low duty non-connectable adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL) */
.low_duty_nonconn_max_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL, /**< Low duty non-connectable adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL) */
.low_duty_nonconn_duration = 30, /**< Low duty non-connectable advertising duration in seconds (0 for infinite) */
},
/* GATT configuration */
.gatt_cfg = /**< GATT settings */
{
.appearance = APPEARANCE_GENERIC_TAG, /**< GATT appearance (see #gatt_appearance_e) */
.client_max_links = 3, /**< Client config: maximum number of servers that local client can connect to */
.server_max_links = 0, /**< Server config: maximum number of remote clients connections allowed by the local */
.max_attr_len = 360, /**< Maximum attribute length; gki_cfg must have a corresponding buffer pool that can hold this length */
},
/* Application managed l2cap protocol configuration */
.rfcomm_cfg =
{
.max_links = 0, /**< Maximum number of simultaneous connected remote devices*/
.max_ports = 0 /**< Maximum number of simultaneous RFCOMM ports */
},
.l2cap_application =
{
.max_links = 0, /**< Maximum number of application-managed l2cap links (BR/EDR and LE) */
/* BR EDR l2cap configuration */
.max_psm = 0, /**< Maximum number of application-managed BR/EDR PSMs */
.max_channels = 0, /**< Maximum number of application-managed BR/EDR channels */
/* LE L2cap connection-oriented channels configuration */
.max_le_psm = 3, /**< Maximum number of application-managed LE PSMs */
.max_le_channels = 3, /**< Maximum number of application-managed LE channels */
},
/* Audio/Video Distribution configuration */
.avdt_cfg =
{
.max_links = 0, /**< Maximum simultaneous audio/video links */
},
/* Audio/Video Remote Control configuration */
.avrc_cfg =
{
.roles = 0, /**< Mask of local roles supported (AVRC_CONN_INITIATOR|AVRC_CONN_ACCEPTOR) */
.max_links = 0 /**< Maximum simultaneous remote control links */
},
.addr_resolution_db_size = 20,
};
/*****************************************************************************
* mico_bt_stack buffer pool configuration
*
* Configure buffer pools used by the stack
*
* Pools must be ordered in increasing buf_size.
* If a pool runs out of buffers, the next pool will be used
*****************************************************************************/
const mico_bt_cfg_buf_pool_t mico_bt_cfg_buf_pools[MICO_BT_CFG_NUM_BUF_POOLS] = {
/* { buf_size, buf_count } */
{ 64, 4 }, /* Small Buffer Pool */
{ 360, 4 }, /* Medium Buffer Pool (used for HCI & RFCOMM control messages, min recommended size is 360) */
{ 360, 12 }, /* Large Buffer Pool (used for HCI ACL messages) */
{ 600, 1 }, /* Extra Large Buffer Pool - Used for avdt media packets and miscellaneous (if not needed, set buf_count to 0) */
};

View file

@ -0,0 +1,333 @@
/** @file
*
*/
#include "mico.h"
#include "mico_bt_smartbridge.h"
#include "mico_bt_smartbridge_gatt.h"
#include "bt_smartbridge_stack_interface.h"
#include "bt_smartbridge_helper.h"
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Static Function Declarations
******************************************************/
/******************************************************
* Variable Definitions
******************************************************/
/******************************************************
* Function Definitions
******************************************************/
OSStatus mico_bt_smartbridge_gatt_discover_all_primary_services( const mico_bt_smartbridge_socket_t *socket,
mico_bt_smart_attribute_list_t *service_list )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || service_list == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_discover_all_primary_services( socket->connection_handle, service_list );
}
OSStatus mico_bt_smartbridge_gatt_discover_primary_services_by_uuid( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *service_list )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || uuid == NULL || service_list == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_discover_primary_services_by_uuid( socket->connection_handle, uuid, service_list );
}
OSStatus mico_bt_smartbridge_gatt_find_included_services( const mico_bt_smartbridge_socket_t *socket,
uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *include_list )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || include_list == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_find_included_services( socket->connection_handle, start_handle, end_handle,
include_list );
}
OSStatus mico_bt_smartbridge_gatt_discover_all_characteristics_in_a_service( const mico_bt_smartbridge_socket_t *socket,
uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *characteristic_list )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || characteristic_list == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_discover_all_characteristics_in_a_service( socket->connection_handle, start_handle,
end_handle, characteristic_list );
}
OSStatus mico_bt_smartbridge_gatt_discover_characteristic_by_uuid( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle,
mico_bt_smart_attribute_list_t *characteristic_list )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || uuid == NULL || characteristic_list == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_discover_characteristic_by_uuid( socket->connection_handle, uuid, start_handle,
end_handle, characteristic_list );
}
OSStatus mico_bt_smartbridge_gatt_discover_handle_and_type_of_all_characteristic_descriptors(
const mico_bt_smartbridge_socket_t *socket, uint16_t start_handle, uint16_t end_handle,
mico_bt_smart_attribute_list_t *descriptor_list )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || descriptor_list == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_discover_all_characteristic_descriptors( socket->connection_handle, start_handle,
end_handle, descriptor_list );
}
OSStatus mico_bt_smartbridge_gatt_read_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket,
uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || uuid == NULL || descriptor == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_read_characteristic_descriptor( socket->connection_handle, handle, uuid, descriptor );
}
OSStatus mico_bt_smartbridge_gatt_read_long_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket,
uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || uuid == NULL || descriptor == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_read_long_characteristic_descriptor( socket->connection_handle, handle, uuid,
descriptor );
}
OSStatus mico_bt_smartbridge_gatt_write_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *descriptor )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || descriptor == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_write_characteristic_descriptor( socket->connection_handle,
(mico_bt_smart_attribute_t *)descriptor );
}
OSStatus mico_bt_smartbridge_gatt_write_long_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *descriptor )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || descriptor == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_write_long_characteristic_descriptor( socket->connection_handle,
(mico_bt_smart_attribute_t *)descriptor );
}
OSStatus mico_bt_smartbridge_gatt_read_characteristic_value( const mico_bt_smartbridge_socket_t *socket,
uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **characteristic_value )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || uuid == NULL || characteristic_value == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_read_characteristic_value( socket->connection_handle, handle, uuid,
characteristic_value );
}
OSStatus mico_bt_smartbridge_gatt_read_characteristic_values_using_uuid( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *characteristic_value_list )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || uuid == NULL || characteristic_value_list == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_read_characteristic_values_using_uuid( socket->connection_handle, uuid,
characteristic_value_list );
}
OSStatus mico_bt_smartbridge_gatt_read_long_characteristic_value( const mico_bt_smartbridge_socket_t *socket,
uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **characteristic_value )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || uuid == NULL || characteristic_value == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_read_long_characteristic_value( socket->connection_handle, handle, uuid,
characteristic_value );
}
OSStatus mico_bt_smartbridge_gatt_write_characteristic_value_without_response( const mico_bt_smartbridge_socket_t
*socket, const mico_bt_smart_attribute_t *characteristic_value )
{
UNUSED_PARAMETER( socket );
UNUSED_PARAMETER( characteristic_value );
return MICO_BT_UNSUPPORTED;
}
OSStatus mico_bt_smartbridge_gatt_signed_write_characteristic_value_without_response(
const mico_bt_smartbridge_socket_t *socket, const mico_bt_smart_attribute_t *characteristic_value )
{
UNUSED_PARAMETER( socket );
UNUSED_PARAMETER( characteristic_value );
return MICO_BT_UNSUPPORTED;
}
OSStatus mico_bt_smartbridge_gatt_write_characteristic_value( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *characteristic_value )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || characteristic_value == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_write_characteristic_value( socket->connection_handle,
(mico_bt_smart_attribute_t *)characteristic_value );
}
OSStatus mico_bt_smartbridge_gatt_write_long_characteristic_value( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *characteristic_value )
{
mico_bt_smartbridge_socket_status_t status;
if ( socket == NULL || characteristic_value == NULL ) {
return MICO_BT_BADARG;
}
mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status );
if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) {
return MICO_BT_SOCKET_NOT_CONNECTED;
}
return smartbridge_bt_interface_write_long_characteristic_value( socket->connection_handle,
(mico_bt_smart_attribute_t *)characteristic_value );
}
OSStatus mico_bt_smartbridge_gatt_reliable_write_characteristic_value( const mico_bt_smartbridge_socket_t *socket,
const mico_bt_smart_attribute_t *characteristic_value )
{
UNUSED_PARAMETER( socket );
UNUSED_PARAMETER( characteristic_value );
return MICO_BT_UNSUPPORTED;
}

View file

@ -0,0 +1,32 @@
src =Split('''
mico_bt_management.c
mico_bt_peripheral.c
mico_bt_smartbridge_gatt.c
mico_bt_smartbridge.c
mico_bt_smartbridge_cfg.c
internal/bt_peripheral_stack_interface.c
internal/bt_smart_attribute.c
internal/bt_smartbridge_att_cache_manager.c
internal/bt_smartbridge_socket_manager.c
internal/bt_smartbridge_helper.c
internal/bt_smartbridge_stack_interface.c
LinkListUtils.c
StringUtils.c
''')
component =aos_component('bt_smart', src)
global_includes =Split('''
include
''')
for i in global_includes:
component.add_global_includes(i)
includes =Split('''
internal
''')
for i in includes:
component.add_includes(i)

View file

@ -0,0 +1,275 @@
#pragma once
#include "data_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BTEWICED TRUE
#if 1
//oscar++
#define BTM_DEFAULT_AUTH_REQ BTM_AUTH_SPGB_NO //oscar
//#define HCI_DEFAULT_INACT_TOUT 11200 //7sec (11200*0.625) for minray
//oscar--
#endif
#define BTM_INCLUDED TRUE # Makefile only
#define BTM_CMD_POOL_ID GKI_POOL_ID_1
#define BTM_CLB_INCLUDED FALSE
#define BTM_CLB_RX_INCLUDED FALSE
#define BTM_TBFC_INCLUDED FALSE
#define BTM_SCO_INCLUDED FALSE
#define BTM_SCO_HCI_INCLUDED FALSE
#define BTM_INQ_DB_INCLUDED FALSE
#define BTM_BUSY_LEVEL_CHANGE_INCLUDED FALSE
#define BTM_ALLOW_CONN_IF_NONDISCOVER TRUE
#define BTM_MAX_REM_BD_NAME_LEN 10
#define BTM_DUMO_ADDR_CENTRAL_ENABLED FALSE
#define BTM_APP_DEV_INIT bte_post_reset
#define BTM_INTERNAL_LINKKEY_STORAGE_INCLUDED TRUE
#define BTM_BLE_PRIVACY_SPT TRUE
#define BTM_USE_CONTROLLER_PRIVATE_ADDRESS FALSE
#define BTM_BLE_HOST_ADDR_RESOLUTION FALSE
#define BTM_PCM2_INCLUDED FALSE
#define BTM_COEX_INCLUDED FALSE
#define BTM_N2BT_INCLUDED FALSE
#define BTU_INCLUDED TRUE # Makefile only
#define BTUTHIN_INCLUDED FALSE # Makefile only
#define BTU_BTC_SNK_INCLUDED FALSE
#define BTU_STACK_LITE_ENABLED FALSE
#define BTU_DYNAMIC_CB_INCLUDED TRUE
#define BTU_MUTEX_INCLUDED TRUE
#define L2CAP_INCLUDED TRUE
#define L2CAP_CMD_POOL_ID GKI_POOL_ID_1
#define L2CAP_FCR_INCLUDED FALSE
#define L2CAP_UCD_INCLUDED FALSE
#define L2CAP_WAKE_PARKED_LINK FALSE
#define L2CAP_NON_FLUSHABLE_PB_INCLUDED FALSE
#define L2CAP_ROUND_ROBIN_CHANNEL_SERVICE FALSE
#define L2CAP_MTU_SIZE ((UINT16)(HCI_ACL_POOL_BUF_SIZE - BT_HDR_SIZE - 8)) /* ACL bufsize minus BT_HDR, and l2cap/hci packet headers */
#define L2CAP_LE_COC_INCLUDED TRUE
#define RFCOMM_INCLUDED TRUE
#define RFCOMM_USE_EXTERNAL_SCN TRUE
#define RFCOMM_CMD_POOL_ID GKI_POOL_ID_1
#define RFCOMM_DATA_POOL_ID GKI_POOL_ID_2
#define MAX_RFC_PORTS (p_btm_cfg_settings->rfcomm_cfg.max_ports)
#define MAX_BD_CONNECTIONS (p_btm_cfg_settings->rfcomm_cfg.max_links)
#define PORT_RX_CRITICAL_WM ((UINT32)(L2CAP_MTU_SIZE-L2CAP_MIN_OFFSET-RFCOMM_DATA_OVERHEAD)*PORT_RX_BUF_CRITICAL_WM)
#define PORT_RX_LOW_WM ((UINT32)(L2CAP_MTU_SIZE-L2CAP_MIN_OFFSET-RFCOMM_DATA_OVERHEAD)*PORT_RX_BUF_LOW_WM)
#define PORT_RX_HIGH_WM ((UINT32)(L2CAP_MTU_SIZE-L2CAP_MIN_OFFSET-RFCOMM_DATA_OVERHEAD)*PORT_RX_BUF_HIGH_WM)
#define PORT_RX_BUF_LOW_WM 2
#define PORT_RX_BUF_HIGH_WM 3
#define PORT_RX_BUF_CRITICAL_WM 5
#define PORT_TX_HIGH_WM ((UINT32)(L2CAP_MTU_SIZE-L2CAP_MIN_OFFSET-RFCOMM_DATA_OVERHEAD)*PORT_TX_BUF_HIGH_WM)
#define PORT_TX_CRITICAL_WM ((UINT32)(L2CAP_MTU_SIZE-L2CAP_MIN_OFFSET-RFCOMM_DATA_OVERHEAD)*PORT_TX_BUF_CRITICAL_WM)
#define PORT_TX_BUF_HIGH_WM 3
#define PORT_TX_BUF_CRITICAL_WM 5
#define PORT_CREDIT_RX_LOW 2
#define PORT_CREDIT_RX_MAX 3
/* HID definitions */
#define HID_DEV_INCLUDED FALSE
#define HID_DEV_MAX_DESCRIPTOR_SIZE 200
#define HID_DEV_SET_CONN_MODE FALSE
/* AVDT/A2DP/AVRC definitions */
#define A2D_INCLUDED FALSE
#define A2D_SBC_INCLUDED FALSE
#define A2D_M12_INCLUDED FALSE
#define A2D_M24_INCLUDED FALSE
#define AVDT_INCLUDED FALSE
#define AVDT_REPORTING FALSE
#define AVDT_MULTIPLEXING FALSE
#define AVDT_NUM_LINKS (p_btm_cfg_settings->avdt_cfg.max_links)
#define AVDT_CMD_POOL_ID GKI_POOL_ID_1
#define AVDT_DATA_POOL_ID GKI_POOL_ID_3
#define AVDT_DATA_POOL_SIZE GKI_BUF3_SIZE
#define AVRC_INCLUDED FALSE
#define AVCT_INCLUDED FALSE
#define AVCT_NUM_LINKS (p_btm_cfg_settings->avrc_cfg.max_links)
#define AVCT_NUM_CONN (avct_cb.num_conn)
#define AVRC_SEC_MASK (p_btm_cfg_settings->security_requirement_mask)
#define AVRC_CONTROL_MTU (L2CAP_MTU_SIZE)
#define AVRC_BROWSE_MTU (L2CAP_MTU_SIZE)
#define GATT_FIXED_DB TRUE
#define GATTS_APPU_USE_GATT_TRACE FALSE
#define GATT_MAX_APPS 4
#define GATT_MAX_SR_PROFILES 3
#define GATT_MAX_PHY_CHANNEL (GATT_CL_MAX_LCB + GATT_MAX_SCCB)
#define GATT_MAX_ATTR_LEN (p_btm_cfg_settings->gatt_cfg.max_attr_len)
#define GATT_MAX_MTU_SIZE 517
#define GATT_CL_MAX_LCB (p_btm_cfg_settings->gatt_cfg.client_max_links)
#define GATT_MAX_SCCB (p_btm_cfg_settings->gatt_cfg.server_max_links)
#define GATTP_TRANSPORT_SUPPORTED GATT_TRANSPORT_LE //GATT_TRANSPORT_LE_BR_EDR
#define GATTC_NOTIF_TIMEOUT 3
#define GATT_OVER_BREDR_INCLUDED FALSE
#define SIM_ACCESS_INCLUDED FALSE
#define SAP_SERVER_INCLUDED FALSE
#define SAP_CLIENT_INCLUDED FALSE
#define BLE_INCLUDED TRUE
#define SMP_INCLUDED TRUE
#define GAP_INCLUDED TRUE
#define SMP_HOST_ENCRYPT_INCLUDED TRUE
#define SMP_LE_SC_INCLUDED TRUE
#define SMP_LE_SC_OOB_INCLUDED FALSE
#define ATT_DEBUG FALSE
#define SMP_DEBUG FALSE
#define BLE_BRCM_INCLUDED TRUE
#define BLE_BRCM_MULTI_ADV_INCLUDED FALSE
#define BLE_DATA_LEN_EXT_INCLUDED TRUE
#define BLE_LLT_INCLUDED TRUE
#define SMP_CONFORMANCE_TESTING FALSE
#define AMP_INCLUDED FALSE
#define GPS_INCLUDED FALSE
#define GKI_NUM_FIXED_BUF_POOLS MICO_BT_CFG_NUM_BUF_POOLS
#define GKI_NUM_TOTAL_BUF_POOLS MICO_BT_CFG_NUM_BUF_POOLS
#define GKI_BUF0_SIZE (p_btm_cfg_buf_pools[GKI_POOL_ID_0].buf_size)
#define GKI_BUF0_MAX (p_btm_cfg_buf_pools[GKI_POOL_ID_0].buf_count)
#define GKI_BUF1_SIZE (p_btm_cfg_buf_pools[GKI_POOL_ID_1].buf_size)
#define GKI_BUF1_MAX (p_btm_cfg_buf_pools[GKI_POOL_ID_1].buf_count)
#define GKI_BUF2_SIZE (p_btm_cfg_buf_pools[GKI_POOL_ID_2].buf_size)
#define GKI_BUF2_MAX (p_btm_cfg_buf_pools[GKI_POOL_ID_2].buf_count)
#define GKI_BUF3_SIZE (p_btm_cfg_buf_pools[GKI_POOL_ID_3].buf_size)
#define GKI_BUF3_MAX (p_btm_cfg_buf_pools[GKI_POOL_ID_3].buf_count)
#define GKI_DYNAMIC_POOL_CFG TRUE
#define GKI_DYNAMIC_MEMORY FALSE
#define GKI_USE_DYNAMIC_BUFFERS TRUE
#define HCIC_INCLUDED TRUE
#define HCI_CMD_POOL_ID GKI_POOL_ID_1
#define HCI_CMD_POOL_BUF_SIZE (p_btm_cfg_buf_pools[HCI_CMD_POOL_ID].buf_size)
#define HCI_ACL_POOL_ID GKI_POOL_ID_2
#define HCI_ACL_POOL_BUF_SIZE (p_btm_cfg_buf_pools[HCI_ACL_POOL_ID].buf_size)
#define HCI_SCO_POOL_ID GKI_POOL_ID_2
#define HCI_USE_VARIABLE_SIZE_CMD_BUF TRUE
#define HCISU_H4_INCLUDED TRUE
#define HCILP_INCLUDED TRUE
#define HCILP_SLEEP_MODE 0
#define H4IBSS_INCLUDED FALSE
#define H4IBSS_DEBUG FALSE
#define SLIP_INCLUDED FALSE
#define SLIP_STATIS_INCLUDED FALSE
#define SLIP_SW_FLOW_CTRL TRUE //FALSE
#define BT_TRACE_SLIP FALSE
#define SLIP_SLEEP_TO 5000
#define SLIP_HOST_SLIDING_WINDOW_SIZE 7
#define BTM_INQ_DB_SIZE 1
#define BTM_SEC_MAX_DEVICE_RECORDS (p_btm_cfg_settings->max_simultaneous_links)
#if !defined(BTM_USE_CONTROLLER_PRIVATE_ADDRESS) || (BTM_USE_CONTROLLER_PRIVATE_ADDRESS == FALSE)
#define BTM_SEC_HOST_PRIVACY_ADDR_RESOLUTION_TABLE_SIZE (p_btm_cfg_settings->addr_resolution_db_size) //william, 50 oscar
#endif
#define BTM_SEC_MAX_SERVICE_RECORDS 4
#define BTM_SEC_SERVICE_NAME_LEN 0
#define BTM_MAX_LOC_BD_NAME_LEN 0
#define BTM_MAX_PM_RECORDS 1
#define BTM_MAX_VSE_CALLBACKS 1
#define BTM_BLE_MAX_BG_CONN_DEV_NUM 2
#define BTM_OOB_INCLUDED FALSE
#define BTM_BR_SC_INCLUDED FALSE
#define BTM_CROSS_TRANSP_KEY_DERIVATION FALSE
#define BTM_PWR_MGR_INCLUDED FALSE
#define BT_BRCM_VS_INCLUDED TRUE
#define BTTRC_INCLUDED FALSE
#define BTTRC_PARSER_INCLUDED FALSE
#define MAX_TRACE_RAM_SIZE 10
#define SDP_INCLUDED TRUE
#define SDP_CLIENT_ENABLED TRUE
#define SDP_SERVER_ENABLED TRUE
#define SDP_POOL_ID GKI_POOL_ID_2
#define SDP_MAX_CONNECTIONS 1
#define SDP_MAX_RECORDS 3
#define SDP_MAX_REC_ATTR 8
#define SDP_MAX_UUID_FILTERS 3
#define SDP_MAX_ATTR_FILTERS 12
#define SDP_MAX_PROTOCOL_PARAMS 2
#define SDP_RAW_DATA_SERVER FALSE
#if (defined(BTU_DYNAMIC_CB_INCLUDED) && (BTU_DYNAMIC_CB_INCLUDED == TRUE))
#define MAX_L2CAP_CLIENTS (btu_cb.l2c_cfg_max_clients)
#define MAX_L2CAP_LINKS (btu_cb.l2c_cfg_max_links)
#define MAX_L2CAP_CHANNELS (btu_cb.l2c_cfg_max_channels)
#define BTM_INIT_CLASS_OF_DEVICE (p_btm_cfg_settings->device_class)
/* Connection Oriented Channel configuration */
#define MAX_L2CAP_BLE_CLIENTS (p_btm_cfg_settings->l2cap_application.max_le_psm)
#define MAX_L2CAP_BLE_CHANNELS (p_btm_cfg_settings->l2cap_application.max_le_channels)
#else /* BTU_DYNAMIC_CB_INCLUDED */
#define MAX_L2CAP_CLIENTS 3
#define MAX_L2CAP_LINKS 1
#define MAX_L2CAP_CHANNELS 4
#endif /* BTU_DYNAMIC_CB_INCLUDED */
#define GAP_CONN_INCLUDED FALSE
#define HCISU_TASK 0
#define BTU_TASK 1
#define BTE_APPL_TASK 2
#define GKI_MAX_TASKS 3
#define BTE_IDLE_TASK_INCLUDED FALSE
#define BTE_IDLE_TASK_SIZE 0xA0
#define BTE_HCI_TASK_SIZE 0x100
#define BTE_BTU_TASK_SIZE 0x400
/* Miscellaneous application configuration */
#define _MAX_PATH 16
#define TICKS_PER_SEC 1000
#define USERIAL_HCI_PORT USERIAL_PORT_1
#define GKI_SHUTDOWN_EVT APPL_EVT_7
#define THREAD_EVT_QUEUE_MSG_SIZE 4
#define THREAD_EVT_QUEUE_NUM_MSG 10
#ifndef BT_TRACE_PROTOCOL
#define BT_TRACE_PROTOCOL FALSE
#endif
#ifndef BT_USE_TRACES
#define BT_USE_TRACES FALSE
#endif
#ifndef BT_TRACE_VERBOSE
#define BT_TRACE_VERBOSE FALSE
#endif
#define USE_EXTERNAL_HCD 1
#define GPIO_BT_WAKE 40 // 0
#define GPIO_HOST_WAKE 41 // 1
#define GPIO_BT_REG 42 // 21
//*************
#define BTM_EIR_CLIENT_INCLUDED FALSE
#define BTM_EIR_SERVER_INCLUDED FALSE
#define BTM_EIR_DEFAULT_FEC_REQUIRED FALSE
#define BTM_SSR_INCLUDED FALSE
//***************
#ifdef __cplusplus
} /*extern "C" */
#endif

View file

@ -0,0 +1,30 @@
NAME := lib_ble_dual_mode
BTE_PLATFORM_DIR := ../BTE_platform
GLOBAL_INCLUDES += . \
../include
# Include BTE stack as component
#$(NAME)_COMPONENTS := libraries/bluetooth/BTE
BLUETOOTH_LIB_TYPE := dual_mode
ifneq ($(wildcard $(CURDIR)BTE_$(BLUETOOTH_LIB_TYPE).$(HOST_ARCH).$(TOOLCHAIN_NAME).release.a),)
$(NAME)_PREBUILT_LIBRARY := BTE_$(BLUETOOTH_LIB_TYPE).$(HOST_ARCH).$(TOOLCHAIN_NAME).release.a
else
# Build from source (MXCHIP internal)
include $(CURDIR)$(BLUETOOTH_LIB_TYPE)_src.mk
endif
# Include appropriate firmware as component
$(NAME)_COMPONENTS += bluetooth/mk3239/firmware
$(NAME)_SOURCES += $(BTE_PLATFORM_DIR)/mico_bt_bus.c \
$(BTE_PLATFORM_DIR)/mico_bt_hcd.c \
$(BTE_PLATFORM_DIR)/mico_bt_logmsg.c \
$(BTE_PLATFORM_DIR)/mico_bt_nvram_access.c \
$(BTE_PLATFORM_DIR)/mico_upio.c
VALID_PLATFORMS := MK3238 MK3239

View file

@ -0,0 +1,233 @@
BLUETOOTH_LIB_TYPE ?= dual_mode
NAME := BTE_$(BLUETOOTH_LIB_TYPE)
################################################################################
# Supported variants #
################################################################################
SUPPORTED_BT_CHIPS := 43438A0 43438A1
################################################################################
# Default settings #
################################################################################
#COMPLETE_BT_CHIP_NAME := BCM$(BT_CHIP)$(BT_CHIP_REVISION)
BTEDIR := ../BTE
PROTO_DISP_DIR := ../BTE/proto_disp
BTESOURCES := \
$(BTEDIR)/Components/hcis/hcill_proto.c \
$(BTEDIR)/Components/hcis/hcilp.c \
$(BTEDIR)/Components/hcis/hcisu_h4.c \
$(BTEDIR)/Components/hcis/hciutil.c \
$(BTEDIR)/Components/stack/brcm/brcm_ble.c \
$(BTEDIR)/Components/stack/brcm/brcm_prm.c \
$(BTEDIR)/Components/stack/brcm/brcm_tbfc.c \
$(BTEDIR)/Components/stack/brcm/bte_brcm.c \
$(BTEDIR)/Components/stack/btm/btm_acl.c \
$(BTEDIR)/Components/stack/btm/btm_cfg.c \
$(BTEDIR)/Components/stack/btm/btm_dev.c \
$(BTEDIR)/Components/stack/btm/btm_devctl.c \
$(BTEDIR)/Components/stack/btm/btm_inq.c \
$(BTEDIR)/Components/stack/btm/btm_main.c \
$(BTEDIR)/Components/stack/btm/btm_pm.c \
$(BTEDIR)/Components/stack/btm/btm_sco.c \
$(BTEDIR)/Components/stack/btm/btm_sec.c \
$(BTEDIR)/Components/stack/btm/btm_sec_nvram.c \
$(BTEDIR)/Components/stack/btu/btu_hcif.c \
$(BTEDIR)/Components/stack/btu/btu_init.c \
$(BTEDIR)/Components/stack/btu/btu_task.c \
$(BTEDIR)/Components/stack/hcic/hcicmds.c \
$(BTEDIR)/Components/stack/l2cap/l2c_api.c \
$(BTEDIR)/Components/stack/l2cap/l2c_csm.c \
$(BTEDIR)/Components/stack/l2cap/l2c_fcr.c \
$(BTEDIR)/Components/stack/l2cap/l2c_fcr_patch.c \
$(BTEDIR)/Components/stack/l2cap/l2c_link.c \
$(BTEDIR)/Components/stack/l2cap/l2c_main.c \
$(BTEDIR)/Components/stack/l2cap/l2c_utils.c \
$(BTEDIR)/Components/stack/sdp/sdp_api.c \
$(BTEDIR)/Components/stack/sdp/sdp_db.c \
$(BTEDIR)/Components/stack/sdp/sdp_discovery.c \
$(BTEDIR)/Components/stack/sdp/sdp_main.c \
$(BTEDIR)/Components/stack/sdp/sdp_server.c \
$(BTEDIR)/Components/stack/sdp/sdp_utils.c \
$(BTEDIR)/Components/stack/wbt/wbt_ext.c \
$(BTEDIR)/Projects/bte/main/bte_hcisu.c \
$(BTEDIR)/Projects/bte/main/bte_init.c \
$(BTEDIR)/Projects/bte/main/bte_load.c \
$(BTEDIR)/Projects/bte/main/bte_version.c
BTE_RFCOMM_SOURCES := \
$(BTEDIR)/Components/stack/rfcomm/port_api.c \
$(BTEDIR)/Components/stack/rfcomm/port_rfc.c \
$(BTEDIR)/Components/stack/rfcomm/port_utils.c \
$(BTEDIR)/Components/stack/rfcomm/rfc_l2cap_if.c \
$(BTEDIR)/Components/stack/rfcomm/rfc_mx_fsm.c \
$(BTEDIR)/Components/stack/rfcomm/rfc_port_fsm.c \
$(BTEDIR)/Components/stack/rfcomm/rfc_port_if.c \
$(BTEDIR)/Components/stack/rfcomm/rfc_ts_frames.c \
$(BTEDIR)/Components/stack/rfcomm/rfc_utils.c
#####ifndef MINDRAY ####oscar for mindray
BTE_AVRC_SOURCES := \
$(BTEDIR)/Components/stack/avrc/avrc_api.c \
$(BTEDIR)/Components/stack/avrc/avrc_sdp.c \
$(BTEDIR)/Components/stack/avrc/avrc_opt.c \
$(BTEDIR)/Components/stack/avrc/avrc_bld_ct.c \
$(BTEDIR)/Components/stack/avrc/avrc_bld_tg.c \
$(BTEDIR)/Components/stack/avrc/avrc_pars_ct.c \
$(BTEDIR)/Components/stack/avrc/avrc_pars_tg.c \
$(BTEDIR)/Components/stack/avrc/avrc_utils.c \
$(BTEDIR)/mico_bt_api/mico_bt_avrc_wrapper.c
BTE_AVCT_SOURCES := \
$(BTEDIR)/Components/stack/avct/avct_api.c \
$(BTEDIR)/Components/stack/avct/avct_ccb.c \
$(BTEDIR)/Components/stack/avct/avct_l2c.c \
$(BTEDIR)/Components/stack/avct/avct_l2c_br.c \
$(BTEDIR)/Components/stack/avct/avct_lcb.c \
$(BTEDIR)/Components/stack/avct/avct_bcb_act.c \
$(BTEDIR)/Components/stack/avct/avct_lcb_act.c
BTE_A2DP_SOURCES := \
$(BTEDIR)/Components/stack/a2dp/a2d_api.c \
$(BTEDIR)/Components/stack/a2dp/a2d_sbc.c \
$(BTEDIR)/Components/stack/a2dp/a2d_m12.c \
$(BTEDIR)/Components/stack/a2dp/a2d_m24.c \
$(BTEDIR)/mico_bt_api/mico_bt_a2d_wrapper.c
BTE_AVDT_SOURCES := \
$(BTEDIR)/Components/stack/avdt/avdt_ad.c \
$(BTEDIR)/Components/stack/avdt/avdt_api.c \
$(BTEDIR)/Components/stack/avdt/avdt_ccb.c \
$(BTEDIR)/Components/stack/avdt/avdt_l2c.c \
$(BTEDIR)/Components/stack/avdt/avdt_scb.c \
$(BTEDIR)/Components/stack/avdt/avdt_scb_act.c \
$(BTEDIR)/Components/stack/avdt/avdt_msg.c \
$(BTEDIR)/Components/stack/avdt/avdt_ccb_act.c \
$(BTEDIR)/mico_bt_api/mico_bt_avdt_wrapper.c
#####endif
BTE_GATT_SMP_SOURCES := \
$(BTEDIR)/Components/stack/gatt/att_protocol.c \
$(BTEDIR)/Components/stack/gatt/gatt_attr.c \
$(BTEDIR)/Components/stack/gatt/gatt_cl.c \
$(BTEDIR)/Components/stack/gatt/gatt_sr.c \
$(BTEDIR)/Components/stack/gatt/gatt_api.c \
$(BTEDIR)/Components/stack/gatt/gatt_auth.c \
$(BTEDIR)/Components/stack/gatt/gatt_main.c \
$(BTEDIR)/Components/stack/gatt/gatt_utils.c \
$(BTEDIR)/Components/stack/gatt/legattdb/legattdb.c \
$(BTEDIR)/Components/stack/smp/aes.c \
$(BTEDIR)/Components/stack/smp/p_256_curvepara.c \
$(BTEDIR)/Components/stack/smp/p_256_ecc_pp.c \
$(BTEDIR)/Components/stack/smp/p_256_multprecision.c \
$(BTEDIR)/Components/stack/smp/smp_act.c \
$(BTEDIR)/Components/stack/smp/smp_api.c \
$(BTEDIR)/Components/stack/smp/smp_br_main.c \
$(BTEDIR)/Components/stack/smp/smp_cmac.c \
$(BTEDIR)/Components/stack/smp/smp_keys.c \
$(BTEDIR)/Components/stack/smp/smp_l2c.c \
$(BTEDIR)/Components/stack/smp/smp_main.c \
$(BTEDIR)/Components/stack/smp/smp_utils.c \
$(BTEDIR)/Components/stack/hcic/hciblecmds.c \
$(BTEDIR)/Components/stack/l2cap/l2c_ble.c \
$(BTEDIR)/Components/stack/l2cap/l2c_ble_conn.c \
$(BTEDIR)/Components/stack/l2cap/l2c_ble_utils.c \
$(BTEDIR)/Components/stack/btm/btm_ble.c \
$(BTEDIR)/Components/stack/btm/btm_ble_addr.c \
$(BTEDIR)/Components/stack/btm/btm_ble_bgconn.c \
$(BTEDIR)/Components/stack/btm/btm_ble_gap.c \
$(BTEDIR)/Components/stack/btm/btm_ble_privacy.c \
$(BTEDIR)/Components/stack/gap/gap_api.c \
$(BTEDIR)/Components/stack/gap/gap_ble.c \
$(BTEDIR)/Components/stack/gap/gap_conn.c \
$(BTEDIR)/Components/stack/gap/gap_utils.c \
$(BTEDIR)/mico_bt_api/mico_bt_l2c_le_wrapper.c \
$(BTEDIR)/mico_bt_api/mico_bt_ble_wrapper.c \
$(BTEDIR)/mico_bt_api/mico_bt_dev_wrapper.c \
$(BTEDIR)/mico_bt_api/mico_bt_gatt_wrapper.c \
$(BTEDIR)/mico_bt_api/mico_bt_rfcomm_wrapper.c \
$(BTEDIR)/mico_bt_api/mico_bt_sdp_wrapper.c \
$(BTEDIR)/mico_bt_api/mico_bt_gatt.c \
$(BTEDIR)/mico_bt_api/mico_bt_sdp.c
GKI_SOURCES := \
$(BTEDIR)/Components/gki/common/gki_buffer.c \
$(BTEDIR)/Components/gki/common/gki_debug.c \
$(BTEDIR)/Components/gki/common/gki_time.c \
$(BTEDIR)/Components/gki/mico/gki_mico.c
UDRV_SOURCES := \
$(BTEDIR)/Components/udrv/mico/userial_mico.c
PROTODISP_SOURCES := \
$(PROTO_DISP_DIR)/hcidisp.c \
$(PROTO_DISP_DIR)/sdpdisp.c
PROTODISP_INCLUDES := \
$(PROTO_DISP_DIR)
BTEINCLUDES := \
$(BTEDIR)/Components/hcis \
$(BTEDIR)/Components/hcis/include \
$(BTEDIR)/Components/stack/include \
$(BTEDIR)/Components/stack/avrc \
$(BTEDIR)/Components/stack/avct \
$(BTEDIR)/Components/stack/avdt \
$(BTEDIR)/Components/stack/a2dp \
$(BTEDIR)/Components/stack/btm \
$(BTEDIR)/Components/stack/brcm \
$(BTEDIR)/Components/stack/l2cap \
$(BTEDIR)/Components/stack/sdp \
$(BTEDIR)/Components/stack/gap \
$(BTEDIR)/Components/stack/gatt \
$(BTEDIR)/Components/stack/gatt/legattdb/inc \
$(BTEDIR)/Components/stack/smp \
$(BTEDIR)/Components/stack/hid \
$(BTEDIR)/Components/stack/wbt \
$(BTEDIR)/Components/rpc/include \
$(BTEDIR)/Components/gki/mico \
$(BTEDIR)/Components/gki/common \
$(BTEDIR)/Components/udrv/include
$(NAME)_SOURCES := \
$(BTEDIR)/mico_bt_api/mico_bt_main.c \
$(GKI_SOURCES) \
$(BTESOURCES) \
$(BTE_GATT_SMP_SOURCES) \
$(BTE_RFCOMM_SOURCES) \
$(PROTODISP_SOURCES) \
$(UDRV_SOURCES)
$(NAME)_SOURCES += $(BTEDIR)/Projects/bte/embedded/mico/lib/mico_post_reset.c \
$(BTEDIR)/Projects/bte/embedded/mico/lib/mico_stubs.c
$(NAME)_INCLUDES := $(BTEINCLUDES) \
$(PROTODISP_INCLUDES) \
$(BTEDIR)/Projects/bte/main \
../include \
.
$(NAME)_CFLAGS += -Wno-unused-function -Wno-unused-variable -Wno-unused-value -Wno-unused-label
$(NAME)_DEFINES := MICO_BTE_LIB
GLOBAL_DEFINES += BUILDCFG BLUETOOTH_BTE GATT_ENABLE
#GLOBAL_DEFINES += BUILDCFG BLUETOOTH_BTE \
#GATT_ENABLE WBT_EXT_ENABLE SCO_ENABLE A2DP_ENABLE

View file

@ -0,0 +1,189 @@
#temporarily disable .a
#in dual_mode_src.mk
src =Split('''
../BTE/mico_bt_api/mico_bt_main.c
../BTE/Components/gki/common/gki_buffer.c
../BTE/Components/gki/common/gki_debug.c
../BTE/Components/gki/common/gki_time.c
../BTE/Components/gki/mico/gki_mico.c
../BTE/Components/hcis/hcill_proto.c
../BTE/Components/hcis/hcilp.c
../BTE/Components/hcis/hcisu_h4.c
../BTE/Components/hcis/hciutil.c
../BTE/Components/stack/brcm/brcm_ble.c
../BTE/Components/stack/brcm/brcm_prm.c
../BTE/Components/stack/brcm/brcm_tbfc.c
../BTE/Components/stack/brcm/bte_brcm.c
../BTE/Components/stack/btm/btm_acl.c
../BTE/Components/stack/btm/btm_cfg.c
../BTE/Components/stack/btm/btm_dev.c
../BTE/Components/stack/btm/btm_devctl.c
../BTE/Components/stack/btm/btm_inq.c
../BTE/Components/stack/btm/btm_main.c
../BTE/Components/stack/btm/btm_pm.c
../BTE/Components/stack/btm/btm_sco.c
../BTE/Components/stack/btm/btm_sec.c
../BTE/Components/stack/btm/btm_sec_nvram.c
../BTE/Components/stack/btu/btu_hcif.c
../BTE/Components/stack/btu/btu_init.c
../BTE/Components/stack/btu/btu_task.c
../BTE/Components/stack/hcic/hcicmds.c
../BTE/Components/stack/l2cap/l2c_api.c
../BTE/Components/stack/l2cap/l2c_csm.c
../BTE/Components/stack/l2cap/l2c_fcr.c
../BTE/Components/stack/l2cap/l2c_fcr_patch.c
../BTE/Components/stack/l2cap/l2c_link.c
../BTE/Components/stack/l2cap/l2c_main.c
../BTE/Components/stack/l2cap/l2c_utils.c
../BTE/Components/stack/sdp/sdp_api.c
../BTE/Components/stack/sdp/sdp_db.c
../BTE/Components/stack/sdp/sdp_discovery.c
../BTE/Components/stack/sdp/sdp_main.c
../BTE/Components/stack/sdp/sdp_server.c
../BTE/Components/stack/sdp/sdp_utils.c
../BTE/Components/stack/wbt/wbt_ext.c
../BTE/Projects/bte/main/bte_hcisu.c
../BTE/Projects/bte/main/bte_init.c
../BTE/Projects/bte/main/bte_load.c
../BTE/Projects/bte/main/bte_version.c
../BTE/Components/stack/gatt/att_protocol.c
../BTE/Components/stack/gatt/gatt_attr.c
../BTE/Components/stack/gatt/gatt_cl.c
../BTE/Components/stack/gatt/gatt_sr.c
../BTE/Components/stack/gatt/gatt_api.c
../BTE/Components/stack/gatt/gatt_auth.c
../BTE/Components/stack/gatt/gatt_main.c
../BTE/Components/stack/gatt/gatt_utils.c
../BTE/Components/stack/gatt/legattdb/legattdb.c
../BTE/Components/stack/smp/aes.c
../BTE/Components/stack/smp/p_256_curvepara.c
../BTE/Components/stack/smp/p_256_ecc_pp.c
../BTE/Components/stack/smp/p_256_multprecision.c
../BTE/Components/stack/smp/smp_act.c
../BTE/Components/stack/smp/smp_api.c
../BTE/Components/stack/smp/smp_br_main.c
../BTE/Components/stack/smp/smp_cmac.c
../BTE/Components/stack/smp/smp_keys.c
../BTE/Components/stack/smp/smp_l2c.c
../BTE/Components/stack/smp/smp_main.c
../BTE/Components/stack/smp/smp_utils.c
../BTE/Components/stack/hcic/hciblecmds.c
../BTE/Components/stack/l2cap/l2c_ble.c
../BTE/Components/stack/l2cap/l2c_ble_conn.c
../BTE/Components/stack/l2cap/l2c_ble_utils.c
../BTE/Components/stack/btm/btm_ble.c
../BTE/Components/stack/btm/btm_ble_addr.c
../BTE/Components/stack/btm/btm_ble_bgconn.c
../BTE/Components/stack/btm/btm_ble_gap.c
../BTE/Components/stack/btm/btm_ble_privacy.c
../BTE/Components/stack/gap/gap_api.c
../BTE/Components/stack/gap/gap_ble.c
../BTE/Components/stack/gap/gap_conn.c
../BTE/Components/stack/gap/gap_utils.c
../BTE/mico_bt_api/mico_bt_l2c_le_wrapper.c
../BTE/mico_bt_api/mico_bt_ble_wrapper.c
../BTE/mico_bt_api/mico_bt_dev_wrapper.c
../BTE/mico_bt_api/mico_bt_gatt_wrapper.c
../BTE/mico_bt_api/mico_bt_rfcomm_wrapper.c
../BTE/mico_bt_api/mico_bt_sdp_wrapper.c
../BTE/mico_bt_api/mico_bt_gatt.c
../BTE/mico_bt_api/mico_bt_sdp.c
../BTE/Components/stack/rfcomm/port_api.c
../BTE/Components/stack/rfcomm/port_rfc.c
../BTE/Components/stack/rfcomm/port_utils.c
../BTE/Components/stack/rfcomm/rfc_l2cap_if.c
../BTE/Components/stack/rfcomm/rfc_mx_fsm.c
../BTE/Components/stack/rfcomm/rfc_port_fsm.c
../BTE/Components/stack/rfcomm/rfc_port_if.c
../BTE/Components/stack/rfcomm/rfc_ts_frames.c
../BTE/Components/stack/rfcomm/rfc_utils.c
../BTE/proto_disp/hcidisp.c
../BTE/proto_disp/sdpdisp.c
../BTE/Components/udrv/mico/userial_mico.c
../BTE/Projects/bte/embedded/mico/lib/mico_post_reset.c
../BTE/Projects/bte/embedded/mico/lib/mico_stubs.c
''')
component =aos_component('BTE_dual_mode', src)
global_macros =Split('''
BUILDCFG
BLUETOOTH_BTE
GATT_ENABLE
''')
for i in global_macros:
component.add_global_macros(i)
includes =Split('''
../BTE/Components/hcis
../BTE/Components/hcis/include
../BTE/Components/stack/include
../BTE/Components/stack/avrc
../BTE/Components/stack/avct
../BTE/Components/stack/avdt
../BTE/Components/stack/a2dp
../BTE/Components/stack/btm
../BTE/Components/stack/brcm
../BTE/Components/stack/l2cap
../BTE/Components/stack/sdp
../BTE/Components/stack/gap
../BTE/Components/stack/gatt
../BTE/Components/stack/gatt/legattdb/inc
../BTE/Components/stack/smp
../BTE/Components/stack/hid
../BTE/Components/stack/wbt
../BTE/Components/rpc/include
../BTE/Components/gki/mico
../BTE/Components/gki/common
../BTE/Components/udrv/include
../BTE/proto_disp
../BTE/Projects/bte/main
../include
.
''')
for i in includes:
component.add_includes(i)
macros =Split('''
MICO_BTE_LIB
''')
for i in macros:
component.add_macros(i)
cflags =Split('''
-Wno-unused-function
-Wno-unused-variable
-Wno-unused-value
-Wno-unused-label
''')
for i in cflags:
component.add_cflags(i)
#in dual_mode.mk
includes =Split('''
.
../include
''')
for i in includes:
component.add_global_includes(i)
component.add_comp_deps('device/bluetooth/mk3239/firmware')
src =Split('''
../BTE_platform/mico_bt_bus.c
../BTE_platform/mico_bt_hcd.c
../BTE_platform/mico_bt_logmsg.c
../BTE_platform/mico_bt_nvram_access.c
../BTE_platform/mico_upio.c
''')
for i in src:
component.add_sources(i)
aos_global_config.set('VALID_PLATFORMS',['MK3238','MK3239'])

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,992 @@
/*****************************************************************************
** *
** Name: bt_firmware_image.c *
** *
** Description: Bluetooth Controller Firmware patch *
** *
** Copyright (c) 2015, Broadcom Corp., All Rights Reserved. *
******************************************************************************/
#include <stdint.h>
const char brcm_patch_version[] = "BCM4343A0_37.4MHz_WSDB-751GNB_TEST_ONLY.hcd";
const uint8_t brcm_patchram_format = 1;
const uint8_t brcm_patchram_buf[] = {
0x4C, 0xFC, 0x46, 0x50, 0x07, 0x21, 0x00, 0x42, 0x52, 0x43, 0x4D, 0x63, 0x66, 0x67, 0x53, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x01, 0x04, 0x18, 0x92, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x12, 0xA0, 0x43, 0x43, 0x00,
0x01, 0x1C, 0x92, 0x07, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x4C, 0xFC, 0xFF, 0x92, 0x07, 0x21, 0x00,
0x42, 0x52, 0x43, 0x4D, 0x63, 0x66, 0x67, 0x44, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x7E, 0x00, 0x00, 0x03, 0x03, 0x23, 0x42, 0x43, 0x4D, 0x34, 0x33, 0x34, 0x33, 0x41, 0x30, 0x20, 0x33, 0x37, 0x2E, 0x34, 0x4D, 0x48, 0x7A, 0x20, 0x57, 0x53, 0x44,
0x42, 0x2D, 0x37, 0x35, 0x31, 0x47, 0x4E, 0x42, 0x2D, 0x30, 0x30, 0x35, 0x38, 0x00, 0x16, 0x03, 0x02, 0x00, 0x00, 0x03, 0x01, 0x05, 0x4E, 0x05, 0x20, 0x00, 0x00, 0x02, 0x01, 0xB0, 0x03, 0x08, 0x01, 0x32, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, 0x70, 0x00, 0x64, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xAC, 0x00, 0x32, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x2F, 0x00, 0x8C,
0x00, 0x32, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0x10, 0x11, 0x01, 0x78, 0x00, 0x32, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xBD, 0xBD, 0xBD, 0xBD, 0xD8, 0x2B, 0x20, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x32, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0D, 0x0D, 0x64, 0x01, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x01, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x70, 0x01, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x10,
0x00, 0x00, 0x00, 0x74, 0x01, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x15, 0x00, 0x00, 0x00, 0x78, 0x01, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x19, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x60, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x84,
0x01, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x21, 0x00, 0x00, 0x00, 0x4C, 0xFC, 0xFF, 0x8D, 0x08, 0x21, 0x00, 0x60, 0x06, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x33, 0x03, 0x00, 0x00, 0x64, 0x06, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x3A,
0x00, 0x00, 0x64, 0x06, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x3A, 0x00, 0x00, 0x68, 0x06, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x68, 0x05, 0x00, 0x00, 0x6C, 0x06, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xA8, 0x30, 0x00, 0x00, 0x70, 0x06,
0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xE8, 0x3E, 0x00, 0x00, 0x74, 0x06, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1C, 0x32, 0x00, 0x00, 0x78, 0x06, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xBB, 0x33, 0x00, 0x00, 0x7C, 0x06, 0x41, 0x00, 0xFF, 0xFF,
0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x40, 0x01, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x44, 0x01, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x00, 0x00, 0x4C, 0x01, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x08,
0x00, 0x00, 0x50, 0x01, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x07, 0x00, 0x00, 0x54, 0x01, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x05, 0x08, 0x00, 0x00, 0x5C, 0x01, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x09, 0x00, 0x00, 0x60, 0x01,
0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x64, 0x01, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x0A,
0x00, 0x00, 0xE0, 0x06, 0x41, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x9C, 0x01, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC0, 0x2B, 0x20, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x3E,
0x20, 0x00, 0x6C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xFC, 0xFF, 0x88, 0x09, 0x21, 0x00, 0x00, 0x09, 0x01, 0x04, 0x02, 0x11, 0x00, 0x00, 0x22, 0x03, 0x02, 0x01, 0x00, 0xF0, 0x01, 0x10, 0x04, 0x00, 0x00, 0x00, 0x28, 0x15, 0x32, 0x00,
0x00, 0x00, 0x7F, 0xFE, 0x34, 0x10, 0x20, 0x00, 0xF0, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x28, 0x15, 0x32, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x34, 0x10, 0x20, 0x00, 0xF0, 0x01, 0x10, 0x02, 0x00, 0x00, 0x00, 0x28, 0x15, 0x32, 0x00, 0x00, 0x00,
0x7F, 0xFE, 0x34, 0x10, 0x20, 0x00, 0xF0, 0x01, 0xA0, 0x01, 0x03, 0x00, 0x00, 0x00, 0x10, 0x15, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0x14, 0x15, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0x18, 0x15,
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0x1C, 0x15, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x4C, 0x00, 0x00, 0x20, 0x15, 0x32, 0x00, 0xFF, 0xFF, 0xFA, 0xFF, 0x05, 0x01, 0x06, 0x06, 0x24, 0x15, 0x32, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x15, 0x32, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x34, 0x10, 0x20, 0x00, 0x34, 0x15, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x38, 0x15, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x50, 0x15, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCA, 0x06, 0x00, 0x00, 0x2C, 0x09, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x64, 0x00, 0x51, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x78, 0x08,
0x64, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0xBE, 0x03, 0x04, 0x06, 0x0A,
0x23, 0x3C, 0x5A, 0x6E, 0x7D, 0x05, 0xF0, 0x05, 0xDC, 0x05, 0x4C, 0xFC, 0xFF, 0x83, 0x0A,
0x21, 0x00, 0x0E, 0x06, 0x90, 0x06, 0x18, 0x06, 0x2C, 0x06, 0x18, 0x06, 0x4A, 0x06, 0xCC, 0x06, 0x54, 0x06, 0x68, 0x06, 0x54, 0x06, 0x86, 0x06, 0x08, 0x07, 0x90, 0x06, 0xAE, 0x06, 0x9A, 0x06, 0xCC, 0x06, 0x4E, 0x07, 0xD6, 0x06, 0xF4, 0x06,
0xE0, 0x06, 0x12, 0x07, 0x94, 0x07, 0x1C, 0x07, 0x3A, 0x07, 0x26, 0x07, 0x58, 0x07, 0xDA, 0x07, 0x62, 0x07, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0xB6, 0x03, 0xCA, 0x03, 0xAC, 0x03, 0xB6, 0x03, 0x98, 0x03,
0xF2, 0x03, 0x06, 0x04, 0xE8, 0x03, 0xF2, 0x03, 0xD4, 0x03, 0x2E, 0x04, 0x42, 0x04, 0x24, 0x04, 0x2E, 0x04, 0x10, 0x04, 0x74, 0x04, 0x88, 0x04, 0x6A, 0x04, 0x74, 0x04, 0x56, 0x04, 0xBA, 0x04, 0xCE, 0x04, 0xB0, 0x04, 0xBA, 0x04, 0x9C, 0x04,
0x00, 0x05, 0x14, 0x05, 0xF6, 0x04, 0x00, 0x05, 0xE2, 0x04, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x60, 0x00, 0x05, 0x9C, 0x02, 0xFF, 0xA0, 0x02, 0xFF, 0xA4, 0x02, 0xFF, 0xA8, 0x02,
0xFF, 0xAC, 0x02, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x05, 0xC8, 0x02, 0xFF, 0xCC, 0x02, 0xFF, 0xD0, 0x02, 0xFF, 0xD4, 0x02, 0xFF, 0xD8, 0x02, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x05, 0x88, 0x03, 0xFF, 0x8C, 0x03, 0xFF, 0x90, 0x03, 0xFF, 0x94, 0x03,
0xFF, 0x98, 0x03, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x05, 0x9C, 0x03, 0xFF, 0xA0, 0x03, 0xFF, 0xA4, 0x03, 0xFF, 0xA8, 0x03, 0xFF, 0xAC, 0x03, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x05, 0x80, 0x03, 0xFF, 0x84, 0x03, 0xFF, 0xA0, 0x06, 0xFF, 0xB4, 0x02,
0xFF, 0x38, 0x07, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x04, 0xA4, 0x06, 0xFF, 0x5C, 0x4C, 0xFC, 0xFF, 0x7E, 0x0B, 0x21, 0x00, 0x06, 0xFF, 0x98, 0x06, 0xFF, 0x64, 0x06, 0xFF, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x42, 0x42, 0x42, 0x42, 0x42, 0xA9, 0xA8,
0xA8, 0xA8, 0xA7, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xA4, 0xF4, 0x18, 0x02, 0xFA, 0x65, 0x03, 0xCC, 0x15, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0xA9, 0xA8, 0xA8, 0xA8, 0xA7, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xA4, 0xF4, 0x1A,
0x02, 0xFA, 0x66, 0x03, 0xCC, 0x15, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x58, 0x58, 0x58, 0x58, 0x58, 0xA8, 0xA7, 0xA7, 0xA7, 0xA7, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xA4, 0xF4, 0x1F, 0x02, 0xFA, 0x66, 0x03, 0xCC, 0x15, 0x85, 0x85, 0x85, 0x85, 0x85,
0x69, 0x69, 0x69, 0x69, 0x69, 0xA8, 0xA7, 0xA7, 0xA7, 0xA7, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xA4, 0xF4, 0x1F, 0x02, 0xFA, 0x66, 0x03, 0xCC, 0x15, 0x99, 0x99, 0x99, 0x99, 0x99, 0x74, 0x74, 0x74, 0x74, 0x74, 0xA8, 0xA7, 0xA7, 0xA7, 0xA7, 0xC8,
0xC8, 0xC8, 0xC8, 0xC8, 0xA4, 0xF4, 0x1F, 0x02, 0xFA, 0x67, 0x03, 0xCC, 0x15, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0x82, 0x82, 0x82, 0x82, 0x82, 0xA8, 0xA7, 0xA7, 0xA7, 0xA7, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xA4, 0xF4, 0x1F, 0x02, 0xFA, 0x67, 0x23,
0xFF, 0x15, 0x01, 0x07, 0xB5, 0x03, 0x00, 0x06, 0x0A,
0x23, 0x3C, 0x5A, 0x6E, 0x7D, 0x05, 0x0C, 0x03, 0x0C, 0x03, 0x2A, 0x03, 0x3E, 0x03, 0x48, 0x03, 0x48, 0x03, 0x48, 0x03, 0x66, 0x03, 0x7A, 0x03, 0x84, 0x03, 0x84, 0x03, 0x84, 0x03, 0xA2, 0x03, 0xB6, 0x03, 0xC0, 0x03, 0xCA, 0x03, 0xCA, 0x03,
0xE8, 0x03, 0xFC, 0x03, 0x06, 0x04, 0x10, 0x04, 0x10, 0x04, 0x2E, 0x04, 0x42, 0x04, 0x4C, 0x04, 0x56, 0x04, 0x56, 0x04, 0x74, 0x04, 0x4C, 0xFC, 0xFF, 0x79, 0x0C, 0x21, 0x00, 0x88, 0x04, 0x92, 0x04, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14,
0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x30, 0x02, 0x30, 0x02, 0x30, 0x02, 0x30, 0x02, 0x30, 0x02, 0x6C, 0x02, 0x6C, 0x02, 0x6C, 0x02, 0x6C, 0x02, 0x6C, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0xEE, 0x02, 0xEE, 0x02, 0xEE,
0x02, 0xEE, 0x02, 0xEE, 0x02, 0x34, 0x03, 0x34, 0x03, 0x34, 0x03, 0x34, 0x03, 0x34, 0x03, 0x7A, 0x03, 0x7A, 0x03, 0x7A, 0x03, 0x7A, 0x03, 0x7A, 0x03, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x06, 0x00, 0x00,
0x00, 0x60, 0x00, 0x05, 0x9C, 0x02, 0xFF, 0xA0, 0x02, 0xFF, 0xA4, 0x02, 0xFF, 0xA8, 0x02, 0xFF, 0xAC, 0x02, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x05, 0xC8, 0x02, 0xFF, 0xCC, 0x02, 0xFF, 0xD0, 0x02, 0xFF, 0xD4, 0x02, 0xFF, 0xD8, 0x02, 0xFF, 0x00,
0x00, 0x60, 0x00, 0x05, 0x88, 0x03, 0xFF, 0x8C, 0x03, 0xFF, 0x90, 0x03, 0xFF, 0x94, 0x03, 0xFF, 0x98, 0x03, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x05, 0x9C, 0x03, 0xFF, 0xA0, 0x03, 0xFF, 0xA4, 0x03, 0xFF, 0xA8, 0x03, 0xFF, 0xAC, 0x03, 0xFF, 0x00,
0x00, 0x60, 0x00, 0x05, 0x80, 0x03, 0xFF, 0x84, 0x03, 0xFF, 0xA0, 0x06, 0xFF, 0xB4, 0x02, 0xFF, 0x38, 0x07, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x03, 0xA4, 0x06, 0xFF, 0x5C, 0x06, 0xFF, 0x98, 0x06, 0xFF, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x42, 0x42,
0x42, 0x42, 0x42, 0xA9, 0xA8, 0xA8, 0xA8, 0xA7, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xA4, 0xF4, 0x18, 0x03, 0xFA, 0x65, 0x03, 0xCC, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0xA9, 0xA8, 0xA8, 0xA8, 0xA7, 0xC8, 0xC8, 0xC8, 0xC8,
0x4C, 0xFC, 0xFF, 0x74, 0x0D, 0x21, 0x00, 0xC8, 0xA4, 0xF4, 0x1A, 0x03, 0xFA, 0x66, 0x03, 0xCC, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x58, 0x58, 0x58, 0x58, 0x58, 0xA8, 0xA7, 0xA7, 0xA7, 0xA7, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xA4, 0xF4, 0x1F, 0x03,
0xFA, 0x66, 0x03, 0xCC, 0x85, 0x85, 0x85, 0x85, 0x85, 0x69, 0x69, 0x69, 0x69, 0x69, 0xA8, 0xA7, 0xA7, 0xA7, 0xA7, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xA4, 0xF4, 0x1F, 0x03, 0xFA, 0x66, 0x03, 0xCC, 0x99, 0x99, 0x99, 0x99, 0x99, 0x74, 0x74, 0x74,
0x74, 0x74, 0xA8, 0xA7, 0xA7, 0xA7, 0xA7, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xA4, 0xF4, 0x1F, 0x03, 0xFA, 0x67, 0x03, 0xCC, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0x82, 0x82, 0x82, 0x82, 0x82, 0xA8, 0xA7, 0xA7, 0xA7, 0xA7, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
0xA4, 0xF4, 0x1F, 0x03, 0xFA, 0x67, 0x23, 0xFF, 0x02, 0x07, 0x7F, 0x04, 0x06, 0x05, 0xF0, 0x05, 0xDC, 0x05, 0x0E, 0x06, 0x90, 0x06, 0x18, 0x06, 0x2C, 0x06, 0x18, 0x06, 0x4A, 0x06, 0xCC, 0x06, 0x54, 0x06, 0x68, 0x06, 0x54, 0x06, 0x86, 0x06,
0x08, 0x07, 0x90, 0x06, 0xAE, 0x06, 0x9A, 0x06, 0xCC, 0x06, 0x4E, 0x07, 0xD6, 0x06, 0xF4, 0x06, 0xE0, 0x06, 0x12, 0x07, 0x94, 0x07, 0x1C, 0x07, 0x3A, 0x07, 0x26, 0x07, 0x58, 0x07, 0xDA, 0x07, 0x62, 0x07, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF,
0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x05, 0x9C, 0x02, 0xFF, 0xA0, 0x02, 0xFF, 0xA4, 0x02, 0xFF, 0xA8, 0x02, 0xFF, 0xAC, 0x02, 0xFF, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x6C, 0x6C,
0x6C, 0x6C, 0x6C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x99, 0x99, 0x99, 0x99, 0x99, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0x4C, 0xFC, 0xFF, 0x6F, 0x0E, 0x21, 0x00, 0x02, 0x07, 0x7F, 0x00, 0x06, 0x05, 0x0C, 0x03, 0x0C, 0x03, 0x2A, 0x03, 0x3E, 0x03, 0x48,
0x03, 0x48, 0x03, 0x48, 0x03, 0x66, 0x03, 0x7A, 0x03, 0x84, 0x03, 0x84, 0x03, 0x84, 0x03, 0xA2, 0x03, 0xB6, 0x03, 0xC0, 0x03, 0xCA, 0x03, 0xCA, 0x03, 0xE8, 0x03, 0xFC, 0x03, 0x06, 0x04, 0x10, 0x04, 0x10, 0x04, 0x2E, 0x04, 0x42, 0x04, 0x4C,
0x04, 0x56, 0x04, 0x56, 0x04, 0x74, 0x04, 0x88, 0x04, 0x92, 0x04, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x14, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x05, 0x9C, 0x02, 0xFF, 0xA0, 0x02, 0xFF, 0xA4, 0x02, 0xFF, 0xA8,
0x02, 0xFF, 0xAC, 0x02, 0xFF, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x99, 0x99, 0x99, 0x99, 0x99, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0x00, 0x07, 0x04, 0x3F, 0x00,
0x00, 0x00, 0x03, 0x01, 0xC4, 0x01, 0xFC, 0x09, 0x20, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x2C, 0x2C,
0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x41, 0x41, 0x00, 0x00, 0x34, 0x34, 0x00, 0x00, 0x49, 0x49, 0x00, 0x00, 0x20, 0x20, 0x01, 0x01, 0x50, 0x50, 0x00, 0x00, 0x24, 0x24, 0x01, 0x01, 0x58, 0x58, 0x00, 0x00, 0x40, 0x40,
0x01, 0x01, 0x8A, 0x8A, 0x00, 0x00, 0x60, 0x60, 0x01, 0x01, 0x8B, 0x8B, 0x00, 0x00, 0x64, 0x64, 0x01, 0x01, 0x8C, 0x8C, 0x00, 0x00, 0x60, 0x60, 0x02, 0x02, 0x8D, 0x8D, 0x00, 0x00, 0x64, 0x64, 0x02, 0x02, 0x8E, 0x8E, 0x4C, 0xFC, 0xFF, 0x6A,
0x0F, 0x21, 0x00, 0x00, 0x00, 0x68, 0x68, 0x02, 0x02, 0x8F, 0x8F, 0x00, 0x00, 0x6C, 0x6C, 0x02, 0x02, 0x96, 0x96, 0x00, 0x00, 0x70, 0x70, 0x02, 0x02, 0xA5, 0xA5, 0x00, 0x00, 0x50, 0x50, 0x03, 0x03, 0xA6, 0xA6, 0x00, 0x00, 0x54, 0x54, 0x03,
0x03, 0xDD, 0xDD, 0x00, 0x00, 0x74, 0x74, 0x03, 0x03, 0xE5, 0xE5, 0x00, 0x00, 0x78, 0x78, 0x03, 0x03, 0xED, 0xED, 0x00, 0x00, 0x98, 0x98, 0x03, 0x03, 0xEE, 0xEE, 0x00, 0x00, 0xFC, 0xFC, 0x03, 0x03, 0xEF, 0xEF, 0x00, 0x00, 0xBC, 0xBC, 0x03,
0x03, 0xEF, 0xEF, 0x00, 0x00, 0xBC, 0xBC, 0x03, 0x03, 0x03, 0x01, 0x64, 0xBC, 0x0A,
0x20, 0x00, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x41, 0x00, 0x04, 0x01, 0x49, 0x00, 0x24, 0x01, 0x50, 0x00, 0x40, 0x01, 0x58, 0x00, 0x60, 0x01, 0x52, 0x00,
0x48, 0x01, 0x53, 0x00, 0x4C, 0x01, 0x54, 0x00, 0x50, 0x01, 0x55, 0x00, 0x54, 0x01, 0x56, 0x00, 0x58, 0x01, 0x57, 0x00, 0x5C, 0x01, 0x66, 0x00, 0x98, 0x01, 0x6E, 0x00, 0xB8, 0x01, 0x76, 0x00, 0xD8, 0x01, 0x7E, 0x00, 0xF8, 0x01, 0x7F, 0x00,
0xFC, 0x01, 0x7F, 0x00, 0xFC, 0x01, 0x7F, 0x00, 0xFC, 0x01, 0x7F, 0x00, 0xFC, 0x01, 0x7F, 0x00, 0xFC, 0x01, 0x03, 0x01, 0x3A, 0x1C, 0x0B, 0x20, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x1D, 0x00, 0x00,
0x0E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x04,
0x4C, 0xFC, 0xFF, 0x65, 0x10, 0x21, 0x00, 0x07, 0x98, 0x01, 0x04, 0x32, 0x1F, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x1C, 0x01, 0x00, 0x1A, 0x02, 0x00, 0x17, 0x02, 0x00, 0x15, 0x12, 0x00, 0x13, 0x50, 0x00, 0x11, 0x64, 0x00, 0x0F, 0x11, 0x00, 0x0E,
0x03, 0x00, 0x0D, 0x14, 0x00, 0x0B, 0x50, 0x00, 0x0A,
0x64, 0x00, 0x09, 0x23, 0x00, 0x08, 0x23, 0x00, 0x07, 0x03, 0x00, 0x07, 0x16, 0x00, 0x06, 0x15, 0x00, 0x05, 0x13, 0x00, 0x05, 0x16, 0x00, 0x04, 0x13, 0x00, 0x04, 0x26, 0x00, 0x04, 0x19, 0x00, 0x03, 0x05, 0x00, 0x03, 0x08, 0x00, 0x03, 0x2A,
0x00, 0x02, 0x03, 0x00, 0x02, 0x16, 0x00, 0x02, 0x09, 0x00, 0x02, 0x2B, 0x00, 0x02, 0x3D, 0x00, 0x02, 0x3F, 0x00, 0x01, 0x02, 0x00, 0x01, 0x15, 0x00, 0x01, 0x18, 0x00, 0x01, 0x3A, 0x00, 0x01, 0x1D, 0x00, 0x01, 0x1F, 0x00, 0x01, 0x8F, 0x00,
0x01, 0xEF, 0x00, 0x01, 0x3F, 0x01, 0x01, 0x8F, 0x01, 0x01, 0xCF, 0x01, 0x01, 0x0F, 0x02, 0x01, 0x4F, 0x02, 0x01, 0x7F, 0x02, 0x01, 0xAF, 0x02, 0x01, 0xCF, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x07, 0x98, 0x01, 0x00, 0x32, 0x1F,
0x00, 0x00, 0x1D, 0x00, 0x00, 0x1C, 0x01, 0x00, 0x1A, 0x02, 0x00, 0x17, 0x02, 0x00, 0x15, 0x12, 0x00, 0x13, 0x50, 0x00, 0x11, 0x64, 0x00, 0x0F, 0x11, 0x00, 0x0E, 0x03, 0x00, 0x0D, 0x14, 0x00, 0x0B, 0x50, 0x00, 0x0A,
0x64, 0x00, 0x09, 0x23, 0x00, 0x08, 0x23, 0x00, 0x07, 0x03, 0x00, 0x07, 0x16, 0x00, 0x06, 0x15, 0x00, 0x05, 0x13, 0x00, 0x05, 0x16, 0x00, 0x04, 0x13, 0x00, 0x04, 0x26, 0x00, 0x04, 0x19, 0x00, 0x03, 0x05, 0x00, 0x03, 0x08, 0x00, 0x03, 0x2A,
0x00, 0x02, 0x03, 0x00, 0x02, 0x16, 0x00, 0x02, 0x09, 0x00, 0x02, 0x2B, 0x00, 0x4C, 0xFC, 0xFF, 0x60, 0x11, 0x21, 0x00, 0x02, 0x3D, 0x00, 0x02, 0x3F, 0x00, 0x01, 0x02, 0x00, 0x01, 0x15, 0x00, 0x01, 0x18, 0x00, 0x01, 0x3A, 0x00, 0x01, 0x1D,
0x00, 0x01, 0x1F, 0x00, 0x01, 0x8F, 0x00, 0x01, 0xEF, 0x00, 0x01, 0x3F, 0x01, 0x01, 0x8F, 0x01, 0x01, 0xCF, 0x01, 0x01, 0x0F, 0x02, 0x01, 0x4F, 0x02, 0x01, 0x7F, 0x02, 0x01, 0xAF, 0x02, 0x01, 0xCF, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
0x03, 0x07, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x0A,
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
0x02, 0xFE, 0x0B, 0xE4, 0xFE, 0x1C, 0x01, 0xE4, 0xFE, 0x1C, 0x01, 0x0A,
0x02, 0xFE, 0x0B, 0xF1, 0xFF, 0x0F, 0x00, 0xF1, 0xFF, 0x0F, 0x00, 0x0F, 0x03, 0x28, 0x02, 0x78, 0x14, 0x7F, 0x5A, 0x00, 0x14, 0x02, 0x14, 0x1E, 0x00, 0x02, 0x03, 0x00, 0x1E, 0xAA, 0x33, 0x19, 0x05, 0xCF, 0x00, 0x80, 0x0A,
0x92, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0xB4, 0x01, 0x10, 0x03, 0x21, 0x00, 0xF6, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00,
0x00, 0xF3, 0x00, 0x00, 0x00, 0xF3, 0x00, 0x00, 0x00, 0xF2, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0xEF, 0x00, 0x00, 0x00, 0xED, 0x00, 0x00, 0x00, 0xEB, 0x00, 0x00, 0x00, 0xEA, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00,
0x00, 0xE6, 0x00, 0x00, 0x00, 0xE5, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0xE2, 0x00, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xDF, 0x00, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x4C,
0xFC, 0xFF, 0x5B, 0x12, 0x21, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00, 0xDB, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0xD7, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00, 0xD5, 0x00, 0x00, 0x00,
0xD4, 0x00, 0x00, 0x00, 0xD3, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00, 0x00, 0xD1, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0xCF, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0xCD, 0x00, 0x00, 0x00, 0xCD, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00,
0xCC, 0x00, 0x00, 0x00, 0xCB, 0x00, 0x00, 0x00, 0x03, 0x01, 0x40, 0x04, 0x02, 0x21, 0x00, 0x00, 0x10, 0x0A,
0x0F, 0x26, 0x0D, 0x24, 0x0B, 0x00, 0x0A,
0x35, 0x08, 0x36, 0x07, 0x02, 0x07, 0x0A,
0x06, 0x1E, 0x05, 0x39, 0x04, 0x0C, 0x04, 0x31, 0x03, 0x16, 0x03, 0x3B, 0x02, 0x20, 0x02, 0x0E, 0x02, 0x38, 0x01, 0x28, 0x01, 0x10, 0x01, 0x00, 0x01, 0x30, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x01, 0x40, 0x40, 0x02, 0x21, 0x00, 0x00, 0x08, 0x14, 0x07, 0x0A,
0x05, 0x0E, 0x03, 0x08, 0x02, 0x12, 0x01, 0x04, 0x01, 0x1C, 0x00, 0x18, 0x00, 0x16, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14,
0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x03, 0x01, 0x05, 0xF4, 0x03, 0x21, 0x00, 0x90, 0x03, 0x01, 0x0C, 0x88, 0x1D, 0x20, 0x00, 0x01, 0x01, 0x30, 0x00, 0x02, 0x0A,
0x0A,
0x00, 0x03, 0x01, 0x0C, 0x00, 0x02, 0x0D, 0x00, 0x00, 0xF0, 0x66, 0xF9, 0x10, 0x4C, 0xFC, 0xFF, 0x56, 0x13, 0x21, 0x00, 0xBD, 0x00, 0x00, 0x03, 0x01, 0x14, 0x08, 0x02, 0x0D, 0x00, 0x8F, 0xB0, 0x00, 0x24, 0x01, 0x48, 0xC4, 0x61, 0x6E, 0xF7,
0x3C, 0xBD, 0x00, 0x3D, 0x20, 0x00, 0x03, 0x01, 0x0A,
0x18, 0x02, 0x0D, 0x00, 0x00, 0xF0, 0x66, 0xFA, 0x70, 0xBD, 0x03, 0x01, 0x0A,
0x1E, 0x02, 0x0D, 0x00, 0x00, 0xF0, 0x60, 0xFD, 0x10, 0xBD, 0x03, 0x01, 0x0C, 0x24, 0x02, 0x0D, 0x00, 0x00, 0xF0, 0x87, 0xFE, 0xF0, 0xBD, 0x00, 0x00, 0x03, 0x01, 0x10, 0x2C, 0x02, 0x0D, 0x00, 0x40, 0xF2, 0x01, 0x40, 0xA4, 0xF8, 0x44, 0x00,
0xA3, 0xF7, 0xBC, 0xBF, 0x03, 0x01, 0x0C, 0x38, 0x02, 0x0D, 0x00, 0x01, 0xF0, 0xC8, 0xFA, 0x70, 0xBD, 0x00, 0x00, 0x03, 0x01, 0x0C, 0x40, 0x02, 0x0D, 0x00, 0x01, 0xF0, 0x8E, 0xFB, 0xBD, 0xE8, 0xFE, 0x8F, 0x03, 0x01, 0x0C, 0x48, 0x02, 0x0D,
0x00, 0x01, 0xF0, 0xD9, 0xFB, 0x70, 0xBD, 0x00, 0x00, 0x03, 0x01, 0x08, 0x50, 0x02, 0x0D, 0x00, 0x01, 0xF0, 0x2A, 0xBD, 0x03, 0x01, 0x0C, 0x54, 0x02, 0x0D, 0x00, 0xBD, 0xE8, 0xF7, 0x4F, 0x01, 0xF0, 0x42, 0xBD, 0x03, 0x01, 0x0C, 0x5C, 0x02,
0x0D, 0x00, 0x01, 0xF0, 0xDE, 0xFD, 0x56, 0xF7, 0x3E, 0xBB, 0x03, 0x01, 0x18, 0x64, 0x02, 0x0D, 0x00, 0x20, 0x46, 0x29, 0x46, 0x01, 0xF0, 0xE0, 0xFD, 0x08, 0xB1, 0x57, 0xF7, 0x06, 0xBC, 0x57, 0xF7, 0x18, 0xBC, 0x00, 0x00, 0x03, 0x01, 0x10,
0x78, 0x02, 0x0D, 0x00, 0x29, 0x46, 0x01, 0xF0, 0xF3, 0xFD, 0x8C, 0xF7, 0xD5, 0xBD, 0x00, 0x00, 0x03, 0x01, 0x14, 0x84, 0x02, 0x0D, 0x00, 0x0F, 0xB4, 0x21, 0x46, 0x01, 0xF0, 0x8B, 0xFF, 0x0F, 0xBC, 0x83, 0xF7, 0x33, 0xBC, 0x00, 0x00, 0x03,
0x01, 0x08, 0x94, 0x02, 0x0D, 0x00, 0x87, 0xF7, 0xD1, 0x4C, 0xFC, 0xFF, 0x51, 0x14, 0x21, 0x00, 0xFB, 0x03, 0x01, 0x10, 0x98, 0x02, 0x0D, 0x00, 0xE8, 0x60, 0x01, 0x20, 0xA8, 0x76, 0x97, 0xF7, 0x9F, 0xB9, 0x00, 0x00, 0x03, 0x01, 0x14, 0xA4,
0x02, 0x0D, 0x00, 0x88, 0x46, 0x04, 0x46, 0x02, 0xF0, 0xA9, 0xFB, 0x20, 0x46, 0x86, 0xF7, 0x97, 0xBD, 0x00, 0x00, 0x03, 0x01, 0x14, 0xB4, 0x02, 0x0D, 0x00, 0x28, 0x46, 0x02, 0xF0, 0x09, 0xFD, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x66, 0xF7,
0x01, 0xBD, 0x03, 0x01, 0x24, 0xC4, 0x02, 0x0D, 0x00, 0x0F, 0xB4, 0x02, 0xF0, 0xE3, 0xFE, 0x01, 0x28, 0x03, 0xD1, 0x0F, 0xBC, 0x4F, 0xF0, 0x01, 0x00, 0x70, 0xBD, 0x0F, 0xBC, 0x04, 0x46, 0x4F, 0xF6, 0xFF, 0x75, 0x95, 0xF7, 0x05, 0xBB, 0x00,
0x00, 0x03, 0x01, 0x0C, 0xE4, 0x02, 0x0D, 0x00, 0x02, 0xF0, 0x06, 0xFF, 0xBD, 0xE8, 0xFF, 0x81, 0x03, 0x01, 0x0C, 0xEC, 0x02, 0x0D, 0x00, 0x03, 0xF0, 0x7E, 0xFA, 0x83, 0xF7, 0x13, 0xB8, 0x03, 0x01, 0x0C, 0xF4, 0x02, 0x0D, 0x00, 0x03, 0xF0,
0x6C, 0xFD, 0x10, 0xBD, 0x00, 0x00, 0x03, 0x01, 0x10, 0xFC, 0x02, 0x0D, 0x00, 0x06, 0xB0, 0x03, 0xF0, 0x45, 0xFE, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0x03, 0x01, 0x0C, 0x08, 0x03, 0x0D, 0x00, 0x04, 0xF0, 0x4A, 0xFA, 0xBD, 0xE8, 0xF0, 0x9F,
0x03, 0x01, 0x0C, 0x10, 0x03, 0x0D, 0x00, 0x04, 0xF0, 0x4C, 0xFB, 0x10, 0xBD, 0x00, 0x00, 0x03, 0x01, 0x0C, 0x18, 0x03, 0x0D, 0x00, 0x16, 0x24, 0x04, 0x60, 0xBC, 0xF7, 0x58, 0xBE, 0x03, 0x01, 0x14, 0x20, 0x03, 0x0D, 0x00, 0x01, 0x20, 0xA8,
0x70, 0xAF, 0x71, 0xEE, 0x71, 0x20, 0x88, 0xBE, 0xF7, 0x35, 0xB8, 0x00, 0x00, 0x03, 0x01, 0x14, 0x30, 0x03, 0x0D, 0x00, 0x30, 0x46, 0x05, 0xF0, 0x11, 0xFE, 0x60, 0x4C, 0xFC, 0xFF, 0x4C, 0x15, 0x21, 0x00, 0x68, 0x10, 0xF0, 0x06, 0x0F, 0xBD,
0xF7, 0x30, 0xB8, 0x03, 0x01, 0x0C, 0x40, 0x03, 0x0D, 0x00, 0x05, 0xF0, 0xA0, 0xFE, 0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x01, 0x14, 0x48, 0x03, 0x0D, 0x00, 0x03, 0xB4, 0x05, 0xF0, 0xE9, 0xFE, 0x03, 0xBC, 0x02, 0x24, 0x40, 0x68, 0xAF, 0xF7, 0x8C,
0xB8, 0x03, 0x01, 0x0A,
0x58, 0x03, 0x0D, 0x00, 0x06, 0xF0, 0x45, 0xF8, 0x70, 0xBD, 0x03, 0x01, 0x0C, 0x5E, 0x03, 0x0D, 0x00, 0x06, 0xF0, 0x8F, 0xF8, 0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x01, 0x0A,
0x66, 0x03, 0x0D, 0x00, 0x06, 0xF0, 0xCA, 0xF8, 0x70, 0xBD, 0x03, 0x01, 0x0C, 0x6C, 0x03, 0x0D, 0x00, 0x06, 0xF0, 0x22, 0xF9, 0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x01, 0x0C, 0x74, 0x03, 0x0D, 0x00, 0x06, 0xF0, 0xC0, 0xF9, 0x32, 0xF7, 0x48, 0xBB,
0x03, 0x01, 0x0C, 0x7C, 0x03, 0x0D, 0x00, 0x06, 0xF0, 0xD2, 0xF9, 0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x01, 0x0C, 0x84, 0x03, 0x0D, 0x00, 0x21, 0x46, 0x06, 0xF0, 0xFF, 0xF9, 0x70, 0xBD, 0x03, 0x01, 0x0C, 0x8C, 0x03, 0x0D, 0x00, 0x20, 0x46, 0x06,
0xF0, 0x19, 0xFA, 0x70, 0xBD, 0x03, 0x01, 0x10, 0x94, 0x03, 0x0D, 0x00, 0x02, 0x28, 0x01, 0xD9, 0x4A, 0xF7, 0xE6, 0xBB, 0x4A, 0xF7, 0xE7, 0xBB, 0x03, 0x01, 0x20, 0xA0, 0x03, 0x0D, 0x00, 0x41, 0x7C, 0x02, 0x29, 0x08, 0xD0, 0x03, 0x29, 0x06,
0xD0, 0x00, 0x7C, 0x16, 0x28, 0x03, 0xD0, 0x17, 0x28, 0x01, 0xD0, 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x03, 0x01, 0x74, 0xBC, 0x03, 0x0D, 0x00, 0x2D, 0xE9, 0xFE, 0x43, 0xDF, 0xF8, 0xF0, 0x80, 0x98, 0xF8, 0x02, 0x60, 0x8C, 0xF7,
0x32, 0xFB, 0x10, 0xB1, 0x98, 0xF8, 0x01, 0x60, 0x1C, 0xE0, 0x38, 0x48, 0x00, 0x4C, 0xFC, 0xFF, 0x47, 0x16, 0x21, 0x00, 0x25, 0x6F, 0x46, 0xD0, 0xE9, 0x00, 0x12, 0x80, 0x68, 0x00, 0x91, 0xCD, 0xE9, 0x01, 0x20, 0x57, 0xF8, 0x25, 0x00, 0x04,
0x68, 0x07, 0xE0, 0x20, 0x1F, 0xFF, 0xF7, 0xD6, 0xFF, 0x10, 0xB1, 0x98, 0xF8, 0x01, 0x60, 0x04, 0xE0, 0x24, 0x68, 0x57, 0xF8, 0x25, 0x00, 0xA0, 0x42, 0xF3, 0xD1, 0x6D, 0x1C, 0xED, 0xB2, 0x03, 0x2D, 0xEB, 0xD3, 0x98, 0xF8, 0x03, 0x10, 0x8E,
0x42, 0x08, 0xD0, 0x88, 0xF8, 0x03, 0x60, 0x03, 0xB0, 0x31, 0x46, 0xBD, 0xE8, 0xF0, 0x43, 0x02, 0x20, 0x74, 0xF7, 0x68, 0xBA, 0xBD, 0xE8, 0xFE, 0x83, 0x03, 0x01, 0xA8, 0x01, 0x2C, 0x04, 0x0D, 0x00, 0x70, 0xB5, 0x23, 0x4C, 0x01, 0x26, 0x84,
0xF8, 0x3C, 0x60, 0x6E, 0xF7, 0xB3, 0xFA, 0x00, 0x25, 0x4F, 0xF6, 0xFF, 0x70, 0x25, 0x61, 0xE0, 0x86, 0xA5, 0x61, 0x6E, 0xF7, 0xBA, 0xFE, 0x6E, 0xF7, 0xF0, 0xFF, 0x1C, 0x48, 0x62, 0xF7, 0xFD, 0xFB, 0x20, 0xB9, 0x1A, 0x48, 0x00, 0x68, 0x00,
0x1F, 0x6E, 0xF7, 0x7A, 0xFF, 0x6E, 0xF7, 0x45, 0xFF, 0x17, 0x48, 0xE5, 0x60, 0x62, 0xF7, 0xF1, 0xFB, 0x08, 0xB9, 0x6E, 0xF7, 0xF6, 0xFD, 0x6D, 0xF7, 0x3F, 0xFE, 0x01, 0x20, 0x89, 0xF7, 0x89, 0xFF, 0x0D, 0x48, 0x00, 0x78, 0x08, 0xB1, 0xFF,
0xF7, 0x9B, 0xFF, 0x01, 0x20, 0x6D, 0xF7, 0x64, 0xFA, 0x18, 0xB9, 0x0E, 0x48, 0x62, 0xF7, 0xDD, 0xFB, 0x28, 0xB1, 0x6D, 0xF7, 0x73, 0xFD, 0x51, 0xF7, 0x96, 0xFA, 0x30, 0x46, 0x70, 0xBD, 0x0A,
0x48, 0x01, 0x22, 0x11, 0x46, 0x03, 0x68, 0x10, 0x46, 0x5B, 0x1D, 0x6D, 0xF7, 0x57, 0xFA, 0xF2, 0xE7, 0x28, 0x68, 0x0D, 0x00, 0x18, 0x68, 0x0D, 0x00, 0x00, 0x3D, 0x20, 0x00, 0xF0, 0x1B, 0x20, 0x00, 0xE0, 0x1B, 0x20, 0x00, 0xE8, 0x1B, 0x4C,
0xFC, 0xFF, 0x42, 0x17, 0x21, 0x00, 0x20, 0x00, 0xBC, 0x2A, 0x20, 0x00, 0x03, 0x01, 0x44, 0xD0, 0x04, 0x0D, 0x00, 0x10, 0xB5, 0x00, 0x21, 0x0C, 0x48, 0x4D, 0xF7, 0x29, 0xF8, 0xA1, 0xF7, 0xB5, 0xFA, 0x00, 0x28, 0x10, 0xD1, 0x73, 0xF7, 0x0E,
0xFF, 0x04, 0x46, 0x07, 0x48, 0x48, 0xF7, 0x8A, 0xFF, 0x20, 0xB9, 0x06, 0x48, 0x00, 0x78, 0x08, 0xB1, 0x6D, 0xF7, 0x43, 0xFD, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x73, 0xF7, 0x03, 0xBF, 0x10, 0xBD, 0x00, 0x00, 0xE4, 0x3C, 0x20, 0x00, 0x8E,
0x1B, 0x20, 0x00, 0x03, 0x01, 0x4C, 0x10, 0x05, 0x0D, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x0D, 0x21, 0x3E, 0x20, 0x5C, 0xF7, 0x51, 0xFA, 0xC0, 0xB1, 0x06, 0x21, 0x81, 0x70, 0xA9, 0x8F, 0xA0, 0xF8, 0x03, 0x10, 0x21, 0x88, 0xA0, 0xF8,
0x05, 0x10, 0x61, 0x88, 0xA0, 0xF8, 0x07, 0x10, 0xA1, 0x88, 0xA0, 0xF8, 0x09, 0x10, 0xE1, 0x88, 0xA0, 0xF8, 0x0B, 0x10, 0x29, 0x6C, 0x41, 0xF4, 0x80, 0x31, 0x29, 0x64, 0xB2, 0xF7, 0xD1, 0xFD, 0x00, 0x20, 0x70, 0xBD, 0x07, 0x20, 0x70, 0xBD,
0x00, 0x00, 0x03, 0x01, 0x1C, 0x58, 0x05, 0x0D, 0x00, 0xFE, 0x49, 0x09, 0x78, 0x88, 0x42, 0x05, 0xD2, 0xFD, 0x49, 0x00, 0xEB, 0x40, 0x00, 0x01, 0xEB, 0x40, 0x00, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x03, 0x01, 0x48, 0x70, 0x05, 0x0D, 0x00,
0x1C, 0xB5, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, 0x0C, 0x46, 0xCB, 0x88, 0x8A, 0x88, 0x49, 0x88, 0x20, 0x88, 0x46, 0xF7, 0x3C, 0xFC, 0x70, 0xB1, 0x20, 0x7A, 0x63, 0x88, 0x98, 0x42, 0x0A,
0xD2, 0x00, 0x20, 0x4F, 0xF6, 0xFF, 0x72, 0x04, 0xEB, 0x40, 0x01, 0xB1, 0xF8, 0x0B, 0x10, 0x91, 0x42, 0x03, 0xD0, 0x99, 0x42, 0x01, 0xD3, 0x1E, 0x20, 0x1C, 0x4C, 0xFC, 0xFF, 0x3D, 0x18, 0x21, 0x00, 0xBD, 0x40, 0x1C, 0x06, 0x28, 0xF2, 0xD3,
0x00, 0x20, 0x1C, 0xBD, 0x03, 0x01, 0x4C, 0xB4, 0x05, 0x0D, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x90, 0xF8, 0xD2, 0x00, 0xFF, 0xF7, 0xCB, 0xFF, 0x22, 0x88, 0xB5, 0xF8, 0xC6, 0x10, 0xB2, 0xEB, 0x51, 0x0F, 0x03, 0xD8, 0x63, 0x88, 0xB3,
0xEB, 0x51, 0x0F, 0x06, 0xD2, 0x01, 0x88, 0x8A, 0x42, 0x0D, 0xD3, 0x61, 0x88, 0x40, 0x88, 0x81, 0x42, 0x09, 0xD8, 0x28, 0x89, 0xA1, 0x88, 0x88, 0x42, 0x05, 0xD1, 0x68, 0x89, 0xE1, 0x88, 0x88, 0x42, 0x01, 0xD1, 0x00, 0x20, 0x70, 0xBD, 0x01,
0x20, 0x70, 0xBD, 0x03, 0x01, 0xF0, 0x01, 0xFC, 0x05, 0x0D, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0xD6, 0x4A, 0x90, 0xF8, 0xD2, 0x80, 0x04, 0x46, 0xC8, 0xEB, 0xC8, 0x00, 0x12, 0x68, 0x00, 0xEB, 0x40, 0x00, 0x02, 0xEB, 0x00, 0x16, 0x08, 0x7B, 0x28,
0x27, 0x01, 0xF1, 0x10, 0x05, 0x0D, 0x28, 0x26, 0xD0, 0xB4, 0xF8, 0x44, 0x00, 0x40, 0x05, 0x02, 0xD5, 0x40, 0x46, 0xB0, 0xF7, 0xB8, 0xFD, 0x69, 0x89, 0x40, 0x46, 0xAB, 0xF7, 0x40, 0xF8, 0xD8, 0xB3, 0x68, 0x89, 0xAD, 0xF8, 0x00, 0x00, 0x01,
0x20, 0xA4, 0xF8, 0x44, 0x00, 0x68, 0x78, 0xE0, 0x75, 0x68, 0x88, 0x20, 0x83, 0xA8, 0x88, 0x60, 0x83, 0xE8, 0x88, 0xA0, 0x83, 0x28, 0x89, 0xE0, 0x83, 0x69, 0x46, 0x40, 0x46, 0xA1, 0xF7, 0xC3, 0xFD, 0x16, 0xF8, 0x8B, 0x0F, 0x40, 0xF0, 0x0A,
0x00, 0x30, 0x70, 0xBD, 0xE8, 0xF8, 0x83, 0x28, 0x7B, 0xC0, 0x07, 0xFA, 0xD0, 0x69, 0x89, 0x40, 0x46, 0xAB, 0xF7, 0x1D, 0xF8, 0x18, 0xB3, 0x68, 0x89, 0xAD, 0xF8, 0x00, 0x00, 0x40, 0x20, 0xA4, 0xF8, 0x44, 0x00, 0x68, 0x78, 0xE0, 0x75, 0x68,
0x88, 0x20, 0x83, 0xA8, 0x4C, 0xFC, 0xFF, 0x38, 0x19, 0x21, 0x00, 0x88, 0x60, 0x83, 0xE8, 0x88, 0xA0, 0x83, 0x28, 0x89, 0xE0, 0x83, 0x69, 0x46, 0x40, 0x46, 0xA1, 0xF7, 0x1F, 0xFE, 0x16, 0xF8, 0x8B, 0x0F, 0x40, 0xF0, 0x1A, 0x00, 0xDB, 0xE7,
0xFF, 0xE7, 0x20, 0x6C, 0x80, 0x07, 0x07, 0xD5, 0x84, 0xF8, 0x21, 0x71, 0x94, 0xF8, 0xD2, 0x10, 0x08, 0x20, 0xA3, 0xF7, 0x3E, 0xFD, 0x06, 0xE0, 0xB4, 0xF8, 0x44, 0x00, 0x4F, 0xF6, 0xFE, 0x31, 0x08, 0x40, 0xA4, 0xF8, 0x44, 0x00, 0x84, 0xF8,
0xC3, 0x70, 0x40, 0x46, 0xBD, 0xE8, 0xF8, 0x43, 0x01, 0x21, 0xA3, 0xF7, 0x93, 0xBB, 0x03, 0x01, 0xBA, 0x01, 0xE8, 0x06, 0x0D, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x90, 0xF8, 0xD2, 0x60, 0x00, 0x6C, 0x0A,
0x7C, 0x01, 0xF1, 0x10, 0x05, 0x80, 0x06, 0x07, 0xD5, 0x20, 0x46, 0xA9, 0xF7, 0xC6, 0xFC, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xB0, 0xF7, 0x4A, 0xBD, 0x11, 0x2A, 0x45, 0xD1, 0x68, 0x78, 0x0F, 0x28, 0x42, 0xD1, 0xB4, 0xF8, 0x44, 0x00, 0x20,
0xF4, 0x80, 0x60, 0xA4, 0xF8, 0x44, 0x00, 0x30, 0x46, 0xB0, 0xF7, 0x3C, 0xFD, 0x94, 0xF8, 0xD1, 0x00, 0x10, 0xB9, 0xA8, 0x78, 0x1A, 0x28, 0x0B, 0xD0, 0x20, 0x6C, 0x80, 0x07, 0x29, 0xD5, 0xA8, 0x78, 0x84, 0xF8, 0x21, 0x01, 0xB1, 0xB2, 0xBD,
0xE8, 0x70, 0x40, 0x08, 0x20, 0xA3, 0xF7, 0xFC, 0xBC, 0x30, 0x46, 0xB0, 0xF7, 0x27, 0xFD, 0x73, 0xF7, 0xD6, 0xFD, 0x05, 0x46, 0xB4, 0xF8, 0x26, 0x21, 0xB4, 0xF8, 0x24, 0x11, 0x20, 0x46, 0x46, 0xF7, 0x69, 0xFB, 0xB4, 0xF8, 0x1C, 0x01, 0xA4,
0xF8, 0x48, 0x00, 0xB4, 0xF8, 0x1E, 0x01, 0xA4, 0xF8, 0x4A, 0x00, 0x20, 0x6C, 0x40, 0xF0, 0x02, 0x00, 0x20, 0x64, 0x28, 0x46, 0x73, 0xF7, 0xC3, 0xFD, 0x20, 0x46, 0xBD, 0xE8, 0x4C, 0xFC, 0xFF, 0x33, 0x1A, 0x21, 0x00, 0x70, 0x40, 0xAB, 0xF7,
0x09, 0xB9, 0xB4, 0xF8, 0x44, 0x00, 0x4F, 0xF6, 0xFE, 0x31, 0x08, 0x40, 0xA4, 0xF8, 0x44, 0x00, 0x70, 0xBD, 0x03, 0x01, 0x5C, 0x9E, 0x07, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x0E, 0x46, 0x87, 0xB0, 0x91, 0x46, 0x83, 0x46, 0x00, 0x25, 0xB1,
0xF8, 0x09, 0x10, 0x00, 0xF0, 0xD4, 0xFD, 0x82, 0x46, 0x00, 0x24, 0x4F, 0xF6, 0xFF, 0x77, 0x0D, 0xF1, 0x04, 0x08, 0x06, 0xEB, 0x44, 0x00, 0xB0, 0xF8, 0x0B, 0x00, 0xB8, 0x42, 0x09, 0xD0, 0x41, 0x00, 0x50, 0x46, 0x6E, 0xF7, 0x14, 0xFF, 0x48,
0xF8, 0x24, 0x00, 0x6D, 0x1C, 0x64, 0x1C, 0x06, 0x2C, 0xEF, 0xD3, 0x01, 0xAB, 0x2A, 0x46, 0x31, 0x46, 0x58, 0x46, 0xCD, 0xF8, 0x00, 0x90, 0x03, 0xF0, 0x07, 0xFD, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x03, 0x01, 0x64, 0xF6, 0x07, 0x0D, 0x00,
0x2D, 0xE9, 0xF0, 0x43, 0x87, 0xB0, 0x81, 0x46, 0x16, 0x46, 0x0D, 0x46, 0x17, 0x22, 0x68, 0x46, 0x74, 0xF7, 0x83, 0xFF, 0x01, 0x20, 0x4F, 0xF6, 0xFF, 0x77, 0x05, 0xEB, 0x40, 0x01, 0x40, 0x1C, 0xA1, 0xF8, 0x0B, 0x70, 0x06, 0x28, 0xF8, 0xD3,
0x00, 0x24, 0xE8, 0x46, 0x08, 0xEB, 0x44, 0x00, 0xB0, 0xF8, 0x0B, 0x00, 0xB8, 0x42, 0x0E, 0xD0, 0xA5, 0xF8, 0x0B, 0x00, 0x06, 0xAA, 0x29, 0x46, 0x48, 0x46, 0xFF, 0xF7, 0xB1, 0xFF, 0x30, 0xB1, 0x06, 0x98, 0xB0, 0x42, 0x03, 0xD3, 0x01, 0x20,
0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x64, 0x1C, 0x06, 0x2C, 0xE7, 0xD3, 0x00, 0x20, 0xF7, 0xE7, 0x03, 0x01, 0x22, 0x56, 0x08, 0x0D, 0x00, 0x03, 0x46, 0x08, 0x46, 0x4A, 0xB1, 0x06, 0xE0, 0xB0, 0xFB, 0xF2, 0xF1, 0x02, 0xFB, 0x11, 0x01, 0x00,
0x29, 0x03, 0xD0, 0x40, 0x1E, 0x98, 0x42, 0x4C, 0xFC, 0xFF, 0x2E, 0x1B, 0x21, 0x00, 0xF6, 0xD2, 0x00, 0x20, 0x70, 0x47, 0x03, 0x01, 0xB2, 0x01, 0x74, 0x08, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x85, 0xB0, 0x04, 0x46, 0x90, 0x46, 0x1D, 0x46,
0x4E, 0x00, 0x4F, 0xF6, 0xFF, 0x79, 0x21, 0xD0, 0x73, 0xF7, 0x3B, 0xFD, 0x07, 0x46, 0x94, 0xF8, 0xD2, 0x00, 0xA3, 0xF7, 0x28, 0xFB, 0x83, 0x46, 0x94, 0xF8, 0xD2, 0x00, 0x00, 0xF0, 0x8F, 0xFD, 0x01, 0x90, 0x38, 0x46, 0x73, 0xF7, 0x31, 0xFD,
0x0D, 0xF1, 0x08, 0x0A,
0x06, 0x23, 0x42, 0x46, 0x31, 0x46, 0x20, 0x46, 0xCD, 0xF8, 0x00, 0xA0, 0x03, 0xF0, 0x3D, 0xFD, 0x80, 0x46, 0x01, 0x98, 0xB0, 0xFB, 0xF6, 0xF7, 0x7F, 0x1C, 0x77, 0x43, 0x00, 0x24, 0x1C, 0xE0, 0x00, 0x20, 0xA5, 0xF8, 0x09, 0x00, 0x49, 0x46,
0x05, 0xEB, 0x40, 0x02, 0x40, 0x1C, 0xA2, 0xF8, 0x0B, 0x10, 0x06, 0x28, 0xF8, 0xD3, 0x05, 0xB0, 0x85, 0xE7, 0x3A, 0xF8, 0x14, 0x00, 0x01, 0x99, 0x38, 0x44, 0x6F, 0xF7, 0x0C, 0xF8, 0xB0, 0xFB, 0xF6, 0xF1, 0x06, 0xFB, 0x11, 0x00, 0x40, 0x08,
0x05, 0xEB, 0x44, 0x01, 0x64, 0x1C, 0xA1, 0xF8, 0x0B, 0x00, 0x44, 0x45, 0xED, 0xD3, 0x48, 0x46, 0x06, 0x2C, 0x05, 0xD2, 0x05, 0xEB, 0x44, 0x01, 0x64, 0x1C, 0xA1, 0xF8, 0x0B, 0x00, 0xF7, 0xE7, 0xA5, 0xF8, 0x09, 0xB0, 0xDF, 0xE7, 0x03, 0x01,
0x48, 0x22, 0x09, 0x0D, 0x00, 0x70, 0xB5, 0x0E, 0x46, 0x15, 0x46, 0x1C, 0x46, 0x51, 0x00, 0x03, 0xF0, 0x78, 0xFD, 0xC0, 0xF3, 0x47, 0x02, 0x22, 0x72, 0x29, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x8C, 0xFF, 0x00, 0x28, 0x10, 0xD1, 0x03, 0x22, 0x22,
0x72, 0x29, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x84, 0xFF, 0x00, 0x28, 0x08, 0xD1, 0x05, 0xE0, 0xE0, 0x28, 0x20, 0x00, 0x40, 0x70, 0x4C, 0xFC, 0xFF, 0x29, 0x1C, 0x21, 0x00, 0x0D, 0x00, 0xC0, 0x28, 0x20, 0x00, 0x20, 0x72, 0x28, 0x46, 0x70, 0xBD,
0x03, 0x01, 0xB0, 0x01, 0x66, 0x09, 0x0D, 0x00, 0x70, 0xB5, 0x8E, 0xB0, 0x04, 0x46, 0xAD, 0xF8, 0x04, 0x30, 0x12, 0x98, 0xAD, 0xF8, 0x06, 0x00, 0x0D, 0x46, 0x16, 0x46, 0x94, 0xF8, 0xD2, 0x00, 0x6B, 0x46, 0xFF, 0xF7, 0xCF, 0xFF, 0xAD, 0xF8,
0x00, 0x00, 0x01, 0x46, 0xAD, 0xF8, 0x02, 0x00, 0x6B, 0x46, 0x0C, 0xAA, 0x20, 0x46, 0xFF, 0xF7, 0x6E, 0xFF, 0x94, 0xF8, 0x20, 0x21, 0x31, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x59, 0xFF, 0x38, 0xB9, 0xB4, 0xF8, 0x1C, 0x01, 0xA8, 0x42, 0x2B, 0xD1,
0xB4, 0xF8, 0x1E, 0x01, 0xB0, 0x42, 0x27, 0xD1, 0x18, 0x22, 0x69, 0x46, 0x06, 0xA8, 0x8C, 0xF7, 0x67, 0xFE, 0x94, 0xF8, 0x20, 0x01, 0x8D, 0xF8, 0x08, 0x00, 0xB4, 0xF8, 0x22, 0x01, 0xAD, 0xF8, 0x09, 0x00, 0x00, 0x20, 0x69, 0x46, 0x04, 0xEB,
0x40, 0x02, 0x01, 0xEB, 0x40, 0x03, 0xB2, 0xF8, 0x28, 0x21, 0x40, 0x1C, 0xA3, 0xF8, 0x0B, 0x20, 0x06, 0x28, 0xF4, 0xD3, 0x69, 0x46, 0x20, 0x46, 0x0C, 0x9A, 0xFF, 0xF7, 0x01, 0xFF, 0x20, 0xB9, 0x18, 0x22, 0x06, 0xA9, 0x68, 0x46, 0x8C, 0xF7,
0x47, 0xFE, 0x00, 0x20, 0x8D, 0xF8, 0x08, 0x00, 0x69, 0x46, 0x20, 0x46, 0xAB, 0xF7, 0xBC, 0xF9, 0x0E, 0xB0, 0x70, 0xBD, 0x03, 0x01, 0xFC, 0x02, 0x12, 0x0A,
0x0D, 0x00, 0x7C, 0xB5, 0x04, 0x46, 0x90, 0xF8, 0xD1, 0x00, 0x01, 0xF1, 0x10, 0x05, 0x01, 0x28, 0x1C, 0xD1, 0xB4, 0xF8, 0x44, 0x00, 0x41, 0x05, 0x03, 0xD4, 0xB4, 0xF8, 0x46, 0x10, 0x49, 0x05, 0x14, 0xD5, 0x4F, 0xF6, 0xFE, 0x31, 0x08, 0x40,
0xA4, 0xF8, 0x44, 0x00, 0xB4, 0xF8, 0x46, 0x00, 0x08, 0x40, 0xA4, 0xF8, 0x46, 0x4C, 0xFC, 0xFF, 0x24, 0x1D, 0x21, 0x00, 0x00, 0x20, 0x6C, 0x80, 0x07, 0x07, 0xD5, 0x23, 0x21, 0x20, 0x46, 0xB2, 0xF7, 0x37, 0xFC, 0x20, 0x6C, 0x20, 0xF0, 0x02,
0x00, 0x20, 0x64, 0xB4, 0xF8, 0x44, 0x00, 0x38, 0xB1, 0x40, 0x05, 0x02, 0xD5, 0x0F, 0x22, 0x23, 0x21, 0x10, 0xE0, 0x0F, 0x22, 0x2A, 0x21, 0x0D, 0xE0, 0xB4, 0xF8, 0x46, 0x00, 0x40, 0xF2, 0x01, 0x46, 0x30, 0x42, 0xF6, 0xD1, 0x6D, 0x1C, 0x29,
0x46, 0x20, 0x46, 0xAA, 0xF7, 0xA4, 0xFD, 0x01, 0x00, 0x06, 0xD0, 0x0F, 0x22, 0x02, 0xB0, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xAB, 0xF7, 0x56, 0xB9, 0x94, 0xF8, 0xD1, 0x00, 0x01, 0x28, 0x06, 0xD0, 0x01, 0xAA, 0x29, 0x46, 0x20, 0x46, 0xFF,
0xF7, 0x79, 0xFE, 0x00, 0x28, 0x69, 0xD0, 0x29, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x7E, 0xFD, 0x01, 0x00, 0x03, 0xD0, 0xFC, 0x48, 0x80, 0x68, 0x80, 0x06, 0x5C, 0xD5, 0x28, 0x88, 0xA4, 0xF8, 0x1C, 0x01, 0x68, 0x88, 0xA4, 0xF8, 0x1E, 0x01, 0xA8,
0x88, 0xA0, 0x83, 0xE8, 0x88, 0xE0, 0x83, 0x28, 0x7A, 0x84, 0xF8, 0x20, 0x01, 0xB5, 0xF8, 0x09, 0x00, 0xA4, 0xF8, 0x22, 0x01, 0x00, 0x20, 0x05, 0xEB, 0x40, 0x02, 0x04, 0xEB, 0x40, 0x03, 0xB2, 0xF8, 0x0B, 0x20, 0x40, 0x1C, 0xA3, 0xF8, 0x28,
0x21, 0x06, 0x28, 0xF4, 0xD3, 0x00, 0x20, 0x84, 0xF8, 0x21, 0x01, 0x69, 0xB1, 0x29, 0x46, 0x20, 0x46, 0xB2, 0xF7, 0x29, 0xFC, 0x01, 0x00, 0x04, 0xD0, 0x0F, 0x22, 0x20, 0x46, 0xAB, 0xF7, 0x16, 0xF9, 0x7C, 0xBD, 0xA4, 0xF8, 0x44, 0x60, 0x7C,
0xBD, 0xA4, 0xF8, 0x44, 0x60, 0x20, 0x6C, 0x40, 0xF0, 0x02, 0x00, 0x20, 0x64, 0x94, 0xF8, 0xD1, 0x00, 0x01, 0x28, 0x1A, 0xD0, 0x73, 0xF7, 0xE4, 0xFB, 0x06, 0x46, 0xB4, 0xF8, 0x4E, 0x20, 0x4C, 0xFC, 0xFF, 0x1F, 0x1E, 0x21, 0x00, 0xB4, 0xF8,
0x4C, 0x10, 0x20, 0x46, 0x46, 0xF7, 0x77, 0xF9, 0x28, 0x88, 0xA4, 0xF8, 0x48, 0x00, 0x68, 0x88, 0xA4, 0xF8, 0x4A, 0x00, 0xA8, 0x88, 0xA0, 0x83, 0xE8, 0x88, 0xE0, 0x83, 0x30, 0x46, 0x73, 0xF7, 0xD3, 0xFB, 0x20, 0x46, 0xAA, 0xF7, 0x1B, 0xFF,
0x7C, 0xBD, 0xE8, 0x88, 0x00, 0x90, 0xAB, 0x88, 0x6A, 0x88, 0x29, 0x88, 0x20, 0x46, 0xFF, 0xF7, 0xF5, 0xFE, 0x7C, 0xBD, 0x0F, 0x22, 0x1A, 0x21, 0xC7, 0xE7, 0x0F, 0x22, 0x20, 0x21, 0xC4, 0xE7, 0x03, 0x01, 0x6C, 0x8A, 0x0B, 0x0D, 0x00, 0x30,
0xB5, 0x89, 0xB0, 0x04, 0x46, 0xB0, 0xF8, 0x1C, 0x01, 0xAD, 0xF8, 0x00, 0x00, 0xB4, 0xF8, 0x1E, 0x01, 0xAD, 0xF8, 0x02, 0x00, 0x94, 0xF8, 0x20, 0x01, 0x8D, 0xF8, 0x08, 0x00, 0xB4, 0xF8, 0x22, 0x01, 0xAD, 0xF8, 0x09, 0x00, 0x0D, 0x46, 0x00,
0x22, 0x68, 0x46, 0x04, 0xEB, 0x42, 0x01, 0x00, 0xEB, 0x42, 0x03, 0xB1, 0xF8, 0x28, 0x11, 0x52, 0x1C, 0xA3, 0xF8, 0x0B, 0x10, 0x06, 0x2A, 0xF4, 0xD3, 0x06, 0xAA, 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0xE4, 0xFD, 0x07, 0xAA, 0x29, 0x46, 0x20,
0x46, 0xFF, 0xF7, 0xDF, 0xFD, 0xDD, 0xE9, 0x06, 0x01, 0x81, 0x42, 0x02, 0xD3, 0x01, 0x20, 0x09, 0xB0, 0x30, 0xBD, 0x00, 0x20, 0xFB, 0xE7, 0x03, 0x01, 0xF4, 0x01, 0xF2, 0x0B, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0x90, 0xF8, 0xD1,
0x00, 0x10, 0x31, 0x01, 0x28, 0x07, 0xD0, 0x49, 0x1C, 0x0D, 0x46, 0x20, 0x46, 0xAA, 0xF7, 0xE2, 0xFC, 0x06, 0x00, 0x07, 0xD0, 0x4E, 0xE0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x10, 0x22, 0x24, 0x21, 0xAB, 0xF7, 0x93, 0xB8, 0xB4, 0xF8, 0x1C,
0x71, 0x28, 0x88, 0x87, 0x42, 0x00, 0xD8, 0x07, 0x46, 0x4C, 0xFC, 0xFF, 0x1A, 0x1F, 0x21, 0x00, 0xB4, 0xF8, 0x1E, 0x01, 0x69, 0x88, 0x88, 0x42, 0x00, 0xD3, 0x08, 0x46, 0x80, 0x46, 0x29, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0xA4, 0xFF, 0x98, 0xB3,
0x28, 0x7A, 0x84, 0xF8, 0x20, 0x01, 0xB5, 0xF8, 0x09, 0x00, 0xA4, 0xF8, 0x22, 0x01, 0x00, 0x20, 0x05, 0xEB, 0x40, 0x01, 0x04, 0xEB, 0x40, 0x02, 0xB1, 0xF8, 0x0B, 0x10, 0x40, 0x1C, 0xA2, 0xF8, 0x28, 0x11, 0x06, 0x28, 0xF4, 0xD3, 0x47, 0x45,
0x1F, 0xD8, 0xA8, 0x88, 0xA1, 0x8B, 0x88, 0x42, 0x1B, 0xD1, 0xE8, 0x88, 0xE1, 0x8B, 0x88, 0x42, 0x17, 0xD1, 0x73, 0xF7, 0x40, 0xFB, 0x05, 0x46, 0xB4, 0xF8, 0x26, 0x21, 0xB4, 0xF8, 0x24, 0x11, 0x20, 0x46, 0x46, 0xF7, 0xD3, 0xF8, 0xA4, 0xF8,
0x48, 0x70, 0xA4, 0xF8, 0x4A, 0x80, 0x28, 0x46, 0x73, 0xF7, 0x35, 0xFB, 0x20, 0x46, 0xAA, 0xF7, 0x7D, 0xFE, 0x1E, 0xB9, 0xBD, 0xE8, 0xF0, 0x81, 0xFF, 0xE7, 0x1E, 0x26, 0x10, 0x22, 0x31, 0x46, 0x20, 0x46, 0xAB, 0xF7, 0x46, 0xF8, 0x20, 0x6C,
0x80, 0x07, 0x08, 0xD5, 0x84, 0xF8, 0x21, 0x61, 0x94, 0xF8, 0xD2, 0x10, 0xBD, 0xE8, 0xF0, 0x41, 0x08, 0x20, 0xA3, 0xF7, 0x39, 0xBA, 0xB4, 0xF8, 0x44, 0x00, 0x4F, 0xF6, 0xFE, 0x31, 0x08, 0x40, 0xA4, 0xF8, 0x44, 0x00, 0xE2, 0xE7, 0x03, 0x01,
0x7C, 0xE2, 0x0C, 0x0D, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x48, 0x7C, 0x0E, 0x28, 0x1C, 0xD0, 0x12, 0x28, 0x0D, 0xD0, 0xFF, 0x28, 0x0A,
0xD1, 0x20, 0x6C, 0x01, 0x21, 0xB1, 0xEB, 0x10, 0x6F, 0x05, 0xD1, 0x00, 0x21, 0xC4, 0xF8, 0xDC, 0x10, 0x40, 0xF4, 0x00, 0x50, 0x20, 0x64, 0x10, 0xBD, 0x69, 0x48, 0x00, 0x78, 0xC0, 0x06, 0xFA, 0xD5, 0x94, 0xF8, 0xD2, 0x00, 0xB0, 0xF7, 0x42,
0xFA, 0xB4, 0xF8, 0x44, 0x00, 0x4C, 0xFC, 0xFF, 0x15, 0x20, 0x21, 0x00, 0x20, 0xF4, 0x00, 0x70, 0x12, 0xE0, 0x94, 0xF8, 0xD2, 0x00, 0xB0, 0xF7, 0x39, 0xFA, 0x20, 0x6C, 0x40, 0x05, 0x07, 0xD5, 0x1A, 0x21, 0x20, 0x46, 0xB2, 0xF7, 0xDB, 0xFA,
0x20, 0x6C, 0x20, 0xF4, 0x80, 0x60, 0x20, 0x64, 0xB4, 0xF8, 0x44, 0x00, 0x20, 0xF0, 0x08, 0x00, 0xA4, 0xF8, 0x44, 0x00, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xA3, 0xF7, 0x01, 0xBA, 0x03, 0x01, 0xE0, 0x03, 0x5A, 0x0D, 0x0D, 0x00, 0x2D, 0xE9,
0xF0, 0x4F, 0x04, 0x46, 0x55, 0x49, 0x90, 0xF8, 0xD2, 0x00, 0x85, 0xB0, 0xC0, 0xEB, 0xC0, 0x00, 0x09, 0x68, 0x00, 0xEB, 0x40, 0x00, 0x01, 0xEB, 0x00, 0x18, 0x98, 0xF8, 0x8B, 0x00, 0x20, 0xF0, 0x08, 0x01, 0x88, 0xF8, 0x8B, 0x10, 0x94, 0xF8,
0xD2, 0x00, 0x69, 0x46, 0x1E, 0x30, 0x64, 0xF7, 0x15, 0xF8, 0x00, 0x28, 0x7E, 0xD0, 0xB4, 0xF8, 0x44, 0x00, 0x40, 0x05, 0x5D, 0xD5, 0xB4, 0xF8, 0x48, 0x00, 0xB4, 0xF8, 0x4A, 0x10, 0x88, 0x42, 0x03, 0xD0, 0x94, 0xF8, 0x20, 0x21, 0xFF, 0xF7,
0x54, 0xFD, 0x45, 0x00, 0x94, 0xF8, 0xD2, 0x00, 0xFF, 0xF7, 0xD0, 0xFB, 0x85, 0x80, 0xE5, 0xB3, 0xB4, 0xF8, 0x22, 0x11, 0x20, 0x46, 0x00, 0xF0, 0xCB, 0xFA, 0x83, 0x46, 0x20, 0x6C, 0x00, 0x26, 0x20, 0xF4, 0x80, 0x20, 0x4F, 0xF6, 0xFF, 0x7A,
0x20, 0x64, 0x04, 0xEB, 0x46, 0x07, 0xB7, 0xF8, 0x28, 0x01, 0x50, 0x45, 0x39, 0xD0, 0x41, 0x00, 0x58, 0x46, 0x6E, 0xF7, 0x09, 0xFC, 0xB0, 0xFB, 0xF5, 0xF1, 0x81, 0x46, 0x05, 0xFB, 0x11, 0x90, 0xA7, 0xF8, 0x28, 0x01, 0x5F, 0xEA, 0x49, 0x10,
0x15, 0xD4, 0x94, 0xF8, 0xD2, 0x00, 0x00, 0xF0, 0xDC, 0xFA, 0x40, 0x01, 0x22, 0xD5, 0x4F, 0xF0, 0x80, 0x60, 0xB0, 0xFB, 0xF5, 0xF1, 0x69, 0x4C, 0xFC, 0xFF, 0x10, 0x21, 0x21, 0x00, 0x43, 0x48, 0x46, 0x6E, 0xF7, 0x78, 0xFD, 0xB0, 0xFB, 0xF5,
0xF1, 0x05, 0xFB, 0x11, 0x01, 0xA7, 0xF8, 0x28, 0x11, 0x40, 0x01, 0x12, 0xD5, 0x02, 0x23, 0xB7, 0xF8, 0x28, 0x01, 0x2A, 0x46, 0x00, 0x21, 0x00, 0xE0, 0x0E, 0xE0, 0x64, 0xF7, 0x9D, 0xFE, 0xA7, 0xF8, 0x28, 0x01, 0x01, 0x20, 0xB0, 0x40, 0x21,
0x6C, 0xC0, 0xF3, 0x00, 0x00, 0x41, 0xEA, 0x80, 0x40, 0x20, 0x64, 0x76, 0x1C, 0x06, 0x2E, 0xBF, 0xD3, 0xB8, 0xF8, 0x8E, 0x10, 0xA8, 0xF8, 0x94, 0x10, 0x94, 0xF8, 0xD2, 0x00, 0xAA, 0xF7, 0xF9, 0xFC, 0xAD, 0xF8, 0x10, 0x00, 0x94, 0xF8, 0xD2,
0x00, 0x04, 0xA9, 0xA1, 0xF7, 0xBA, 0xF9, 0xBD, 0xF8, 0x10, 0x20, 0x01, 0xA9, 0x20, 0x46, 0xAA, 0xF7, 0xD3, 0xFC, 0x94, 0xF8, 0xD2, 0x00, 0x0C, 0x22, 0x01, 0xA9, 0xB3, 0xF7, 0x00, 0xFA, 0x0B, 0x49, 0x00, 0xE0, 0x16, 0xE0, 0x18, 0xB3, 0x00,
0x98, 0x09, 0x68, 0x00, 0xEB, 0x40, 0x00, 0x01, 0xEB, 0x80, 0x00, 0x80, 0x79, 0x84, 0xF8, 0xD6, 0x00, 0x98, 0xF8, 0x8B, 0x00, 0x40, 0xF0, 0x0A,
0x01, 0x3F, 0xE0, 0x48, 0x7F, 0x20, 0x00, 0x80, 0x7F, 0x20, 0x00, 0xC0, 0x28, 0x20, 0x00, 0xC4, 0x30, 0x20, 0x00, 0x00, 0x23, 0x4F, 0xF4, 0x53, 0x72, 0x40, 0xF2, 0xA1, 0x31, 0x61, 0x48, 0x74, 0xF7, 0x45, 0xF9, 0x94, 0xF8, 0xD2, 0x10, 0x08,
0x20, 0xA3, 0xF7, 0x35, 0xF9, 0x02, 0xE5, 0x00, 0x98, 0xB4, 0xF8, 0xC6, 0x20, 0x00, 0xEB, 0x40, 0x03, 0x08, 0x68, 0x00, 0xEB, 0x83, 0x01, 0x4A, 0x80, 0x00, 0x99, 0xB4, 0xF8, 0xC4, 0x20, 0x01, 0xEB, 0x41, 0x01, 0x00, 0xEB, 0x81, 0x01, 0x04,
0xF1, 0xD2, 0x04, 0x0A,
0x80, 0x00, 0x99, 0xA2, 0x78, 0x01, 0xEB, 0x41, 0x01, 0x00, 0xEB, 0x81, 0x01, 0x4C, 0xFC, 0xFF, 0x0B, 0x22, 0x21, 0x00, 0x4A, 0x72, 0x00, 0x99, 0x22, 0x79, 0x01, 0xEB, 0x41, 0x01, 0x00, 0xEB, 0x81, 0x00, 0x82, 0x71, 0x21, 0x78, 0x4F, 0xF0,
0x08, 0x00, 0xA3, 0xF7, 0x0E, 0xF9, 0x98, 0xF8, 0x8B, 0x00, 0x20, 0xF0, 0x02, 0x01, 0x88, 0xF8, 0x8B, 0x10, 0xD5, 0xE4, 0x03, 0x01, 0xA6, 0x02, 0x36, 0x0F, 0x0D, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x46, 0x49, 0x90, 0xF8, 0xD2, 0x00, 0x88, 0xB0,
0xC0, 0xEB, 0xC0, 0x00, 0x09, 0x68, 0x00, 0xEB, 0x40, 0x00, 0x01, 0xEB, 0x00, 0x15, 0xE0, 0x88, 0xB4, 0xF8, 0x1C, 0x11, 0x88, 0x42, 0x22, 0xD3, 0xB4, 0xF8, 0x1E, 0x11, 0x88, 0x42, 0x1E, 0xD8, 0x20, 0x89, 0xA1, 0x8B, 0x88, 0x42, 0x1A, 0xD1,
0x60, 0x89, 0xE1, 0x8B, 0x88, 0x42, 0x16, 0xD1, 0xB4, 0xF8, 0x26, 0x01, 0x10, 0xB9, 0xB4, 0xF8, 0x24, 0x11, 0x49, 0xB1, 0xB4, 0xF8, 0x4C, 0x10, 0xB4, 0xF8, 0x24, 0x21, 0x91, 0x42, 0x0A,
0xD1, 0xB4, 0xF8, 0x4E, 0x10, 0x81, 0x42, 0x06, 0xD1, 0x15, 0xF8, 0x8B, 0x0F, 0x40, 0xF0, 0x08, 0x00, 0x28, 0x70, 0x00, 0x20, 0x4E, 0xE0, 0x95, 0xF8, 0x8B, 0x00, 0x6E, 0x46, 0x20, 0xF0, 0x08, 0x00, 0x85, 0xF8, 0x8B, 0x00, 0x0F, 0x20, 0x8D,
0xF8, 0x00, 0x00, 0xB4, 0xF8, 0x1C, 0x01, 0xAD, 0xF8, 0x01, 0x00, 0xB4, 0xF8, 0x1E, 0x01, 0xAD, 0xF8, 0x03, 0x00, 0xA0, 0x8B, 0xAD, 0xF8, 0x05, 0x00, 0xE0, 0x8B, 0xAD, 0xF8, 0x07, 0x00, 0xB4, 0xF8, 0x1E, 0x21, 0xB4, 0xF8, 0x1C, 0x11, 0x94,
0xF8, 0xD2, 0x00, 0x73, 0x1C, 0xFF, 0xF7, 0xA0, 0xFC, 0x01, 0x46, 0x9D, 0xF8, 0x09, 0x00, 0x18, 0xB9, 0xAD, 0xF8, 0x01, 0x10, 0xAD, 0xF8, 0x03, 0x10, 0x73, 0x1C, 0x06, 0xAA, 0x20, 0x46, 0xFF, 0xF7, 0x3C, 0xFC, 0x9D, 0xF8, 0x09, 0x00, 0x84,
0x4C, 0xFC, 0xFF, 0x06, 0x23, 0x21, 0x00, 0xF8, 0x20, 0x01, 0xBD, 0xF8, 0x0A,
0x00, 0xA4, 0xF8, 0x22, 0x01, 0x00, 0x20, 0x06, 0xEB, 0x40, 0x01, 0x04, 0xEB, 0x40, 0x02, 0x89, 0x89, 0x40, 0x1C, 0xA2, 0xF8, 0x28, 0x11, 0x06, 0x28, 0xF5, 0xD3, 0x94, 0xF8, 0xD2, 0x00, 0x18, 0x22, 0x69, 0x46, 0xB3, 0xF7, 0x2F, 0xF9, 0x00,
0x28, 0x0C, 0xD1, 0x15, 0xF8, 0x8B, 0x0F, 0x40, 0xF0, 0x08, 0x00, 0x28, 0x70, 0x07, 0x20, 0x84, 0xF8, 0x21, 0x01, 0x94, 0xF8, 0xD2, 0x10, 0x08, 0x20, 0xA3, 0xF7, 0x7C, 0xF8, 0x08, 0xB0, 0x70, 0xBD, 0x07, 0x00, 0x02, 0x00, 0xC0, 0x28, 0x20,
0x00, 0x03, 0x01, 0x98, 0x04, 0x58, 0x10, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x45, 0x88, 0x06, 0x79, 0x28, 0x46, 0x70, 0xF7, 0x74, 0xFC, 0x04, 0x00, 0x44, 0xD0, 0x7B, 0x4F, 0xDF, 0xF8, 0xEC, 0x91, 0xDF, 0xF8, 0xEC, 0xA1, 0x4F, 0xF0, 0xFF,
0x08, 0x12, 0x2E, 0x3B, 0xD2, 0xDF, 0xE8, 0x06, 0xF0, 0x3A, 0x09, 0x22, 0x1E, 0x3A, 0x47, 0x3A, 0x52, 0x5E, 0x86, 0x3C, 0x3A, 0x8B, 0xBB, 0xC0, 0xCA, 0xCF, 0xD4, 0xA8, 0xF7, 0x9B, 0xFC, 0x18, 0xB1, 0x28, 0x46, 0xAF, 0xF7, 0x7A, 0xF8, 0x09,
0xE0, 0x70, 0x48, 0x3C, 0x21, 0x00, 0x78, 0xB2, 0xF7, 0xDA, 0xF8, 0x78, 0x6C, 0x70, 0xF7, 0x4E, 0xFD, 0xC7, 0xF8, 0x44, 0x80, 0xBD, 0xE8, 0xF0, 0x47, 0xA8, 0xF7, 0x24, 0xBC, 0x28, 0x46, 0xAF, 0xF7, 0x68, 0xF8, 0xF5, 0xE7, 0x28, 0x46, 0xAF,
0xF7, 0x64, 0xF8, 0x03, 0x20, 0xAD, 0xF7, 0xB6, 0xFB, 0x00, 0x20, 0xAD, 0xF7, 0x9E, 0xFB, 0xD9, 0xF8, 0x00, 0x00, 0x40, 0x04, 0x0A,
0xD4, 0xAF, 0xF7, 0x3D, 0xFF, 0x00, 0x28, 0x06, 0xD0, 0x28, 0x46, 0xB0, 0xF7, 0x65, 0xF8, 0xB0, 0xF7, 0x2E, 0xF8, 0x8A, 0xF8, 0x00, 0x00, 0x4C, 0xFC, 0xFF, 0x01, 0x24, 0x21, 0x00, 0xBD, 0xE8, 0xF0, 0x87, 0x02, 0x20, 0xAD, 0xF7, 0x9F, 0xFB,
0x00, 0x20, 0xAD, 0xF7, 0x87, 0xFB, 0xBD, 0xE8, 0xF0, 0x47, 0x00, 0x20, 0xAD, 0xF7, 0xD5, 0xBB, 0x71, 0xF7, 0x8F, 0xF9, 0x10, 0xB1, 0x20, 0x46, 0xA3, 0xF7, 0xD0, 0xF8, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0xAE, 0xF7, 0x90, 0xBF, 0xB4, 0xF8,
0x44, 0x00, 0x20, 0xF0, 0x02, 0x00, 0xA4, 0xF8, 0x44, 0x00, 0x20, 0x6A, 0xE0, 0x60, 0x94, 0xF8, 0x24, 0x00, 0x20, 0x74, 0x88, 0xE0, 0xB4, 0xF8, 0x44, 0x00, 0x4F, 0xF6, 0xFE, 0x31, 0x08, 0x40, 0xA4, 0xF8, 0x44, 0x00, 0x20, 0x6C, 0x80, 0x07,
0x7E, 0xD5, 0x45, 0x49, 0xC5, 0xEB, 0xC5, 0x00, 0x00, 0xEB, 0x40, 0x00, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x90, 0xF8, 0x8B, 0x00, 0x00, 0x07, 0x01, 0xD5, 0x00, 0x21, 0x07, 0xE0, 0x94, 0xF8, 0x21, 0x11, 0x19, 0xB1, 0x00, 0x20, 0x84, 0xF8,
0x21, 0x01, 0x00, 0xE0, 0x07, 0x21, 0x20, 0x46, 0xB2, 0xF7, 0xA0, 0xF8, 0x20, 0x6C, 0x20, 0xF0, 0x02, 0x00, 0x20, 0x64, 0x60, 0xE0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0xA9, 0xF7, 0x94, 0xB9, 0xD9, 0xF8, 0x00, 0x00, 0x44, 0xF2, 0x10, 0x01,
0x08, 0x42, 0x0C, 0xD0, 0x94, 0xF8, 0xD1, 0x00, 0x68, 0xB1, 0x00, 0x21, 0x28, 0x46, 0xB2, 0xF7, 0x57, 0xF8, 0x00, 0x20, 0xA8, 0xF7, 0x0F, 0xFC, 0x00, 0x20, 0xA8, 0xF7, 0x04, 0xFC, 0xBD, 0xE8, 0xF0, 0x47, 0x60, 0xF7, 0x5D, 0xB9, 0xAD, 0xF7,
0x74, 0xFB, 0x18, 0xB1, 0x00, 0x21, 0x28, 0x46, 0xB2, 0xF7, 0x46, 0xF8, 0x00, 0x20, 0xAD, 0xF7, 0x8C, 0xFB, 0x00, 0x20, 0xAD, 0xF7, 0x6D, 0xFB, 0xAF, 0xF7, 0xBD, 0xFE, 0x00, 0x28, 0xEA, 0xD0, 0x28, 0x46, 0xAF, 0xF7, 0xE5, 0xFF, 0xAF, 0xF7,
0xAE, 0x4C, 0xFC, 0xFF, 0xFC, 0x24, 0x21, 0x00, 0xFF, 0x8A, 0xF8, 0x00, 0x00, 0xE2, 0xE7, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0xAD, 0xF7, 0xAF, 0xBD, 0xB4, 0xF8, 0x44, 0x00, 0x20, 0xF0, 0x40, 0x00, 0xA4, 0xF8, 0x44, 0x00, 0x28, 0x46, 0xA6,
0xF7, 0x6E, 0xFB, 0x1C, 0xE0, 0xB4, 0xF8, 0x46, 0x00, 0x40, 0xF4, 0x00, 0x70, 0x15, 0xE0, 0xA0, 0x8F, 0xBD, 0xE8, 0xF0, 0x47, 0x33, 0xF7, 0x26, 0xBA, 0xB4, 0xF8, 0x44, 0x00, 0xC0, 0x06, 0x3F, 0xF5, 0x61, 0xAF, 0xB4, 0xF8, 0x46, 0x00, 0xC1,
0x06, 0xF9, 0xD4, 0x21, 0x6C, 0x40, 0xF0, 0x10, 0x00, 0x21, 0xF4, 0x00, 0x71, 0x41, 0xF0, 0x40, 0x01, 0x21, 0x64, 0xA4, 0xF8, 0x46, 0x00, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0xA2, 0xF7, 0x82, 0xBF, 0xD8, 0xE1, 0x20, 0x00, 0x24, 0x29, 0x20,
0x00, 0x99, 0x32, 0x20, 0x00, 0xE0, 0x28, 0x20, 0x00, 0xC0, 0x28, 0x20, 0x00, 0x03, 0x01, 0xF4, 0x01, 0x6C, 0x12, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0xAD, 0xF7, 0xF7, 0xFE, 0x00, 0xB1, 0x40, 0x20, 0x40, 0xF0, 0x08, 0x05, 0xA0,
0x69, 0x00, 0x22, 0x41, 0x79, 0x00, 0x79, 0x61, 0xF7, 0x7C, 0xFE, 0x07, 0x46, 0x4F, 0xF4, 0x48, 0x11, 0x4F, 0xF4, 0x18, 0x10, 0xC8, 0x65, 0x29, 0x46, 0x05, 0x20, 0x6F, 0xF7, 0x47, 0xFD, 0x27, 0x4D, 0xD5, 0xF8, 0xF4, 0x02, 0x20, 0xF4, 0x7F,
0x40, 0xC5, 0xF8, 0xF4, 0x02, 0xD5, 0xF8, 0xF4, 0x02, 0x40, 0xF0, 0x00, 0x40, 0xC5, 0xF8, 0xF4, 0x02, 0x28, 0x68, 0x40, 0xF0, 0x02, 0x00, 0x45, 0xF8, 0xA0, 0x09, 0x20, 0x49, 0x1E, 0x48, 0x08, 0x60, 0x1F, 0x49, 0x4F, 0xF0, 0x01, 0x00, 0x08,
0x60, 0xAD, 0xF7, 0xC8, 0xFE, 0x00, 0xB1, 0x01, 0x20, 0xAD, 0xF7, 0x37, 0xFF, 0x1B, 0x48, 0x19, 0x49, 0x38, 0x31, 0x4C, 0xFC, 0xFF, 0xF7, 0x25, 0x21, 0x00, 0x40, 0x68, 0x08, 0x60, 0xA0, 0x69, 0x19, 0x49, 0xC0, 0x79, 0x40, 0xF0, 0x80, 0x00,
0x08, 0x60, 0xA0, 0x69, 0x17, 0x4E, 0x80, 0x79, 0x00, 0x28, 0xA0, 0x7B, 0x13, 0xD0, 0x01, 0x21, 0x61, 0xF7, 0x68, 0xFF, 0x13, 0x4E, 0xE8, 0x69, 0x80, 0x36, 0x40, 0xF0, 0x00, 0x70, 0xE8, 0x61, 0x6E, 0x61, 0x11, 0x48, 0x80, 0x8A, 0xC5, 0xF8,
0x04, 0x03, 0x0A,
0x49, 0x00, 0x20, 0x0C, 0x39, 0x08, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x21, 0x61, 0xF7, 0x54, 0xFF, 0xA0, 0x69, 0x00, 0x22, 0x01, 0x68, 0x38, 0x46, 0x09, 0x1D, 0x62, 0xF7, 0x95, 0xFA, 0xE9, 0xE7, 0xA0, 0x80, 0x31, 0x00, 0x40, 0x23, 0x00,
0x01, 0x6C, 0x8B, 0x31, 0x00, 0xE0, 0x8A, 0x31, 0x00, 0x38, 0x29, 0x20, 0x00, 0xA4, 0x86, 0x31, 0x00, 0x05, 0x00, 0x00, 0x80, 0x80, 0x7F, 0x20, 0x00, 0x03, 0x01, 0x66, 0x5C, 0x13, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x0F, 0x46, 0x05, 0x46,
0xFD, 0x49, 0x90, 0xF8, 0xD2, 0x00, 0xC0, 0xEB, 0xC0, 0x00, 0x09, 0x68, 0x00, 0xEB, 0x40, 0x00, 0x01, 0xEB, 0x00, 0x14, 0x72, 0xF7, 0xC3, 0xFF, 0xB4, 0xF8, 0x8E, 0x10, 0x06, 0x46, 0x78, 0x1A, 0x80, 0xB2, 0x47, 0xF6, 0xFF, 0x72, 0x90, 0x42,
0x07, 0xD2, 0xB5, 0xF8, 0xC6, 0x10, 0x41, 0x43, 0xD4, 0xF8, 0x04, 0x01, 0x6E, 0xF7, 0x30, 0xF9, 0x08, 0xE0, 0xC8, 0x1B, 0xB5, 0xF8, 0xC6, 0x10, 0x80, 0xB2, 0x41, 0x43, 0xD4, 0xF8, 0x04, 0x01, 0x6E, 0xF7, 0xAD, 0xFA, 0x04, 0x46, 0x30, 0x46,
0x72, 0xF7, 0xA9, 0xFF, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x01, 0x1A, 0xBE, 0x13, 0x0D, 0x00, 0xE7, 0x49, 0xC0, 0xEB, 0xC0, 0x00, 0x00, 0xEB, 0x40, 0x00, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0xD0, 0x4C, 0xFC, 0xFF, 0xF2, 0x26, 0x21,
0x00, 0xF8, 0x04, 0x01, 0x70, 0x47, 0x03, 0x01, 0x38, 0xD4, 0x13, 0x0D, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x08, 0x0A,
0x00, 0x21, 0x61, 0xF7, 0xFB, 0xFD, 0x95, 0xF8, 0xD0, 0x20, 0x00, 0x21, 0x92, 0x07, 0x00, 0xD5, 0x00, 0x1F, 0xA2, 0x07, 0x07, 0xD0, 0xE2, 0x43, 0x92, 0x07, 0x05, 0xD1, 0xD9, 0x4A, 0x12, 0x78, 0x90, 0x42, 0x00, 0xD2, 0x00, 0xB9, 0x01, 0x21,
0x08, 0x46, 0x70, 0xBD, 0x03, 0x01, 0xC4, 0x01, 0x08, 0x14, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x0F, 0x46, 0x05, 0x46, 0x00, 0x26, 0x44, 0xF7, 0x07, 0xF9, 0x04, 0x46, 0xC7, 0xF3, 0xC0, 0x08, 0x39, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0xD8, 0xFF,
0x00, 0x28, 0xC8, 0xD0, 0x6C, 0xB1, 0x60, 0x8C, 0x40, 0xF0, 0x10, 0x00, 0x60, 0x84, 0xE8, 0x7B, 0x38, 0xB9, 0x20, 0x46, 0x44, 0xF7, 0xF7, 0xF8, 0x18, 0xB1, 0x60, 0x8C, 0x40, 0xF0, 0x80, 0x00, 0x60, 0x84, 0x01, 0x21, 0xB8, 0xF1, 0x00, 0x0F,
0x09, 0xD0, 0xC5, 0x4A, 0xB5, 0xF8, 0x8E, 0x00, 0x12, 0x88, 0x80, 0x1A, 0x40, 0x1C, 0x02, 0x28, 0x1C, 0xD8, 0x00, 0x27, 0x1A, 0xE0, 0x5C, 0xB1, 0xE8, 0x7B, 0x01, 0x28, 0x08, 0xD1, 0x60, 0x8C, 0x40, 0xF0, 0x80, 0x00, 0x60, 0x84, 0xB5, 0xF8,
0x8E, 0x20, 0x62, 0xF3, 0xC3, 0x00, 0x60, 0x84, 0xBA, 0x48, 0x00, 0x68, 0x80, 0x07, 0x08, 0xD5, 0x85, 0xF8, 0x9C, 0x10, 0x28, 0x6D, 0x01, 0x81, 0xB7, 0x48, 0x02, 0x68, 0x22, 0xF0, 0x08, 0x02, 0x02, 0x60, 0x01, 0x26, 0xB5, 0x48, 0x00, 0x88,
0x68, 0xB1, 0xB5, 0x48, 0xB6, 0x1C, 0x01, 0x70, 0xB4, 0x48, 0x01, 0x70, 0xB4, 0x48, 0xB5, 0x49, 0x06, 0x70, 0x00, 0x20, 0x08, 0x80, 0xB4, 0x49, 0xB5, 0xF8, 0x8E, 0x00, 0x08, 0x80, 0x1F, 0x4C, 0xFC, 0xFF, 0xED, 0x27, 0x21, 0x00, 0xB1, 0x39,
0x46, 0x28, 0x46, 0xAF, 0xF7, 0x04, 0xFF, 0x01, 0x20, 0x78, 0xE7, 0x03, 0x01, 0x88, 0x01, 0xC8, 0x14, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x0F, 0x46, 0x80, 0x46, 0x44, 0xF7, 0xA8, 0xF8, 0x04, 0x46, 0xAC, 0x48, 0x05, 0x68, 0x00, 0x26, 0xB8,
0x07, 0x33, 0xD5, 0x94, 0xB3, 0x29, 0x46, 0x40, 0x46, 0xFF, 0xF7, 0x75, 0xFF, 0x98, 0xB1, 0xE0, 0x68, 0x10, 0xF4, 0x70, 0x2F, 0x0F, 0xD0, 0x28, 0x0A,
0x00, 0x21, 0x61, 0xF7, 0x6E, 0xFD, 0xA3, 0x49, 0x09, 0x78, 0x88, 0x42, 0x21, 0xDB, 0x28, 0x07, 0x1F, 0xD5, 0x04, 0x21, 0x40, 0x46, 0xAF, 0xF7, 0x99, 0xFF, 0x01, 0x26, 0x19, 0xE0, 0x60, 0x7A, 0x4F, 0xEA, 0x10, 0x10, 0x80, 0x07, 0x14, 0xD5,
0x60, 0x8C, 0xC0, 0x06, 0x11, 0xD5, 0x20, 0x46, 0x44, 0xF7, 0x80, 0xF8, 0x68, 0xB9, 0xE0, 0x68, 0x10, 0xF4, 0x70, 0x4F, 0x09, 0xD0, 0x04, 0xF1, 0x26, 0x04, 0x60, 0x78, 0x21, 0x78, 0x88, 0x42, 0x03, 0xD0, 0x02, 0x21, 0x40, 0x46, 0xAF, 0xF7,
0x7D, 0xFF, 0x30, 0x46, 0x36, 0xE7, 0x03, 0x01, 0x34, 0x4C, 0x15, 0x0D, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x8D, 0x48, 0x04, 0x68, 0x28, 0x46, 0x21, 0x46, 0xA1, 0xF7, 0x02, 0xFD, 0x28, 0x46, 0x44, 0xF7, 0x8E, 0xFB, 0x21, 0x46, 0x28, 0x46, 0xFF,
0xF7, 0x4F, 0xFF, 0x00, 0x28, 0x05, 0xD1, 0x21, 0x46, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xA1, 0xF7, 0x82, 0xBC, 0x70, 0xBD, 0x03, 0x01, 0xD2, 0x02, 0x7C, 0x15, 0x0D, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x00, 0x7C, 0x00, 0x21, 0x85, 0xF7, 0x48,
0xF9, 0x84, 0xF8, 0x0A,
0x01, 0x00, 0x26, 0xA4, 0xF8, 0x8C, 0x60, 0x84, 0xF8, 0x9D, 0x60, 0x94, 0xF8, 0x27, 0x11, 0x49, 0x1C, 0x84, 0xF8, 0x27, 0x4C, 0xFC, 0xFF, 0xE8, 0x28, 0x21, 0x00, 0x11, 0xE0, 0x7B, 0x10, 0xB9, 0x20, 0x46, 0xA0, 0xF7, 0xE1, 0xFC, 0x20, 0x6D,
0x90, 0xF8, 0x18, 0x11, 0x29, 0xB1, 0xD0, 0xF8, 0x0C, 0x11, 0x01, 0xF1, 0x01, 0x01, 0xC0, 0xF8, 0x0C, 0x11, 0x74, 0x48, 0x05, 0x68, 0xA8, 0x07, 0x0F, 0xD5, 0x94, 0xF8, 0x27, 0x01, 0x01, 0x28, 0x0B, 0xD1, 0x71, 0x48, 0x80, 0x78, 0x18, 0xB9,
0x94, 0xF8, 0x3B, 0x01, 0x06, 0x28, 0x1A, 0xD0, 0x94, 0xF9, 0x0A,
0x11, 0x20, 0x46, 0xA2, 0xF7, 0x9A, 0xFF, 0x20, 0x46, 0x44, 0xF7, 0xF7, 0xFA, 0xAF, 0xF7, 0xF9, 0xFF, 0xC5, 0xF3, 0x41, 0x00, 0x03, 0x28, 0x14, 0xD0, 0x67, 0x49, 0x01, 0x20, 0x81, 0xF8, 0x44, 0x00, 0xA8, 0x07, 0x20, 0x6D, 0x29, 0xD5, 0xD0,
0xF8, 0xF4, 0x10, 0x49, 0x1C, 0xC0, 0xF8, 0xF4, 0x10, 0x29, 0xE0, 0x94, 0xF9, 0x0A,
0x01, 0x10, 0xB1, 0x84, 0xF8, 0x3C, 0x01, 0xE3, 0xE7, 0x7F, 0x20, 0xFA, 0xE7, 0xA0, 0x7B, 0x6E, 0xF7, 0xE0, 0xF9, 0xC4, 0xF8, 0xA4, 0x00, 0x20, 0x46, 0xFF, 0xF7, 0x8D, 0xFF, 0x20, 0x46, 0xA1, 0xF7, 0x17, 0xFC, 0xE0, 0x7B, 0x29, 0x46, 0x00,
0x28, 0x20, 0x46, 0x08, 0xD0, 0xA1, 0xF7, 0x58, 0xFB, 0x00, 0x21, 0x20, 0x46, 0x61, 0xF7, 0xCD, 0xFD, 0x84, 0xF8, 0x8A, 0x60, 0x30, 0xE0, 0xA1, 0xF7, 0xB7, 0xFB, 0xF5, 0xE7, 0xD0, 0xF8, 0xF0, 0x10, 0x01, 0xF1, 0x01, 0x01, 0xC0, 0xF8, 0xF0,
0x10, 0x20, 0x6D, 0x90, 0xF8, 0x18, 0x11, 0x61, 0xB1, 0xA9, 0x07, 0x05, 0xD5, 0xD0, 0xF8, 0x14, 0x11, 0x49, 0x1C, 0xC0, 0xF8, 0x14, 0x11, 0x04, 0xE0, 0xD0, 0xF8, 0x10, 0x11, 0x49, 0x1C, 0xC0, 0xF8, 0x10, 0x11, 0x84, 0xF8, 0x26, 0x61, 0x29,
0x46, 0x20, 0x46, 0xFF, 0xF7, 0x1A, 0xFF, 0xA8, 0x07, 0x0B, 0xD5, 0x40, 0x49, 0x4C, 0xFC, 0xFF, 0xE3, 0x29, 0x21, 0x00, 0x94, 0xF8, 0x8A, 0x00, 0x09, 0x78, 0x88, 0x42, 0x05, 0xD2, 0xE1, 0x7B, 0x19, 0xB1, 0x40, 0x1C, 0x84, 0xF8, 0x8A, 0x00,
0x02, 0xE0, 0x20, 0x46, 0xA1, 0xF7, 0xB3, 0xF9, 0x20, 0x46, 0xAF, 0xF7, 0x97, 0xFF, 0x94, 0xF8, 0x30, 0x01, 0x20, 0xF0, 0x04, 0x00, 0x84, 0xF8, 0x30, 0x01, 0x70, 0xBD, 0x03, 0x01, 0xDA, 0x01, 0xCA, 0x16, 0x0D, 0x00, 0x70, 0xB5, 0x2E, 0x4E,
0x04, 0x46, 0x30, 0x68, 0x2F, 0x48, 0x00, 0x68, 0x80, 0x07, 0x3E, 0xD5, 0x20, 0x46, 0x44, 0xF7, 0x54, 0xFA, 0x05, 0x46, 0x94, 0xF8, 0x09, 0x01, 0x08, 0xBB, 0x9E, 0xF7, 0xDD, 0xFC, 0xE0, 0x7B, 0x01, 0x28, 0x1C, 0xD1, 0xA0, 0x7B, 0x6E, 0xF7,
0x78, 0xF9, 0xA1, 0x69, 0x20, 0xF0, 0x01, 0x05, 0xA9, 0x42, 0x09, 0xD0, 0x28, 0x46, 0x6E, 0xF7, 0x09, 0xF9, 0xA0, 0x69, 0x29, 0x46, 0x6E, 0xF7, 0xFD, 0xF8, 0x40, 0x00, 0xC4, 0xF8, 0x84, 0x00, 0x20, 0x46, 0x6B, 0xF7, 0xDC, 0xFA, 0xA0, 0x7B,
0x6E, 0xF7, 0x63, 0xF9, 0xA0, 0x62, 0x20, 0x46, 0xA1, 0xF7, 0x57, 0xFD, 0x05, 0x46, 0x30, 0x68, 0x00, 0x21, 0x00, 0x0A,
0x61, 0xF7, 0x51, 0xFC, 0x01, 0x46, 0x20, 0x46, 0xAD, 0xF7, 0xAD, 0xF9, 0x15, 0xB1, 0x20, 0x46, 0xA1, 0xF7, 0x6B, 0xF9, 0x94, 0xF8, 0x81, 0x00, 0x01, 0x28, 0x04, 0xD1, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xA1, 0xF7, 0x13, 0xBD, 0x70, 0xBD,
0x00, 0x00, 0xC0, 0x28, 0x20, 0x00, 0xB4, 0x32, 0x20, 0x00, 0xD2, 0x32, 0x20, 0x00, 0xD4, 0x32, 0x20, 0x00, 0x38, 0x29, 0x20, 0x00, 0xCC, 0x32, 0x20, 0x00, 0xC8, 0x32, 0x20, 0x00, 0xC9, 0x32, 0x20, 0x00, 0xCA, 0x32, 0x20, 0x00, 0xCE, 0x32,
0x20, 0x00, 0xD0, 0x32, 0x20, 0x00, 0x98, 0x8B, 0x31, 0x00, 0xB5, 0x4C, 0xFC, 0xFF, 0xDE, 0x2A, 0x21, 0x00, 0x32, 0x20, 0x00, 0xAC, 0x8B, 0x31, 0x00, 0x9D, 0x28, 0x20, 0x00, 0xFC, 0x53, 0x20, 0x00, 0xAB, 0x28, 0x20, 0x00, 0x03, 0x01, 0x30,
0xA0, 0x17, 0x0D, 0x00, 0x10, 0xB5, 0x08, 0x48, 0x06, 0x4C, 0x2C, 0x22, 0x04, 0x60, 0x07, 0x49, 0x20, 0x46, 0x8B, 0xF7, 0x6E, 0xFF, 0xAF, 0xF2, 0xE9, 0x00, 0x20, 0x62, 0xAF, 0xF2, 0x3F, 0x20, 0xA0, 0x61, 0x10, 0xBD, 0x40, 0x73, 0x0D, 0x00,
0xC4, 0x28, 0x20, 0x00, 0x20, 0xA7, 0x08, 0x00, 0x03, 0x01, 0x80, 0x01, 0xCC, 0x17, 0x0D, 0x00, 0x70, 0xB5, 0x04, 0x46, 0xAD, 0xF7, 0x3A, 0xFC, 0x08, 0xB1, 0x40, 0x26, 0x00, 0xE0, 0x00, 0x26, 0x6B, 0xF7, 0x61, 0xF8, 0x10, 0xB9, 0x6B, 0xF7,
0x98, 0xF8, 0x00, 0xB3, 0x00, 0x25, 0x94, 0xF8, 0x27, 0x00, 0x31, 0x46, 0x03, 0x28, 0x1E, 0xD0, 0x0C, 0x20, 0x6F, 0xF7, 0x99, 0xFA, 0x94, 0xF8, 0x27, 0x20, 0x10, 0x48, 0x01, 0x2A, 0x0E, 0x49, 0x02, 0x68, 0x02, 0xEA, 0x01, 0x02, 0x02, 0x60,
0x01, 0x68, 0x12, 0xD0, 0x0C, 0x4A, 0x11, 0x43, 0x01, 0x60, 0x1D, 0xB1, 0xA0, 0x7B, 0x6E, 0xF7, 0xE5, 0xF8, 0xA0, 0x61, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xA7, 0xF7, 0x81, 0xBA, 0x6A, 0xF7, 0xAE, 0xFA, 0x01, 0x25, 0xDB, 0xE7, 0x0D, 0x20,
0xDF, 0xE7, 0x41, 0xF0, 0x80, 0x71, 0xEB, 0xE7, 0xFF, 0xFF, 0x00, 0xFE, 0x94, 0x83, 0x31, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x01, 0xE8, 0x01, 0x48, 0x18, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0xC8, 0x43, 0x17, 0x46, 0x80, 0x07,
0x65, 0xD1, 0x20, 0x6D, 0x90, 0xF8, 0xBA, 0x20, 0x12, 0xB9, 0x90, 0xF8, 0xBB, 0x00, 0xE8, 0xB3, 0x08, 0x0A,
0x00, 0x21, 0x61, 0xF7, 0xB6, 0xFB, 0x39, 0x78, 0xB8, 0xB3, 0x2D, 0x4C, 0xFC, 0xFF, 0xD9, 0x2B, 0x21, 0x00, 0x4A, 0x12, 0x78, 0x90, 0x42, 0x54, 0xD2, 0x11, 0xB1, 0x01, 0x29, 0x3D, 0xD0, 0x4D, 0xE0, 0x25, 0x6D, 0x95, 0xF8, 0xBA, 0x00, 0x60,
0xB3, 0xB4, 0xF8, 0x8E, 0x10, 0xB4, 0xF8, 0x94, 0x00, 0x08, 0x1A, 0x80, 0xB2, 0x01, 0x28, 0x41, 0xD9, 0xB4, 0xF8, 0x90, 0x20, 0x52, 0x1C, 0x10, 0x44, 0x86, 0xB2, 0x70, 0x1A, 0xB5, 0xF8, 0xC6, 0x10, 0x80, 0xB2, 0x41, 0x43, 0xD4, 0xF8, 0x04,
0x01, 0x6D, 0xF7, 0xA4, 0xFE, 0x95, 0xF8, 0xD5, 0x10, 0x09, 0xB1, 0x80, 0xF0, 0x80, 0x60, 0xB5, 0xF8, 0xCA, 0x20, 0xB5, 0xF8, 0xC8, 0x10, 0x6E, 0xF7, 0xED, 0xF8, 0x01, 0x46, 0xB5, 0xF8, 0xCA, 0x00, 0xB1, 0xFB, 0xF0, 0xF2, 0x00, 0xFB, 0x12,
0x11, 0x40, 0x1A, 0x40, 0x08, 0x28, 0x83, 0x01, 0xE0, 0x1F, 0xE0, 0x1B, 0xE0, 0x7E, 0x81, 0x28, 0x8B, 0x78, 0x80, 0x76, 0x1E, 0xA4, 0xF8, 0x90, 0x60, 0xB4, 0xF8, 0x8E, 0x00, 0xA4, 0xF8, 0x94, 0x00, 0x10, 0xE0, 0x20, 0x6D, 0x90, 0xF8, 0xBB,
0x00, 0x60, 0xB1, 0xB4, 0xF8, 0x8E, 0x00, 0xB4, 0xF8, 0x96, 0x10, 0xA4, 0xF8, 0x96, 0x00, 0x41, 0x1A, 0xB4, 0xF8, 0x92, 0x00, 0x08, 0x44, 0xA4, 0xF8, 0x92, 0x00, 0xF8, 0x80, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x20, 0xFB, 0xE7, 0x00,
0x00, 0xB4, 0x32, 0x20, 0x00, 0x03, 0x01, 0x38, 0x2C, 0x19, 0x0D, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x04, 0xF1, 0x28, 0x01, 0x90, 0xF8, 0x34, 0x00, 0x0E, 0x46, 0x9E, 0xF7, 0xED, 0xFC, 0x05, 0x46, 0xCB, 0x48, 0x00, 0x68, 0x41, 0xB2, 0x49, 0xB1,
0x28, 0x46, 0x9E, 0xF7, 0x7B, 0xFD, 0x6D, 0x1C, 0x31, 0x46, 0xE8, 0xB2, 0x9E, 0xF7, 0xE0, 0xFC, 0x84, 0xF8, 0x34, 0x00, 0x00, 0x20, 0x70, 0xBD, 0x03, 0x01, 0x28, 0x60, 0x19, 0x4C, 0xFC, 0xFF, 0xD4, 0x2C, 0x21, 0x00, 0x0D, 0x00, 0x10, 0xB5,
0x90, 0xF8, 0x34, 0x20, 0x00, 0xF1, 0x28, 0x01, 0x10, 0x46, 0x9E, 0xF7, 0xD4, 0xFC, 0x80, 0x1C, 0xC0, 0xB2, 0x40, 0xF0, 0x80, 0x01, 0xBD, 0x48, 0x00, 0x1D, 0x8F, 0xF7, 0x04, 0xFD, 0x00, 0x20, 0x10, 0xBD, 0x03, 0x01, 0x7E, 0x84, 0x19, 0x0D,
0x00, 0x70, 0xB5, 0x06, 0x46, 0xAF, 0xF7, 0xF7, 0xFA, 0xB9, 0x4C, 0x20, 0x68, 0xB9, 0x49, 0x48, 0x60, 0x20, 0x6B, 0xB9, 0x4D, 0x08, 0x60, 0x28, 0x68, 0x06, 0xF1, 0x02, 0x06, 0x88, 0x60, 0xF0, 0xB2, 0x40, 0xF0, 0x80, 0x01, 0xB5, 0x48, 0x8F,
0xF7, 0xED, 0xFC, 0x01, 0x21, 0x29, 0x60, 0xB4, 0x48, 0x02, 0x69, 0x42, 0xF0, 0x01, 0x02, 0x02, 0x61, 0x02, 0x68, 0x42, 0xF0, 0x01, 0x02, 0x02, 0x60, 0x4F, 0xF0, 0x18, 0x00, 0x44, 0xF8, 0xC8, 0x09, 0x4F, 0xF0, 0xCF, 0x00, 0xC4, 0xF8, 0xF8,
0x00, 0x29, 0x60, 0x4F, 0xF0, 0x00, 0x01, 0xAB, 0x48, 0x8F, 0xF7, 0xD4, 0xFC, 0xA9, 0x4C, 0x00, 0x21, 0x24, 0x1D, 0x20, 0x46, 0x8F, 0xF7, 0xCE, 0xFC, 0x01, 0x20, 0x47, 0xF7, 0x9C, 0xFB, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x6C, 0x21, 0x8F,
0xF7, 0xC5, 0xBC, 0x03, 0x01, 0x6A, 0xFE, 0x19, 0x0D, 0x00, 0x70, 0xB5, 0xA2, 0x48, 0x4F, 0xF4, 0x80, 0x71, 0x00, 0x68, 0x01, 0x60, 0x01, 0x60, 0xA0, 0x4C, 0x9E, 0x4D, 0x61, 0x68, 0x05, 0xF1, 0x04, 0x06, 0xC8, 0x07, 0x1C, 0xD0, 0xA0, 0x68,
0xC1, 0xB2, 0x30, 0x46, 0x8F, 0xF7, 0xB2, 0xFC, 0x60, 0x68, 0xC1, 0xB2, 0x28, 0x46, 0x8F, 0xF7, 0xAD, 0xFC, 0x92, 0x48, 0x90, 0x49, 0x42, 0x68, 0x0A,
0x60, 0x02, 0x68, 0x0A,
0x63, 0x90, 0x49, 0x80, 0x68, 0x08, 0x60, 0x90, 0x48, 0x01, 0x69, 0x21, 0xF0, 0x01, 0x01, 0x01, 0x61, 0x01, 0x4C, 0xFC, 0xFF, 0xCF, 0x2D, 0x21, 0x00, 0x68, 0x21, 0xF0, 0x01, 0x01, 0x01, 0x60, 0x70, 0xBD, 0xC9, 0xB2, 0x28, 0x46, 0x8F, 0xF7,
0x96, 0xFC, 0xA0, 0x68, 0xC1, 0xB2, 0x30, 0x46, 0xE2, 0xE7, 0x03, 0x01, 0xC8, 0x01, 0x64, 0x1A, 0x0D, 0x00, 0x7C, 0xB5, 0x04, 0x46, 0x6A, 0xF7, 0x2C, 0xFF, 0x00, 0x28, 0x5A, 0xD0, 0x6F, 0xF7, 0x26, 0xFE, 0x00, 0x28, 0x56, 0xD1, 0x94, 0xF8,
0x32, 0x00, 0x02, 0x28, 0x52, 0xD0, 0x84, 0x48, 0x90, 0xF8, 0x30, 0x00, 0x20, 0xB1, 0x92, 0xF7, 0x84, 0xFA, 0xB0, 0xF5, 0x1C, 0x7F, 0x49, 0xD9, 0x6A, 0xF7, 0x35, 0xFD, 0x02, 0x25, 0x01, 0x28, 0x1D, 0xD1, 0xA0, 0x7B, 0x69, 0x46, 0x6D, 0xF7,
0x97, 0xFF, 0x00, 0x98, 0x80, 0x07, 0xF8, 0xD1, 0x01, 0x99, 0x60, 0x6A, 0x81, 0x42, 0xF4, 0xD3, 0x94, 0xF8, 0x32, 0x00, 0x01, 0x28, 0x0E, 0xD1, 0x20, 0x46, 0x9E, 0xF7, 0xC8, 0xFC, 0x94, 0xF8, 0x34, 0x00, 0x4E, 0x28, 0x20, 0x46, 0x04, 0xD9,
0x84, 0xF8, 0x32, 0x50, 0x91, 0xF7, 0xD0, 0xF8, 0x01, 0xE0, 0x9E, 0xF7, 0x33, 0xFC, 0x94, 0xF8, 0x3C, 0x00, 0x40, 0x1C, 0xC0, 0xB2, 0x84, 0xF8, 0x3C, 0x00, 0x9C, 0x28, 0x0A,
0xD9, 0x94, 0xF8, 0x32, 0x00, 0x01, 0x28, 0x06, 0xD1, 0x20, 0x46, 0x84, 0xF8, 0x32, 0x50, 0x91, 0xF7, 0xBC, 0xF8, 0x9E, 0xF7, 0xAF, 0xFD, 0x6A, 0xF7, 0xFF, 0xFC, 0x00, 0x28, 0x0F, 0xD1, 0x94, 0xF8, 0x32, 0x00, 0x01, 0x28, 0x02, 0xD1, 0x20,
0x46, 0x9E, 0xF7, 0x9E, 0xFC, 0x94, 0xF8, 0x32, 0x00, 0x02, 0x28, 0x04, 0xD0, 0x20, 0x46, 0xBD, 0xE8, 0x7C, 0x40, 0x6A, 0xF7, 0x98, 0xB9, 0x7C, 0xBD, 0x03, 0x01, 0xB8, 0x02, 0x28, 0x1B, 0x0D, 0x00, 0x2D, 0xE9, 0xFF, 0x41, 0x04, 0x46, 0x0D,
0x00, 0x15, 0xD0, 0xA6, 0xF7, 0x5B, 0xFD, 0x4C, 0xFC, 0xFF, 0xCA, 0x2E, 0x21, 0x00, 0x00, 0x26, 0x01, 0x27, 0x01, 0x2D, 0x08, 0xD0, 0x02, 0x2D, 0x12, 0xD0, 0x04, 0x2D, 0x0B, 0xD1, 0x94, 0xF8, 0x32, 0x00, 0x01, 0x28, 0x5D, 0xD0, 0x66, 0xE0,
0x6A, 0xF7, 0xD3, 0xFC, 0x21, 0x46, 0xA0, 0x42, 0x03, 0xD0, 0x81, 0xF8, 0x3D, 0x70, 0xBD, 0xE8, 0xFF, 0x81, 0x81, 0xF8, 0x3D, 0x60, 0xFA, 0xE7, 0x94, 0xF8, 0x32, 0x00, 0x00, 0x28, 0xF6, 0xD1, 0x49, 0x48, 0x00, 0x68, 0xC0, 0xF3, 0x02, 0x10,
0xA0, 0x73, 0x94, 0xF8, 0x3D, 0x00, 0x38, 0xB1, 0x84, 0xF8, 0x35, 0x60, 0x94, 0xF8, 0x34, 0x00, 0xAF, 0xF7, 0x28, 0xFA, 0xAF, 0xF7, 0x4F, 0xFA, 0x84, 0xF8, 0x32, 0x70, 0xA0, 0x7B, 0x02, 0xA9, 0x6D, 0xF7, 0x1B, 0xFF, 0x02, 0x98, 0x10, 0xF0,
0x03, 0x00, 0x06, 0xD0, 0x01, 0x28, 0x07, 0xD0, 0x02, 0x28, 0x28, 0xD0, 0x03, 0x28, 0x08, 0xD1, 0x28, 0xE0, 0x02, 0x21, 0x02, 0x98, 0x01, 0xE0, 0x01, 0x21, 0x02, 0x98, 0x6D, 0xF7, 0x76, 0xFC, 0x00, 0x90, 0x50, 0x20, 0x01, 0x90, 0xA0, 0x7B,
0x02, 0xAB, 0x02, 0x46, 0x69, 0x46, 0x6D, 0xF7, 0xBC, 0xFD, 0x02, 0x98, 0x20, 0x62, 0x03, 0x98, 0x60, 0x62, 0x68, 0x46, 0x6D, 0xF7, 0xAC, 0xFE, 0x40, 0x08, 0x69, 0x46, 0x6D, 0xF7, 0xB0, 0xFE, 0xA0, 0x7B, 0x6B, 0x46, 0x02, 0x46, 0x04, 0xF1,
0x20, 0x01, 0x6D, 0xF7, 0xB5, 0xFC, 0x20, 0x46, 0x9E, 0xF7, 0xA1, 0xFB, 0xAF, 0xE7, 0x04, 0x21, 0x02, 0x98, 0xDB, 0xE7, 0x03, 0x21, 0x02, 0x98, 0xD8, 0xE7, 0x94, 0xF8, 0x34, 0x00, 0x4E, 0x28, 0x08, 0xD9, 0x02, 0x21, 0x20, 0x46, 0x84, 0xF8,
0x32, 0x10, 0x91, 0xF7, 0x2A, 0xF8, 0x94, 0xF8, 0x32, 0x00, 0xC0, 0xB1, 0x1D, 0x4D, 0xA0, 0x7B, 0x69, 0x46, 0x6D, 0xF7, 0xD2, 0xFE, 0x00, 0x98, 0xC0, 0x4C, 0xFC, 0xFF, 0xC5, 0x2F, 0x21, 0x00, 0x43, 0x80, 0x07, 0x03, 0xD1, 0x01, 0x98, 0x29,
0x68, 0x88, 0x42, 0xF3, 0xD8, 0x6A, 0xF7, 0xD4, 0xFD, 0xA0, 0x42, 0x03, 0xD0, 0xAF, 0xF7, 0x20, 0xFA, 0xAF, 0xF7, 0x48, 0xFA, 0x94, 0xF8, 0x32, 0x00, 0x02, 0x28, 0x83, 0xD0, 0x84, 0xF8, 0x32, 0x60, 0x80, 0xE7, 0x03, 0x01, 0x50, 0x5C, 0x1C,
0x0D, 0x00, 0xAF, 0xF2, 0xFB, 0x10, 0x0F, 0x49, 0x08, 0x60, 0xAF, 0xF2, 0x3F, 0x10, 0x0E, 0x49, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x00, 0x01, 0x60, 0x00, 0xC8, 0x00, 0x64, 0x00, 0x2C, 0x68, 0x0D, 0x00, 0xBC, 0x01, 0x60, 0x00, 0x04, 0x01,
0x60, 0x00, 0x60, 0x01, 0x65, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x7C, 0x1B, 0x20, 0x00, 0x94, 0x38, 0x20, 0x00, 0xB0, 0x59, 0x20, 0x00, 0x24, 0x86, 0x31, 0x00, 0xBC, 0x2A, 0x20, 0x00, 0x38, 0x30, 0x20, 0x00, 0x34, 0x30, 0x20, 0x00, 0x03, 0x01,
0x1A, 0xA8, 0x1C, 0x0D, 0x00, 0x90, 0xF8, 0x56, 0x00, 0x09, 0x49, 0x01, 0xEB, 0xC0, 0x41, 0x09, 0x48, 0x01, 0x60, 0x01, 0x68, 0x89, 0x06, 0xFC, 0xD4, 0x70, 0x47, 0x03, 0x01, 0x26, 0xBE, 0x1C, 0x0D, 0x00, 0x90, 0xF8, 0x56, 0x00, 0x06, 0x49,
0x01, 0xEB, 0xC0, 0x41, 0x03, 0x48, 0x01, 0x60, 0x01, 0x68, 0x89, 0x06, 0xFC, 0xD4, 0x70, 0x47, 0x20, 0x00, 0x05, 0x00, 0x00, 0x8D, 0x31, 0x00, 0x20, 0x00, 0x04, 0x00, 0x03, 0x01, 0xC0, 0x02, 0xE0, 0x1C, 0x0D, 0x00, 0x2D, 0xE9, 0xF7, 0x4F,
0x82, 0xB0, 0x04, 0x00, 0x18, 0xD0, 0xB4, 0xF8, 0x50, 0x10, 0xB4, 0xF8, 0x4E, 0x00, 0x0D, 0x1A, 0x95, 0x42, 0x00, 0xD9, 0x15, 0x46, 0x28, 0x44, 0xA4, 0xF8, 0x4E, 0x00, 0x20, 0x6C, 0xA9, 0x46, 0x28, 0x44, 0x20, 0x64, 0x61, 0x6A, 0x04, 0xF1,
0x10, 0x00, 0x4F, 0x4C, 0xFC, 0xFF, 0xC0, 0x30, 0x21, 0x00, 0xF0, 0x00, 0x0A,
0x00, 0x90, 0x51, 0xB9, 0x60, 0xF7, 0x9A, 0xFF, 0x18, 0xB1, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x20, 0x69, 0x60, 0x62, 0xC4, 0xF8, 0x2C, 0xA0, 0xD4, 0xF8, 0x24, 0x80, 0x04, 0xF1, 0x55, 0x0B, 0x57, 0xE0, 0xB4, 0xF8, 0x4C, 0x10,
0xE0, 0x6A, 0x0E, 0x1A, 0xAE, 0x42, 0x00, 0xD9, 0x2E, 0x46, 0xA1, 0x69, 0x08, 0xF1, 0x0C, 0x07, 0x38, 0x44, 0x0B, 0x68, 0x32, 0x46, 0x03, 0x99, 0x98, 0x47, 0x03, 0x90, 0x94, 0xF8, 0x54, 0x00, 0x30, 0xB1, 0xE0, 0x6A, 0x32, 0x46, 0xC1, 0x19,
0x58, 0x46, 0x86, 0xF7, 0x56, 0xFF, 0x08, 0xE0, 0x94, 0xF8, 0x55, 0x00, 0x28, 0xB1, 0xE0, 0x6A, 0x32, 0x46, 0xC1, 0x19, 0x58, 0x46, 0x86, 0xF7, 0x34, 0xFF, 0xE0, 0x6A, 0xAD, 0x1B, 0x30, 0x44, 0xE0, 0x62, 0xB4, 0xF8, 0x4C, 0x10, 0x88, 0x42,
0x2C, 0xD1, 0x40, 0x46, 0x60, 0xF7, 0x59, 0xFF, 0x04, 0xF1, 0x08, 0x01, 0x40, 0x46, 0x60, 0xF7, 0x4D, 0xFF, 0xC4, 0xF8, 0x2C, 0xA0, 0x00, 0x98, 0x60, 0xF7, 0x54, 0xFF, 0xD8, 0xB1, 0xC4, 0xF8, 0x24, 0xA0, 0x5D, 0xB1, 0xB4, 0xF8, 0x4E, 0x00,
0xA9, 0xEB, 0x05, 0x09, 0xA0, 0xEB, 0x05, 0x00, 0xA4, 0xF8, 0x4E, 0x00, 0x20, 0x6C, 0xA0, 0xEB, 0x05, 0x00, 0x20, 0x64, 0xE0, 0x69, 0xB4, 0xF8, 0x4E, 0x20, 0x81, 0x68, 0xD9, 0xB1, 0xC1, 0x8B, 0xCB, 0x06, 0x18, 0xD5, 0xC1, 0xF3, 0x01, 0x03,
0x01, 0x2B, 0x06, 0xD0, 0x08, 0xE0, 0x20, 0x69, 0x60, 0x62, 0x80, 0x46, 0x00, 0x2D, 0xA5, 0xD1, 0xEC, 0xE7, 0x83, 0x8B, 0x93, 0x42, 0x04, 0xD9, 0x8B, 0x07, 0x08, 0xD1, 0x83, 0x8B, 0x93, 0x42, 0x05, 0xD3, 0x21, 0xF0, 0x10, 0x01, 0xC1, 0x83,
0x82, 0x68, 0x81, 0x69, 0x90, 0x47, 0xA0, 0x69, 0x4C, 0xFC, 0xFF, 0xBB, 0x31, 0x21, 0x00, 0xC1, 0x8B, 0x41, 0xF0, 0x10, 0x01, 0xC1, 0x83, 0x20, 0x46, 0x86, 0xF7, 0x98, 0xFD, 0x48, 0x46, 0x80, 0xE7, 0x03, 0x01, 0x14, 0x1C, 0x1E, 0x0D, 0x00,
0x10, 0x48, 0x00, 0x68, 0x00, 0x28, 0x02, 0xD0, 0x01, 0x68, 0x49, 0x1C, 0x01, 0x60, 0x70, 0x47, 0x03, 0x01, 0x3C, 0x2C, 0x1E, 0x0D, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x08, 0x46, 0x01, 0x26, 0x90, 0xF8, 0xA3, 0x00, 0xB5, 0xF8, 0x0B, 0x40, 0xA9,
0x7A, 0x40, 0x09, 0x00, 0x22, 0x9F, 0xF7, 0x96, 0xFD, 0x00, 0x28, 0x09, 0xD0, 0x40, 0x88, 0xA0, 0x42, 0x00, 0xD2, 0x04, 0x46, 0x2A, 0x7A, 0x21, 0x46, 0x30, 0x46, 0x55, 0xF7, 0xF5, 0xF9, 0x01, 0x20, 0x70, 0xBD, 0x8C, 0x31, 0x20, 0x00, 0x03,
0x01, 0x20, 0x64, 0x1E, 0x0D, 0x00, 0x10, 0xB5, 0x42, 0x68, 0x0C, 0x46, 0x02, 0xB1, 0x90, 0x47, 0x62, 0x68, 0x00, 0x2A, 0x03, 0xD0, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x10, 0x47, 0x10, 0xBD, 0x00, 0x00, 0x03, 0x01, 0x84, 0x02, 0x80, 0x1E,
0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x87, 0xB0, 0x17, 0x46, 0x00, 0xF1, 0x09, 0x04, 0x52, 0xF7, 0xF8, 0xFC, 0x72, 0xF7, 0xB2, 0xF9, 0x72, 0xF7, 0x35, 0xFA, 0x06, 0x90, 0x01, 0x20, 0x77, 0xF7, 0x91, 0xFB, 0x7F, 0x4D, 0x28, 0x69, 0x40, 0xF0,
0x01, 0x00, 0x28, 0x61, 0x28, 0x68, 0x40, 0xF0, 0x01, 0x00, 0x28, 0x60, 0x4F, 0xF4, 0x48, 0x1B, 0xDB, 0xF8, 0x00, 0x00, 0x7A, 0x4E, 0x00, 0x90, 0x30, 0x68, 0x01, 0x90, 0x79, 0x48, 0x00, 0x68, 0x02, 0x90, 0x56, 0xF8, 0xB8, 0x0C, 0xDF, 0xF8,
0xDC, 0x91, 0x03, 0x90, 0xD9, 0xF8, 0x00, 0x00, 0xDF, 0xF8, 0xD8, 0x81, 0x04, 0x90, 0xD8, 0xF8, 0x00, 0x00, 0x4F, 0xF0, 0x00, 0x0A,
0x05, 0x90, 0xCB, 0xF8, 0x4C, 0xFC, 0xFF, 0xB6, 0x32, 0x21, 0x00, 0x00, 0xA0, 0x4F, 0xF0, 0x64, 0x00, 0x47, 0xF7, 0x1C, 0xF9, 0x01, 0x20, 0x30, 0x60, 0x6C, 0x48, 0xD4, 0xF8, 0x06, 0x10, 0x01, 0x60, 0xE0, 0x78, 0x40, 0xF0, 0x80, 0x00, 0x46,
0xF8, 0xB8, 0x0C, 0x4F, 0xF4, 0xC0, 0x41, 0xC8, 0xF8, 0x00, 0x10, 0xC8, 0x20, 0x47, 0xF7, 0x0A,
0xF9, 0xA0, 0x88, 0x40, 0xF4, 0x00, 0x51, 0xC9, 0xF8, 0x00, 0x10, 0x41, 0xF2, 0x88, 0x30, 0x47, 0xF7, 0x01, 0xF9, 0xA1, 0x88, 0xC9, 0xF8, 0x00, 0x10, 0xC8, 0xF8, 0x00, 0xA0, 0x00, 0x98, 0xCB, 0xF8, 0x00, 0x00, 0x01, 0x98, 0x30, 0x60, 0x5A,
0x49, 0x02, 0x98, 0x08, 0x60, 0x03, 0x98, 0x46, 0xF8, 0xB8, 0x0C, 0x04, 0x98, 0xC9, 0xF8, 0x00, 0x00, 0x05, 0x98, 0xC8, 0xF8, 0x00, 0x00, 0x77, 0xF7, 0x5F, 0xFB, 0x28, 0x69, 0x20, 0xF0, 0x01, 0x00, 0x28, 0x61, 0x28, 0x68, 0x20, 0xF0, 0x01,
0x00, 0x28, 0x60, 0x06, 0x98, 0x72, 0xF7, 0xCE, 0xF9, 0x52, 0xF7, 0xA5, 0xFC, 0x87, 0xF8, 0x05, 0xA0, 0x0E, 0x20, 0x38, 0x70, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x03, 0x01, 0x3A, 0x80, 0x1F, 0x0D, 0x00, 0x10, 0xB5, 0x4C, 0x49, 0x00, 0x22,
0x04, 0x46, 0xC1, 0xE9, 0x0A,
0x22, 0x87, 0xF7, 0x32, 0xF9, 0x71, 0xF7, 0xFC, 0xFB, 0x18, 0xB1, 0xBD, 0xE8, 0x10, 0x40, 0x8C, 0xF7, 0x57, 0xBB, 0x01, 0x20, 0x5A, 0xF7, 0xAE, 0xFC, 0xB4, 0xF8, 0x09, 0x00, 0x00, 0x21, 0x31, 0xF7, 0x2F, 0xFD, 0xBD, 0xE8, 0x10, 0x40, 0x01,
0xF0, 0xEB, 0xBE, 0x03, 0x01, 0x30, 0xB6, 0x1F, 0x0D, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x0A,
0x22, 0x55, 0x21, 0x0C, 0x20, 0x31, 0xF7, 0x38, 0xFD, 0x01, 0x46, 0x08, 0x30, 0x22, 0x68, 0xC0, 0xF8, 0x02, 0x20, 0x62, 0x68, 0xC0, 0xF8, 0x06, 0x20, 0x22, 0x4C, 0xFC, 0xFF, 0xB1, 0x33, 0x21, 0x00, 0x89, 0x42, 0x81, 0xBD, 0xE8, 0x10, 0x40,
0x08, 0x46, 0x31, 0xF7, 0xA7, 0xBC, 0x03, 0x01, 0x6A, 0xE2, 0x1F, 0x0D, 0x00, 0x3E, 0xB5, 0x00, 0xF1, 0x09, 0x04, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0xD4, 0xF8, 0x03, 0x00, 0x00, 0x90, 0xD4, 0xF8, 0x07, 0x00, 0x01, 0x90, 0xB4,
0xF8, 0x0B, 0x00, 0xAD, 0xF8, 0x08, 0x00, 0x15, 0x46, 0x68, 0x46, 0x8B, 0xF7, 0x71, 0xFC, 0x21, 0x7B, 0x09, 0x06, 0x17, 0xD4, 0x14, 0x28, 0x15, 0xD3, 0x27, 0x49, 0x0A,
0x22, 0x09, 0x1D, 0xE0, 0x1C, 0x70, 0xF7, 0x3F, 0xFE, 0x00, 0x28, 0x0C, 0xD0, 0xE0, 0x1C, 0x70, 0xF7, 0x8C, 0xFE, 0x8D, 0xF7, 0x13, 0xF8, 0x20, 0xB1, 0x8D, 0xF7, 0x41, 0xF8, 0xE0, 0x1C, 0xFF, 0xF7, 0xBD, 0xFF, 0x8B, 0xF7, 0x2F, 0xFF, 0x3E,
0xBD, 0x12, 0x20, 0x68, 0x71, 0x3E, 0xBD, 0x03, 0x01, 0x34, 0x48, 0x20, 0x0D, 0x00, 0x30, 0xB4, 0x09, 0x30, 0x11, 0x23, 0xC1, 0x78, 0x02, 0x29, 0x03, 0xD1, 0x44, 0x68, 0x85, 0x68, 0xAC, 0x42, 0x02, 0xD0, 0x53, 0x71, 0x30, 0xBC, 0x70, 0x47,
0x15, 0x4A, 0x02, 0xF8, 0x0D, 0x1C, 0x41, 0x68, 0x91, 0x67, 0x81, 0x68, 0xD1, 0x67, 0x40, 0x68, 0x30, 0xBC, 0x01, 0xF0, 0xE5, 0xBB, 0x03, 0x01, 0x28, 0x78, 0x20, 0x0D, 0x00, 0x00, 0x20, 0xD0, 0x80, 0x10, 0x81, 0x50, 0x81, 0x90, 0x81, 0xD0,
0x81, 0x10, 0x82, 0x50, 0x82, 0x90, 0x82, 0xD0, 0x82, 0x10, 0x83, 0x50, 0x83, 0x90, 0x83, 0xD0, 0x83, 0x10, 0x84, 0x50, 0x84, 0x90, 0x84, 0x70, 0x47, 0x03, 0x01, 0x24, 0x9C, 0x20, 0x0D, 0x00, 0x70, 0x47, 0x00, 0x00, 0x60, 0x01, 0x65, 0x00,
0xBC, 0x01, 0x60, 0x00, 0x9C, 0x04, 0x32, 0x00, 0xA0, 0x04, 0x32, 0x00, 0xFC, 0x04, 0x41, 0x00, 0x4C, 0xFC, 0xFF, 0xAC, 0x34, 0x21, 0x00, 0x18, 0x3F, 0x20, 0x00, 0xF0, 0x59, 0x20, 0x00, 0x03, 0x01, 0xA4, 0x01, 0xBC, 0x20, 0x0D, 0x00, 0x2D,
0xE9, 0xF0, 0x41, 0x00, 0xF1, 0x09, 0x04, 0x15, 0x46, 0x40, 0x7B, 0x00, 0x21, 0x81, 0xF7, 0x28, 0xFB, 0x10, 0xB9, 0xE0, 0x78, 0x27, 0x28, 0x03, 0xD9, 0x12, 0x20, 0x68, 0x71, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x20, 0xA5, 0xF7, 0x43, 0xFC, 0x10,
0xF0, 0xFF, 0x00, 0x68, 0x71, 0xF6, 0xD1, 0x20, 0x79, 0x72, 0xF7, 0x17, 0xFE, 0xE7, 0x4E, 0x0C, 0x27, 0x30, 0x60, 0x58, 0xB3, 0x60, 0x79, 0x30, 0x71, 0x20, 0x79, 0x70, 0x71, 0xE0, 0x78, 0xE3, 0x49, 0x40, 0x00, 0xF0, 0x71, 0x00, 0x20, 0xB0,
0x71, 0x40, 0xF2, 0xE2, 0x40, 0x30, 0x81, 0xBE, 0x20, 0x08, 0x60, 0x4F, 0xF0, 0x00, 0x00, 0x77, 0xF7, 0x51, 0xFA, 0xDD, 0x48, 0x07, 0x60, 0xDD, 0x48, 0x01, 0x69, 0x41, 0xF0, 0x01, 0x01, 0x01, 0x61, 0x01, 0x68, 0x41, 0xF0, 0x01, 0x01, 0x01,
0x60, 0x30, 0x68, 0x62, 0x79, 0x21, 0x79, 0x00, 0xF1, 0x04, 0x00, 0xA5, 0xF7, 0x5C, 0xFC, 0xA5, 0xF7, 0x6B, 0xFC, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xA5, 0xF7, 0x26, 0xBC, 0x02, 0x20, 0xA5, 0xF7, 0x09, 0xFC, 0x6F, 0x71, 0xBE, 0xE7, 0x03,
0x01, 0x4A, 0x5C, 0x21, 0x0D, 0x00, 0x1C, 0xB5, 0x77, 0xF7, 0x5A, 0xFA, 0xCC, 0x49, 0xB0, 0x20, 0x08, 0x60, 0xCB, 0x48, 0x4F, 0xF0, 0x00, 0x04, 0x04, 0x60, 0xCA, 0x48, 0x01, 0x69, 0x21, 0xF0, 0x01, 0x01, 0x01, 0x61, 0x01, 0x68, 0x21, 0xF0,
0x01, 0x01, 0x01, 0x60, 0x4F, 0xF0, 0x02, 0x00, 0xA5, 0xF7, 0xF0, 0xFB, 0x10, 0xF0, 0xFF, 0x0F, 0xAD, 0xF8, 0x02, 0x40, 0x03, 0xD0, 0x68, 0x46, 0xA2, 0xF7, 0x27, 0xFD, 0x1C, 0xBD, 0xA5, 0xF7, 0x05, 0xFC, 0x4C, 0xFC, 0xFF, 0xA7, 0x35, 0x21,
0x00, 0x1C, 0xBD, 0x03, 0x01, 0x1A, 0xA2, 0x21, 0x0D, 0x00, 0x10, 0xB5, 0x0C, 0x46, 0x90, 0xF8, 0xD2, 0x00, 0xFE, 0xF7, 0xD5, 0xF9, 0x21, 0x8A, 0x01, 0x80, 0x61, 0x8A, 0x41, 0x80, 0x10, 0xBD, 0x03, 0x01, 0xB8, 0x02, 0xB8, 0x21, 0x0D, 0x00,
0x7C, 0xB5, 0x00, 0xF1, 0x09, 0x05, 0x00, 0x26, 0x80, 0x89, 0x6F, 0xF7, 0xFB, 0xFB, 0x04, 0x00, 0x7E, 0xD0, 0xB4, 0xF8, 0x44, 0x00, 0xC0, 0x07, 0x03, 0xD1, 0xB4, 0xF8, 0x46, 0x00, 0xC0, 0x07, 0x01, 0xD0, 0x23, 0x26, 0x80, 0xE0, 0xB5, 0xF8,
0x0F, 0x10, 0xB5, 0xF8, 0x0D, 0x00, 0xCD, 0xE9, 0x00, 0x01, 0xB5, 0xF8, 0x0B, 0x30, 0xB5, 0xF8, 0x09, 0x20, 0xB5, 0xF8, 0x07, 0x10, 0xB5, 0xF8, 0x05, 0x00, 0x44, 0xF7, 0x00, 0xFE, 0x00, 0x28, 0x6B, 0xD0, 0x94, 0xF8, 0xD2, 0x00, 0xFE, 0xF7,
0xA7, 0xF9, 0xB5, 0xF8, 0x05, 0x10, 0x01, 0x80, 0xB5, 0xF8, 0x07, 0x10, 0x41, 0x80, 0x20, 0x6C, 0x01, 0x04, 0x2E, 0xD5, 0x94, 0xF8, 0xB0, 0x10, 0x4A, 0x07, 0x2A, 0xD5, 0x89, 0x07, 0x28, 0xD5, 0xB4, 0xF8, 0x44, 0x10, 0x49, 0x05, 0x22, 0xD4,
0xB4, 0xF8, 0x46, 0x10, 0x4A, 0x05, 0x1E, 0xD4, 0xB5, 0xF8, 0x05, 0x20, 0xA4, 0xF8, 0x1C, 0x21, 0xB5, 0xF8, 0x07, 0x20, 0xA4, 0xF8, 0x1E, 0x21, 0xB5, 0xF8, 0x09, 0x20, 0xA2, 0x83, 0xB5, 0xF8, 0x0B, 0x20, 0xE2, 0x83, 0xB5, 0xF8, 0x0D, 0x20,
0xA4, 0xF8, 0x24, 0x21, 0xB5, 0xF8, 0x0F, 0x20, 0xA4, 0xF8, 0x26, 0x21, 0x40, 0xF0, 0x02, 0x00, 0x20, 0x64, 0x00, 0x20, 0x84, 0xF8, 0x21, 0x01, 0x41, 0xF4, 0x80, 0x60, 0x2B, 0xE0, 0x0C, 0x26, 0x32, 0xE0, 0x94, 0xF8, 0xD1, 0x00, 0x08, 0xB1,
0x1A, 0x26, 0x2D, 0xE0, 0x86, 0x48, 0x70, 0xF7, 0xB1, 0xFB, 0xB5, 0xF8, 0x4C, 0xFC, 0xFF, 0xA2, 0x36, 0x21, 0x00, 0x0F, 0x20, 0xB5, 0xF8, 0x0D, 0x10, 0x20, 0x46, 0x44, 0xF7, 0xD0, 0xFD, 0xB5, 0xF8, 0x05, 0x00, 0xA4, 0xF8, 0x48, 0x00, 0xB5,
0xF8, 0x07, 0x00, 0xA4, 0xF8, 0x4A, 0x00, 0xB5, 0xF8, 0x09, 0x00, 0xA0, 0x83, 0xB5, 0xF8, 0x0B, 0x00, 0xE0, 0x83, 0x20, 0x6C, 0x40, 0xF0, 0x02, 0x00, 0x20, 0x64, 0x78, 0x48, 0x70, 0xF7, 0x9B, 0xFB, 0xB4, 0xF8, 0x46, 0x00, 0x00, 0xE0, 0x09,
0xE0, 0x40, 0xF0, 0x01, 0x00, 0xA4, 0xF8, 0x46, 0x00, 0x20, 0x46, 0xA1, 0xF7, 0x42, 0xFF, 0x02, 0xE0, 0x12, 0x26, 0x00, 0xE0, 0x02, 0x26, 0x28, 0x88, 0x31, 0x46, 0xBD, 0xE8, 0x7C, 0x40, 0x31, 0xF7, 0xBB, 0xBB, 0x03, 0x01, 0x98, 0x02, 0xEC,
0x22, 0x0D, 0x00, 0x2D, 0xE9, 0xFC, 0x47, 0x00, 0xF1, 0x09, 0x04, 0x16, 0x46, 0x80, 0x89, 0x6F, 0xF7, 0x60, 0xFB, 0x05, 0x00, 0x7D, 0xD0, 0x28, 0x6C, 0xC1, 0x03, 0x77, 0xD5, 0x20, 0xF4, 0x80, 0x30, 0x28, 0x64, 0xB4, 0xF8, 0x0F, 0x10, 0xB4,
0xF8, 0x0D, 0x00, 0xCD, 0xE9, 0x00, 0x01, 0xB4, 0xF8, 0x0B, 0x30, 0xB4, 0xF8, 0x09, 0x20, 0xB4, 0xF8, 0x07, 0x10, 0xB4, 0xF8, 0x05, 0x00, 0x44, 0xF7, 0x69, 0xFD, 0x4F, 0xF0, 0x12, 0x09, 0xF0, 0xB3, 0x95, 0xF8, 0xD2, 0x00, 0xFE, 0xF7, 0x0F,
0xF9, 0xB4, 0xF8, 0x05, 0x10, 0x01, 0x80, 0xB4, 0xF8, 0x07, 0x10, 0x41, 0x80, 0xB5, 0xF8, 0x1C, 0x71, 0xB4, 0xF8, 0x05, 0x00, 0x87, 0x42, 0x00, 0xD8, 0x07, 0x46, 0xB5, 0xF8, 0x1E, 0x11, 0xB4, 0xF8, 0x07, 0x00, 0x81, 0x42, 0x00, 0xD2, 0x08,
0x46, 0x80, 0x46, 0x47, 0x45, 0x31, 0xD8, 0x95, 0xF8, 0xD1, 0x00, 0x50, 0xB1, 0xB4, 0xF8, 0x0B, 0x00, 0x00, 0x90, 0xB4, 0xF8, 0x09, 0x30, 0x42, 0x46, 0x39, 0x46, 0x28, 0x46, 0xFE, 0x4C, 0xFC, 0xFF, 0x9D, 0x37, 0x21, 0x00, 0xF7, 0xF2, 0xFA,
0x1F, 0xE0, 0x46, 0x48, 0x70, 0xF7, 0x31, 0xFB, 0xB4, 0xF8, 0x0F, 0x20, 0xB4, 0xF8, 0x0D, 0x10, 0x28, 0x46, 0x44, 0xF7, 0x50, 0xFD, 0xA5, 0xF8, 0x48, 0x70, 0xA5, 0xF8, 0x4A, 0x80, 0xB4, 0xF8, 0x09, 0x00, 0xA8, 0x83, 0xB4, 0xF8, 0x0B, 0x00,
0xE8, 0x83, 0x28, 0x6C, 0x00, 0xE0, 0x0C, 0xE0, 0x40, 0xF0, 0x02, 0x00, 0x28, 0x64, 0x39, 0x48, 0x70, 0xF7, 0x1D, 0xFB, 0x28, 0x46, 0xA9, 0xF7, 0xEE, 0xFA, 0x70, 0x79, 0x12, 0x28, 0x02, 0xD0, 0x0D, 0xE0, 0x86, 0xF8, 0x05, 0x90, 0xB5, 0xF8,
0x44, 0x00, 0x4F, 0xF6, 0xFE, 0x31, 0x08, 0x40, 0xA5, 0xF8, 0x44, 0x00, 0x0F, 0x22, 0x3B, 0x21, 0x28, 0x46, 0xA9, 0xF7, 0xAF, 0xFC, 0xB4, 0xF8, 0x03, 0x00, 0xF0, 0x80, 0xBD, 0xE8, 0xFC, 0x87, 0x03, 0xE0, 0xFF, 0xE7, 0x0C, 0x20, 0x70, 0x71,
0xF5, 0xE7, 0x02, 0x20, 0xFB, 0xE7, 0x03, 0x01, 0x48, 0x00, 0x24, 0x0D, 0x00, 0x70, 0xB5, 0x00, 0xF1, 0x09, 0x04, 0x15, 0x46, 0x80, 0x89, 0x6F, 0xF7, 0xD7, 0xFA, 0xB8, 0xB1, 0x01, 0x6C, 0xCA, 0x03, 0x0E, 0xD5, 0x21, 0xF4, 0x80, 0x31, 0x01,
0x64, 0xB0, 0xF8, 0x44, 0x10, 0x4F, 0xF6, 0xFE, 0x32, 0x11, 0x40, 0xA0, 0xF8, 0x44, 0x10, 0x61, 0x79, 0x0F, 0x22, 0xA9, 0xF7, 0x8A, 0xFC, 0x01, 0xE0, 0x0C, 0x20, 0x68, 0x71, 0xB4, 0xF8, 0x03, 0x00, 0xE8, 0x80, 0x70, 0xBD, 0x02, 0x20, 0xF8,
0xE7, 0x03, 0x01, 0x14, 0x44, 0x24, 0x0D, 0x00, 0x17, 0x48, 0x81, 0x68, 0xC2, 0xF8, 0x06, 0x10, 0xC0, 0x68, 0xC2, 0xF8, 0x0A,
0x00, 0x70, 0x47, 0x03, 0x01, 0x60, 0x54, 0x24, 0x0D, 0x00, 0x70, 0xB5, 0x14, 0x4C, 0x0E, 0x46, 0x00, 0xF1, 0x09, 0x05, 0xA1, 0x69, 0x31, 0xB1, 0xB0, 0xF8, 0x09, 0x4C, 0xFC, 0xFF, 0x98, 0x38, 0x21, 0x00, 0x00, 0xBD, 0xE8, 0x70, 0x40, 0x0C,
0x21, 0x31, 0xF7, 0xCE, 0xBA, 0x0B, 0x48, 0x70, 0xF7, 0xBB, 0xFA, 0xA7, 0xF7, 0x88, 0xFE, 0x0C, 0x48, 0xA5, 0x61, 0xC4, 0xE9, 0x02, 0x04, 0x07, 0x48, 0x70, 0xF7, 0xB8, 0xFA, 0x00, 0x20, 0x30, 0x70, 0x70, 0xBD, 0x00, 0x00, 0x08, 0xE3, 0x20,
0x00, 0x94, 0x80, 0x31, 0x00, 0x34, 0x09, 0x64, 0x00, 0x60, 0x01, 0x65, 0x00, 0x10, 0x29, 0x20, 0x00, 0x80, 0x7F, 0x20, 0x00, 0x1C, 0xE3, 0x20, 0x00, 0x93, 0x6E, 0x01, 0x00, 0x03, 0x01, 0x1E, 0xB0, 0x24, 0x0D, 0x00, 0x32, 0x49, 0x00, 0x20,
0x6F, 0xF0, 0x7F, 0x02, 0x0B, 0x18, 0x40, 0x1C, 0x83, 0xF8, 0x38, 0x20, 0x07, 0x28, 0xF9, 0xD3, 0x00, 0x20, 0x08, 0x73, 0x70, 0x47, 0x03, 0x01, 0x1E, 0xCA, 0x24, 0x0D, 0x00, 0x10, 0xB5, 0x40, 0x21, 0x2B, 0x48, 0x9B, 0xF7, 0x66, 0xFD, 0xFF,
0xF7, 0xEC, 0xFF, 0x28, 0x48, 0xFF, 0x21, 0x01, 0x60, 0x00, 0x21, 0x41, 0x73, 0x10, 0xBD, 0x03, 0x01, 0xBC, 0x01, 0xE4, 0x24, 0x0D, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x25, 0x48, 0x00, 0x21, 0x5D, 0xF7, 0xC1, 0xFD, 0x0D, 0xB1, 0x5C, 0xF7, 0x94,
0xFA, 0x00, 0xF0, 0x4B, 0xF9, 0x01, 0x20, 0x51, 0xF7, 0x44, 0xFB, 0x74, 0xF7, 0xD2, 0xFE, 0x53, 0xF7, 0xEA, 0xFE, 0x58, 0xF7, 0x5D, 0xF9, 0x8B, 0xF7, 0x75, 0xFF, 0x28, 0x46, 0x70, 0xF7, 0x36, 0xFC, 0x1B, 0x49, 0x00, 0x20, 0x04, 0x46, 0xC1,
0xE9, 0x0C, 0x00, 0x19, 0x48, 0x04, 0x70, 0x7F, 0xF7, 0x51, 0xFD, 0x5A, 0xF7, 0x6F, 0xFA, 0x5C, 0xF7, 0x94, 0xFB, 0x5C, 0xF7, 0x47, 0xFD, 0x4F, 0xF4, 0xC0, 0x20, 0x00, 0x21, 0x5D, 0xF7, 0x85, 0xFD, 0x90, 0xF7, 0x92, 0xFF, 0x12, 0x48, 0x00,
0x68, 0x00, 0x07, 0x01, 0xD5, 0x4C, 0xFC, 0xFF, 0x93, 0x39, 0x21, 0x00, 0x5A, 0xF7, 0xDD, 0xF8, 0x00, 0x2D, 0x12, 0xD0, 0x0F, 0x48, 0x0F, 0x49, 0x04, 0x70, 0x08, 0x78, 0x40, 0xF0, 0x03, 0x00, 0x08, 0x70, 0xC0, 0x43, 0x80, 0x07, 0x01, 0xD1,
0x0C, 0x48, 0x04, 0x70, 0xFF, 0xF7, 0xAE, 0xFF, 0x05, 0x48, 0xC0, 0xF8, 0x96, 0x40, 0xA0, 0xF8, 0x9A, 0x40, 0x70, 0xBD, 0x00, 0x00, 0x6C, 0x73, 0x0D, 0x00, 0x01, 0x7C, 0x46, 0x00, 0x18, 0x3F, 0x20, 0x00, 0xEF, 0x2B, 0x20, 0x00, 0xE4, 0x1D,
0x20, 0x00, 0x36, 0x23, 0x20, 0x00, 0xF8, 0x2B, 0x20, 0x00, 0xF0, 0x2B, 0x20, 0x00, 0x03, 0x01, 0xB0, 0x02, 0x9C, 0x25, 0x0D, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x04, 0x46, 0x80, 0x78, 0x12, 0x22, 0x88, 0x46, 0x08, 0x28, 0x18, 0xD0, 0x0A,
0x28, 0x11, 0xD3, 0x94, 0xF9, 0x0B, 0x50, 0x94, 0xF9, 0x0C, 0x60, 0x94, 0xF9, 0x08, 0x10, 0x94, 0xF9, 0x09, 0x00, 0x81, 0x42, 0x07, 0xDC, 0x94, 0xF9, 0x0A,
0x10, 0x88, 0x42, 0x03, 0xDC, 0xA9, 0x42, 0x01, 0xDC, 0xB5, 0x42, 0x0B, 0xDD, 0xD8, 0xF8, 0x00, 0x00, 0x42, 0x71, 0xBD, 0xE8, 0xFE, 0x8F, 0xE0, 0x79, 0x7F, 0x25, 0x20, 0xF0, 0x08, 0x00, 0xE0, 0x71, 0x2E, 0x46, 0xE5, 0xE7, 0xE0, 0x79, 0x00,
0xF0, 0x0F, 0x01, 0xE1, 0x71, 0x20, 0x79, 0x01, 0x28, 0x10, 0xD0, 0x02, 0x28, 0xED, 0xD1, 0x94, 0xF9, 0x0A,
0x00, 0x8D, 0xE8, 0x61, 0x00, 0xB4, 0xF8, 0x05, 0x00, 0x94, 0xF9, 0x09, 0x30, 0x94, 0xF9, 0x08, 0x20, 0x40, 0xF4, 0x70, 0x40, 0x61, 0xF7, 0x5D, 0xFC, 0xDE, 0xE7, 0x28, 0x48, 0x4F, 0xF0, 0x02, 0x0A,
0x00, 0x78, 0xA0, 0xB3, 0xB4, 0xF8, 0x05, 0x00, 0x01, 0x21, 0x70, 0xF7, 0x4D, 0xFE, 0x07, 0x00, 0x2E, 0xD0, 0xDF, 0xF8, 0x8C, 0x90, 0xB9, 0x6A, 0xC9, 0xF8, 0x04, 0x4C, 0xFC, 0xFF, 0x8E, 0x3A, 0x21, 0x00, 0x10, 0xB9, 0x8D, 0xA9, 0xF8, 0x08,
0x10, 0xFF, 0xF7, 0x34, 0xFF, 0xFF, 0x21, 0x00, 0x20, 0xC9, 0xF8, 0x00, 0x10, 0x89, 0xF8, 0x0D, 0x00, 0x89, 0xF8, 0x0B, 0x00, 0xF8, 0x69, 0xC0, 0xF3, 0xC4, 0x00, 0x08, 0x38, 0x05, 0x28, 0x16, 0xD2, 0x39, 0x68, 0xC9, 0xF8, 0x00, 0x10, 0x01,
0x21, 0x89, 0xF8, 0x0D, 0x10, 0xE1, 0x79, 0x48, 0x46, 0x07, 0x29, 0xB0, 0xD8, 0x01, 0x74, 0x21, 0x7A, 0x41, 0x74, 0x61, 0x7A, 0x81, 0x74, 0xA1, 0x7A, 0xC1, 0x74, 0x05, 0x75, 0x46, 0x75, 0x89, 0xF8, 0x0B, 0xA0, 0xA4, 0xE7, 0xFF, 0xE7, 0xB4,
0xF8, 0x05, 0x00, 0x6F, 0xF7, 0x91, 0xF9, 0x58, 0xB1, 0x94, 0xF9, 0x0A,
0x10, 0x8D, 0xE8, 0x62, 0x00, 0x94, 0xF9, 0x09, 0x30, 0x94, 0xF9, 0x08, 0x20, 0xE1, 0x79, 0x90, 0xF8, 0xD2, 0x00, 0xB0, 0xE7, 0xD8, 0xF8, 0x00, 0x10, 0x81, 0xF8, 0x05, 0xA0, 0x8D, 0xE7, 0x00, 0x00, 0xE8, 0x6F, 0x0D, 0x00, 0x6C, 0x73, 0x0D,
0x00, 0x03, 0x01, 0x9A, 0x01, 0xC8, 0x26, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x00, 0xF1, 0x09, 0x01, 0x05, 0x7B, 0x40, 0x7B, 0x4E, 0x79, 0x10, 0x72, 0x95, 0x71, 0xC0, 0xF3, 0x41, 0x01, 0x14, 0x46, 0x00, 0xF0, 0x01, 0x07, 0xD6, 0x71, 0x03,
0x29, 0x05, 0xD0, 0x29, 0x06, 0x05, 0xD5, 0x11, 0x20, 0x50, 0x71, 0xBD, 0xE8, 0xF0, 0x81, 0x12, 0x20, 0xFA, 0xE7, 0x04, 0x2D, 0x01, 0xD2, 0x22, 0x49, 0x01, 0xE0, 0x21, 0x49, 0x09, 0x1D, 0xAB, 0x07, 0x4F, 0xEA, 0xD3, 0x6C, 0x0A,
0x68, 0xFF, 0x23, 0x03, 0xFA, 0x0C, 0xF3, 0x9A, 0x43, 0x00, 0xFA, 0x0C, 0xF0, 0x10, 0x43, 0x1B, 0x4A, 0x08, 0x60, 0x10, 0x68, 0x4F, 0xEA, 0x85, 0x03, 0x4F, 0xF0, 0x0F, 0x01, 0x01, 0xFA, 0x03, 0xF1, 0x20, 0xEA, 0x4C, 0xFC, 0xFF, 0x89, 0x3B,
0x21, 0x00, 0x01, 0x00, 0x10, 0x60, 0x87, 0xF0, 0x01, 0x02, 0x4F, 0xF0, 0x00, 0x01, 0x28, 0x46, 0xA3, 0xF7, 0x42, 0xFE, 0x27, 0xB1, 0x28, 0x46, 0xA3, 0xF7, 0x28, 0xFE, 0xC6, 0xB2, 0x03, 0xE0, 0x31, 0x46, 0x28, 0x46, 0xA3, 0xF7, 0x14, 0xFE,
0xE6, 0x71, 0x00, 0x20, 0x60, 0x71, 0xC9, 0xE7, 0x03, 0x01, 0x36, 0x5E, 0x27, 0x0D, 0x00, 0x70, 0xB5, 0x00, 0xF1, 0x09, 0x05, 0x00, 0x7B, 0x02, 0x21, 0x14, 0x46, 0xB1, 0xEB, 0xD0, 0x0F, 0x02, 0xD8, 0x30, 0x20, 0x50, 0x71, 0x70, 0xBD, 0xA3,
0xF7, 0x10, 0xFE, 0xE0, 0x71, 0xE8, 0x78, 0xA0, 0x71, 0x00, 0x20, 0x60, 0x71, 0x70, 0xBD, 0x00, 0x00, 0x68, 0x00, 0x32, 0x00, 0x88, 0x00, 0x32, 0x00, 0x03, 0x01, 0x30, 0x90, 0x27, 0x0D, 0x00, 0x70, 0xB5, 0x09, 0x4D, 0x00, 0x24, 0xC4, 0xEB,
0x04, 0x10, 0x00, 0xEB, 0x84, 0x10, 0x05, 0xEB, 0x80, 0x00, 0xB0, 0xF8, 0xD0, 0x10, 0xC9, 0x04, 0x01, 0xD5, 0x8A, 0xF7, 0xED, 0xFE, 0x64, 0x1C, 0x03, 0x2C, 0xF0, 0xD3, 0x70, 0xBD, 0x00, 0x00, 0x5C, 0x73, 0x20, 0x00, 0x03, 0x01, 0x38, 0xBC,
0x27, 0x0D, 0x00, 0x10, 0xB5, 0x77, 0xF7, 0xD7, 0xFC, 0x00, 0x28, 0x11, 0xD0, 0x77, 0xF7, 0xB1, 0xFC, 0x00, 0x28, 0x0D, 0xD0, 0x77, 0xF7, 0x8E, 0xFC, 0x00, 0x28, 0x09, 0xD0, 0x05, 0x48, 0x00, 0x23, 0x1A, 0x46, 0xB0, 0xF9, 0x04, 0x10, 0xC0,
0x78, 0xBD, 0xE8, 0x10, 0x40, 0x77, 0xF7, 0x75, 0xBB, 0x10, 0xBD, 0x58, 0x23, 0x20, 0x00, 0x03, 0x01, 0x54, 0xF0, 0x27, 0x0D, 0x00, 0x70, 0xB5, 0x01, 0x46, 0x6C, 0x4D, 0x6F, 0xF0, 0x7F, 0x00, 0x01, 0x29, 0x0A,
0xD0, 0x28, 0x7B, 0x80, 0x1D, 0x07, 0x21, 0xB0, 0xFB, 0xF1, 0xF2, 0x01, 0xFB, 0x12, 0x00, 0x28, 0x44, 0x90, 0x4C, 0xFC, 0xFF, 0x84, 0x3C, 0x21, 0x00, 0xF9, 0x38, 0x00, 0x70, 0xBD, 0x00, 0x21, 0x0A,
0x46, 0x0B, 0x46, 0x6C, 0x18, 0x94, 0xF9, 0x38, 0x40, 0x14, 0xF1, 0x80, 0x06, 0x02, 0xD0, 0x52, 0x1C, 0x23, 0x44, 0xD2, 0xB2, 0x49, 0x1C, 0xC9, 0xB2, 0x07, 0x29, 0xF2, 0xD3, 0x00, 0x2A, 0xEC, 0xD0, 0xB3, 0xFB, 0xF2, 0xF0, 0x40, 0xB2, 0x70,
0xBD, 0x03, 0x01, 0xC2, 0x02, 0x40, 0x28, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x5F, 0x58, 0x4D, 0x28, 0x68, 0x70, 0xF7, 0x8E, 0xFA, 0x04, 0x00, 0x66, 0xD0, 0xE0, 0x69, 0xC0, 0xF3, 0xC4, 0x00, 0x08, 0x38, 0x05, 0x28, 0x60, 0xD2, 0xDF, 0xF8, 0x4C,
0xB1, 0x9B, 0xF8, 0x05, 0x00, 0xFF, 0xF7, 0xC4, 0xFF, 0x02, 0x46, 0x4F, 0xF0, 0x01, 0x09, 0x85, 0xF8, 0x3F, 0x90, 0x80, 0x30, 0x53, 0xD0, 0x29, 0x7C, 0xE8, 0x7A, 0x95, 0xF9, 0x11, 0x70, 0x95, 0xF9, 0x12, 0xA0, 0x95, 0xF9, 0x13, 0x60, 0x95,
0xF9, 0x14, 0xC0, 0x95, 0xF9, 0x15, 0x80, 0xB4, 0xF8, 0x64, 0x30, 0x00, 0x29, 0x43, 0xD0, 0x06, 0x28, 0x41, 0xD0, 0xBA, 0x42, 0x32, 0xDC, 0x02, 0x28, 0x3D, 0xD0, 0x48, 0x07, 0x3B, 0xD5, 0x9B, 0xF8, 0x03, 0x00, 0xDC, 0x46, 0x4F, 0xF0, 0x02,
0x08, 0x10, 0xB9, 0x9C, 0xF8, 0x04, 0x00, 0xE8, 0xB1, 0x00, 0x20, 0x01, 0x46, 0x2E, 0x18, 0x96, 0xF9, 0x38, 0x60, 0xBE, 0x42, 0x03, 0xDC, 0x80, 0x36, 0x01, 0xD0, 0x49, 0x1C, 0xC9, 0xB2, 0x40, 0x1C, 0xC0, 0xB2, 0x07, 0x28, 0xF2, 0xD3, 0xE0,
0x69, 0xC0, 0xF3, 0xC4, 0x00, 0x08, 0x28, 0x03, 0xD1, 0x9C, 0xF8, 0x06, 0x40, 0x8C, 0x42, 0x05, 0xD9, 0x0A,
0x28, 0x18, 0xD1, 0x9B, 0xF8, 0x07, 0x00, 0x88, 0x42, 0x14, 0xD8, 0x85, 0xF8, 0x0B, 0x80, 0xBD, 0xE8, 0xF0, 0x5F, 0x02, 0x21, 0x18, 0x46, 0x9B, 0xF7, 0x4C, 0xFC, 0xFF, 0x7F, 0x3D, 0x21, 0x00, 0xF6, 0xBC, 0x52, 0x45, 0x0C, 0xDC, 0x08, 0xB1,
0x03, 0x28, 0x07, 0xD1, 0x88, 0x07, 0x03, 0xD5, 0x01, 0x21, 0x18, 0x46, 0x9B, 0xF7, 0xEB, 0xFC, 0x85, 0xF8, 0x0B, 0x90, 0xBD, 0xE8, 0xF0, 0x9F, 0xB2, 0x42, 0x0E, 0xDC, 0x03, 0x28, 0x08, 0xD0, 0x02, 0x28, 0xF7, 0xD1, 0x01, 0x24, 0x09, 0xFA,
0x04, 0xF0, 0x08, 0x42, 0x03, 0xD0, 0x21, 0x46, 0x11, 0xE0, 0x00, 0x24, 0xF7, 0xE7, 0xEC, 0x72, 0xEC, 0xE7, 0x00, 0x24, 0x62, 0x45, 0x01, 0xDC, 0x30, 0xB9, 0xE7, 0xE7, 0x42, 0x45, 0x0A,
0xDC, 0x01, 0x28, 0x01, 0xD0, 0x02, 0x28, 0xE1, 0xD1, 0xC8, 0x07, 0xF0, 0xD0, 0x00, 0x21, 0x18, 0x46, 0x9B, 0xF7, 0xC5, 0xFC, 0xEB, 0xE7, 0x03, 0x28, 0xD8, 0xD0, 0x08, 0x07, 0x03, 0xD5, 0x03, 0x21, 0x18, 0x46, 0x9B, 0xF7, 0xBC, 0xFC, 0x03,
0x20, 0xE8, 0x72, 0xCF, 0xE7, 0x03, 0x01, 0x36, 0x7E, 0x29, 0x0D, 0x00, 0x0B, 0x48, 0x00, 0x78, 0x00, 0x28, 0x0E, 0xD0, 0x08, 0x48, 0xC1, 0x7B, 0x00, 0x29, 0x0A,
0xD0, 0x90, 0xF8, 0x3F, 0x10, 0x00, 0x29, 0x06, 0xD1, 0x01, 0x68, 0xFF, 0x29, 0x03, 0xD0, 0x40, 0x7B, 0x01, 0x28, 0x00, 0xD1, 0x4D, 0xE7, 0x70, 0x47, 0x00, 0x00, 0x6C, 0x73, 0x0D, 0x00, 0xE8, 0x6F, 0x0D, 0x00, 0x03, 0x01, 0x14, 0xB0, 0x29,
0x0D, 0x00, 0x10, 0xB5, 0xAE, 0xF7, 0x32, 0xFC, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0xE0, 0xBF, 0x00, 0x00, 0x03, 0x01, 0x20, 0xC0, 0x29, 0x0D, 0x00, 0x05, 0x48, 0x10, 0xB5, 0x80, 0x7B, 0x20, 0xB9, 0x86, 0xF7, 0xFB, 0xFB, 0x08, 0xB1, 0x02,
0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xB0, 0x59, 0x20, 0x00, 0x03, 0x01, 0x26, 0xDC, 0x29, 0x0D, 0x00, 0x21, 0x4A, 0x02, 0xF1, 0x38, 0x4C, 0xFC, 0xFF, 0x7A, 0x3E, 0x21, 0x00, 0x01, 0x13, 0x7B, 0x58, 0x54, 0x10, 0x7B, 0x07,
0x21, 0x40, 0x1C, 0xB0, 0xFB, 0xF1, 0xF3, 0x01, 0xFB, 0x13, 0x00, 0x10, 0x73, 0x00, 0x20, 0x82, 0xF8, 0x3F, 0x00, 0x70, 0x47, 0x03, 0x01, 0x72, 0xFE, 0x29, 0x0D, 0x00, 0x70, 0xB5, 0x19, 0x4E, 0x04, 0x46, 0x30, 0x78, 0x00, 0x28, 0x26, 0xD0,
0x16, 0x48, 0x41, 0x7B, 0x01, 0x29, 0x22, 0xD1, 0x00, 0x68, 0x94, 0xF8, 0xA8, 0x10, 0x88, 0x42, 0x1D, 0xD1, 0x70, 0x78, 0x18, 0xB1, 0x20, 0x46, 0x83, 0xF7, 0xAA, 0xFE, 0x03, 0xE0, 0x20, 0x7C, 0x00, 0x21, 0x83, 0xF7, 0xF4, 0xFE, 0x05, 0x46,
0xB0, 0x78, 0x88, 0xB1, 0x94, 0xF8, 0xA8, 0x00, 0x70, 0xF7, 0x9F, 0xFF, 0x6C, 0xF7, 0xC1, 0xFF, 0x04, 0x46, 0xF1, 0x68, 0x6C, 0xF7, 0x35, 0xFD, 0xB1, 0x68, 0x81, 0x42, 0x03, 0xD8, 0x28, 0x46, 0xFF, 0xF7, 0xC3, 0xFF, 0xF4, 0x60, 0x70, 0xBD,
0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xBC, 0xE7, 0x00, 0x00, 0x6C, 0x73, 0x0D, 0x00, 0xE8, 0x6F, 0x0D, 0x00, 0x03, 0x01, 0x92, 0x02, 0x6C, 0x2A, 0x0D, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0xCE, 0x4F, 0x69, 0x46, 0x01, 0xA8, 0x3C, 0x68, 0x64, 0xF7,
0xD4, 0xFF, 0x38, 0x60, 0x54, 0xB1, 0xA0, 0x42, 0x03, 0xD0, 0xCA, 0x48, 0x00, 0x78, 0xA0, 0x74, 0x04, 0xE0, 0x00, 0x98, 0x10, 0xB9, 0x20, 0x46, 0x64, 0xF7, 0xB8, 0xFF, 0x38, 0x68, 0x4F, 0xF0, 0x01, 0x08, 0x00, 0x26, 0x20, 0xB1, 0xA0, 0x42,
0x0D, 0xD0, 0x64, 0xF7, 0x89, 0xFF, 0x08, 0xE0, 0xC0, 0x48, 0x10, 0x30, 0x05, 0x46, 0x51, 0xF7, 0x57, 0xF9, 0x10, 0xB9, 0x28, 0x46, 0x51, 0xF7, 0x6B, 0xF9, 0x38, 0x68, 0x08, 0xB1, 0x00, 0x98, 0x28, 0xB1, 0xBE, 0x85, 0x87, 0xF8, 0x32, 0x60,
0x87, 0xF8, 0x33, 0x4C, 0xFC, 0xFF, 0x75, 0x3F, 0x21, 0x00, 0x80, 0x50, 0xE0, 0x97, 0xF8, 0x33, 0x00, 0x58, 0xB1, 0x01, 0x25, 0x87, 0xF8, 0x30, 0x60, 0x14, 0xB1, 0x14, 0xF8, 0xEE, 0x0F, 0x60, 0x70, 0x38, 0x68, 0x10, 0xF8, 0xEE, 0x1F, 0x41,
0x70, 0x25, 0xE0, 0x01, 0x98, 0x10, 0xB3, 0x01, 0x25, 0x64, 0xF7, 0x2B, 0xFE, 0x08, 0xB1, 0xAE, 0x48, 0x00, 0xE0, 0xAE, 0x48, 0x04, 0x78, 0x97, 0xF8, 0x32, 0x00, 0xA0, 0x42, 0x13, 0xD8, 0x5C, 0xF7, 0x40, 0xF8, 0xC0, 0x43, 0x80, 0x07, 0x0B,
0xD0, 0x87, 0xF8, 0x30, 0x60, 0xB8, 0x6A, 0x70, 0xB1, 0x90, 0xF8, 0xEF, 0x10, 0xA1, 0x42, 0x0A,
0xD2, 0x89, 0x1D, 0x80, 0xF8, 0xEF, 0x10, 0x06, 0xE0, 0x87, 0xF8, 0x30, 0x80, 0xF2, 0xE7, 0x87, 0xF8, 0x30, 0x80, 0x00, 0xE0, 0x00, 0x25, 0x87, 0xF8, 0x33, 0x60, 0x15, 0xB1, 0x87, 0xF8, 0x32, 0x60, 0xBE, 0x62, 0x97, 0xF8, 0x30, 0x00, 0x18,
0xB1, 0x04, 0x21, 0x38, 0x68, 0x64, 0xF7, 0xF3, 0xFD, 0x38, 0x68, 0x00, 0xF1, 0xEE, 0x00, 0x86, 0x70, 0xC6, 0x70, 0x06, 0x71, 0x46, 0x71, 0x86, 0x71, 0x01, 0x78, 0x40, 0x78, 0x08, 0x44, 0xC0, 0xB2, 0x87, 0xF8, 0x31, 0x00, 0xB8, 0x85, 0x4F,
0xF0, 0x01, 0x00, 0xBD, 0xE8, 0xFC, 0x81, 0x03, 0x01, 0xCC, 0x02, 0x7A, 0x2B, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0x90, 0xF8, 0x98, 0x00, 0x18, 0xB9, 0x20, 0x68, 0x01, 0x6A, 0x20, 0x46, 0x88, 0x47, 0x57, 0xF7, 0x3F, 0xFC, 0x01,
0x26, 0x20, 0xB1, 0x94, 0xF8, 0x98, 0x00, 0x02, 0x28, 0x09, 0xD0, 0x5F, 0xE0, 0x04, 0xF8, 0x99, 0x6F, 0x20, 0x79, 0x20, 0xF0, 0x01, 0x00, 0x20, 0x71, 0xA4, 0xF1, 0x99, 0x04, 0x56, 0xE0, 0xE0, 0x7B, 0x68, 0xB9, 0x5E, 0xF7, 0x42, 0xFE, 0x50,
0xB1, 0x94, 0xF8, 0x94, 0x00, 0x4C, 0xFC, 0xFF, 0x70, 0x40, 0x21, 0x00, 0xC0, 0xF3, 0xC3, 0x00, 0x40, 0x1F, 0x03, 0x28, 0x03, 0xD3, 0x94, 0xF8, 0xA8, 0x00, 0x5E, 0xF7, 0xE0, 0xFA, 0x7A, 0x48, 0x05, 0x68, 0x04, 0xF1, 0x94, 0x00, 0x29, 0x46,
0x07, 0x46, 0x84, 0xF7, 0xD6, 0xFB, 0x94, 0xF8, 0x94, 0x00, 0x94, 0xF8, 0x9C, 0x20, 0xC0, 0xF3, 0x02, 0x01, 0xC2, 0xF3, 0x02, 0x02, 0x91, 0x42, 0x26, 0xD1, 0x72, 0x49, 0xC9, 0x7C, 0xC9, 0x06, 0x0D, 0xD5, 0x71, 0x49, 0xC0, 0xF3, 0xC3, 0x00,
0x09, 0x68, 0x09, 0x68, 0xC1, 0xF3, 0xC3, 0x31, 0x88, 0x42, 0x04, 0xD1, 0x29, 0x46, 0x20, 0x46, 0x8E, 0xF7, 0x78, 0xFA, 0x22, 0xE0, 0x00, 0x23, 0x2A, 0x46, 0x04, 0xF1, 0x28, 0x01, 0x38, 0x46, 0x84, 0xF7, 0x8A, 0xF9, 0x94, 0xF8, 0x99, 0x00,
0x01, 0x28, 0x01, 0xD0, 0x84, 0xF8, 0xF3, 0x60, 0x94, 0xF8, 0x9D, 0x00, 0xC0, 0x07, 0x11, 0xD0, 0x00, 0x20, 0x84, 0xF8, 0xE8, 0x00, 0x0D, 0xE0, 0x40, 0x07, 0x0B, 0xD1, 0x68, 0x03, 0x09, 0xD5, 0x15, 0xF4, 0x60, 0x1F, 0x06, 0xD1, 0x02, 0x20,
0x84, 0xF8, 0x99, 0x00, 0x29, 0x46, 0x38, 0x46, 0x84, 0xF7, 0x1A, 0xF9, 0xE0, 0x7B, 0x01, 0x28, 0x20, 0xD1, 0x94, 0xF8, 0x98, 0x00, 0x01, 0x28, 0x1A, 0xD0, 0x02, 0x28, 0x1A, 0xD1, 0x94, 0xF8, 0x94, 0x00, 0x10, 0xF0, 0x78, 0x0F, 0x02, 0xD1,
0xD4, 0xF8, 0xA4, 0x10, 0x81, 0xB1, 0xC0, 0xF3, 0xC3, 0x01, 0x01, 0x29, 0x0A,
0xD1, 0xD4, 0xF8, 0xA4, 0x10, 0x39, 0xB9, 0x4D, 0x4A, 0xD4, 0xF8, 0xC8, 0x10, 0x12, 0x68, 0x11, 0x42, 0x01, 0xD0, 0x01, 0x06, 0x01, 0xD4, 0x40, 0x07, 0x01, 0xD1, 0x6E, 0xF7, 0x15, 0xFA, 0x94, 0xF8, 0x9B, 0x00, 0x00, 0x28, 0x06, 0xD1, 0x84,
0xF8, 0x9B, 0x60, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x64, 0x4C, 0xFC, 0xFF, 0x6B, 0x41, 0x21, 0x00, 0xF7, 0x1A, 0xBD, 0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x01, 0x0E, 0xC2, 0x2C, 0x0D, 0x00, 0xAF, 0xF2, 0x49, 0x10, 0x41, 0x49, 0x88, 0x61, 0x70,
0x47, 0x03, 0x01, 0x1A, 0xCC, 0x2C, 0x0D, 0x00, 0x40, 0x49, 0x0A,
0x68, 0x82, 0x42, 0x05, 0xD1, 0xFF, 0x20, 0x08, 0x60, 0x00, 0x20, 0x48, 0x73, 0xFF, 0xF7, 0xE8, 0xBB, 0x70, 0x47, 0x03, 0x01, 0x8E, 0x02, 0xE2, 0x2C, 0x0D, 0x00, 0x70, 0xB5, 0x31, 0x4D, 0x28, 0x68, 0x80, 0x7B, 0x6C, 0xF7, 0x7D, 0xFE, 0x29,
0x68, 0xC9, 0x6E, 0x6C, 0xF7, 0x0A,
0xFE, 0x29, 0x68, 0x36, 0x4E, 0x2D, 0x4B, 0x91, 0xF8, 0xED, 0x20, 0xC2, 0xB1, 0x91, 0xF8, 0xE5, 0x20, 0x9A, 0xB9, 0x2F, 0x4C, 0xD1, 0xF8, 0xC8, 0x20, 0x24, 0x68, 0x22, 0x42, 0x06, 0xD0, 0x91, 0xF8, 0x94, 0x40, 0x24, 0x06, 0x09, 0xD4, 0x34,
0x78, 0xA0, 0x42, 0x06, 0xD8, 0x2D, 0x48, 0x2D, 0x4C, 0x00, 0x68, 0x24, 0x68, 0x20, 0x43, 0x02, 0x42, 0x01, 0xD0, 0x9C, 0x78, 0x00, 0xE0, 0x5C, 0x78, 0x91, 0xF8, 0xE5, 0x00, 0x18, 0xB1, 0x18, 0x5C, 0xA0, 0x42, 0x00, 0xD9, 0x04, 0x46, 0x26,
0x48, 0x00, 0x68, 0x00, 0x07, 0x00, 0xD5, 0xDC, 0x78, 0xD1, 0xF8, 0xC0, 0x00, 0x40, 0x1C, 0x16, 0xD0, 0x88, 0x7B, 0x6C, 0xF7, 0x46, 0xFE, 0x29, 0x68, 0xD1, 0xF8, 0xC0, 0x10, 0x6C, 0xF7, 0xDA, 0xFD, 0x1F, 0x49, 0x00, 0x28, 0x07, 0xDB, 0x2A,
0x68, 0x4F, 0xF0, 0xFF, 0x30, 0xC2, 0xF8, 0xC0, 0x00, 0x3F, 0x20, 0x08, 0x70, 0x03, 0xE0, 0x08, 0x78, 0x84, 0x42, 0x00, 0xD2, 0x04, 0x46, 0x70, 0x78, 0x40, 0xB1, 0x45, 0x2C, 0x06, 0xD1, 0x28, 0x68, 0x90, 0xF8, 0xA8, 0x00, 0x54, 0xF7, 0x7F,
0xFD, 0x00, 0xB1, 0x0F, 0x24, 0x21, 0x46, 0x28, 0x68, 0x69, 0xF7, 0x4C, 0xFC, 0xFF, 0x66, 0x42, 0x21, 0x00, 0xFD, 0xFF, 0x11, 0x48, 0x00, 0x78, 0x85, 0xF8, 0x34, 0x00, 0x70, 0xBD, 0xA0, 0x6C, 0x20, 0x00, 0xD8, 0x23, 0x20, 0x00, 0xBF, 0x23,
0x20, 0x00, 0xBE, 0x23, 0x20, 0x00, 0x2C, 0x8B, 0x31, 0x00, 0x18, 0x3F, 0x20, 0x00, 0x84, 0x31, 0x20, 0x00, 0xA8, 0x25, 0x20, 0x00, 0xE8, 0x23, 0x20, 0x00, 0x6C, 0x73, 0x0D, 0x00, 0xF8, 0x6F, 0x0D, 0x00, 0x2C, 0x30, 0x20, 0x00, 0xD4, 0x23,
0x20, 0x00, 0xE4, 0x1D, 0x20, 0x00, 0xC0, 0x23, 0x20, 0x00, 0xC8, 0x23, 0x20, 0x00, 0x03, 0x01, 0x44, 0xEC, 0x2D, 0x0D, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x69, 0xF7, 0x8C, 0xFB, 0xA8, 0xB1, 0x14, 0x48, 0x4F, 0xF4, 0x46, 0x11, 0x00, 0x8B, 0x88,
0x66, 0x12, 0x48, 0x00, 0x68, 0x00, 0x07, 0x0C, 0xD5, 0x11, 0x49, 0xA0, 0x69, 0x0A,
0x68, 0xC0, 0x0A,
0x82, 0x42, 0x05, 0xD1, 0x94, 0xF8, 0x5F, 0x00, 0x40, 0x1C, 0x84, 0xF8, 0x5F, 0x00, 0x00, 0xE0, 0x08, 0x60, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x92, 0xF7, 0x99, 0xBF, 0x03, 0x01, 0x38, 0x2C, 0x2E, 0x0D, 0x00, 0x10, 0xB5, 0x0A,
0x48, 0x08, 0x4C, 0x2C, 0x22, 0x04, 0x60, 0x09, 0x49, 0x20, 0x46, 0x8A, 0xF7, 0x28, 0xFC, 0xAF, 0xF2, 0x53, 0x00, 0x60, 0x60, 0x10, 0xBD, 0x00, 0x00, 0x18, 0x3F, 0x20, 0x00, 0xE4, 0x1D, 0x20, 0x00, 0x3C, 0x68, 0x0D, 0x00, 0xAC, 0x73, 0x0D,
0x00, 0x5C, 0x30, 0x20, 0x00, 0x34, 0xAB, 0x08, 0x00, 0x03, 0x01, 0xB4, 0x04, 0x60, 0x2E, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0x81, 0x7B, 0x4F, 0xF4, 0x46, 0x18, 0x08, 0xF5, 0x00, 0x70, 0x01, 0x60, 0x41, 0x68, 0x21, 0xF0, 0x80,
0x01, 0x41, 0x60, 0x95, 0x48, 0x90, 0xF8, 0x30, 0x00, 0x10, 0xB1, 0x6E, 0xF7, 0xA1, 0x4C, 0xFC, 0xFF, 0x61, 0x43, 0x21, 0x00, 0xF9, 0x78, 0xB1, 0x20, 0x46, 0x68, 0xF7, 0x9A, 0xFF, 0x00, 0x21, 0x20, 0x46, 0x69, 0xF7, 0x4B, 0xFB, 0x94, 0xF8,
0x61, 0x10, 0x80, 0xB2, 0x8A, 0x1C, 0x82, 0x42, 0x0D, 0xD8, 0x40, 0x1A, 0x87, 0xB2, 0x11, 0xE0, 0xA0, 0x7B, 0x90, 0xF7, 0x53, 0xFF, 0xA0, 0x7B, 0x90, 0xF7, 0xF9, 0xFF, 0x40, 0xF2, 0x71, 0x21, 0xB0, 0xFB, 0xF1, 0xF0, 0xEB, 0xE7, 0x94, 0xF8,
0x62, 0x20, 0x8A, 0x42, 0x71, 0xD8, 0x82, 0x42, 0x6F, 0xD8, 0x02, 0x27, 0x00, 0x26, 0x84, 0xF8, 0x60, 0x60, 0xA0, 0x7B, 0x6C, 0xF7, 0x8D, 0xFD, 0x80, 0x1C, 0x20, 0xF0, 0x01, 0x00, 0x81, 0xB2, 0x94, 0xF8, 0x5B, 0x00, 0x90, 0xB1, 0xB4, 0xF8,
0x50, 0x00, 0x47, 0xF6, 0xFF, 0x72, 0x08, 0x1A, 0x21, 0x8D, 0x08, 0x1A, 0x20, 0xF0, 0x01, 0x00, 0x80, 0xB2, 0x81, 0x1E, 0x91, 0x42, 0x00, 0xD3, 0x02, 0x20, 0xB8, 0x42, 0x00, 0xD3, 0x38, 0x46, 0x60, 0x85, 0x7D, 0xE0, 0xA0, 0x8D, 0x40, 0xB1,
0x70, 0x4B, 0x22, 0x68, 0x1B, 0x68, 0x9A, 0x42, 0x09, 0xD1, 0x6F, 0x4A, 0x12, 0x68, 0x12, 0x07, 0x05, 0xD5, 0x20, 0x8D, 0xB8, 0x42, 0x00, 0xD2, 0x07, 0x46, 0x67, 0x85, 0x6C, 0xE0, 0x22, 0x8D, 0xBA, 0x42, 0x00, 0xD2, 0x17, 0x46, 0x67, 0x85,
0xB4, 0xF8, 0x50, 0x20, 0x03, 0x23, 0x89, 0x1A, 0xCA, 0x17, 0x01, 0xEB, 0x12, 0x72, 0x22, 0xF0, 0x0F, 0x02, 0x89, 0x1A, 0x8D, 0xB2, 0x94, 0xF8, 0x62, 0x10, 0x02, 0x29, 0x09, 0xD0, 0x03, 0xFA, 0x05, 0xF1, 0x94, 0xF8, 0x58, 0x20, 0x89, 0xB2,
0x32, 0xB3, 0x31, 0xEA, 0x00, 0x00, 0x06, 0xD0, 0x30, 0xE0, 0x01, 0x20, 0xA8, 0x40, 0x84, 0xF8, 0x58, 0x60, 0x81, 0xB2, 0x1C, 0xE0, 0x59, 0x4A, 0x94, 0xF8, 0x59, 0x00, 0x12, 0x78, 0x90, 0x42, 0x4C, 0xFC, 0xFF, 0x5C, 0x44, 0x21, 0x00, 0x14,
0xD2, 0x94, 0xF8, 0x5A, 0x00, 0x02, 0x28, 0x00, 0xD3, 0x7D, 0xB1, 0x6E, 0xF7, 0x9C, 0xF8, 0x94, 0xF8, 0x59, 0x00, 0x40, 0x1C, 0x84, 0xF8, 0x59, 0x00, 0x00, 0x2D, 0x03, 0xD1, 0x14, 0xF8, 0x5A, 0x0F, 0x40, 0x1C, 0x20, 0x70, 0xBD, 0xE8, 0xF0,
0x81, 0x18, 0xE0, 0x84, 0xF8, 0x58, 0x60, 0x00, 0x20, 0x04, 0xEB, 0x40, 0x02, 0x92, 0x8D, 0x31, 0xEA, 0x02, 0x02, 0x02, 0xD1, 0x40, 0x1C, 0x10, 0x28, 0xF6, 0xD3, 0x10, 0x28, 0x0A,
0xD0, 0x84, 0xF8, 0x60, 0x00, 0x94, 0xF8, 0x60, 0x00, 0x02, 0x26, 0x04, 0xEB, 0x40, 0x00, 0x4F, 0xF6, 0xFF, 0x72, 0x80, 0x8D, 0x12, 0xE0, 0xBD, 0xE8, 0xF0, 0x41, 0x6E, 0xF7, 0x71, 0xB8, 0x03, 0xFA, 0x05, 0xF1, 0x01, 0x43, 0xAD, 0x1C, 0x88,
0xB2, 0x05, 0xF0, 0x0F, 0x05, 0x03, 0xFA, 0x05, 0xF1, 0x89, 0xB2, 0x90, 0x42, 0x10, 0xD0, 0x81, 0x43, 0x0E, 0xD0, 0xB6, 0x1C, 0xB7, 0x42, 0xEE, 0xD8, 0x61, 0x8D, 0x40, 0xF2, 0x71, 0x22, 0x01, 0xFB, 0x02, 0xF0, 0x94, 0xF8, 0x5C, 0x20, 0x42,
0xB1, 0x49, 0x1C, 0x61, 0x85, 0x30, 0x49, 0x05, 0xE0, 0xB7, 0x42, 0x00, 0xD2, 0x3E, 0x46, 0x66, 0x85, 0xEE, 0xE7, 0x2E, 0x49, 0x09, 0x88, 0x08, 0x44, 0x2D, 0x49, 0x08, 0x60, 0x04, 0xF1, 0x56, 0x04, 0xD8, 0xF8, 0x88, 0x00, 0x61, 0x7A, 0xA2,
0x7A, 0x01, 0xEB, 0x10, 0x31, 0x01, 0xF0, 0x10, 0x00, 0x11, 0x44, 0x01, 0xF0, 0x0F, 0x01, 0x40, 0xEA, 0x01, 0x00, 0x14, 0xF8, 0x56, 0x19, 0x09, 0xB1, 0x80, 0xF0, 0x10, 0x00, 0x23, 0x49, 0x0A,
0x68, 0x22, 0xF0, 0x1F, 0x02, 0x02, 0x43, 0x0A,
0x60, 0x21, 0x48, 0x90, 0xF9, 0x06, 0x00, 0x83, 0xF7, 0x0B, 0xFC, 0x00, 0x21, 0xA3, 0xF7, 0xF2, 0xF8, 0x94, 0xF8, 0x57, 0x4C, 0xFC, 0xFF, 0x57, 0x45, 0x21, 0x00, 0x00, 0x00, 0x21, 0x6D, 0xF7, 0x55, 0xFE, 0x6E, 0xF7, 0x20, 0xFA, 0x00, 0x28,
0x8D, 0xD1, 0x32, 0x20, 0xA0, 0x74, 0x8A, 0xE7, 0x03, 0x01, 0x68, 0x90, 0x30, 0x0D, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x10, 0x48, 0x00, 0x68, 0x00, 0x07, 0x16, 0xD5, 0x0D, 0x49, 0x20, 0x68, 0x09, 0x68, 0x88, 0x42, 0x11, 0xD1, 0x02, 0x21, 0x20,
0x46, 0x69, 0xF7, 0x1F, 0xFB, 0x94, 0xF8, 0x56, 0x10, 0x00, 0x29, 0x21, 0x8D, 0x05, 0xD0, 0x01, 0xEB, 0x51, 0x01, 0x81, 0x42, 0x04, 0xDC, 0x01, 0x20, 0x10, 0xBD, 0xB0, 0xEB, 0x51, 0x0F, 0xFA, 0xDA, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xB0,
0x59, 0x20, 0x00, 0x5C, 0x30, 0x20, 0x00, 0xE4, 0x1D, 0x20, 0x00, 0x61, 0x30, 0x20, 0x00, 0x66, 0x30, 0x20, 0x00, 0x64, 0x30, 0x20, 0x00, 0x0C, 0x8B, 0x31, 0x00, 0xAC, 0x86, 0x31, 0x00, 0xF7, 0x1D, 0x20, 0x00, 0x03, 0x01, 0xB4, 0x03, 0xF4,
0x30, 0x0D, 0x00, 0x70, 0xB5, 0x86, 0xB0, 0x04, 0x46, 0x6C, 0xF7, 0x5E, 0xFC, 0x85, 0xB2, 0x21, 0x8C, 0x28, 0x46, 0x6C, 0xF7, 0xB8, 0xFC, 0x5E, 0x49, 0x09, 0x88, 0x88, 0x42, 0x6E, 0xD3, 0x69, 0xF7, 0x01, 0xFC, 0x00, 0x26, 0x30, 0xB1, 0x94,
0xF8, 0x33, 0x00, 0xFD, 0x28, 0x06, 0xD0, 0xFE, 0x28, 0x38, 0xD0, 0x64, 0xE0, 0xB4, 0xF9, 0x1C, 0x50, 0xA6, 0x83, 0x71, 0xE0, 0x61, 0x8C, 0x28, 0x46, 0x6C, 0xF7, 0xA1, 0xFC, 0x54, 0x49, 0x09, 0x78, 0x88, 0x42, 0x02, 0xD3, 0x84, 0xF8, 0x32,
0x60, 0x65, 0x84, 0x51, 0x49, 0x94, 0xF9, 0x32, 0x00, 0x09, 0x78, 0x88, 0x42, 0x4E, 0xDA, 0x4F, 0x4A, 0x92, 0xF9, 0x00, 0x30, 0x98, 0x42, 0x49, 0xDD, 0x4E, 0x4A, 0x09, 0x1A, 0x12, 0x78, 0x91, 0x42, 0x00, 0xDD, 0x11, 0x46, 0x4C, 0x4C, 0xFC,
0xFF, 0x52, 0x46, 0x21, 0x00, 0x4A, 0x4D, 0xB2, 0x19, 0x1A, 0x92, 0xF9, 0x00, 0x20, 0x91, 0x42, 0x00, 0xDA, 0x11, 0x46, 0x4A, 0xB2, 0xB4, 0xF9, 0x1C, 0x10, 0xA9, 0x42, 0x04, 0xDC, 0x91, 0x42, 0x01, 0xDA, 0x15, 0x46, 0x00, 0xE0, 0x0D, 0x46,
0x49, 0x1B, 0xA1, 0x83, 0x28, 0x44, 0x84, 0xF8, 0x32, 0x00, 0x3B, 0xE0, 0xB4, 0xF9, 0x1C, 0x00, 0x64, 0x28, 0x02, 0xDA, 0x10, 0xF1, 0x64, 0x0F, 0x25, 0xDC, 0x76, 0xF7, 0xC2, 0xFF, 0x10, 0xB3, 0x76, 0xF7, 0xA0, 0xFF, 0xF8, 0xB1, 0xB4, 0xF9,
0x1C, 0x00, 0x00, 0x28, 0x01, 0xDC, 0x00, 0xF2, 0xE2, 0x40, 0x02, 0xA9, 0x6C, 0xF7, 0xC3, 0xFB, 0x02, 0xA8, 0x6C, 0xF7, 0xB8, 0xFB, 0x27, 0x21, 0xAD, 0xF8, 0x10, 0x10, 0x40, 0xF2, 0x71, 0x22, 0xB0, 0xFB, 0xF2, 0xF1, 0x02, 0xFB, 0x11, 0x00,
0xAD, 0xF8, 0x14, 0x00, 0x8D, 0xF8, 0x13, 0x10, 0x04, 0xA8, 0x8B, 0xF7, 0xA9, 0xF9, 0xA6, 0x83, 0x00, 0x25, 0x0C, 0xE0, 0x47, 0xE0, 0x2A, 0x48, 0xB4, 0xF9, 0x1C, 0x50, 0x00, 0x78, 0x85, 0x42, 0x04, 0xDC, 0x28, 0x48, 0x90, 0xF9, 0x00, 0x00,
0x85, 0x42, 0x00, 0xDA, 0x05, 0x46, 0xA0, 0x8B, 0x40, 0x1B, 0xA0, 0x83, 0xA0, 0x8B, 0x10, 0xB9, 0x01, 0x20, 0x84, 0xF8, 0x34, 0x00, 0xE6, 0x83, 0x6C, 0xF7, 0xCE, 0xFB, 0x20, 0x84, 0x00, 0x2D, 0x2D, 0xD0, 0x69, 0xF7, 0x77, 0xFB, 0x20, 0xB1,
0x00, 0x2D, 0x16, 0xDD, 0xCD, 0xE9, 0x00, 0x65, 0x1B, 0xE0, 0x00, 0x2D, 0x04, 0xDD, 0x69, 0x46, 0x28, 0x46, 0x6C, 0xF7, 0x84, 0xFB, 0x14, 0xE0, 0x02, 0xA9, 0x68, 0x42, 0x6C, 0xF7, 0x7F, 0xFB, 0x00, 0x22, 0x00, 0x96, 0x02, 0xAB, 0x69, 0x46,
0x10, 0x46, 0x01, 0x96, 0x6C, 0xF7, 0x78, 0xFA, 0x07, 0xE0, 0x6F, 0xF0, 0x70, 0x40, 0x00, 0x90, 0x4C, 0xFC, 0xFF, 0x4D, 0x47, 0x21, 0x00, 0x00, 0x20, 0x6C, 0xF7, 0x63, 0xF9, 0x28, 0x44, 0x01, 0x90, 0x69, 0x46, 0x00, 0x20, 0x6C, 0xF7, 0x4D,
0xFA, 0x68, 0x46, 0x68, 0xF7, 0x5E, 0xFD, 0x00, 0x20, 0x6C, 0xF7, 0x28, 0xFA, 0x06, 0xB0, 0x70, 0xBD, 0xDA, 0x22, 0x20, 0x00, 0xD6, 0x22, 0x20, 0x00, 0xD4, 0x22, 0x20, 0x00, 0xD5, 0x22, 0x20, 0x00, 0xD2, 0x22, 0x20, 0x00, 0xD3, 0x22, 0x20,
0x00, 0xD0, 0x22, 0x20, 0x00, 0xD1, 0x22, 0x20, 0x00, 0x03, 0x01, 0x56, 0xA4, 0x32, 0x0D, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x20, 0x04, 0xF8, 0x6A, 0x0F, 0x60, 0x70, 0xA0, 0x70, 0xE0, 0x70, 0x20, 0x71, 0x14, 0xF8, 0x3D, 0x1C, 0x81, 0xF0,
0x02, 0x01, 0x21, 0xF0, 0x01, 0x01, 0x04, 0xF8, 0x3D, 0x1C, 0xE0, 0x71, 0x20, 0x72, 0xA0, 0x73, 0xA4, 0xF1, 0x6A, 0x04, 0xE0, 0x6C, 0x8F, 0xF7, 0x5B, 0xFF, 0xA0, 0x6C, 0x8F, 0xF7, 0x77, 0xFF, 0x94, 0xF8, 0x6F, 0x00, 0x00, 0x28, 0x07, 0xD0,
0x20, 0x46, 0x98, 0xF7, 0xC9, 0xFB, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x98, 0xF7, 0x04, 0xBC, 0x10, 0xBD, 0x03, 0x01, 0xC8, 0x02, 0xF6, 0x32, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0x01, 0x21, 0x69, 0xF7, 0xF5, 0xF9, 0x05, 0x46,
0x94, 0xF8, 0x71, 0x00, 0x00, 0x26, 0x60, 0xB1, 0x94, 0xF8, 0x68, 0x00, 0xA8, 0x42, 0x7D, 0xDC, 0x94, 0xF8, 0x69, 0x00, 0xA8, 0x42, 0x02, 0xDD, 0x20, 0x46, 0x68, 0xF7, 0x9A, 0xFD, 0x84, 0xF8, 0x71, 0x60, 0xFE, 0x4F, 0x00, 0x2D, 0x6D, 0xDB,
0x20, 0x46, 0x69, 0xF7, 0xC9, 0xFA, 0x58, 0xB9, 0xFB, 0x49, 0xA0, 0x7B, 0x09, 0x68, 0xC1, 0xF3, 0x02, 0x11, 0x88, 0x42, 0x04, 0xD0, 0x94, 0xF8, 0x69, 0x00, 0xC0, 0x1E, 0xA8, 0x42, 0x13, 0xDD, 0x94, 0xF8, 0x4C, 0xFC, 0xFF, 0x48, 0x48, 0x21,
0x00, 0x69, 0x00, 0xA8, 0x42, 0x0F, 0xDD, 0x20, 0x46, 0x69, 0xF7, 0xB5, 0xFA, 0x20, 0xB9, 0xE0, 0x7B, 0x10, 0xB9, 0x94, 0xF8, 0x72, 0x00, 0x30, 0xB1, 0x94, 0xF8, 0x68, 0x00, 0xA8, 0x42, 0x0B, 0xDA, 0xA0, 0x89, 0x20, 0xB1, 0x08, 0xE0, 0x20,
0x46, 0x69, 0xF7, 0xF3, 0xFB, 0x45, 0xE0, 0x29, 0x46, 0x20, 0x46, 0x87, 0xF7, 0x30, 0xFD, 0x80, 0xB1, 0x94, 0xF8, 0x68, 0x00, 0x01, 0x26, 0xA8, 0x42, 0x1E, 0xD1, 0x65, 0xF7, 0xC8, 0xF8, 0x10, 0xB1, 0x94, 0xF8, 0x77, 0x00, 0x58, 0xB1, 0x19,
0x21, 0xA1, 0x74, 0x20, 0x46, 0x84, 0xF8, 0x74, 0x60, 0x2D, 0xE0, 0x20, 0x46, 0x84, 0xF8, 0x74, 0x60, 0x87, 0xF7, 0xAA, 0xF9, 0xDF, 0xE7, 0x0B, 0x21, 0xA1, 0x74, 0xE0, 0x7B, 0x01, 0x28, 0xF0, 0xD1, 0xDA, 0x48, 0x01, 0x78, 0x89, 0x1E, 0x06,
0xFA, 0x01, 0xF0, 0x84, 0xF8, 0x77, 0x00, 0xE8, 0xE7, 0x94, 0xF8, 0x30, 0x20, 0x94, 0xF8, 0x2A, 0x10, 0xD5, 0x4B, 0x11, 0x44, 0x0A,
0x18, 0xAA, 0x42, 0x23, 0xD1, 0x84, 0xF8, 0x74, 0x60, 0xE0, 0x8B, 0x06, 0x28, 0x06, 0xD1, 0x94, 0xF8, 0x68, 0x00, 0x01, 0x28, 0x02, 0xD1, 0xCF, 0x49, 0x02, 0x20, 0x08, 0x70, 0x93, 0xF8, 0x30, 0x00, 0x20, 0xB1, 0x38, 0x68, 0x10, 0xB1, 0x20,
0x46, 0x87, 0xF7, 0x7F, 0xF9, 0x69, 0xF7, 0x7A, 0xF8, 0x01, 0x28, 0x00, 0xE0, 0x11, 0xE0, 0x10, 0xD1, 0x20, 0x46, 0x87, 0xF7, 0x44, 0xFC, 0xC6, 0x49, 0x38, 0x60, 0x08, 0x60, 0xBD, 0xE8, 0xF0, 0x41, 0x5D, 0xF7, 0xA9, 0xBC, 0x00, 0xEB, 0x41,
0x00, 0xA8, 0x42, 0xEB, 0xD1, 0x84, 0xF8, 0x74, 0x60, 0xE0, 0xE7, 0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x01, 0xE4, 0x01, 0x3A, 0x34, 0x0D, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x69, 0xF7, 0x65, 0x4C, 0xFC, 0xFF, 0x43, 0x49, 0x21, 0x00, 0xF8, 0x00, 0x26,
0x01, 0x25, 0x58, 0xB1, 0xB9, 0x48, 0x00, 0x21, 0x06, 0x70, 0x20, 0x46, 0x87, 0xF7, 0xAE, 0xFD, 0x20, 0x46, 0xFF, 0xF7, 0x25, 0xFF, 0x84, 0xF8, 0x5B, 0x50, 0x70, 0xBD, 0x20, 0x46, 0x69, 0xF7, 0x3E, 0xFA, 0x00, 0x28, 0xF9, 0xD0, 0x20, 0x46,
0xE1, 0x8B, 0x87, 0xF7, 0x9F, 0xFD, 0xA0, 0x7B, 0x6C, 0xF7, 0xB8, 0xFA, 0xA1, 0x69, 0x6C, 0xF7, 0x46, 0xFA, 0xE1, 0x8B, 0x89, 0x1E, 0x88, 0x42, 0x0C, 0xD8, 0x20, 0x46, 0x87, 0xF7, 0x0B, 0xFC, 0xA4, 0x49, 0x08, 0x60, 0xA8, 0x49, 0x08, 0x60,
0xA8, 0x48, 0x05, 0x60, 0x6C, 0xF7, 0x8F, 0xFA, 0xA7, 0x49, 0x08, 0x60, 0x94, 0xF8, 0x5B, 0x00, 0x98, 0xB1, 0x5E, 0xF7, 0x7F, 0xFF, 0x45, 0xF7, 0x0E, 0xFE, 0x01, 0x28, 0x0B, 0xD1, 0x20, 0x46, 0x5E, 0xF7, 0xBD, 0xFB, 0x38, 0xB1, 0x94, 0xF8,
0x6F, 0x00, 0x20, 0xB1, 0x84, 0xF8, 0x6E, 0x50, 0x20, 0x46, 0x98, 0xF7, 0xE5, 0xFA, 0x84, 0xF8, 0x5B, 0x60, 0x94, 0xF8, 0x6B, 0x00, 0xE8, 0xB9, 0x94, 0xF8, 0x28, 0x00, 0x01, 0x28, 0x0D, 0xD0, 0x94, 0xF8, 0x24, 0x00, 0x94, 0xF8, 0x2C, 0x10,
0xC0, 0xF3, 0x02, 0x00, 0xC1, 0xF3, 0x02, 0x01, 0x88, 0x42, 0x03, 0xD1, 0x94, 0xF8, 0x29, 0x00, 0x02, 0x28, 0x0B, 0xD0, 0x20, 0x46, 0x5E, 0xF7, 0x9A, 0xFB, 0x38, 0xB1, 0x94, 0xF8, 0x6F, 0x00, 0x20, 0xB1, 0x84, 0xF8, 0x6E, 0x50, 0x20, 0x46,
0x98, 0xF7, 0xC2, 0xFA, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x87, 0xF7, 0x0E, 0xBD, 0x03, 0x01, 0xA2, 0x01, 0x1A, 0x35, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0x81, 0xB1, 0x02, 0x29, 0x12, 0xD0, 0x05, 0x29, 0x85, 0xD1, 0x94, 0xF8,
0x72, 0x00, 0x10, 0xB1, 0x00, 0x20, 0x84, 0xF8, 0x4C, 0xFC, 0xFF, 0x3E, 0x4A, 0x21, 0x00, 0x72, 0x00, 0x82, 0x48, 0x01, 0x68, 0x21, 0xF0, 0x03, 0x01, 0x49, 0x1C, 0x01, 0x60, 0x78, 0xE7, 0xBD, 0xE8, 0xF0, 0x41, 0x87, 0xF7, 0xAB, 0xBA, 0x7D,
0x49, 0x94, 0xF8, 0x56, 0x00, 0x08, 0x60, 0x7A, 0x49, 0x20, 0x6D, 0xDC, 0x31, 0x08, 0x60, 0x94, 0xF8, 0x39, 0x00, 0x83, 0xF7, 0xE6, 0xFE, 0x60, 0x6C, 0x76, 0x4A, 0x75, 0x4C, 0x90, 0xF8, 0xA9, 0x10, 0x75, 0x48, 0x73, 0x4E, 0x7C, 0x32, 0xA9,
0x38, 0x98, 0x34, 0xA8, 0x36, 0x13, 0x1D, 0x25, 0x1D, 0x37, 0x1D, 0x02, 0x29, 0x10, 0x60, 0x0E, 0xD0, 0x70, 0x48, 0x18, 0x60, 0x6D, 0x49, 0x6F, 0x48, 0x90, 0x31, 0x08, 0x60, 0x6F, 0x48, 0x20, 0x60, 0x6F, 0x48, 0x28, 0x60, 0x6F, 0x48, 0x30,
0x60, 0x6F, 0x48, 0x38, 0x60, 0x48, 0xE7, 0x6E, 0x48, 0x18, 0x60, 0x6E, 0x48, 0x20, 0x60, 0x6E, 0x48, 0x28, 0x60, 0x6E, 0x48, 0x30, 0x60, 0x6E, 0x48, 0xF3, 0xE7, 0x03, 0x01, 0xFA, 0x03, 0xB8, 0x35, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x90,
0xF8, 0x72, 0x10, 0x45, 0x6C, 0x04, 0x46, 0x00, 0x29, 0x7E, 0xD1, 0x04, 0xF1, 0x28, 0x04, 0x69, 0x4A, 0x21, 0x7C, 0x11, 0x60, 0x69, 0x4A, 0x61, 0x7C, 0x11, 0x60, 0x14, 0xF8, 0x28, 0x19, 0x04, 0xF1, 0x24, 0x06, 0x11, 0xB9, 0x31, 0x46, 0x83,
0xF7, 0xAC, 0xFB, 0x95, 0xF8, 0xA8, 0x00, 0x31, 0x46, 0x9C, 0xF7, 0xC0, 0xFD, 0x02, 0x21, 0x20, 0x46, 0x69, 0xF7, 0x79, 0xF8, 0x06, 0x46, 0x00, 0x20, 0x84, 0xF8, 0x5B, 0x00, 0x94, 0xF8, 0x28, 0x00, 0x01, 0x27, 0x02, 0x28, 0x03, 0xD0, 0xE0,
0x7B, 0x00, 0x28, 0x6C, 0xD0, 0x71, 0xE0, 0x94, 0xF8, 0x24, 0x00, 0x94, 0xF8, 0x2C, 0x10, 0xC0, 0xF3, 0x02, 0x00, 0xC1, 0xF3, 0x02, 0x01, 0x88, 0x42, 0x22, 0x4C, 0xFC, 0xFF, 0x39, 0x4B, 0x21, 0x00, 0xD1, 0xA8, 0x7B, 0x6C, 0xF7, 0xDD, 0xF9,
0xE8, 0x66, 0x31, 0x46, 0x20, 0x46, 0x88, 0xF7, 0x54, 0xF8, 0x94, 0xF8, 0x28, 0x00, 0x02, 0x28, 0x5B, 0xD1, 0x94, 0xF8, 0x58, 0x00, 0xF0, 0xBB, 0x95, 0xF8, 0xA8, 0x00, 0x83, 0xF7, 0x04, 0xFF, 0x05, 0x46, 0x68, 0xF7, 0xD3, 0xFB, 0x20, 0xB1,
0x28, 0x46, 0x68, 0xF7, 0x61, 0xFF, 0x18, 0xB1, 0x4B, 0xE0, 0x84, 0xF8, 0x58, 0x70, 0x48, 0xE0, 0x28, 0x46, 0x69, 0xF7, 0x21, 0xFB, 0xF8, 0xE7, 0x95, 0xF8, 0x9C, 0x10, 0xC1, 0xF3, 0x02, 0x01, 0x88, 0x42, 0x35, 0xD1, 0xA8, 0x7B, 0x6C, 0xF7,
0xB4, 0xF9, 0xE8, 0x66, 0x29, 0x46, 0x20, 0x46, 0x69, 0xF7, 0xA4, 0xFB, 0x48, 0xB1, 0x60, 0x6A, 0xC5, 0xF8, 0x94, 0x00, 0xA0, 0x6A, 0xC5, 0xF8, 0x98, 0x00, 0x28, 0x68, 0x01, 0x6A, 0x28, 0x46, 0x20, 0xE0, 0x95, 0xF8, 0xA8, 0x00, 0x83, 0xF7,
0xD7, 0xFE, 0x80, 0x46, 0x68, 0xF7, 0xA6, 0xFB, 0xD0, 0xB1, 0x40, 0x46, 0x68, 0xF7, 0x5B, 0xFC, 0x10, 0x28, 0x15, 0xD1, 0x41, 0x46, 0x20, 0x46, 0x69, 0xF7, 0x88, 0xFB, 0x01, 0xE0, 0x18, 0xE0, 0x71, 0xE0, 0x68, 0xB1, 0x60, 0x6A, 0xC5, 0xF8,
0x94, 0x00, 0xA0, 0x6A, 0xC5, 0xF8, 0x98, 0x00, 0x88, 0xF8, 0x21, 0x70, 0xD8, 0xF8, 0x00, 0x00, 0x01, 0x6A, 0x40, 0x46, 0x88, 0x47, 0x08, 0xE0, 0x6D, 0xF7, 0x98, 0xFE, 0x05, 0xE0, 0x94, 0xF8, 0x77, 0x00, 0x40, 0xF0, 0x01, 0x00, 0x84, 0xF8,
0x77, 0x00, 0x94, 0xF8, 0x77, 0x00, 0x30, 0xB1, 0xE0, 0x7B, 0x20, 0xB9, 0xA0, 0x7C, 0x0B, 0x28, 0x01, 0xD1, 0x19, 0x20, 0xA0, 0x74, 0x94, 0xF8, 0x68, 0x00, 0xB0, 0x42, 0x3B, 0xDD, 0x94, 0xF8, 0x77, 0x00, 0x80, 0xBB, 0xE0, 0x7B, 0x01, 0x28,
0x2E, 0xE0, 0xB0, 0x26, 0x4C, 0xFC, 0xFF, 0x34, 0x4C, 0x21, 0x00, 0x20, 0x00, 0x24, 0x86, 0x31, 0x00, 0xA6, 0x26, 0x20, 0x00, 0xB0, 0x59, 0x20, 0x00, 0xA4, 0x26, 0x20, 0x00, 0x4C, 0x1C, 0x20, 0x00, 0x48, 0x1C, 0x20, 0x00, 0x50, 0x1C, 0x20,
0x00, 0x08, 0x8A, 0x31, 0x00, 0x0C, 0x8D, 0x31, 0x00, 0x89, 0xA4, 0xF4, 0x01, 0xEC, 0x33, 0x66, 0x01, 0xAA, 0x28, 0x25, 0x1F, 0xCD, 0xB4, 0xF6, 0x01, 0xEB, 0xAC, 0xF5, 0x01, 0x0E, 0x39, 0xF7, 0x01, 0x89, 0x10, 0xF2, 0x01, 0xAA, 0x94, 0xF2,
0x01, 0xCD, 0x18, 0xF3, 0x01, 0xEB, 0x8C, 0xF3, 0x01, 0x0E, 0x21, 0xF4, 0x01, 0x10, 0x23, 0x20, 0x00, 0x14, 0x23, 0x20, 0x00, 0x06, 0xE0, 0x05, 0xD1, 0x16, 0x48, 0x00, 0x78, 0x80, 0x1E, 0x87, 0x40, 0x84, 0xF8, 0x77, 0x70, 0x94, 0xF8, 0x2A,
0x00, 0x01, 0x28, 0x0B, 0xD9, 0x94, 0xF8, 0x68, 0x00, 0xB0, 0x42, 0x07, 0xDD, 0x6D, 0xF7, 0x97, 0xFE, 0x00, 0x28, 0x03, 0xD1, 0x94, 0xF8, 0x2A, 0x00, 0x40, 0x1E, 0xA0, 0x81, 0x43, 0xE6, 0x03, 0x01, 0x42, 0xAE, 0x37, 0x0D, 0x00, 0x10, 0xB5,
0x0C, 0x48, 0x0B, 0x4C, 0x2C, 0x22, 0x04, 0x60, 0x0B, 0x49, 0x20, 0x46, 0x89, 0xF7, 0x67, 0xFF, 0xAF, 0xF2, 0xCD, 0x40, 0x60, 0x62, 0xAF, 0xF2, 0x8D, 0x30, 0x60, 0x60, 0xAF, 0xF2, 0xB5, 0x20, 0x20, 0x61, 0xAF, 0xF2, 0x1B, 0x20, 0x20, 0x62,
0x10, 0xBD, 0x00, 0x00, 0xA6, 0x26, 0x20, 0x00, 0xD8, 0x73, 0x0D, 0x00, 0xAC, 0x26, 0x20, 0x00, 0x84, 0xA5, 0x08, 0x00, 0x03, 0x01, 0x40, 0xEC, 0x37, 0x0D, 0x00, 0x70, 0xB5, 0x0B, 0x4C, 0x60, 0x68, 0x3D, 0xF7, 0x2E, 0xFD, 0x20, 0x68, 0x3D,
0xF7, 0x2B, 0xFD, 0x08, 0x4D, 0x00, 0x24, 0x28, 0x68, 0x10, 0xB1, 0x71, 0xF7, 0x8A, 0xFB, 0x2C, 0x60, 0x06, 0x4D, 0x28, 0x68, 0x00, 0x4C, 0xFC, 0xFF, 0x2F, 0x4D, 0x21, 0x00, 0x28, 0x02, 0xD0, 0x71, 0xF7, 0x83, 0xFB, 0x2C, 0x60, 0x70, 0xBD,
0x00, 0x00, 0x1C, 0xD6, 0x20, 0x00, 0x8C, 0x31, 0x20, 0x00, 0x90, 0x31, 0x20, 0x00, 0x03, 0x01, 0x1E, 0x28, 0x38, 0x0D, 0x00, 0xC4, 0x48, 0xC5, 0x49, 0xC0, 0x69, 0x00, 0xF0, 0x07, 0x00, 0x08, 0x70, 0xC3, 0x49, 0x00, 0x20, 0x48, 0x60, 0x08,
0x31, 0x08, 0x60, 0x88, 0x80, 0x70, 0x47, 0x03, 0x01, 0x62, 0x42, 0x38, 0x0D, 0x00, 0x70, 0xB5, 0xC0, 0x49, 0x00, 0x24, 0x22, 0x46, 0x0B, 0x68, 0x25, 0x46, 0xB3, 0xFB, 0xF0, 0xF1, 0x00, 0xFB, 0x11, 0x36, 0xB6, 0xEB, 0x50, 0x0F, 0x00, 0xD9,
0x49, 0x1C, 0xB0, 0xEB, 0x13, 0x1F, 0x06, 0xD9, 0x48, 0x42, 0xC2, 0xB2, 0x08, 0x23, 0xF7, 0x2A, 0x12, 0xD9, 0x01, 0x25, 0x10, 0xE0, 0x80, 0x23, 0xB1, 0xF5, 0x80, 0x5F, 0x03, 0xD2, 0x00, 0x20, 0xA0, 0xEB, 0x11, 0x10, 0xC2, 0xB2, 0x01, 0xF0,
0x0F, 0x00, 0x41, 0x08, 0x00, 0xF0, 0x01, 0x04, 0x04, 0xEB, 0x50, 0x00, 0x40, 0xEA, 0x01, 0x14, 0xAD, 0x48, 0xC3, 0x60, 0x85, 0x60, 0x02, 0x60, 0x84, 0x61, 0x70, 0xBD, 0x03, 0x01, 0xBA, 0x01, 0xA0, 0x38, 0x0D, 0x00, 0xF0, 0xB5, 0xA7, 0x48,
0x01, 0x78, 0x02, 0x29, 0x54, 0xD1, 0x04, 0x22, 0x00, 0x24, 0x4F, 0xF4, 0xCA, 0x00, 0x02, 0x64, 0xC0, 0xF8, 0xB0, 0x41, 0x52, 0x1C, 0x08, 0x2A, 0xF9, 0xD3, 0xC2, 0x68, 0x42, 0xF0, 0x02, 0x02, 0xC2, 0x60, 0xC2, 0x68, 0x9E, 0x4D, 0x22, 0xF0,
0x03, 0x02, 0x22, 0xF4, 0x82, 0x22, 0xAB, 0x78, 0x22, 0xF4, 0xC0, 0x62, 0x42, 0xEA, 0x43, 0x22, 0x42, 0xF0, 0x04, 0x02, 0xC2, 0x60, 0xFF, 0x23, 0xC0, 0xF8, 0xC4, 0x31, 0x04, 0x64, 0x4F, 0xF4, 0x88, 0x62, 0xC0, 0xF8, 0x00, 0x22, 0x2A, 0x78,
0x4C, 0xFC, 0xFF, 0x2A, 0x4E, 0x21, 0x00, 0x96, 0x08, 0x06, 0x64, 0xD0, 0xF8, 0x44, 0xC0, 0x96, 0x07, 0xF7, 0x0E, 0x03, 0xFA, 0x07, 0xF6, 0x2C, 0xEA, 0x06, 0x0C, 0x11, 0x26, 0xBE, 0x40, 0x46, 0xEA, 0x0C, 0x06, 0x46, 0x64, 0x04, 0x64, 0x41,
0xEA, 0x02, 0x12, 0x42, 0xF4, 0x80, 0x62, 0xC0, 0xF8, 0x18, 0x22, 0x6A, 0x78, 0x95, 0x08, 0x05, 0x64, 0x46, 0x6C, 0x95, 0x07, 0xED, 0x0E, 0xAB, 0x40, 0x9E, 0x43, 0x02, 0x23, 0xAB, 0x40, 0x33, 0x43, 0x43, 0x64, 0x04, 0x64, 0x41, 0xEA, 0x02,
0x11, 0x41, 0xF4, 0x80, 0x31, 0xC0, 0xF8, 0x1C, 0x12, 0x4F, 0xF0, 0x01, 0x11, 0xC0, 0xF8, 0x20, 0x12, 0x01, 0x21, 0xC0, 0xF8, 0x24, 0x12, 0xF0, 0xBD, 0x03, 0x01, 0x50, 0x56, 0x39, 0x0D, 0x00, 0x70, 0xB5, 0x00, 0x28, 0x21, 0xD0, 0x0E, 0x28,
0x1F, 0xD8, 0x7B, 0x4B, 0x59, 0x5C, 0x7B, 0x4B, 0x4F, 0xEA, 0x51, 0x01, 0x18, 0x44, 0x10, 0xF8, 0x01, 0x3C, 0xA3, 0xEB, 0x01, 0x00, 0x80, 0x1E, 0x00, 0xD5, 0x00, 0x20, 0x5C, 0x18, 0xA4, 0x1E, 0x4E, 0x2C, 0x00, 0xDB, 0x4E, 0x24, 0x01, 0x23,
0x09, 0xE0, 0x02, 0xEB, 0xE0, 0x01, 0x00, 0xF0, 0x07, 0x06, 0x0D, 0x78, 0x03, 0xFA, 0x06, 0xF6, 0xB5, 0x43, 0x0D, 0x70, 0x40, 0x1C, 0xA0, 0x42, 0xF3, 0xDD, 0x70, 0xBD, 0x03, 0x01, 0x6A, 0xA2, 0x39, 0x0D, 0x00, 0xF0, 0xB5, 0x6C, 0x4A, 0x00,
0x20, 0x03, 0x21, 0x52, 0x68, 0x05, 0x46, 0x06, 0x24, 0xC2, 0xF3, 0x03, 0x32, 0x0A,
0xB1, 0x0E, 0x2A, 0x01, 0xD9, 0x00, 0x20, 0xF0, 0xBD, 0x61, 0x4E, 0x05, 0x27, 0x08, 0x36, 0x16, 0xF8, 0x10, 0x30, 0x93, 0x42, 0x03, 0xD1, 0x06, 0xEB, 0x40, 0x00, 0x47, 0x70, 0xF2, 0xE7, 0x3D, 0xB9, 0x06, 0xEB, 0x40, 0x03, 0x5B, 0x78, 0x43,
0xB1, 0xA3, 0x42, 0x01, 0x4C, 0xFC, 0xFF, 0x25, 0x4F, 0x21, 0x00, 0xD2, 0x01, 0x46, 0x1C, 0x46, 0x40, 0x1C, 0x03, 0x28, 0xEB, 0xD3, 0x03, 0xD0, 0x09, 0xE0, 0x01, 0x46, 0x01, 0x25, 0xF7, 0xE7, 0x03, 0x29, 0x04, 0xD2, 0x06, 0xEB, 0x41, 0x00,
0x06, 0xF8, 0x11, 0x20, 0x47, 0x70, 0x01, 0x20, 0xF0, 0xBD, 0x03, 0x01, 0x40, 0x08, 0x3A, 0x0D, 0x00, 0x4E, 0x49, 0x10, 0xB5, 0x48, 0x68, 0x40, 0x1C, 0x48, 0x60, 0xC9, 0x78, 0xB0, 0xFB, 0xF1, 0xF2, 0x01, 0xFB, 0x12, 0x00, 0x00, 0x28, 0x10,
0xD1, 0x48, 0x4B, 0x00, 0x24, 0x08, 0x33, 0x03, 0xEB, 0x40, 0x02, 0x51, 0x78, 0x31, 0xB1, 0x49, 0x1E, 0x11, 0xF0, 0xFF, 0x01, 0x51, 0x70, 0x01, 0xD1, 0x03, 0xF8, 0x10, 0x40, 0x40, 0x1C, 0x03, 0x28, 0xF1, 0xD3, 0x10, 0xBD, 0x03, 0x01, 0x34,
0x44, 0x3A, 0x0D, 0x00, 0x10, 0xB5, 0x01, 0x46, 0x00, 0x20, 0x8A, 0x78, 0xC9, 0x78, 0x02, 0x2A, 0x0F, 0xD1, 0x4F, 0xF4, 0xCA, 0x00, 0x40, 0x6E, 0x3F, 0x4A, 0xC9, 0x07, 0x50, 0x60, 0x07, 0xD0, 0xC0, 0xF3, 0x00, 0x10, 0x10, 0xB1, 0xFF, 0xF7,
0x9C, 0xFF, 0x08, 0xB1, 0x8A, 0xF7, 0x1E, 0xFA, 0x01, 0x20, 0x10, 0xBD, 0x03, 0x01, 0x56, 0x74, 0x3A, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x07, 0x46, 0x00, 0x24, 0xFF, 0x22, 0x0A,
0x21, 0xA2, 0xF7, 0xCD, 0xF9, 0x34, 0x48, 0x40, 0x68, 0xC0, 0xF3, 0x03, 0x33, 0xC0, 0xF3, 0x42, 0x25, 0xC0, 0xF3, 0x00, 0x10, 0x78, 0xB1, 0x01, 0x2D, 0x00, 0xD9, 0x01, 0x25, 0x29, 0x4E, 0x08, 0x36, 0x16, 0xF8, 0x14, 0x00, 0x18, 0xB1, 0x3A,
0x46, 0x29, 0x46, 0xFF, 0xF7, 0x54, 0xFF, 0x64, 0x1C, 0x03, 0x2C, 0xF5, 0xD3, 0x04, 0xE0, 0x3A, 0x46, 0x29, 0x46, 0x18, 0x46, 0xFF, 0xF7, 0x4B, 0xFF, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x4C, 0xFC, 0xFF, 0x20, 0x50, 0x21, 0x00, 0x01,
0x32, 0xC6, 0x3A, 0x0D, 0x00, 0x10, 0xB5, 0x01, 0x20, 0x5C, 0xF7, 0xC0, 0xFD, 0x80, 0x20, 0x45, 0xF7, 0x2B, 0xFB, 0x5C, 0xF7, 0x12, 0xFC, 0xFF, 0xF7, 0xA6, 0xFE, 0x5C, 0xF7, 0x6B, 0xFC, 0x1E, 0x48, 0x00, 0x68, 0xFF, 0xF7, 0xAD, 0xFE, 0xFF,
0xF7, 0xDA, 0xFE, 0xBD, 0xE8, 0x10, 0x40, 0x5C, 0xF7, 0x8D, 0xBD, 0x03, 0x01, 0x26, 0xF4, 0x3A, 0x0D, 0x00, 0x00, 0x23, 0x02, 0x2A, 0x0B, 0xD1, 0x16, 0x29, 0x09, 0xD1, 0x18, 0x49, 0x80, 0x7C, 0x89, 0x78, 0x88, 0x42, 0x04, 0xD3, 0x16, 0x49,
0x08, 0x68, 0x40, 0xF4, 0x80, 0x00, 0x08, 0x60, 0x18, 0x46, 0x70, 0x47, 0x03, 0x01, 0x62, 0x16, 0x3B, 0x0D, 0x00, 0x14, 0x48, 0x00, 0x68, 0x28, 0xB1, 0xAF, 0xF2, 0x59, 0x01, 0x01, 0x60, 0xAF, 0xF2, 0xAF, 0x01, 0x01, 0x62, 0xAF, 0xF2, 0x37,
0x00, 0x0F, 0x49, 0xC8, 0x64, 0xAF, 0xF2, 0xEF, 0x00, 0x0E, 0x49, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0xBC, 0x1D, 0x20, 0x00, 0x27, 0x1C, 0x20, 0x00, 0x40, 0x68, 0x0D, 0x00, 0x5C, 0x1C, 0x20, 0x00, 0xE0, 0x01, 0x65, 0x00, 0xBA, 0xA2, 0x08,
0x00, 0xAC, 0xA2, 0x08, 0x00, 0x60, 0x1C, 0x20, 0x00, 0x58, 0x1C, 0x20, 0x00, 0xD4, 0x28, 0x20, 0x00, 0x68, 0x1C, 0x20, 0x00, 0xB0, 0x1C, 0x20, 0x00, 0x38, 0x50, 0x20, 0x00, 0x30, 0x1C, 0x20, 0x00, 0x03, 0x01, 0xF0, 0x03, 0x74, 0x3B, 0x0D,
0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x7E, 0x4F, 0x05, 0x46, 0x4F, 0xF0, 0x00, 0x08, 0x38, 0x68, 0x20, 0xB9, 0x28, 0x78, 0x00, 0x28, 0x7E, 0xD1, 0x70, 0xF7, 0x35, 0xFB, 0x70, 0xF7, 0xB8, 0xFB, 0x00, 0x90, 0x78, 0x48, 0x22, 0x21, 0x01, 0x60, 0x4F,
0xF4, 0x46, 0x19, 0x00, 0x26, 0xC9, 0xF8, 0x00, 0x62, 0x04, 0x4C, 0xFC, 0xFF, 0x1B, 0x51, 0x21, 0x00, 0x21, 0xC9, 0xF8, 0x04, 0x12, 0x4F, 0xF4, 0x48, 0x14, 0x26, 0x66, 0xC9, 0xF8, 0x00, 0x60, 0x32, 0x20, 0x45, 0xF7, 0xB8, 0xFA, 0x70, 0x48,
0xE0, 0x65, 0x4F, 0xF4, 0x45, 0x11, 0x4F, 0xF0, 0x80, 0x0B, 0xC1, 0xF8, 0x0C, 0xB0, 0xC8, 0x20, 0x45, 0xF7, 0xAD, 0xFA, 0x28, 0x78, 0x4F, 0xF4, 0xCA, 0x0A,
0x4F, 0xF4, 0xC0, 0x04, 0xE0, 0xB1, 0xC4, 0xF8, 0xBC, 0x61, 0x67, 0x48, 0x06, 0x60, 0xD4, 0xF8, 0xFC, 0x02, 0x20, 0xF0, 0x0C, 0x00, 0xC4, 0xF8, 0xFC, 0x02, 0x38, 0x68, 0x48, 0xB1, 0x0A,
0xF5, 0xB0, 0x70, 0x01, 0x69, 0x21, 0xF0, 0x01, 0x01, 0x01, 0x61, 0x01, 0x68, 0x21, 0xF0, 0x01, 0x01, 0x01, 0x60, 0x00, 0x98, 0x70, 0xF7, 0x7E, 0xFB, 0x28, 0x78, 0x34, 0x46, 0xD0, 0xB3, 0x98, 0xE0, 0x00, 0x20, 0x75, 0xF7, 0xD3, 0xFC, 0x01,
0x21, 0x0A,
0xF5, 0xB0, 0x70, 0x39, 0x60, 0x02, 0x69, 0x42, 0xF0, 0x01, 0x02, 0x02, 0x61, 0x02, 0x68, 0x42, 0xF0, 0x01, 0x02, 0x02, 0x60, 0x48, 0x46, 0xC9, 0xF8, 0x00, 0x62, 0xC9, 0xF8, 0x04, 0xB2, 0xEA, 0x78, 0x00, 0x2A, 0xD4, 0xF8, 0xFC, 0x22, 0x02,
0xD0, 0x42, 0xF0, 0x0C, 0x02, 0x03, 0xE0, 0x22, 0xF0, 0x0C, 0x02, 0x42, 0xF0, 0x08, 0x02, 0xC4, 0xF8, 0xFC, 0x22, 0x49, 0x4A, 0x89, 0x46, 0x11, 0x60, 0x69, 0x78, 0x47, 0x4A, 0x89, 0x1E, 0x08, 0x32, 0x11, 0x60, 0x69, 0x78, 0x89, 0x1E, 0x12,
0x1F, 0x11, 0x60, 0x44, 0x49, 0x01, 0x60, 0x00, 0x20, 0x4F, 0xF4, 0x7A, 0x73, 0x4F, 0xF4, 0x45, 0x12, 0x01, 0x46, 0x40, 0x1C, 0x99, 0x42, 0x01, 0xE0, 0x67, 0xE0, 0x0E, 0xE0, 0x02, 0xD8, 0xD1, 0x68, 0x09, 0x06, 0xF5, 0xD5, 0x4F, 0xF4, 0x48,
0x10, 0x4F, 0xF4, 0x00, 0x31, 0x01, 0x66, 0xC8, 0x20, 0x4C, 0xFC, 0xFF, 0x16, 0x52, 0x21, 0x00, 0x45, 0xF7, 0x43, 0xFA, 0xC4, 0xF8, 0xBC, 0x91, 0xAE, 0xE7, 0xE0, 0xB2, 0xA9, 0x78, 0x40, 0xF0, 0x01, 0x00, 0x60, 0xF3, 0x07, 0x04, 0x06, 0x29,
0x19, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x03, 0x07, 0x0E, 0x27, 0x2A, 0x2E, 0x20, 0xF0, 0x1C, 0x00, 0x18, 0x30, 0x0E, 0xE0, 0xC4, 0xF3, 0x07, 0x20, 0x40, 0xF0, 0x01, 0x00, 0x60, 0xF3, 0x0F, 0x24, 0x09, 0xE0, 0xC4, 0xF3, 0x07, 0x21, 0x41, 0xF0,
0x01, 0x01, 0x61, 0xF3, 0x0F, 0x24, 0x40, 0xF0, 0x02, 0x00, 0x60, 0xF3, 0x07, 0x04, 0xE9, 0x78, 0xC4, 0xF3, 0x07, 0x20, 0x61, 0xF3, 0x83, 0x00, 0x60, 0xF3, 0x0F, 0x24, 0x28, 0x79, 0x07, 0x28, 0x0F, 0xD8, 0x00, 0x06, 0x80, 0x0D, 0x40, 0x42,
0x40, 0xB2, 0x11, 0xE0, 0x20, 0xF0, 0xE0, 0x00, 0xEB, 0xE7, 0x20, 0xF0, 0xE0, 0x00, 0x20, 0x30, 0xE7, 0xE7, 0x20, 0xF0, 0xE0, 0x00, 0xA0, 0x30, 0xE3, 0xE7, 0x08, 0x28, 0x02, 0xD0, 0x09, 0x28, 0x05, 0xD0, 0x08, 0xE0, 0x95, 0xF9, 0x05, 0x00,
0x82, 0xF7, 0xAA, 0xFD, 0x02, 0xE0, 0xA8, 0x79, 0x82, 0xF7, 0x3C, 0xFA, 0x80, 0x46, 0x08, 0xF0, 0xFF, 0x01, 0x11, 0x48, 0x8D, 0xF7, 0x20, 0xFB, 0x0B, 0x48, 0x04, 0x60, 0x28, 0x78, 0x20, 0xB1, 0x38, 0x68, 0x10, 0xB1, 0x70, 0xF7, 0xCB, 0xF8,
0x3E, 0x60, 0x01, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x03, 0x01, 0x30, 0x60, 0x3D, 0x0D, 0x00, 0x10, 0xB5, 0x14, 0x46, 0x0C, 0x30, 0xFF, 0xF7, 0x05, 0xFF, 0x00, 0x28, 0x01, 0xD1, 0x12, 0x20, 0x60, 0x71, 0x10, 0xBD, 0x50, 0x68, 0x0D, 0x00, 0xC0,
0x04, 0x41, 0x00, 0x00, 0x02, 0x0C, 0x00, 0x10, 0x84, 0x31, 0x00, 0x01, 0x00, 0x80, 0x00, 0x0C, 0x01, 0x60, 0x00, 0x03, 0x01, 0x20, 0x8C, 0x3D, 0x0D, 0x00, 0x10, 0x4C, 0xFC, 0xFF, 0x11, 0x53, 0x21, 0x00, 0xB5, 0x75, 0xF7, 0x4F, 0xFC, 0x75,
0xF7, 0x40, 0xFC, 0x0D, 0x48, 0x01, 0x68, 0x41, 0xF0, 0x01, 0x01, 0x01, 0x60, 0xBD, 0xE8, 0x10, 0x40, 0x75, 0xF7, 0xF2, 0xBB, 0x03, 0x01, 0x2C, 0xA8, 0x3D, 0x0D, 0x00, 0x10, 0xB5, 0x04, 0x28, 0x0D, 0xD1, 0x70, 0xF7, 0x23, 0xFA, 0x49, 0xF7,
0x48, 0xF9, 0x49, 0xF7, 0xFD, 0xF8, 0x49, 0xF7, 0xD9, 0xF8, 0x49, 0xF7, 0xE8, 0xFA, 0xBD, 0xE8, 0x10, 0x40, 0x70, 0xF7, 0x92, 0xB8, 0x10, 0xBD, 0x7C, 0x2B, 0x20, 0x00, 0x03, 0x01, 0x50, 0xD0, 0x3D, 0x0D, 0x00, 0x0F, 0x48, 0x10, 0xB5, 0x00,
0x68, 0x0D, 0x4C, 0xC0, 0x07, 0x11, 0xD0, 0x2C, 0x21, 0x20, 0x46, 0x70, 0xF7, 0x5A, 0xFA, 0x0B, 0x48, 0x01, 0x68, 0x41, 0xF0, 0x08, 0x01, 0x01, 0x60, 0x20, 0x46, 0x75, 0xF7, 0x3B, 0xFC, 0x75, 0xF7, 0x1C, 0xFC, 0xBD, 0xE8, 0x10, 0x40, 0x75,
0xF7, 0x5C, 0xBC, 0x05, 0x48, 0x4B, 0x21, 0x81, 0x70, 0x02, 0x21, 0xC1, 0x70, 0x10, 0xBD, 0xC4, 0x91, 0x20, 0x00, 0x1C, 0x13, 0x20, 0x00, 0x7C, 0x2B, 0x20, 0x00, 0x69, 0x1E, 0x20, 0x00, 0x03, 0x01, 0x0C, 0x1C, 0x3E, 0x0D, 0x00, 0x1D, 0x49,
0x1C, 0x48, 0x08, 0x60, 0x70, 0x47, 0x03, 0x01, 0x90, 0x01, 0x24, 0x3E, 0x0D, 0x00, 0x70, 0xB5, 0x1C, 0x4D, 0x1C, 0x49, 0x04, 0x46, 0xE8, 0x78, 0x1C, 0x4A, 0xC8, 0x70, 0xA8, 0x78, 0xD1, 0x79, 0x88, 0x42, 0x02, 0xD3, 0x05, 0x20, 0xE8, 0x70,
0x0C, 0xE0, 0x01, 0x21, 0x53, 0x78, 0x07, 0xE0, 0x56, 0x18, 0xB6, 0x78, 0xB0, 0x42, 0x02, 0xD2, 0x49, 0x1E, 0xE9, 0x70, 0x02, 0xE0, 0x49, 0x1C, 0x8B, 0x42, 0xF5, 0xD8, 0x00, 0x21, 0x20, 0x46, 0x4F, 0xF7, 0x7D, 0xFA, 0x10, 0x48, 0x00, 0x68,
0x80, 0x07, 0x03, 0xD5, 0x01, 0x4C, 0xFC, 0xFF, 0x0C, 0x54, 0x21, 0x00, 0x21, 0x20, 0x46, 0x4F, 0xF7, 0x75, 0xFA, 0x0D, 0x48, 0x00, 0x68, 0x00, 0x07, 0x02, 0xD4, 0x20, 0x46, 0x75, 0xF7, 0x6B, 0xFC, 0x20, 0x46, 0x75, 0xF7, 0xE8, 0xFB, 0x09,
0x49, 0x08, 0x78, 0x40, 0x1C, 0x08, 0x70, 0x70, 0xBD, 0x54, 0x68, 0x0D, 0x00, 0x64, 0x1E, 0x20, 0x00, 0x69, 0x1E, 0x20, 0x00, 0x6D, 0x1E, 0x20, 0x00, 0x26, 0x13, 0x20, 0x00, 0x1C, 0x13, 0x20, 0x00, 0x7C, 0x2B, 0x20, 0x00, 0x68, 0x1E, 0x20,
0x00, 0x03, 0x01, 0x22, 0xB0, 0x3E, 0x0D, 0x00, 0x1B, 0x49, 0x1C, 0x4B, 0x8A, 0x78, 0x09, 0x78, 0x01, 0x2A, 0x01, 0xEB, 0x81, 0x01, 0x03, 0xEB, 0xC1, 0x01, 0x02, 0xD0, 0x49, 0x6B, 0x08, 0x60, 0x70, 0x47, 0x89, 0x6B, 0xFB, 0xE7, 0x03, 0x01,
0x6A, 0xCE, 0x3E, 0x0D, 0x00, 0x70, 0xB5, 0x13, 0x48, 0x15, 0x49, 0x12, 0x4A, 0x84, 0x78, 0x00, 0x78, 0x00, 0xEB, 0xC0, 0x00, 0x01, 0xEB, 0x80, 0x06, 0x12, 0x49, 0x0F, 0x48, 0x09, 0x78, 0x00, 0xEB, 0xC1, 0x01, 0xDC, 0x31, 0x00, 0x69, 0x50,
0xF7, 0x08, 0xFE, 0x0E, 0x49, 0x08, 0x70, 0x4F, 0xF7, 0x79, 0xF9, 0x05, 0x46, 0x57, 0xF7, 0x03, 0xF9, 0x06, 0xEB, 0x44, 0x04, 0x20, 0x80, 0x55, 0xF7, 0xD8, 0xFA, 0x01, 0x46, 0x28, 0x46, 0x57, 0xF7, 0x12, 0xF9, 0xE0, 0x80, 0x4F, 0xF4, 0xC0,
0x01, 0x0F, 0x20, 0x88, 0x61, 0x70, 0xBD, 0x4C, 0x1E, 0x20, 0x00, 0x60, 0x10, 0x20, 0x00, 0x5C, 0x4F, 0x20, 0x00, 0xEE, 0x2A, 0x20, 0x00, 0xEF, 0x2A, 0x20, 0x00, 0x03, 0x01, 0x5C, 0x34, 0x3F, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x5F, 0x00, 0x24,
0x05, 0x46, 0x0E, 0x46, 0x93, 0x46, 0x4F, 0xF6, 0xFF, 0x78, 0x01, 0x27, 0x4F, 0xF0, 0x02, 0x09, 0xA2, 0x46, 0x06, 0xEB, 0x44, 0x00, 0xB0, 0x4C, 0xFC, 0xFF, 0x07, 0x55, 0x21, 0x00, 0xF8, 0x28, 0x01, 0x40, 0x45, 0x11, 0xD0, 0x28, 0x80, 0x30,
0x6C, 0x07, 0xFA, 0x04, 0xF1, 0xC0, 0xF3, 0x80, 0x40, 0x08, 0x42, 0x02, 0xD0, 0x85, 0xF8, 0x09, 0x90, 0x01, 0xE0, 0x85, 0xF8, 0x09, 0xA0, 0x59, 0x46, 0x28, 0x46, 0x61, 0xF7, 0x29, 0xF8, 0x28, 0xB1, 0x64, 0x1C, 0x06, 0x2C, 0xE4, 0xD3, 0x00,
0x20, 0xBD, 0xE8, 0xF0, 0x9F, 0x01, 0x20, 0xFB, 0xE7, 0x03, 0x01, 0xC2, 0x04, 0x8C, 0x3F, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x87, 0xB0, 0x00, 0x26, 0x04, 0x46, 0x05, 0x96, 0x90, 0xF8, 0xD2, 0x00, 0xFC, 0xF7, 0xDC, 0xFA, 0x80, 0x46, 0x85,
0xF7, 0x27, 0xF9, 0x94, 0xF8, 0xD2, 0x70, 0x04, 0xA9, 0x1E, 0x37, 0x38, 0x46, 0x60, 0xF7, 0x02, 0xFF, 0xDF, 0xF8, 0x90, 0xB4, 0x05, 0x00, 0x0A,
0xD0, 0x04, 0x98, 0x00, 0xEB, 0x40, 0x01, 0xDB, 0xF8, 0x00, 0x00, 0x00, 0xEB, 0x81, 0x00, 0x06, 0x60, 0x46, 0x60, 0x86, 0x60, 0x03, 0xE0, 0x04, 0xA8, 0x60, 0xF7, 0xD5, 0xFE, 0xF0, 0xB3, 0x08, 0x20, 0x8D, 0xF8, 0x0A,
0x00, 0x4F, 0xF0, 0x01, 0x0A,
0x8D, 0xF8, 0x0B, 0xA0, 0x8D, 0xF8, 0x07, 0x70, 0x94, 0xF8, 0xD0, 0x00, 0xAD, 0xF8, 0x00, 0x60, 0x8D, 0xF8, 0x08, 0x00, 0xAD, 0xF8, 0x02, 0x60, 0x60, 0xF7, 0xD0, 0xFF, 0x8D, 0xF8, 0x09, 0x00, 0xB4, 0xF8, 0x4C, 0x00, 0x4F, 0xF0, 0x02, 0x09,
0x40, 0x1C, 0x20, 0xF0, 0x01, 0x00, 0x80, 0xB2, 0xAD, 0xF8, 0x04, 0x00, 0x02, 0x28, 0x01, 0xD2, 0xAD, 0xF8, 0x04, 0x90, 0xB4, 0xF8, 0x4E, 0x00, 0xBD, 0xF8, 0x04, 0x10, 0x40, 0x1C, 0x20, 0xF0, 0x01, 0x00, 0x88, 0x42, 0x01, 0xD9, 0x40, 0x1A,
0x05, 0x90, 0x94, 0xF8, 0xD2, 0x00, 0xA8, 0xF7, 0x26, 0xFC, 0x05, 0x99, 0x6F, 0xF0, 0x01, 0x02, 0x4C, 0xFC, 0xFF, 0x02, 0x56, 0x21, 0x00, 0x08, 0x44, 0x05, 0x90, 0xB4, 0xF8, 0x48, 0x10, 0x02, 0xEB, 0x41, 0x02, 0x82, 0x42, 0x03, 0xD8, 0x48,
0x00, 0x00, 0xE0, 0x12, 0xE0, 0x80, 0x1E, 0x8D, 0xF8, 0x06, 0x00, 0x94, 0xF8, 0xD1, 0x00, 0xB0, 0xB1, 0x00, 0x2D, 0x7E, 0xD0, 0xB4, 0xF8, 0xC8, 0x00, 0xAD, 0xF8, 0x00, 0x00, 0xB4, 0xF8, 0xCA, 0x00, 0xAD, 0xF8, 0x02, 0x00, 0x94, 0xF8, 0xD5,
0x00, 0x89, 0xE0, 0x00, 0x23, 0x69, 0x22, 0x4F, 0xF4, 0x68, 0x71, 0xF0, 0x48, 0x71, 0xF7, 0x66, 0xF8, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0x27, 0x5D, 0xF7, 0x01, 0xFE, 0x18, 0xB1, 0x5D, 0xF7, 0xCF, 0xFB, 0x00, 0xB9, 0x00, 0x27, 0xB4,
0xF8, 0x44, 0x00, 0x40, 0x05, 0x05, 0xD5, 0xB8, 0xF8, 0x04, 0x00, 0x10, 0xB1, 0xAD, 0xF8, 0x02, 0x00, 0x09, 0xE0, 0xB4, 0xF8, 0x4A, 0x00, 0x3B, 0x46, 0x42, 0x00, 0xB4, 0xF8, 0x48, 0x00, 0x41, 0x00, 0x68, 0x46, 0x61, 0xF7, 0x41, 0xF8, 0xBD,
0xF8, 0x02, 0x00, 0x01, 0x28, 0x0A,
0xD9, 0xDE, 0x49, 0x49, 0x68, 0x40, 0x1E, 0xB1, 0xFB, 0xF0, 0xF2, 0x00, 0xFB, 0x12, 0x10, 0x20, 0xF0, 0x01, 0x00, 0xAD, 0xF8, 0x00, 0x00, 0x94, 0xF8, 0xD2, 0x00, 0x05, 0xAA, 0x69, 0x46, 0xA8, 0xF7, 0xF1, 0xFB, 0x48, 0xBB, 0xB4, 0xF8, 0x44,
0x00, 0x40, 0x05, 0x19, 0xD5, 0xB8, 0xF8, 0x04, 0x00, 0xB0, 0xB1, 0x4A, 0x46, 0x21, 0x46, 0x68, 0x46, 0xCD, 0xF8, 0x0C, 0x90, 0xFF, 0xF7, 0x10, 0xFF, 0xD0, 0xB9, 0x52, 0x46, 0x21, 0x46, 0x68, 0x46, 0xCD, 0xF8, 0x0C, 0xA0, 0xFF, 0xF7, 0x08,
0xFF, 0x90, 0xB9, 0x32, 0x46, 0x21, 0x46, 0x68, 0x46, 0x03, 0x96, 0xFF, 0xF7, 0x01, 0xFF, 0x58, 0xB9, 0x03, 0xA9, 0x68, 0x46, 0x60, 0xF7, 0xE9, 0xFF, 0x30, 0xB9, 0xAD, 0x4C, 0xFC, 0xFF, 0xFD, 0x56, 0x21, 0x00, 0xF8, 0x00, 0x60, 0xB4, 0xF8,
0x4A, 0x00, 0x40, 0x00, 0xAD, 0xF8, 0x02, 0x00, 0xBD, 0xF8, 0x00, 0x00, 0x5D, 0xB1, 0xA4, 0xF8, 0xC8, 0x00, 0xBD, 0xF8, 0x02, 0x00, 0xA4, 0xF8, 0xCA, 0x00, 0x9D, 0xF8, 0x09, 0x00, 0x84, 0xF8, 0xD5, 0x00, 0x17, 0xE0, 0x0A,
0xE0, 0xA4, 0xF8, 0xC4, 0x00, 0xBD, 0xF8, 0x02, 0x00, 0xA4, 0xF8, 0xC6, 0x00, 0x9D, 0xF8, 0x09, 0x00, 0x84, 0xF8, 0xD4, 0x00, 0x0B, 0xE0, 0xB4, 0xF8, 0xC4, 0x00, 0xAD, 0xF8, 0x00, 0x00, 0xB4, 0xF8, 0xC6, 0x00, 0xAD, 0xF8, 0x02, 0x00, 0x94,
0xF8, 0xD4, 0x00, 0x8D, 0xF8, 0x09, 0x00, 0x04, 0x98, 0xDB, 0xF8, 0x00, 0x10, 0x00, 0xEB, 0x40, 0x02, 0x01, 0xEB, 0x82, 0x00, 0x00, 0x9A, 0x02, 0x60, 0x01, 0x9A, 0x42, 0x60, 0x02, 0x9A, 0x82, 0x60, 0x00, 0x2D, 0x7F, 0xF4, 0x6B, 0xAF, 0x04,
0x98, 0x00, 0xEB, 0x40, 0x00, 0x01, 0xEB, 0x80, 0x00, 0x80, 0x79, 0x84, 0xF8, 0xD6, 0x00, 0x61, 0xE7, 0x03, 0x01, 0x38, 0xCA, 0x41, 0x0D, 0x00, 0x49, 0x1C, 0x21, 0xF0, 0x01, 0x01, 0x10, 0xB5, 0x89, 0xB2, 0x81, 0x80, 0x02, 0x29, 0x01, 0xD2,
0x02, 0x21, 0x81, 0x80, 0x52, 0x1C, 0x83, 0x88, 0x22, 0xF0, 0x01, 0x01, 0x8B, 0x42, 0x08, 0xD2, 0x42, 0x88, 0xC9, 0x1A, 0x94, 0x1E, 0x8C, 0x42, 0x01, 0xD2, 0x92, 0x1E, 0x00, 0xE0, 0x0A,
0x46, 0x82, 0x71, 0x10, 0xBD, 0x03, 0x01, 0xBC, 0x02, 0xFE, 0x41, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x05, 0x46, 0x90, 0xF8, 0xD2, 0x00, 0x8B, 0xB0, 0x8A, 0x46, 0x90, 0x46, 0x9B, 0x46, 0x1E, 0x30, 0x04, 0xA9, 0x60, 0xF7, 0xD0, 0xFD, 0x00,
0x28, 0x78, 0xD0, 0x84, 0xF7, 0xEA, 0xFF, 0x04, 0x98, 0x00, 0xEB, 0x40, 0x01, 0x88, 0x48, 0x00, 0x68, 0x00, 0x4C, 0xFC, 0xFF, 0xF8, 0x57, 0x21, 0x00, 0xEB, 0x81, 0x01, 0x08, 0x68, 0x00, 0x90, 0x48, 0x68, 0x01, 0x90, 0x88, 0x68, 0x02, 0x90,
0x0C, 0x68, 0x06, 0x94, 0x48, 0x68, 0x07, 0x90, 0x88, 0x68, 0x08, 0x90, 0x00, 0x20, 0x08, 0x60, 0x48, 0x60, 0x88, 0x60, 0x05, 0xA9, 0x68, 0x46, 0x61, 0xF7, 0xE8, 0xFA, 0xB5, 0xF8, 0x4E, 0x20, 0xB5, 0xF8, 0x4C, 0x10, 0x68, 0x46, 0xFF, 0xF7,
0xB3, 0xFF, 0x02, 0x25, 0x4F, 0xF0, 0x00, 0x09, 0x20, 0x0C, 0x4F, 0x46, 0x09, 0x90, 0xBA, 0xF8, 0x02, 0x00, 0x09, 0x99, 0x40, 0x04, 0x00, 0x0C, 0xAD, 0xF8, 0x02, 0x00, 0x81, 0x42, 0x05, 0xD1, 0x05, 0x98, 0x85, 0x42, 0x02, 0xD2, 0x4F, 0xF0,
0x00, 0x09, 0x40, 0xE0, 0x00, 0x26, 0xB8, 0xF1, 0x00, 0x0F, 0x01, 0xD0, 0x00, 0x24, 0x1E, 0xE0, 0x03, 0xA9, 0x68, 0x46, 0x60, 0xF7, 0x36, 0xFF, 0x01, 0x28, 0x1A, 0xD1, 0x03, 0x98, 0xA8, 0x42, 0x17, 0xD1, 0x4F, 0xF0, 0x01, 0x09, 0x29, 0xE0,
0x0B, 0xEB, 0x84, 0x00, 0xBD, 0xF8, 0x02, 0x10, 0x00, 0x68, 0xB0, 0xFB, 0xF1, 0xF2, 0x01, 0xFB, 0x12, 0x00, 0xAD, 0xF8, 0x00, 0x00, 0x03, 0xA9, 0x68, 0x46, 0x61, 0xF7, 0xAB, 0xFA, 0x03, 0x98, 0xA8, 0x42, 0xEA, 0xD0, 0x64, 0x1C, 0x44, 0x45,
0xEA, 0xD3, 0xBD, 0xF8, 0x02, 0x00, 0x80, 0x1E, 0x80, 0xB2, 0xAD, 0xF8, 0x02, 0x00, 0xBA, 0xF8, 0x00, 0x10, 0xB0, 0xEB, 0x41, 0x0F, 0x02, 0xD3, 0x76, 0x1C, 0x0C, 0x2E, 0xCB, 0xD3, 0x7F, 0x1C, 0x6D, 0x1E, 0x03, 0x2F, 0xB7, 0xD3, 0xB9, 0xF1,
0x00, 0x0F, 0x04, 0xD0, 0x14, 0x98, 0x03, 0x99, 0x01, 0x60, 0x03, 0xE0, 0x10, 0xE0, 0x14, 0x99, 0x00, 0x20, 0x08, 0x60, 0x04, 0x98, 0x00, 0xEB, 0x40, 0x01, 0x4A, 0x48, 0x00, 0x68, 0x00, 0xEB, 0x81, 0x00, 0x06, 0x99, 0x4C, 0xFC, 0xFF, 0xF3,
0x58, 0x21, 0x00, 0x01, 0x60, 0x07, 0x99, 0x41, 0x60, 0x08, 0x99, 0x81, 0x60, 0x48, 0x46, 0x0B, 0xB0, 0xAC, 0xE6, 0x03, 0x01, 0xEE, 0x01, 0x36, 0x43, 0x0D, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, 0x04, 0x46, 0x87, 0xB0, 0x90, 0xF8, 0xD2, 0x00, 0x1F,
0x46, 0x1E, 0x30, 0x06, 0xA9, 0x14, 0x9E, 0x60, 0xF7, 0x35, 0xFD, 0x00, 0x28, 0xEF, 0xD0, 0x06, 0x98, 0xDF, 0xF8, 0xF0, 0xB0, 0x00, 0xEB, 0x40, 0x01, 0x00, 0x25, 0xDB, 0xF8, 0x00, 0x00, 0x00, 0xEB, 0x81, 0x00, 0x01, 0x68, 0x00, 0x91, 0x41,
0x68, 0x01, 0x91, 0x81, 0x68, 0x02, 0x91, 0xD0, 0xF8, 0x00, 0x80, 0xD0, 0xF8, 0x04, 0xA0, 0xD0, 0xF8, 0x08, 0x90, 0x05, 0x60, 0x45, 0x60, 0x85, 0x60, 0x08, 0x98, 0xAD, 0xF8, 0x02, 0x00, 0xB4, 0xF8, 0x4E, 0x20, 0xB4, 0xF8, 0x4C, 0x10, 0x68,
0x46, 0xFF, 0xF7, 0x19, 0xFF, 0xAD, 0xF8, 0x00, 0x50, 0x8D, 0xF8, 0x09, 0x50, 0x2C, 0x46, 0x28, 0xE0, 0x68, 0x46, 0x09, 0x99, 0x60, 0xF7, 0xB1, 0xFE, 0x28, 0xB3, 0x9D, 0xE8, 0x07, 0x00, 0x03, 0xAB, 0x07, 0xC3, 0x03, 0xA8, 0x5F, 0xF7, 0xF8,
0xFE, 0x81, 0xB2, 0xAD, 0xF8, 0x0C, 0x10, 0x00, 0x20, 0x05, 0xE0, 0x06, 0xEB, 0x40, 0x02, 0x12, 0x88, 0x8A, 0x42, 0x14, 0xD0, 0x40, 0x1C, 0xA0, 0x42, 0xF7, 0xD3, 0x06, 0xEB, 0x44, 0x00, 0x6D, 0x1C, 0x01, 0x80, 0xBD, 0xF8, 0x00, 0x00, 0xBD,
0xF8, 0x02, 0x10, 0x80, 0x1C, 0xB0, 0xFB, 0xF1, 0xF2, 0x01, 0xFB, 0x12, 0x00, 0xAD, 0xF8, 0x00, 0x00, 0x64, 0x1C, 0xBC, 0x42, 0xD4, 0xD3, 0x15, 0xB9, 0x09, 0x99, 0x00, 0x20, 0x08, 0x60, 0x06, 0x98, 0x00, 0xEB, 0x40, 0x01, 0xDB, 0xF8, 0x00,
0x00, 0x00, 0xEB, 0x81, 0x00, 0xC0, 0xF8, 0x00, 0x80, 0xC0, 0xF8, 0x04, 0xA0, 0xC0, 0x4C, 0xFC, 0xFF, 0xEE, 0x59, 0x21, 0x00, 0xF8, 0x08, 0x90, 0x28, 0x46, 0x88, 0xE7, 0x03, 0x01, 0x38, 0x20, 0x44, 0x0D, 0x00, 0x0E, 0xB5, 0x1E, 0x30, 0x8D,
0xF8, 0x07, 0x00, 0x88, 0x1E, 0x18, 0x28, 0x01, 0xD9, 0x18, 0x21, 0x00, 0xE0, 0x89, 0x1E, 0x0A,
0x46, 0x01, 0x23, 0x06, 0x21, 0x68, 0x46, 0x60, 0xF7, 0x87, 0xFE, 0xBD, 0xF8, 0x02, 0x00, 0x0E, 0xBD, 0x00, 0x00, 0xC4, 0x30, 0x20, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0xA0, 0x32, 0x00, 0x03, 0x01, 0xA8, 0x02, 0x54, 0x44, 0x0D, 0x00, 0x70,
0xB5, 0x50, 0xF7, 0xD5, 0xFA, 0x04, 0x46, 0x50, 0xF7, 0xE3, 0xFA, 0x05, 0x46, 0x50, 0xF7, 0x1C, 0xFB, 0xB0, 0xF9, 0x00, 0x10, 0xB0, 0xF9, 0x02, 0x20, 0x69, 0x43, 0x4F, 0xEA, 0x81, 0x21, 0x01, 0xEB, 0xC2, 0x11, 0x4F, 0xEA, 0xE1, 0x72, 0x01,
0xEB, 0x92, 0x51, 0x4F, 0xEA, 0xA1, 0x21, 0x09, 0xB2, 0x4F, 0xEA, 0xE1, 0x72, 0x01, 0xEB, 0x52, 0x61, 0xC9, 0x11, 0x00, 0xD5, 0x00, 0x21, 0x1F, 0x29, 0x00, 0xDD, 0x1F, 0x21, 0xF1, 0x4A, 0x11, 0x70, 0xB0, 0xF9, 0x04, 0x10, 0xB0, 0xF9, 0x06,
0x30, 0x69, 0x43, 0x4F, 0xEA, 0x81, 0x21, 0x01, 0xEB, 0xC3, 0x11, 0x4F, 0xEA, 0xE1, 0x73, 0x01, 0xEB, 0x93, 0x51, 0x4F, 0xEA, 0xA1, 0x21, 0x09, 0xB2, 0x4F, 0xEA, 0xE1, 0x73, 0x01, 0xEB, 0x53, 0x61, 0xC9, 0x11, 0x00, 0xD5, 0x00, 0x21, 0x1F,
0x29, 0x00, 0xDD, 0x1F, 0x21, 0x51, 0x70, 0xB0, 0xF9, 0x08, 0x10, 0xB0, 0xF9, 0x0A,
0x30, 0x69, 0x43, 0x4F, 0xEA, 0x81, 0x21, 0x01, 0xEB, 0xC3, 0x11, 0x4F, 0xEA, 0xE1, 0x73, 0x01, 0xEB, 0x93, 0x51, 0x4F, 0xEA, 0xA1, 0x21, 0x09, 0xB2, 0x4F, 0xEA, 0xE1, 0x73, 0x01, 0xEB, 0x53, 0x61, 0xC9, 0x11, 0x00, 0xD5, 0x00, 0x21, 0x1F,
0x29, 0x00, 0x4C, 0xFC, 0xFF, 0xE9, 0x5A, 0x21, 0x00, 0xDD, 0x1F, 0x21, 0x91, 0x70, 0xB0, 0xF9, 0x0C, 0x10, 0xB0, 0xF9, 0x0E, 0x30, 0x61, 0x43, 0x4F, 0xEA, 0x81, 0x21, 0x01, 0xEB, 0xC3, 0x11, 0x4F, 0xEA, 0xE1, 0x73, 0x01, 0xEB, 0x93, 0x51,
0x4F, 0xEA, 0xA1, 0x21, 0x09, 0xB2, 0x4F, 0xEA, 0xE1, 0x73, 0x01, 0xEB, 0x53, 0x61, 0xC9, 0x11, 0x00, 0xD5, 0x00, 0x21, 0x0F, 0x29, 0x00, 0xDD, 0x0F, 0x21, 0xD1, 0x70, 0xB0, 0xF9, 0x10, 0x10, 0xB0, 0xF9, 0x12, 0x00, 0x61, 0x43, 0x4F, 0xEA,
0x81, 0x21, 0x01, 0xEB, 0xC0, 0x10, 0x4F, 0xEA, 0xE0, 0x71, 0x00, 0xEB, 0x91, 0x50, 0x4F, 0xEA, 0xA0, 0x20, 0x00, 0xB2, 0x4F, 0xEA, 0xE0, 0x71, 0x00, 0xEB, 0x51, 0x60, 0xC0, 0x11, 0x00, 0xD5, 0x00, 0x20, 0x0F, 0x28, 0x00, 0xDD, 0x0F, 0x20,
0x10, 0x71, 0x70, 0xBD, 0x03, 0x01, 0x82, 0x03, 0x78, 0x45, 0x0D, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x00, 0x24, 0x26, 0x46, 0x4F, 0xF0, 0x01, 0x09, 0x5C, 0xF7, 0x68, 0xFC, 0x05, 0x46, 0xFF, 0xF7, 0x63, 0xFF, 0xB5, 0x4F, 0x38, 0x68, 0x00, 0xF0,
0xE0, 0x01, 0xB2, 0x48, 0x02, 0x78, 0x02, 0xF0, 0x1F, 0x02, 0x11, 0x43, 0x39, 0x60, 0x39, 0x1F, 0x0A,
0x68, 0x43, 0x78, 0x02, 0xF0, 0xE0, 0x02, 0x03, 0xF0, 0x1F, 0x03, 0x1A, 0x43, 0x0A,
0x60, 0x3A, 0x1D, 0x13, 0x68, 0x90, 0xF8, 0x02, 0xC0, 0x03, 0xF0, 0xE0, 0x03, 0x0C, 0xF0, 0x1F, 0x0C, 0x43, 0xEA, 0x0C, 0x03, 0x13, 0x60, 0xA7, 0x4A, 0x13, 0x68, 0x90, 0xF8, 0x03, 0xC0, 0x03, 0xF0, 0xE0, 0x03, 0x0C, 0xF0, 0x1F, 0x0C, 0x43,
0xEA, 0x0C, 0x03, 0x13, 0x60, 0xDF, 0xF8, 0x84, 0xA2, 0x0A,
0xF1, 0x08, 0x0A,
0xDA, 0xF8, 0x00, 0xC0, 0x00, 0x79, 0x0C, 0xF0, 0xE0, 0x0C, 0x00, 0xF0, 0x1F, 0x00, 0x4C, 0xEA, 0x4C, 0xFC, 0xFF, 0xE4, 0x5B, 0x21, 0x00, 0x00, 0x0C, 0xCA, 0xF8, 0x00, 0xC0, 0x38, 0x68, 0xDF, 0xF8, 0x60, 0xC2, 0x00, 0xF0, 0x1F, 0x00, 0x0C,
0xF1, 0x54, 0x0C, 0x0C, 0xF1, 0x04, 0x08, 0x03, 0x28, 0x03, 0xD3, 0x80, 0x1E, 0xCC, 0xF8, 0x00, 0x00, 0x04, 0xE0, 0x00, 0x23, 0xCC, 0xF8, 0x00, 0x30, 0x18, 0xB1, 0x40, 0x1E, 0xC8, 0xF8, 0x00, 0x00, 0x01, 0xE0, 0xC8, 0xF8, 0x00, 0x30, 0x04,
0x2D, 0x4A, 0xD0, 0xF5, 0xB3, 0x10, 0x68, 0x00, 0xF0, 0x1F, 0x00, 0x08, 0x30, 0xDA, 0xF8, 0x00, 0x20, 0x60, 0xF3, 0x04, 0x02, 0xCA, 0xF8, 0x00, 0x20, 0x87, 0x4B, 0x40, 0x33, 0x1A, 0x68, 0x00, 0xF0, 0x10, 0x00, 0x22, 0xF0, 0x10, 0x02, 0x02,
0x43, 0x1A, 0x60, 0x5D, 0xB3, 0x03, 0x2D, 0x37, 0xD0, 0x08, 0x68, 0x04, 0x2D, 0x00, 0xD0, 0x80, 0x1E, 0x38, 0x60, 0x30, 0xF7, 0x92, 0xFD, 0x00, 0x28, 0x3E, 0xD0, 0x6A, 0x46, 0x02, 0x21, 0x6E, 0x20, 0x30, 0xF7, 0x55, 0xFD, 0xBD, 0xF8, 0x00,
0x00, 0xC1, 0xB2, 0x41, 0xEA, 0x10, 0x20, 0x01, 0x06, 0x01, 0xD5, 0x4F, 0xF0, 0xFF, 0x39, 0x00, 0xF0, 0x7F, 0x00, 0x00, 0xFB, 0x09, 0xF0, 0x40, 0xB2, 0x00, 0x28, 0x29, 0xD0, 0x73, 0x4A, 0x02, 0xEB, 0x84, 0x01, 0x91, 0xF9, 0x00, 0x30, 0x83,
0x42, 0x1A, 0xDC, 0x91, 0xF9, 0x01, 0x10, 0x81, 0x42, 0x01, 0xE0, 0x09, 0xE0, 0x0C, 0xE0, 0x13, 0xDD, 0x6D, 0xB1, 0x04, 0x2D, 0x0B, 0xD0, 0x02, 0xEB, 0x84, 0x00, 0x90, 0xF9, 0x02, 0x60, 0x0F, 0xE0, 0x10, 0x68, 0x00, 0xF0, 0x1F, 0x00, 0xB5,
0xE7, 0x08, 0x68, 0x40, 0x1E, 0xC8, 0xE7, 0x02, 0xEB, 0x84, 0x00, 0x90, 0xF9, 0x03, 0x60, 0x03, 0xE0, 0x64, 0x1C, 0xE4, 0xB2, 0x09, 0x2C, 0xDA, 0xD3, 0x38, 0x68, 0x30, 0x44, 0xC0, 0xB2, 0x38, 0x60, 0xBD, 0x4C, 0xFC, 0xFF, 0xDF, 0x5C, 0x21,
0x00, 0xE8, 0xF8, 0x8F, 0x03, 0x01, 0x68, 0xF6, 0x46, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x06, 0x46, 0x0F, 0x46, 0x4F, 0xF0, 0xFF, 0x35, 0x5C, 0xF7, 0xA9, 0xFB, 0x01, 0x46, 0x59, 0x48, 0x00, 0x24, 0x04, 0xEB, 0x44, 0x02, 0x50, 0xF8, 0x22,
0x20, 0xBA, 0x42, 0x01, 0xD1, 0x25, 0x46, 0x02, 0xE0, 0x64, 0x1C, 0x13, 0x2C, 0xF4, 0xDB, 0x56, 0xB1, 0x6A, 0x1C, 0x08, 0xD0, 0x05, 0xEB, 0x45, 0x02, 0x00, 0xEB, 0x82, 0x00, 0x40, 0x68, 0x31, 0xB1, 0x04, 0x29, 0x04, 0xD0, 0x09, 0xE0, 0x4F,
0xF4, 0x40, 0x70, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xEB, 0x80, 0x00, 0x40, 0x00, 0x09, 0x21, 0xB0, 0xFB, 0xF1, 0xF0, 0xB0, 0xFB, 0xF6, 0xF0, 0x80, 0x08, 0xA0, 0xF5, 0x7C, 0x60, 0xF1, 0xE7, 0x03, 0x01, 0x4A, 0x5A, 0x47, 0x0D, 0x00, 0x30, 0xB5,
0x0C, 0x1A, 0x44, 0x49, 0x4F, 0xF0, 0xFF, 0x33, 0x00, 0x20, 0x00, 0xEB, 0x40, 0x05, 0x51, 0xF8, 0x25, 0x50, 0x95, 0x42, 0x01, 0xD1, 0x03, 0x46, 0x02, 0xE0, 0x40, 0x1C, 0x13, 0x28, 0xF4, 0xDB, 0x00, 0x2C, 0x0C, 0xDD, 0x58, 0x1C, 0x0A,
0xD0, 0x03, 0xEB, 0x43, 0x00, 0x01, 0xEB, 0x80, 0x00, 0x80, 0x68, 0xB0, 0xFB, 0xF4, 0xF0, 0x80, 0x08, 0xA0, 0xF5, 0x5C, 0x60, 0x30, 0xBD, 0x4F, 0xF4, 0xC0, 0x60, 0x30, 0xBD, 0x03, 0x01, 0xE0, 0x01, 0xA0, 0x47, 0x0D, 0x00, 0x2D, 0xE9, 0xF0,
0x47, 0x30, 0x4C, 0x64, 0x34, 0xD4, 0xF8, 0x00, 0x90, 0x20, 0x68, 0x40, 0xF0, 0x18, 0x00, 0x20, 0x60, 0x20, 0x68, 0x00, 0xF0, 0x9D, 0x00, 0x40, 0xF0, 0x05, 0x00, 0x20, 0x60, 0x64, 0x20, 0x6F, 0xF7, 0x02, 0xFF, 0x20, 0x68, 0x00, 0xF0, 0xFB,
0x00, 0x20, 0x60, 0x4F, 0xF4, 0xE1, 0x7A, 0x50, 0x46, 0x6F, 0xF7, 0xF9, 0xFE, 0x4C, 0xFC, 0xFF, 0xDA, 0x5D, 0x21, 0x00, 0x25, 0x1D, 0x28, 0x68, 0x2E, 0x1D, 0xC0, 0xB2, 0x37, 0x68, 0x60, 0xF3, 0x1F, 0x27, 0x20, 0x68, 0x40, 0xF0, 0x24, 0x00,
0x20, 0x60, 0x64, 0x20, 0x6F, 0xF7, 0xEB, 0xFE, 0x20, 0x68, 0x00, 0xF0, 0xFB, 0x00, 0x20, 0x60, 0x50, 0x46, 0x6F, 0xF7, 0xE4, 0xFE, 0x28, 0x68, 0x31, 0x68, 0xC0, 0xB2, 0x60, 0xF3, 0x1F, 0x21, 0x20, 0x68, 0x88, 0x46, 0x00, 0xF0, 0xDE, 0x00,
0x40, 0xF0, 0x04, 0x00, 0x20, 0x60, 0x64, 0x20, 0x6F, 0xF7, 0xD5, 0xFE, 0x20, 0x68, 0x00, 0xF0, 0xFB, 0x00, 0x20, 0x60, 0x50, 0x46, 0x6F, 0xF7, 0xCE, 0xFE, 0x28, 0x68, 0x35, 0x68, 0xC0, 0xB2, 0x60, 0xF3, 0x1F, 0x25, 0xC4, 0xF8, 0x00, 0x90,
0x70, 0xF7, 0x1C, 0xF8, 0x04, 0x46, 0x01, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x56, 0xFF, 0x0A,
0x49, 0x22, 0x46, 0x08, 0x80, 0x41, 0x46, 0x38, 0x46, 0xFF, 0xF7, 0x81, 0xFF, 0x07, 0x49, 0x08, 0x80, 0xBD, 0xE8, 0xF0, 0x87, 0x9E, 0x07, 0x20, 0x00, 0x10, 0x04, 0x60, 0x00, 0x00, 0x07, 0x60, 0x00, 0xFA, 0x6F, 0x0D, 0x00, 0x6C, 0x68, 0x0D,
0x00, 0xB4, 0x06, 0x20, 0x00, 0xB6, 0x06, 0x20, 0x00, 0x03, 0x01, 0x2C, 0x7C, 0x48, 0x0D, 0x00, 0x15, 0x49, 0x0A,
0x68, 0x22, 0xF0, 0x04, 0x02, 0x0A,
0x60, 0x01, 0x28, 0x0B, 0xD9, 0x4F, 0xF4, 0xC8, 0x00, 0xD0, 0xF8, 0xB0, 0x11, 0x41, 0xF0, 0x3F, 0x01, 0xC0, 0xF8, 0xB0, 0x11, 0x01, 0x6F, 0x21, 0xF0, 0x80, 0x01, 0x01, 0x67, 0x70, 0x47, 0x03, 0x01, 0x3C, 0xA4, 0x48, 0x0D, 0x00, 0x01, 0x28,
0x0E, 0xD9, 0x4F, 0xF4, 0xC8, 0x00, 0xD0, 0xF8, 0xB0, 0x11, 0x09, 0x4A, 0x21, 0xF0, 0x3F, 0x01, 0x12, 0x78, 0x11, 0x43, 0xC0, 0xF8, 0xB0, 0x11, 0x01, 0x6F, 0x41, 0xF0, 0x80, 0x01, 0x01, 0x4C, 0xFC, 0xFF, 0xD5, 0x5E, 0x21, 0x00, 0x67, 0x03,
0x48, 0x01, 0x68, 0x41, 0xF0, 0x04, 0x01, 0x01, 0x60, 0x70, 0x47, 0x00, 0x00, 0x28, 0x09, 0x64, 0x00, 0xF4, 0x17, 0x20, 0x00, 0x03, 0x01, 0x2C, 0xDC, 0x48, 0x0D, 0x00, 0x10, 0xB5, 0x5C, 0xF7, 0xBB, 0xFA, 0x13, 0x49, 0x48, 0xB1, 0x03, 0x28,
0x07, 0xD0, 0x02, 0x28, 0x04, 0xD1, 0x11, 0x48, 0x08, 0x60, 0x40, 0xF6, 0xAA, 0x20, 0x48, 0x60, 0x10, 0xBD, 0x0F, 0x48, 0x08, 0x60, 0x40, 0xF6, 0x67, 0x30, 0xF8, 0xE7, 0x03, 0x01, 0x28, 0x04, 0x49, 0x0D, 0x00, 0x0D, 0x4B, 0x4F, 0xF4, 0x7A,
0x70, 0x19, 0x68, 0xC9, 0xB2, 0x02, 0x1E, 0xA0, 0xF1, 0x01, 0x00, 0x01, 0xDD, 0xCA, 0x07, 0xF9, 0xD0, 0x18, 0x68, 0x07, 0x48, 0x1C, 0x30, 0x00, 0x68, 0x00, 0xF0, 0x3F, 0x00, 0x70, 0x47, 0x03, 0x01, 0x20, 0x28, 0x49, 0x0D, 0x00, 0x05, 0x49,
0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x6B, 0x17, 0x20, 0x00, 0x00, 0x40, 0xFF, 0xFF, 0xD9, 0xF6, 0xFE, 0xFF, 0xA8, 0x07, 0x60, 0x00, 0x7C, 0x06, 0x60, 0x00, 0x03, 0x01, 0x48, 0x44, 0x49, 0x0D, 0x00, 0x10, 0xB5, 0x4F, 0xF4, 0xC0, 0x03, 0x00,
0x20, 0xC3, 0xF8, 0xE0, 0x03, 0xC3, 0xF8, 0xE4, 0x03, 0x35, 0x48, 0x01, 0x68, 0x48, 0x78, 0x32, 0x28, 0x01, 0xD9, 0x32, 0x20, 0x48, 0x70, 0x00, 0x20, 0x0C, 0xE0, 0x00, 0xEB, 0x40, 0x02, 0x0A,
0x44, 0x94, 0x78, 0xC3, 0xF8, 0xE8, 0x43, 0xD4, 0x78, 0xC3, 0xF8, 0xE8, 0x43, 0x12, 0x79, 0xC3, 0xF8, 0xE8, 0x23, 0x40, 0x1C, 0x4A, 0x78, 0x82, 0x42, 0xEF, 0xD8, 0x10, 0xBD, 0x03, 0x01, 0x16, 0x88, 0x49, 0x0D, 0x00, 0x29, 0x48, 0x2A, 0x49,
0x42, 0x68, 0x0A,
0x60, 0xC2, 0x68, 0x4A, 0x60, 0x40, 0x69, 0x88, 0x60, 0x70, 0x47, 0x03, 0x01, 0x16, 0x4C, 0xFC, 0xFF, 0xD0, 0x5F, 0x21, 0x00, 0x9A, 0x49, 0x0D, 0x00, 0x25, 0x48, 0x25, 0x49, 0x02, 0x68, 0x0A,
0x60, 0x82, 0x68, 0x4A, 0x60, 0x00, 0x69, 0x88, 0x60, 0x70, 0x47, 0x03, 0x01, 0x98, 0x01, 0xAC, 0x49, 0x0D, 0x00, 0x70, 0xB5, 0x22, 0x48, 0x06, 0x26, 0x00, 0x25, 0x80, 0x68, 0x21, 0x4C, 0x01, 0x7C, 0x22, 0x29, 0x2E, 0xD0, 0x08, 0xDC, 0x01,
0x29, 0x10, 0xD0, 0x06, 0x29, 0x19, 0xD0, 0x10, 0x29, 0x25, 0xD0, 0x21, 0x29, 0x06, 0xD1, 0x27, 0xE0, 0x28, 0x29, 0x17, 0xD0, 0x2A, 0x29, 0x1B, 0xD0, 0x2B, 0x29, 0x1C, 0xD0, 0x25, 0x60, 0xBD, 0xE8, 0x70, 0x40, 0xD9, 0xE7, 0x90, 0xF8, 0xA9,
0x00, 0x1C, 0xE0, 0xFF, 0xF7, 0xCC, 0xFF, 0x26, 0x60, 0x70, 0xBD, 0xFF, 0xF7, 0xD1, 0xFF, 0x25, 0x60, 0x70, 0xBD, 0x90, 0xF8, 0x39, 0x00, 0x03, 0x28, 0xF7, 0xD1, 0xF2, 0xE7, 0x40, 0x8F, 0x43, 0xF2, 0x06, 0x31, 0x08, 0x42, 0xF1, 0xD0, 0xEC,
0xE7, 0x90, 0xF8, 0x60, 0x00, 0x06, 0xE0, 0x40, 0x6A, 0xE4, 0xE7, 0x90, 0xF8, 0x65, 0x00, 0x01, 0xE0, 0x90, 0xF8, 0x59, 0x00, 0x01, 0x28, 0xE4, 0xD1, 0xDF, 0xE7, 0xCC, 0x07, 0x20, 0x00, 0x20, 0x70, 0x0D, 0x00, 0x68, 0x01, 0x60, 0x00, 0x00,
0x3D, 0x20, 0x00, 0x64, 0x08, 0x64, 0x00, 0x03, 0x01, 0x16, 0x40, 0x4A, 0x0D, 0x00, 0x10, 0xB5, 0xF6, 0x4A, 0xF6, 0x49, 0xF7, 0x48, 0x50, 0xF7, 0x5C, 0xF8, 0xF6, 0x49, 0x08, 0x70, 0x10, 0xBD, 0x03, 0x01, 0x24, 0x52, 0x4A, 0x0D, 0x00, 0xF3,
0x48, 0xF5, 0x49, 0xDC, 0x38, 0xC1, 0x60, 0x01, 0xF5, 0x2C, 0x71, 0x01, 0x61, 0xA1, 0xF5, 0x37, 0x70, 0xF2, 0x49, 0x08, 0x60, 0xF2, 0x49, 0x00, 0xF2, 0x4C, 0x50, 0x08, 0x60, 0x70, 0x47, 0x03, 0x01, 0x2C, 0x72, 0x4A, 0x0D, 0x00, 0xF1, 0x4A,
0x4C, 0xFC, 0xFF, 0xCB, 0x60, 0x21, 0x00, 0xF1, 0x4B, 0x01, 0x28, 0x03, 0xD0, 0x02, 0x28, 0x09, 0xD1, 0x18, 0x88, 0x06, 0xE0, 0x10, 0x68, 0x18, 0x80, 0x48, 0x78, 0x01, 0x28, 0x03, 0xD0, 0x43, 0xF6, 0x02, 0x10, 0x10, 0x60, 0x70, 0x47, 0x43,
0xF6, 0x0E, 0x10, 0xFA, 0xE7, 0x03, 0x01, 0x48, 0x9A, 0x4A, 0x0D, 0x00, 0x10, 0xB5, 0xE6, 0x4A, 0xE8, 0x4C, 0x08, 0x32, 0x40, 0xF6, 0xA2, 0x63, 0x01, 0x28, 0x03, 0xD0, 0x02, 0x28, 0x12, 0xD1, 0x20, 0x88, 0x0F, 0xE0, 0x10, 0x68, 0x80, 0xB2,
0x20, 0x80, 0x49, 0x78, 0x01, 0x29, 0x0B, 0xD0, 0xD8, 0x49, 0xDC, 0x39, 0xC9, 0x88, 0xC1, 0xF5, 0x80, 0x51, 0x89, 0xB2, 0x61, 0xF3, 0x1F, 0x10, 0x40, 0xF0, 0x08, 0x00, 0x10, 0x60, 0x10, 0xBD, 0x10, 0x68, 0x63, 0xF3, 0x1F, 0x10, 0xF7, 0xE7,
0x03, 0x01, 0x72, 0xDE, 0x4A, 0x0D, 0x00, 0x70, 0xB5, 0xCE, 0x4A, 0xCF, 0x4B, 0xD1, 0x4D, 0x12, 0x78, 0xDC, 0x3B, 0x02, 0xEB, 0x82, 0x02, 0x03, 0xEB, 0xC2, 0x02, 0xD1, 0x4C, 0x52, 0x7D, 0x50, 0x3D, 0x94, 0x3C, 0xD2, 0x4E, 0x4F, 0xF4, 0xC0,
0x03, 0x01, 0x28, 0x09, 0xD0, 0x02, 0x28, 0x06, 0xD1, 0x48, 0x78, 0x01, 0x28, 0x1A, 0xD0, 0x30, 0x88, 0x20, 0x60, 0x01, 0x20, 0x58, 0x60, 0x70, 0xBD, 0x20, 0x68, 0x80, 0xB2, 0x30, 0x80, 0xD3, 0xF8, 0x04, 0x61, 0x2E, 0x60, 0x49, 0x78, 0x01,
0x29, 0x09, 0xD0, 0x48, 0xF2, 0xFF, 0x01, 0x08, 0x40, 0x02, 0xF0, 0x7F, 0x01, 0x40, 0xEA, 0x01, 0x20, 0x20, 0x60, 0x00, 0x20, 0x58, 0x60, 0xC3, 0xF8, 0x04, 0x21, 0x70, 0xBD, 0x28, 0x68, 0xC3, 0xF8, 0x04, 0x01, 0x70, 0xBD, 0x03, 0x01, 0x3A,
0x4C, 0x4B, 0x0D, 0x00, 0xB7, 0x4B, 0xBE, 0x49, 0x50, 0x3B, 0xBE, 0x4A, 0x01, 0x28, 0x06, 0xD0, 0x02, 0x28, 0x4C, 0xFC, 0xFF, 0xC6, 0x61, 0x21, 0x00, 0x03, 0xD1, 0x58, 0x68, 0x08, 0x60, 0x98, 0x68, 0x10, 0x60, 0x70, 0x47, 0x08, 0x68, 0x58,
0x60, 0x10, 0x68, 0x98, 0x60, 0x08, 0x68, 0x20, 0xF0, 0x3F, 0x00, 0x40, 0xF0, 0x48, 0x00, 0x08, 0x60, 0x10, 0x68, 0x20, 0xF0, 0x02, 0x00, 0xEF, 0xE7, 0x03, 0x01, 0x26, 0x82, 0x4B, 0x0D, 0x00, 0xAA, 0x4A, 0x4F, 0xF4, 0xC0, 0x01, 0x50, 0x3A,
0x01, 0x28, 0x04, 0xD0, 0x02, 0x28, 0x01, 0xD1, 0xD0, 0x68, 0x88, 0x61, 0x70, 0x47, 0x88, 0x69, 0xD0, 0x60, 0x88, 0x69, 0x20, 0xF0, 0x02, 0x00, 0xF7, 0xE7, 0x03, 0x01, 0x46, 0xA4, 0x4B, 0x0D, 0x00, 0x4F, 0xF4, 0xC0, 0x02, 0x01, 0x28, 0x06,
0xD0, 0x02, 0x28, 0x14, 0xD1, 0xD2, 0xF8, 0xFC, 0x02, 0x20, 0xF0, 0x0C, 0x00, 0x0D, 0xE0, 0x48, 0x78, 0x01, 0x28, 0x0D, 0xD0, 0x00, 0x28, 0x0A,
0xD1, 0x88, 0x78, 0x01, 0x28, 0x08, 0xD0, 0xD2, 0xF8, 0xFC, 0x02, 0x20, 0xF0, 0x0C, 0x00, 0x40, 0xF0, 0x08, 0x00, 0xC2, 0xF8, 0xFC, 0x02, 0x70, 0x47, 0xD2, 0xF8, 0xFC, 0x02, 0x40, 0xF0, 0x0C, 0x00, 0xF7, 0xE7, 0x03, 0x01, 0x32, 0xE6, 0x4B,
0x0D, 0x00, 0x91, 0x4B, 0x93, 0x4A, 0x50, 0x3B, 0x18, 0x32, 0x01, 0x28, 0x03, 0xD0, 0x02, 0x28, 0x0A,
0xD1, 0x18, 0x69, 0x07, 0xE0, 0x10, 0x68, 0x18, 0x61, 0x48, 0x78, 0x01, 0x28, 0x10, 0x68, 0x03, 0xD0, 0x40, 0xF4, 0x80, 0x40, 0x10, 0x60, 0x70, 0x47, 0x20, 0xF4, 0x80, 0x40, 0xFA, 0xE7, 0x03, 0x01, 0x32, 0x14, 0x4C, 0x0D, 0x00, 0x85, 0x4B,
0x8E, 0x4A, 0x50, 0x3B, 0x01, 0x28, 0x03, 0xD0, 0x02, 0x28, 0x0A,
0xD1, 0x58, 0x69, 0x07, 0xE0, 0x10, 0x68, 0x58, 0x61, 0x48, 0x78, 0x01, 0x28, 0x10, 0x68, 0x03, 0xD0, 0x40, 0xF4, 0x80, 0x60, 0x10, 0x60, 0x70, 0x4C, 0xFC, 0xFF, 0xC1, 0x62, 0x21, 0x00, 0x47, 0x4F, 0xF6, 0xFF, 0x31, 0x08, 0x40, 0xF9, 0xE7,
0x03, 0x01, 0x08, 0x42, 0x4C, 0x0D, 0x00, 0x08, 0x46, 0x70, 0x47, 0x03, 0x01, 0x26, 0x46, 0x4C, 0x0D, 0x00, 0x81, 0x49, 0x78, 0x4A, 0x1C, 0x39, 0x50, 0x3A, 0x01, 0x28, 0x04, 0xD0, 0x02, 0x28, 0x01, 0xD1, 0x90, 0x69, 0x08, 0x60, 0x70, 0x47,
0x08, 0x68, 0x90, 0x61, 0x08, 0x68, 0x00, 0xF0, 0x03, 0x00, 0xF7, 0xE7, 0x03, 0x01, 0x98, 0x01, 0x68, 0x4C, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x79, 0x4F, 0x78, 0x4E, 0x01, 0x28, 0x18, 0xD0, 0x02, 0x28, 0x14, 0xD1, 0x30, 0x68, 0x39, 0x68,
0x20, 0xF4, 0x00, 0x70, 0x21, 0xF4, 0x00, 0x51, 0x40, 0xF4, 0x80, 0x74, 0x41, 0xF4, 0x80, 0x45, 0x34, 0x60, 0x3D, 0x60, 0x32, 0x20, 0x6F, 0xF7, 0x9A, 0xFC, 0x24, 0xF4, 0x80, 0x70, 0x25, 0xF4, 0x80, 0x41, 0x30, 0x60, 0x39, 0x60, 0xBD, 0xE8,
0xF0, 0x81, 0x48, 0x78, 0x01, 0x28, 0x16, 0xD0, 0x30, 0x68, 0x39, 0x68, 0x20, 0xF4, 0x00, 0x70, 0x40, 0xF4, 0x80, 0x70, 0x21, 0xF4, 0x00, 0x51, 0x41, 0xF4, 0x80, 0x41, 0x30, 0x60, 0x39, 0x60, 0x40, 0xF4, 0x00, 0x70, 0x41, 0xF4, 0x00, 0x51,
0x30, 0x60, 0x39, 0x60, 0xBD, 0xE8, 0xF0, 0x41, 0xC8, 0x20, 0x6F, 0xF7, 0x78, 0xBC, 0x4F, 0xF4, 0x80, 0x40, 0x38, 0x60, 0x30, 0x68, 0x4F, 0xF6, 0xFF, 0x41, 0x08, 0x40, 0x30, 0x60, 0x4F, 0xF4, 0xC0, 0x40, 0x38, 0x60, 0x30, 0x68, 0x80, 0xB2,
0x40, 0xF4, 0x40, 0x70, 0x30, 0x60, 0xD2, 0xE7, 0x03, 0x01, 0x5C, 0xFC, 0x4C, 0x0D, 0x00, 0x10, 0xB5, 0x4B, 0x4C, 0x4D, 0x4A, 0x4D, 0x4B, 0x50, 0x3C, 0x7C, 0x3A, 0x60, 0x33, 0x01, 0x28, 0x09, 0xD0, 0x02, 0x28, 0x06, 0xD1, 0x48, 0x78, 0x01,
0x28, 0x03, 0x4C, 0xFC, 0xFF, 0xBC, 0x63, 0x21, 0x00, 0xD1, 0xE0, 0x69, 0x10, 0x60, 0x20, 0x6A, 0x18, 0x60, 0x10, 0xBD, 0x10, 0x68, 0xE0, 0x61, 0x18, 0x68, 0x20, 0x62, 0x48, 0x78, 0x01, 0x28, 0xF7, 0xD1, 0x3A, 0x48, 0x3B, 0x4C, 0xC9, 0x78,
0x00, 0x78, 0xDC, 0x3C, 0x00, 0xEB, 0x80, 0x00, 0x04, 0xEB, 0xC0, 0x00, 0x29, 0xB1, 0x01, 0x29, 0x03, 0xD0, 0x80, 0x8C, 0x10, 0x60, 0x00, 0x20, 0xE6, 0xE7, 0xC0, 0x8A, 0xFA, 0xE7, 0x03, 0x01, 0x16, 0x54, 0x4D, 0x0D, 0x00, 0x10, 0xB5, 0x74,
0xF7, 0xDA, 0xFC, 0x4E, 0xF7, 0xE7, 0xF9, 0xBD, 0xE8, 0x10, 0x40, 0x48, 0xF7, 0x05, 0xB9, 0x03, 0x01, 0xAA, 0x03, 0x66, 0x4D, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0xEC, 0xA0, 0x9A, 0xF8, 0x04, 0x00, 0xC0, 0x07, 0x72, 0xD0, 0xDF,
0xF8, 0xA8, 0x90, 0x00, 0x26, 0x6F, 0xF0, 0x3E, 0x08, 0xA9, 0xF1, 0xDC, 0x09, 0x06, 0xEB, 0x86, 0x01, 0x09, 0xEB, 0xC1, 0x07, 0xB8, 0x69, 0x00, 0x68, 0x55, 0xF7, 0xC9, 0xF9, 0x05, 0x46, 0xF8, 0x69, 0x00, 0x68, 0x55, 0xF7, 0xC4, 0xF9, 0x04,
0x46, 0x45, 0x45, 0x02, 0xDA, 0x45, 0x46, 0x40, 0x46, 0x03, 0xE0, 0x3F, 0x2D, 0x05, 0xDD, 0x3F, 0x25, 0x28, 0x46, 0x55, 0xF7, 0xBE, 0xF9, 0xB9, 0x69, 0x08, 0x60, 0x40, 0x46, 0x84, 0x42, 0x01, 0xDA, 0x44, 0x46, 0x03, 0xE0, 0x3F, 0x2C, 0x05,
0xDD, 0x3F, 0x24, 0x20, 0x46, 0x55, 0xF7, 0xB1, 0xF9, 0xF9, 0x69, 0x08, 0x60, 0xBB, 0x6A, 0x4A, 0x46, 0x18, 0x68, 0x5E, 0xB1, 0x00, 0xF4, 0x7C, 0x61, 0x4F, 0xEA, 0x91, 0x11, 0x8F, 0x06, 0x5F, 0xD4, 0x09, 0x29, 0x5D, 0xD9, 0x00, 0x2D, 0x05,
0xDB, 0x2F, 0x46, 0x04, 0xE0, 0x00, 0xF4, 0xFC, 0x41, 0x49, 0x0A,
0xF3, 0xE7, 0x6F, 0x42, 0x2F, 0x2F, 0x06, 0xDC, 0x00, 0x4C, 0xFC, 0xFF, 0xB7, 0x64, 0x21, 0x00, 0x2C, 0x01, 0xDB, 0x27, 0x46, 0x00, 0xE0, 0x67, 0x42, 0x2F, 0x2F, 0x01, 0xDD, 0x09, 0x21, 0x43, 0xE0, 0x00, 0x2D, 0x22, 0xDB, 0x2F, 0x46, 0x21,
0xE0, 0x4C, 0x1E, 0x20, 0x00, 0x3C, 0x11, 0x20, 0x00, 0xB0, 0x6C, 0x0D, 0x00, 0x2C, 0x2B, 0x20, 0x00, 0xA0, 0x69, 0x0D, 0x00, 0x00, 0x2B, 0x20, 0x00, 0x34, 0x2B, 0x20, 0x00, 0xAC, 0x06, 0x41, 0x00, 0x5C, 0x10, 0x20, 0x00, 0x5A, 0x10, 0x20,
0x00, 0x58, 0x10, 0x20, 0x00, 0xDC, 0x04, 0x60, 0x00, 0x64, 0x06, 0x60, 0x00, 0xE8, 0x07, 0x41, 0x00, 0xFC, 0x04, 0x41, 0x00, 0x0C, 0x0D, 0x20, 0x00, 0x42, 0xE0, 0x6F, 0x42, 0x1F, 0x2F, 0x06, 0xDC, 0x00, 0x2C, 0x01, 0xDB, 0x27, 0x46, 0x00,
0xE0, 0x67, 0x42, 0x1F, 0x2F, 0x03, 0xDD, 0x0A,
0x29, 0x12, 0xD9, 0x0A,
0x21, 0x10, 0xE0, 0x00, 0x2D, 0x00, 0xDA, 0x6D, 0x42, 0x0F, 0x2D, 0x04, 0xDC, 0x00, 0x2C, 0x00, 0xDA, 0x64, 0x42, 0x0F, 0x2C, 0x03, 0xDD, 0x0B, 0x29, 0x04, 0xD9, 0x0B, 0x21, 0x02, 0xE0, 0x0C, 0x29, 0x00, 0xD9, 0x0C, 0x21, 0x26, 0xB3, 0x20,
0xF4, 0x7C, 0x64, 0x88, 0x01, 0x20, 0x43, 0x18, 0x60, 0x76, 0x1C, 0x05, 0x2E, 0xFF, 0xF4, 0x6A, 0xAF, 0x9A, 0xF8, 0x04, 0x00, 0x80, 0x07, 0x15, 0xD5, 0x00, 0x20, 0x91, 0x6E, 0x0B, 0x68, 0x00, 0xEB, 0x80, 0x01, 0x02, 0xEB, 0xC1, 0x01, 0x8C,
0x69, 0x23, 0x60, 0xD3, 0x6E, 0x1B, 0x68, 0xCC, 0x69, 0x23, 0x60, 0x68, 0xB1, 0x93, 0x6F, 0x1B, 0x68, 0x89, 0x6A, 0x0B, 0x60, 0x40, 0x1C, 0xC0, 0xB2, 0x05, 0x28, 0xEA, 0xD3, 0xBD, 0xE8, 0xF0, 0x87, 0x20, 0xF4, 0xFC, 0x44, 0x48, 0x02, 0xD9,
0xE7, 0x91, 0x6F, 0x0B, 0x68, 0x09, 0x68, 0xC3, 0xF3, 0x85, 0x13, 0x01, 0xF0, 0x3F, 0x01, 0x4C, 0xFC, 0xFF, 0xB2, 0x65, 0x21, 0x00, 0x5B, 0x02, 0x43, 0xEA, 0xC1, 0x03, 0x91, 0x6A, 0x0C, 0x68, 0x23, 0x43, 0xE6, 0xE7, 0x03, 0x01, 0x9C, 0x01,
0x0C, 0x4F, 0x0D, 0x00, 0x02, 0x46, 0x00, 0x20, 0x11, 0x2A, 0x40, 0xD2, 0xDF, 0xE8, 0x02, 0xF0, 0x09, 0x36, 0x34, 0x2D, 0x2B, 0x29, 0x0B, 0x32, 0x0D, 0x32, 0x34, 0x2B, 0x36, 0x36, 0x39, 0x3B, 0x3D, 0x00, 0xA1, 0xF7, 0xD7, 0xB8, 0xA0, 0xF7,
0xF4, 0xBF, 0x1A, 0x4A, 0x13, 0x68, 0x6F, 0xF3, 0x0F, 0x03, 0x42, 0xF8, 0x90, 0x39, 0x05, 0x29, 0x0F, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x0F, 0x03, 0x0F, 0x0F, 0x0F, 0x00, 0x02, 0xF1, 0x7C, 0x02, 0x51, 0x69, 0x48, 0xF6, 0x88, 0x03, 0x41, 0xEA,
0x03, 0x01, 0x51, 0x61, 0x4F, 0xF0, 0xBB, 0x31, 0x11, 0x60, 0x70, 0x47, 0x0E, 0x49, 0xD1, 0x67, 0x70, 0x47, 0xA1, 0xF7, 0x5C, 0xB8, 0xA0, 0xF7, 0xE6, 0xBF, 0x09, 0xB1, 0xA1, 0xF7, 0x17, 0xB8, 0xA1, 0xF7, 0x35, 0xB8, 0x02, 0x20, 0x70, 0x47,
0xA0, 0xF7, 0xEA, 0xBF, 0x08, 0x46, 0xA1, 0xF7, 0x65, 0xB8, 0xA1, 0xF7, 0xE2, 0xB8, 0xA1, 0xF7, 0x00, 0xB9, 0xA0, 0xF7, 0xFA, 0xBF, 0x01, 0x20, 0x70, 0x47, 0x00, 0x00, 0x90, 0x00, 0x32, 0x00, 0xB9, 0xB9, 0xBB, 0xB9, 0x03, 0x01, 0x60, 0xA4,
0x4F, 0x0D, 0x00, 0x67, 0x4B, 0x30, 0xB5, 0x18, 0x44, 0x83, 0x07, 0x0A,
0xD5, 0x50, 0xF8, 0x02, 0x3C, 0x89, 0x1E, 0x1B, 0x0C, 0x80, 0x1C, 0x13, 0x70, 0x1B, 0x0A,
0x53, 0x70, 0x89, 0xB2, 0x02, 0xF1, 0x02, 0x02, 0x4F, 0xEA, 0x91, 0x04, 0x0D, 0xE0, 0x50, 0xF8, 0x04, 0x3B, 0x13, 0x70, 0x4F, 0xEA, 0x13, 0x25, 0x55, 0x70, 0x4F, 0xEA, 0x13, 0x45, 0x95, 0x70, 0x4F, 0xEA, 0x13, 0x63, 0xD3, 0x70, 0x02, 0xF1,
0x04, 0x02, 0x23, 0x00, 0xA4, 0xF1, 0x4C, 0xFC, 0xFF, 0xAD, 0x66, 0x21, 0x00, 0x01, 0x04, 0xA4, 0xB2, 0xEC, 0xD1, 0x89, 0x07, 0x03, 0xD5, 0x00, 0x68, 0x10, 0x70, 0x00, 0x0A,
0x50, 0x70, 0x01, 0x20, 0x30, 0xBD, 0x03, 0x01, 0x7C, 0x00, 0x50, 0x0D, 0x00, 0x0E, 0xB5, 0x51, 0x48, 0x00, 0x68, 0x51, 0x49, 0x00, 0xF0, 0x04, 0x00, 0x09, 0x78, 0x08, 0x43, 0x31, 0xD1, 0x30, 0xF7, 0xBF, 0xF8, 0x00, 0x28, 0x2D, 0xD0, 0x6A,
0x46, 0x0A,
0x21, 0x00, 0x20, 0xFF, 0xF7, 0xC0, 0xFF, 0x9D, 0xF8, 0x00, 0x00, 0x50, 0x28, 0x24, 0xD1, 0x9D, 0xF8, 0x01, 0x00, 0x4F, 0x28, 0x20, 0xD1, 0x9D, 0xF8, 0x02, 0x00, 0x00, 0x28, 0x1C, 0xD0, 0x9D, 0xF8, 0x03, 0x00, 0x00, 0x28, 0x18, 0xD0, 0x9D,
0xF8, 0x04, 0x00, 0x78, 0xB9, 0x9D, 0xF8, 0x05, 0x00, 0x60, 0xB9, 0x9D, 0xF8, 0x06, 0x00, 0x48, 0xB9, 0x9D, 0xF8, 0x07, 0x00, 0x30, 0xB9, 0x9D, 0xF8, 0x08, 0x00, 0x18, 0xB9, 0x9D, 0xF8, 0x09, 0x00, 0x00, 0x28, 0x05, 0xD0, 0x39, 0x48, 0x01,
0x99, 0x01, 0x60, 0xBD, 0xF8, 0x08, 0x10, 0x81, 0x80, 0x0E, 0xBD, 0x03, 0x01, 0x5E, 0x78, 0x50, 0x0D, 0x00, 0x10, 0xB5, 0x04, 0x28, 0x27, 0xD1, 0x36, 0x49, 0x34, 0x48, 0x08, 0x60, 0x36, 0x49, 0x35, 0x48, 0x08, 0x60, 0x37, 0x48, 0x35, 0x49,
0x01, 0x60, 0x37, 0x49, 0x36, 0x48, 0x08, 0x60, 0x38, 0x49, 0x36, 0x48, 0xC1, 0xF8, 0xD4, 0x00, 0x4F, 0xF4, 0x48, 0x10, 0x00, 0x69, 0x01, 0x28, 0x04, 0xD1, 0x34, 0x48, 0x01, 0x68, 0x41, 0xF0, 0x01, 0x01, 0x01, 0x60, 0x91, 0xF7, 0x68, 0xFF,
0x33, 0x49, 0x31, 0x48, 0x88, 0x60, 0x32, 0x49, 0x4F, 0xF0, 0xFF, 0x30, 0x88, 0x60, 0xFF, 0xF7, 0x9C, 0xFF, 0x31, 0x49, 0x30, 0x48, 0x48, 0x60, 0x00, 0x20, 0x10, 0xBD, 0x03, 0x01, 0x0C, 0xD2, 0x50, 0x4C, 0xFC, 0xFF, 0xA8, 0x67, 0x21, 0x00,
0x0D, 0x00, 0x04, 0x21, 0x08, 0x20, 0xA1, 0xF7, 0x7B, 0xB8, 0x03, 0x01, 0x0C, 0xDA, 0x50, 0x0D, 0x00, 0x03, 0x21, 0x08, 0x20, 0xA1, 0xF7, 0x77, 0xB8, 0x03, 0x01, 0xCE, 0x01, 0xE2, 0x50, 0x0D, 0x00, 0x10, 0xB5, 0xAF, 0xF2, 0x6F, 0x00, 0x2A,
0x49, 0x23, 0x4C, 0x08, 0x60, 0x2A, 0x48, 0xA0, 0x64, 0xFF, 0xF7, 0xAE, 0xFC, 0xFE, 0xF7, 0x91, 0xFE, 0xFD, 0xF7, 0x97, 0xFE, 0x27, 0x48, 0x00, 0x68, 0x00, 0x07, 0x02, 0xD5, 0x26, 0x49, 0x0A,
0x20, 0x08, 0x70, 0xFE, 0xF7, 0x4F, 0xFB, 0xFC, 0xF7, 0x46, 0xFB, 0xFD, 0xF7, 0xD5, 0xFD, 0xFC, 0xF7, 0xA0, 0xFD, 0x21, 0x48, 0xE0, 0x67, 0x01, 0xF0, 0x22, 0xF9, 0x00, 0xF0, 0x91, 0xFE, 0x01, 0xF0, 0x51, 0xF9, 0xAF, 0xF2, 0x55, 0x01, 0x1D,
0x48, 0x41, 0x60, 0xAF, 0xF2, 0x65, 0x01, 0x81, 0x60, 0xBD, 0xE8, 0x10, 0x40, 0x45, 0xF7, 0xF2, 0xBE, 0x00, 0x00, 0x7E, 0x11, 0x65, 0x00, 0x80, 0x01, 0x32, 0x00, 0x4E, 0x05, 0x20, 0x00, 0x10, 0x1C, 0x20, 0x00, 0x49, 0x53, 0x0D, 0x00, 0x3C,
0x23, 0x20, 0x00, 0x11, 0x54, 0x0D, 0x00, 0x78, 0x23, 0x20, 0x00, 0x15, 0x54, 0x0D, 0x00, 0xA4, 0x25, 0x20, 0x00, 0xC5, 0x51, 0x0D, 0x00, 0xC8, 0x31, 0x20, 0x00, 0x6D, 0x2A, 0x0D, 0x00, 0x38, 0x50, 0x20, 0x00, 0x28, 0x15, 0x32, 0x00, 0xBD,
0x5F, 0x0D, 0x00, 0xA0, 0xC6, 0x20, 0x00, 0x80, 0x7F, 0x20, 0x00, 0xC1, 0x29, 0x0D, 0x00, 0x9C, 0x5A, 0x20, 0x00, 0xB4, 0x37, 0x20, 0x00, 0x19, 0x54, 0x0D, 0x00, 0xE4, 0x1D, 0x20, 0x00, 0xD8, 0x22, 0x20, 0x00, 0x2D, 0x04, 0x0D, 0x00, 0x04,
0x74, 0x0D, 0x00, 0x03, 0x01, 0x0C, 0xAC, 0x51, 0x0D, 0x00, 0x62, 0x49, 0x00, 0x7B, 0x08, 0x70, 0x70, 0x47, 0x03, 0x4C, 0xFC, 0xFF, 0xA3, 0x68, 0x21, 0x00, 0x01, 0x14, 0xB4, 0x51, 0x0D, 0x00, 0x61, 0x49, 0x09, 0x78, 0x00, 0x29, 0x02, 0xD0,
0x60, 0x49, 0xC8, 0x73, 0x88, 0x73, 0x70, 0x47, 0x03, 0x01, 0x88, 0x03, 0xC4, 0x51, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x06, 0x46, 0x00, 0x20, 0x08, 0x60, 0x5D, 0x48, 0x0C, 0x46, 0x15, 0x46, 0x1F, 0x46, 0x05, 0x2B, 0x70, 0xD0, 0x06, 0xDC,
0x01, 0x2F, 0x6D, 0xD0, 0x02, 0x2F, 0x6B, 0xD0, 0x03, 0x2F, 0x69, 0xD1, 0x08, 0xE0, 0x06, 0x2F, 0x66, 0xD0, 0x55, 0x49, 0x80, 0x31, 0x08, 0x2F, 0x29, 0xD0, 0x3F, 0x2F, 0x60, 0xD1, 0x53, 0xE0, 0x71, 0x2D, 0x14, 0xD0, 0x06, 0xDC, 0x03, 0x2D,
0x09, 0xD0, 0x3F, 0x2D, 0x0B, 0xD0, 0x70, 0x2D, 0x56, 0xD1, 0x10, 0xE0, 0x72, 0x2D, 0x12, 0xD0, 0x73, 0x2D, 0x51, 0xD1, 0x13, 0xE0, 0x01, 0x6A, 0x21, 0x60, 0x40, 0x6A, 0x7B, 0xE0, 0x81, 0x6C, 0x21, 0x60, 0xC0, 0x6C, 0x77, 0xE0, 0x81, 0x6A,
0x21, 0x60, 0xC0, 0x6A, 0x73, 0xE0, 0x01, 0x6B, 0x21, 0x60, 0x40, 0x6B, 0x6F, 0xE0, 0x81, 0x6B, 0x21, 0x60, 0xC0, 0x6B, 0x6B, 0xE0, 0x01, 0x6C, 0x21, 0x60, 0x40, 0x6C, 0x67, 0xE0, 0x1E, 0x2D, 0x0E, 0xD0, 0x06, 0xDC, 0x13, 0x2D, 0x13, 0xD0,
0x17, 0x2D, 0x21, 0xD0, 0x1C, 0x2D, 0x62, 0xD1, 0x1A, 0xE0, 0x1F, 0x2D, 0x08, 0xD0, 0x20, 0x2D, 0x0E, 0xD0, 0x21, 0x2D, 0x5B, 0xD1, 0x0F, 0xE0, 0x01, 0x69, 0x21, 0x60, 0x40, 0x69, 0x52, 0xE0, 0x81, 0x69, 0x21, 0x60, 0xC0, 0x69, 0x4E, 0xE0,
0x01, 0x6D, 0x21, 0x60, 0x40, 0x6D, 0x4A, 0xE0, 0x81, 0x6D, 0x21, 0x60, 0xC0, 0x6D, 0x46, 0xE0, 0x01, 0x6E, 0x21, 0x60, 0x40, 0x6E, 0x42, 0xE0, 0x88, 0x68, 0x20, 0x60, 0xC8, 0x68, 0x3E, 0xE0, 0x08, 0x69, 0x20, 0x60, 0x48, 0x4C, 0xFC, 0xFF,
0x9E, 0x69, 0x21, 0x00, 0x69, 0x3A, 0xE0, 0x25, 0x2D, 0x31, 0xD0, 0x09, 0xDC, 0x14, 0x2D, 0x13, 0xD0, 0x19, 0x2D, 0x15, 0xD0, 0x1A, 0x2D, 0x17, 0xD0, 0x24, 0x2D, 0x33, 0xD1, 0x23, 0xE0, 0x31, 0xE0, 0x85, 0x2D, 0x28, 0xD0, 0xE9, 0x2D, 0x13,
0xD0, 0xA5, 0xF5, 0x80, 0x71, 0x45, 0x39, 0x29, 0xD1, 0x81, 0x68, 0x21, 0x60, 0xC0, 0x68, 0x21, 0xE0, 0x01, 0x68, 0x21, 0x60, 0x40, 0x68, 0x1D, 0xE0, 0x81, 0x6F, 0x21, 0x60, 0xC0, 0x6F, 0x19, 0xE0, 0x08, 0x68, 0x20, 0x60, 0x48, 0x68, 0x15,
0xE0, 0x31, 0x7B, 0x06, 0xF1, 0x09, 0x00, 0x01, 0x29, 0x14, 0xD1, 0x40, 0x68, 0x00, 0xF0, 0x04, 0x00, 0xFF, 0xF7, 0x59, 0xFF, 0x0B, 0xE0, 0x81, 0x6E, 0x21, 0x60, 0xC0, 0x6E, 0x06, 0xE0, 0x01, 0x6F, 0x21, 0x60, 0x40, 0x6F, 0x02, 0xE0, 0x88,
0x69, 0x20, 0x60, 0xC8, 0x69, 0x60, 0x60, 0x20, 0x68, 0x00, 0x28, 0x07, 0xD1, 0x3B, 0x46, 0x2A, 0x46, 0x21, 0x46, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x41, 0xF7, 0x13, 0xBD, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0x3E, 0x70, 0x0D, 0x00, 0xE8,
0x6F, 0x0D, 0x00, 0x6C, 0x73, 0x0D, 0x00, 0xE0, 0x6E, 0x0D, 0x00, 0x03, 0x01, 0xCC, 0x01, 0x48, 0x53, 0x0D, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x01, 0x29, 0x02, 0xD0, 0x02, 0x29, 0x2C, 0xD0, 0x50, 0xE0, 0xA4, 0xF5, 0xE0, 0x40, 0x0A,
0x38, 0x20, 0xD1, 0x88, 0xF7, 0x41, 0xFF, 0x26, 0x49, 0x26, 0x48, 0x44, 0xF7, 0xDF, 0xF8, 0x24, 0x4D, 0x28, 0x88, 0x27, 0x28, 0x05, 0xD0, 0x24, 0x4C, 0x04, 0xEB, 0x80, 0x00, 0x00, 0x68, 0x48, 0xB9, 0x03, 0xE0, 0x1F, 0x48, 0xFD, 0xF7, 0x1C,
0xFA, 0x0A,
0xE0, 0x5E, 0x21, 0x40, 0xF2, 0xCD, 0x40, 0x70, 0xF7, 0x89, 0xF8, 0x28, 0x88, 0x04, 0xEB, 0x4C, 0xFC, 0xFF, 0x99, 0x6A, 0x21, 0x00, 0x80, 0x00, 0x01, 0x68, 0x18, 0x48, 0x88, 0x47, 0x00, 0x24, 0x2B, 0xE0, 0xA4, 0xF5, 0xE0, 0x40, 0x06, 0x38,
0x27, 0xD1, 0xFE, 0xF7, 0x2E, 0xFB, 0x24, 0xE0, 0x16, 0x48, 0x00, 0x68, 0x00, 0x07, 0x1E, 0xD5, 0x15, 0x4D, 0x95, 0xF8, 0x30, 0x00, 0xD0, 0xB1, 0x01, 0x20, 0x45, 0xF8, 0xC8, 0x0F, 0x6E, 0xF7, 0x18, 0xFF, 0x6E, 0xF7, 0x9B, 0xFF, 0x06, 0x46,
0x0F, 0x48, 0xCC, 0x30, 0x6A, 0xF7, 0xEC, 0xFA, 0x30, 0x46, 0x6E, 0xF7, 0x97, 0xFF, 0x6E, 0xF7, 0x87, 0xFD, 0x68, 0x68, 0x4F, 0xF4, 0xC8, 0x61, 0x40, 0x08, 0x6A, 0xF7, 0x8F, 0xFA, 0x40, 0x00, 0x68, 0x60, 0x8E, 0xF7, 0xEC, 0xFE, 0x83, 0xF7,
0xCE, 0xFF, 0x20, 0x46, 0x70, 0xBD, 0x58, 0x23, 0x20, 0x00, 0xC4, 0x5D, 0x20, 0x00, 0x88, 0x9E, 0x08, 0x00, 0xE4, 0x1D, 0x20, 0x00, 0xB0, 0x59, 0x20, 0x00, 0x03, 0x01, 0x08, 0x10, 0x54, 0x0D, 0x00, 0x00, 0x20, 0x70, 0x47, 0x03, 0x01, 0x08,
0x14, 0x54, 0x0D, 0x00, 0x00, 0x20, 0x70, 0x47, 0x03, 0x01, 0x90, 0x02, 0x18, 0x54, 0x0D, 0x00, 0x10, 0xB5, 0x56, 0xF7, 0xDF, 0xFF, 0x30, 0x49, 0x00, 0x20, 0xB7, 0xF7, 0x36, 0xFC, 0x2F, 0x49, 0x25, 0x20, 0xB7, 0xF7, 0x32, 0xFC, 0x2E, 0x49,
0x04, 0x20, 0xB7, 0xF7, 0x2E, 0xFC, 0x2D, 0x49, 0x24, 0x20, 0xB7, 0xF7, 0x2A, 0xFC, 0x2C, 0x49, 0x09, 0x20, 0xB7, 0xF7, 0x26, 0xFC, 0x2B, 0x49, 0x15, 0x20, 0xB7, 0xF7, 0x22, 0xFC, 0x2A, 0x49, 0x26, 0x20, 0xB7, 0xF7, 0x1E, 0xFC, 0x29, 0x49,
0x07, 0x20, 0xB7, 0xF7, 0x1A, 0xFC, 0x28, 0x49, 0x06, 0x20, 0xB7, 0xF7, 0x16, 0xFC, 0x27, 0x49, 0x1A, 0x20, 0xB7, 0xF7, 0x12, 0xFC, 0x27, 0x48, 0x25, 0x49, 0x01, 0x60, 0x26, 0x49, 0x41, 0x60, 0x26, 0x4C, 0xFC, 0xFF, 0x94, 0x6B, 0x21, 0x00,
0x49, 0x1B, 0x20, 0x08, 0x70, 0x26, 0x49, 0x04, 0x20, 0x08, 0x60, 0x25, 0x48, 0xCF, 0x21, 0x01, 0x60, 0x4F, 0xF0, 0xE6, 0x01, 0x41, 0x60, 0x81, 0x60, 0x4F, 0xF0, 0x17, 0x01, 0xC1, 0x60, 0x4F, 0xF0, 0xE8, 0x01, 0x81, 0x64, 0x4F, 0xF0, 0xF2,
0x01, 0x81, 0x61, 0x4F, 0xF0, 0xCE, 0x01, 0xC1, 0x61, 0x4F, 0xF0, 0xD0, 0x01, 0x01, 0x62, 0x4F, 0xF0, 0xC8, 0x01, 0x40, 0xF8, 0x90, 0x1C, 0x4F, 0xF0, 0xEC, 0x01, 0x40, 0xF8, 0x8C, 0x1C, 0x4F, 0xF0, 0x01, 0x01, 0x40, 0xF8, 0x88, 0x1C, 0x4F,
0xF0, 0x40, 0x02, 0x02, 0x61, 0x41, 0x61, 0x13, 0x49, 0x4F, 0xF0, 0x93, 0x00, 0x08, 0x60, 0x56, 0xF7, 0x93, 0xFF, 0x00, 0x20, 0x10, 0xBD, 0x2F, 0x5F, 0x0D, 0x00, 0xB5, 0x5E, 0x0D, 0x00, 0x99, 0x57, 0x0D, 0x00, 0x61, 0x56, 0x0D, 0x00, 0xB1,
0x5B, 0x0D, 0x00, 0x05, 0x5D, 0x0D, 0x00, 0xE9, 0x5D, 0x0D, 0x00, 0x25, 0x55, 0x0D, 0x00, 0xBD, 0x55, 0x0D, 0x00, 0x4D, 0x56, 0x0D, 0x00, 0xD0, 0x02, 0x21, 0x00, 0x18, 0x04, 0x21, 0x00, 0x84, 0x6F, 0x0D, 0x00, 0xF7, 0x03, 0x21, 0x00, 0x7C,
0x37, 0x42, 0x00, 0x94, 0x01, 0x42, 0x00, 0x4C, 0x0D, 0x42, 0x00, 0x03, 0x01, 0x9C, 0x01, 0x24, 0x55, 0x0D, 0x00, 0xF0, 0xB5, 0x3D, 0x48, 0x42, 0x89, 0x3D, 0x48, 0x01, 0x68, 0x43, 0x68, 0xC9, 0xB2, 0xDB, 0xB2, 0x80, 0x68, 0x01, 0xEB, 0x03,
0x21, 0x01, 0xEB, 0x00, 0x40, 0x4F, 0xEA, 0x80, 0x21, 0x38, 0x48, 0x00, 0x68, 0x38, 0x48, 0x00, 0x68, 0x38, 0x48, 0x00, 0x68, 0x02, 0xF5, 0x7A, 0x42, 0x4F, 0xF4, 0x7A, 0x70, 0x02, 0xFB, 0x00, 0xF2, 0x35, 0x48, 0x00, 0x68, 0x10, 0x1A, 0x00,
0xD5, 0x40, 0x42, 0x33, 0x4A, 0x34, 0x4B, 0x33, 0x4D, 0x17, 0x68, 0x4C, 0xFC, 0xFF, 0x8F, 0x6C, 0x21, 0x00, 0x32, 0x4A, 0x1C, 0x1D, 0x08, 0x3D, 0x1E, 0x1F, 0x70, 0x3A, 0xB8, 0x42, 0x13, 0xD2, 0x01, 0xF5, 0x80, 0x50, 0xC0, 0xF3, 0x4E, 0x30,
0xC1, 0xEB, 0x40, 0x31, 0xC7, 0xB2, 0xC1, 0xF3, 0x0D, 0x01, 0x1F, 0x60, 0x00, 0x0A,
0x20, 0x60, 0xC8, 0xB2, 0x28, 0x60, 0x08, 0x0A,
0x30, 0x60, 0x10, 0x68, 0x40, 0xF0, 0x30, 0x00, 0x09, 0xE0, 0xFF, 0x20, 0x18, 0x60, 0x3F, 0x20, 0x20, 0x60, 0x00, 0x20, 0x28, 0x60, 0x30, 0x60, 0x10, 0x68, 0x20, 0xF0, 0x30, 0x00, 0x10, 0x60, 0x00, 0x20, 0xF0, 0xBD, 0x03, 0x01, 0x94, 0x01,
0xBC, 0x55, 0x0D, 0x00, 0x1F, 0x48, 0x10, 0xB5, 0x00, 0x68, 0x00, 0x24, 0x00, 0x28, 0x26, 0xDA, 0x1D, 0x49, 0x88, 0x42, 0x12, 0xD0, 0x89, 0x1C, 0x88, 0x42, 0x10, 0xD1, 0xB6, 0xF7, 0x9F, 0xFB, 0x1A, 0x49, 0x40, 0xB2, 0x91, 0xF9, 0x00, 0x10,
0x88, 0x42, 0x01, 0xDC, 0x01, 0x24, 0x06, 0xE0, 0x17, 0x4A, 0x92, 0xF9, 0x00, 0x20, 0x11, 0x44, 0x81, 0x42, 0x00, 0xDA, 0x02, 0x24, 0x10, 0x48, 0x70, 0x38, 0x01, 0x2C, 0x02, 0xD0, 0x02, 0x2C, 0x09, 0xD1, 0x04, 0xE0, 0x01, 0x68, 0x21, 0xF0,
0x0E, 0x01, 0x89, 0x1D, 0x02, 0xE0, 0x01, 0x68, 0x21, 0xF0, 0x0E, 0x01, 0x01, 0x60, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x00, 0x38, 0x05, 0x21, 0x00, 0x48, 0x01, 0x42, 0x00, 0x48, 0x37, 0x42, 0x00, 0x4C, 0x37, 0x42, 0x00, 0x50, 0x37, 0x42, 0x00,
0x98, 0x02, 0x21, 0x00, 0xF8, 0x03, 0x21, 0x00, 0xA8, 0x0D, 0x42, 0x00, 0xFC, 0x03, 0x21, 0x00, 0x01, 0x00, 0x00, 0x80, 0xF4, 0x03, 0x21, 0x00, 0xF5, 0x03, 0x21, 0x00, 0x03, 0x01, 0x18, 0x4C, 0x56, 0x0D, 0x00, 0x03, 0x48, 0x01, 0x68, 0x21,
0xF0, 0x30, 0x01, 0x01, 0x60, 0x00, 0x20, 0x4C, 0xFC, 0xFF, 0x8A, 0x6D, 0x21, 0x00, 0x70, 0x47, 0x00, 0x00, 0x38, 0x0D, 0x42, 0x00, 0x03, 0x01, 0x28, 0x60, 0x56, 0x0D, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x06, 0x48, 0x00, 0x68, 0x01, 0x20, 0x43,
0xF7, 0x5E, 0xFD, 0x04, 0x48, 0x08, 0x38, 0x00, 0x68, 0xB7, 0xF7, 0x68, 0xFD, 0x20, 0x60, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xD4, 0x0B, 0x42, 0x00, 0x03, 0x01, 0x98, 0x02, 0x84, 0x56, 0x0D, 0x00, 0x10, 0xB5, 0x4F, 0xF4, 0x84, 0x00, 0x41,
0x69, 0x01, 0xF0, 0x40, 0x04, 0x1D, 0x21, 0xC0, 0xF8, 0xC0, 0x10, 0x03, 0x21, 0xC0, 0xF8, 0x38, 0x11, 0xD0, 0xF8, 0x3C, 0x11, 0xC9, 0x07, 0xFB, 0xD1, 0xC0, 0xF8, 0x38, 0x11, 0x0A,
0x22, 0x2B, 0x49, 0x00, 0x20, 0xB5, 0xF7, 0xBA, 0xFF, 0x0A,
0x22, 0x29, 0x49, 0x01, 0x20, 0xB5, 0xF7, 0xB5, 0xFF, 0x0A,
0x22, 0x28, 0x49, 0x02, 0x20, 0xB5, 0xF7, 0xB0, 0xFF, 0x0A,
0x22, 0x26, 0x49, 0x03, 0x20, 0xB5, 0xF7, 0xAB, 0xFF, 0x0A,
0x22, 0x25, 0x49, 0x04, 0x20, 0xB5, 0xF7, 0xA6, 0xFF, 0x0A,
0x22, 0x23, 0x49, 0x05, 0x20, 0xB5, 0xF7, 0xA1, 0xFF, 0x0A,
0x22, 0x22, 0x49, 0x06, 0x20, 0xB5, 0xF7, 0x9C, 0xFF, 0x4F, 0xF0, 0x0A,
0x02, 0x5C, 0xB1, 0x1F, 0x49, 0x07, 0x20, 0xB5, 0xF7, 0x95, 0xFF, 0x0A,
0x22, 0x1E, 0x49, 0x08, 0x20, 0xB5, 0xF7, 0x90, 0xFF, 0x0A,
0x22, 0x1C, 0x49, 0x0B, 0xE0, 0x1C, 0x49, 0x07, 0x20, 0xB5, 0xF7, 0x89, 0xFF, 0x0A,
0x22, 0x1B, 0x49, 0x08, 0x20, 0xB5, 0xF7, 0x84, 0xFF, 0x17, 0x49, 0x0A,
0x22, 0x0A,
0x39, 0x0B, 0x20, 0xB5, 0xF7, 0x7E, 0xFF, 0x0A,
0x22, 0x16, 0x49, 0x09, 0x20, 0xB5, 0xF7, 0x79, 0xFF, 0x0A,
0x22, 0x15, 0x49, 0x10, 0x46, 0xB5, 0xF7, 0x74, 0xFF, 0x3C, 0x22, 0x13, 0x49, 0x10, 0x20, 0x4C, 0xFC, 0xFF, 0x85, 0x6E, 0x21, 0x00, 0xB5, 0xF7, 0x6F, 0xFF, 0x3C, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0x11, 0x49, 0x18, 0x20, 0xB5, 0xF7, 0x68, 0xBF,
0x00, 0x00, 0x82, 0x01, 0x21, 0x00, 0x8C, 0x01, 0x21, 0x00, 0x96, 0x01, 0x21, 0x00, 0xA0, 0x01, 0x21, 0x00, 0xAA, 0x01, 0x21, 0x00, 0xB4, 0x01, 0x21, 0x00, 0xBE, 0x01, 0x21, 0x00, 0xDC, 0x01, 0x21, 0x00, 0xE6, 0x01, 0x21, 0x00, 0x92, 0x6F,
0x0D, 0x00, 0xC8, 0x01, 0x21, 0x00, 0xD2, 0x01, 0x21, 0x00, 0xF0, 0x01, 0x21, 0x00, 0xFA, 0x01, 0x21, 0x00, 0x04, 0x02, 0x21, 0x00, 0x40, 0x02, 0x21, 0x00, 0x03, 0x01, 0x9C, 0x08, 0x98, 0x57, 0x0D, 0x00, 0x2D, 0xE9, 0xF7, 0x4F, 0x07, 0x46,
0xDF, 0x48, 0xDF, 0xF8, 0x74, 0xA3, 0x00, 0x68, 0x07, 0xF5, 0x7A, 0x44, 0x00, 0xF0, 0x03, 0x02, 0x4F, 0xF4, 0x7A, 0x70, 0x44, 0x43, 0xDA, 0x48, 0xDF, 0xF8, 0x6C, 0x93, 0x52, 0x1C, 0x05, 0x68, 0x04, 0xEB, 0x55, 0x00, 0xB0, 0xFB, 0xF5, 0xF6,
0x06, 0xFB, 0x05, 0xF0, 0x80, 0x46, 0xC9, 0xF8, 0x00, 0x00, 0xD5, 0x48, 0x05, 0xFB, 0x02, 0xF1, 0x90, 0xF8, 0x00, 0xB0, 0x01, 0xFB, 0x0B, 0xF0, 0x4F, 0xF7, 0xF6, 0xFD, 0x00, 0x22, 0xD1, 0x4B, 0x55, 0xF7, 0xA5, 0xF9, 0x00, 0x22, 0xD0, 0x4B,
0x4F, 0xF7, 0x69, 0xFC, 0x00, 0x22, 0xCF, 0x4B, 0x55, 0xF7, 0x99, 0xFA, 0x4F, 0xF7, 0xBB, 0xFD, 0xCE, 0x49, 0x08, 0x80, 0xCE, 0x48, 0x80, 0x68, 0x4F, 0xF4, 0x80, 0x42, 0xC0, 0xF3, 0x13, 0x00, 0xA5, 0xFB, 0x00, 0x01, 0x80, 0x18, 0x41, 0xF1,
0x00, 0x01, 0xC2, 0x0B, 0x42, 0xEA, 0x41, 0x42, 0xC8, 0x49, 0x4F, 0xF4, 0x48, 0x10, 0x4A, 0x60, 0x00, 0x68, 0x4F, 0xF0, 0x01, 0x0C, 0xC0, 0xF3, 0x02, 0x10, 0x02, 0x23, 0x70, 0xB3, 0x01, 0x28, 0x2F, 0x4C, 0xFC, 0xFF, 0x80, 0x6F, 0x21, 0x00,
0xD0, 0x02, 0x28, 0x2F, 0xD0, 0x03, 0x28, 0x2F, 0xD0, 0x04, 0x28, 0x2F, 0xD0, 0x05, 0x28, 0x2F, 0xD0, 0x06, 0x28, 0x2F, 0xD0, 0xC1, 0xF8, 0x00, 0xC0, 0x08, 0x68, 0xBC, 0x4B, 0x04, 0xFB, 0x00, 0xF1, 0x01, 0xEB, 0x52, 0x01, 0xB1, 0xFB, 0xF2,
0xF1, 0x02, 0xFB, 0x01, 0xF2, 0x02, 0xEB, 0x50, 0x02, 0xB2, 0xFB, 0xF0, 0xF0, 0x18, 0x60, 0x00, 0x1B, 0x00, 0xD5, 0x40, 0x42, 0xB4, 0x4A, 0x12, 0x68, 0x90, 0x42, 0x1C, 0xD8, 0xB8, 0xEB, 0x04, 0x00, 0x00, 0xD5, 0x40, 0x42, 0x90, 0x42, 0x16,
0xD8, 0x00, 0x20, 0xB1, 0x42, 0x11, 0xD9, 0x18, 0x60, 0x11, 0xE0, 0xFF, 0xE7, 0x0B, 0x60, 0xDB, 0xE7, 0x03, 0x20, 0x08, 0xE0, 0x04, 0x20, 0x06, 0xE0, 0x06, 0x20, 0x04, 0xE0, 0x08, 0x20, 0x02, 0xE0, 0x10, 0x20, 0x00, 0xE0, 0x18, 0x20, 0x08,
0x60, 0xCE, 0xE7, 0xC9, 0xF8, 0x00, 0x00, 0xDD, 0xE9, 0x01, 0x06, 0x4F, 0xF7, 0x88, 0xFD, 0xA3, 0x4B, 0x00, 0x22, 0x4F, 0xF7, 0xDD, 0xFD, 0x89, 0x46, 0x80, 0x46, 0x07, 0xF5, 0x7A, 0x40, 0x4F, 0xF4, 0x7A, 0x71, 0x48, 0x43, 0x4F, 0xF7, 0x7B,
0xFD, 0x4B, 0x46, 0x42, 0x46, 0x01, 0x2E, 0x0B, 0xD0, 0x55, 0xF7, 0x24, 0xFA, 0x4F, 0xF7, 0x46, 0xFD, 0x01, 0x46, 0x99, 0x48, 0x02, 0x68, 0x99, 0x48, 0x94, 0x42, 0x04, 0xD3, 0x1E, 0x22, 0x2D, 0xE0, 0x55, 0xF7, 0x1C, 0xF9, 0xF2, 0xE7, 0x96,
0x4A, 0x12, 0x68, 0x94, 0x42, 0x01, 0xD3, 0x23, 0x22, 0x24, 0xE0, 0x94, 0x4A, 0x12, 0x68, 0x94, 0x42, 0x01, 0xD3, 0x28, 0x22, 0x1E, 0xE0, 0x92, 0x4A, 0x12, 0x68, 0x94, 0x42, 0x01, 0xD3, 0x2D, 0x22, 0x18, 0xE0, 0x90, 0x4A, 0x12, 0x68, 0x94,
0x42, 0x01, 0xD3, 0x46, 0x22, 0x12, 0xE0, 0x8E, 0x4A, 0x12, 0x68, 0x4C, 0xFC, 0xFF, 0x7B, 0x70, 0x21, 0x00, 0x94, 0x42, 0x01, 0xD3, 0x50, 0x22, 0x0C, 0xE0, 0x8C, 0x4A, 0x12, 0x68, 0x94, 0x42, 0x01, 0xD3, 0x5A, 0x22, 0x06, 0xE0, 0x8A, 0x4A,
0x12, 0x68, 0x94, 0x42, 0x01, 0xD3, 0x64, 0x22, 0x00, 0xE0, 0x6E, 0x22, 0x02, 0x60, 0x0A,
0x22, 0xB1, 0xFB, 0xF2, 0xF1, 0x85, 0x4A, 0xD0, 0xF8, 0x00, 0x80, 0x01, 0xFB, 0x08, 0xF1, 0x12, 0x78, 0x88, 0x00, 0x00, 0x21, 0x91, 0x46, 0xA0, 0xF7, 0x43, 0xFA, 0x81, 0x4B, 0x6A, 0x00, 0x1B, 0x68, 0x5F, 0x00, 0x38, 0x18, 0x41, 0xF1, 0x00,
0x03, 0xD9, 0x03, 0x41, 0xEA, 0x50, 0x41, 0xC0, 0x03, 0x40, 0x19, 0x41, 0xF1, 0x00, 0x01, 0x00, 0x23, 0x4F, 0xF7, 0x20, 0xFB, 0xA0, 0xFB, 0x05, 0x36, 0x01, 0xFB, 0x05, 0x61, 0x00, 0x22, 0x00, 0xFB, 0x02, 0x11, 0x9A, 0x0B, 0x42, 0xEA, 0x81,
0x42, 0x89, 0x0B, 0xD5, 0x1B, 0x61, 0xF1, 0x00, 0x06, 0x72, 0x49, 0x08, 0x60, 0x72, 0x48, 0x31, 0x46, 0x05, 0x60, 0x28, 0x46, 0x4F, 0xF7, 0x1A, 0xFD, 0x00, 0x22, 0x5A, 0x4B, 0x55, 0xF7, 0xB6, 0xF8, 0x00, 0x22, 0x59, 0x4B, 0x4F, 0xF7, 0x7A,
0xFB, 0x4F, 0xF7, 0xD0, 0xFC, 0x6B, 0x49, 0x00, 0xFB, 0x0B, 0xF0, 0x40, 0x1C, 0x40, 0x08, 0x08, 0x60, 0x0A,
0x21, 0xB8, 0xFB, 0xF1, 0xF2, 0x00, 0x23, 0x31, 0x46, 0x28, 0x46, 0x4F, 0xF7, 0xF2, 0xFA, 0x04, 0x27, 0x27, 0xFA, 0x09, 0xF7, 0xFB, 0x17, 0x3A, 0x46, 0x4F, 0xF7, 0xEB, 0xFA, 0x62, 0x49, 0x07, 0x46, 0x08, 0x60, 0x00, 0x1B, 0x00, 0xD5, 0x40,
0x42, 0xDF, 0xF8, 0x80, 0x81, 0x4F, 0xF0, 0x09, 0x0B, 0x81, 0x46, 0x5A, 0x46, 0x88, 0xF8, 0x00, 0xB0, 0x00, 0x23, 0x28, 0x46, 0x31, 0x46, 0x4F, 0xF7, 0xD8, 0xFA, 0x80, 0x08, 0x40, 0xEA, 0x81, 0x70, 0xC0, 0x1B, 0x00, 0x4C, 0xFC, 0xFF, 0x76,
0x71, 0x21, 0x00, 0xD5, 0x40, 0x42, 0x57, 0x49, 0x0C, 0x68, 0xA0, 0x42, 0x21, 0xD2, 0x08, 0x22, 0x88, 0xF8, 0x00, 0x20, 0x00, 0x23, 0x28, 0x46, 0x31, 0x46, 0x4F, 0xF7, 0xC6, 0xFA, 0x80, 0x08, 0x40, 0xEA, 0x81, 0x70, 0xC0, 0x1B, 0x00, 0xD5,
0x40, 0x42, 0xA0, 0x42, 0x11, 0xD2, 0x0A,
0x22, 0x88, 0xF8, 0x00, 0x20, 0x00, 0x23, 0x28, 0x46, 0x31, 0x46, 0x4F, 0xF7, 0xB6, 0xFA, 0x80, 0x08, 0x40, 0xEA, 0x81, 0x70, 0xC0, 0x1B, 0x00, 0xD5, 0x40, 0x42, 0xA0, 0x42, 0x01, 0xD2, 0x88, 0xF8, 0x00, 0xB0, 0x98, 0xF8, 0x00, 0x20, 0x00,
0x23, 0x28, 0x46, 0x31, 0x46, 0x4F, 0xF7, 0xA5, 0xFA, 0x4D, 0x08, 0x4F, 0xEA, 0x30, 0x04, 0x40, 0x48, 0x52, 0x46, 0x00, 0x23, 0x04, 0x60, 0x3F, 0x48, 0x00, 0x19, 0x45, 0xF1, 0x00, 0x01, 0x4F, 0xF7, 0x98, 0xFA, 0x3D, 0x49, 0x1F, 0x28, 0x08,
0x60, 0x01, 0xD9, 0x1F, 0x20, 0x08, 0x60, 0x02, 0x46, 0x00, 0x23, 0x20, 0x46, 0x29, 0x46, 0x4F, 0xF7, 0x8C, 0xFA, 0x04, 0x46, 0x38, 0x48, 0x00, 0x21, 0xC9, 0x05, 0x04, 0x60, 0x4F, 0xEA, 0xC9, 0x50, 0x65, 0x08, 0x41, 0xEA, 0x59, 0x21, 0x40,
0x19, 0x41, 0xF1, 0x00, 0x01, 0x22, 0x46, 0x00, 0x23, 0x4F, 0xF7, 0x7B, 0xFA, 0x31, 0x49, 0x22, 0x46, 0x00, 0x23, 0x08, 0x60, 0x4F, 0xF0, 0xE0, 0x50, 0x00, 0x21, 0x28, 0x18, 0x41, 0xF1, 0x25, 0x01, 0x4F, 0xF7, 0x6F, 0xFA, 0x2C, 0x49, 0x22,
0x46, 0x00, 0x23, 0x08, 0x60, 0x4F, 0xF0, 0xA8, 0x40, 0x00, 0x21, 0x28, 0x18, 0x41, 0xF1, 0x6F, 0x01, 0x4F, 0xF7, 0x63, 0xFA, 0x27, 0x49, 0x08, 0x60, 0x01, 0x20, 0xBD, 0xE8, 0xFE, 0x8F, 0x00, 0x80, 0xBB, 0x00, 0x18, 0x37, 0x42, 0x00, 0xF8,
0x00, 0x21, 0x00, 0xD0, 0x02, 0x21, 0x00, 0x4C, 0xFC, 0xFF, 0x71, 0x72, 0x21, 0x00, 0x90, 0x02, 0x21, 0x00, 0x80, 0x84, 0x1E, 0x41, 0x80, 0x84, 0x2E, 0x41, 0x00, 0x00, 0xF0, 0x3F, 0x94, 0x02, 0x21, 0x00, 0x00, 0x10, 0x32, 0x00, 0x9C, 0x6F,
0x0D, 0x00, 0x84, 0x6F, 0x0D, 0x00, 0xF8, 0x03, 0x21, 0x00, 0x00, 0x40, 0x8F, 0x40, 0xA0, 0x02, 0x21, 0x00, 0xDC, 0x02, 0x21, 0x00, 0xA4, 0x02, 0x21, 0x00, 0xA8, 0x02, 0x21, 0x00, 0xAC, 0x02, 0x21, 0x00, 0xB0, 0x02, 0x21, 0x00, 0xB4, 0x02,
0x21, 0x00, 0xB8, 0x02, 0x21, 0x00, 0xBC, 0x02, 0x21, 0x00, 0x91, 0x02, 0x21, 0x00, 0xC0, 0x02, 0x21, 0x00, 0xC4, 0x02, 0x21, 0x00, 0xD4, 0x02, 0x21, 0x00, 0xE4, 0x02, 0x21, 0x00, 0x98, 0x02, 0x21, 0x00, 0x92, 0x02, 0x21, 0x00, 0xC8, 0x02,
0x21, 0x00, 0x9C, 0x02, 0x21, 0x00, 0x00, 0xC0, 0x5D, 0x00, 0xE0, 0x02, 0x21, 0x00, 0xCC, 0x02, 0x21, 0x00, 0xD8, 0x02, 0x21, 0x00, 0xE8, 0x02, 0x21, 0x00, 0xEC, 0x02, 0x21, 0x00, 0x03, 0x01, 0xD8, 0x02, 0xB0, 0x5B, 0x0D, 0x00, 0x2D, 0xE9,
0xF8, 0x4F, 0x49, 0x48, 0x04, 0x68, 0x49, 0x48, 0x00, 0x21, 0x4A, 0x1E, 0x00, 0x78, 0x00, 0x90, 0x02, 0xEB, 0x40, 0x06, 0x47, 0x48, 0x4F, 0xF4, 0x7A, 0x75, 0x4F, 0xF0, 0x01, 0x09, 0x40, 0x89, 0xDF, 0xF8, 0x14, 0xB1, 0x00, 0xF5, 0x7A, 0x40,
0x00, 0xFB, 0x05, 0xF8, 0x43, 0x48, 0x07, 0x78, 0x43, 0x48, 0xD0, 0xF8, 0x00, 0xA0, 0x6E, 0xE0, 0x00, 0x98, 0x76, 0x1E, 0x84, 0x42, 0x01, 0xDB, 0x00, 0x20, 0x04, 0xE0, 0x3F, 0x48, 0x00, 0x78, 0x84, 0x42, 0x01, 0xDC, 0x01, 0x20, 0x81, 0x46,
0x3D, 0x4A, 0x01, 0x21, 0x11, 0x60, 0x34, 0x48, 0x04, 0x60, 0xDF, 0xF8, 0xCC, 0xC0, 0xAC, 0xF1, 0x08, 0x0C, 0xDC, 0xF8, 0x00, 0x30, 0x43, 0xF0, 0x40, 0x4C, 0xFC, 0xFF, 0x6C, 0x73, 0x21, 0x00, 0x03, 0xCC, 0xF8, 0x00, 0x30, 0xDB, 0xF8, 0x00,
0x30, 0x43, 0xF0, 0x40, 0x03, 0xCB, 0xF8, 0x00, 0x30, 0x10, 0x1F, 0x01, 0x60, 0x31, 0x49, 0x2C, 0x39, 0x08, 0x68, 0x0F, 0x60, 0xC0, 0xF3, 0x08, 0x00, 0x4F, 0xF0, 0x00, 0x0E, 0xC2, 0xF8, 0x00, 0xE0, 0x12, 0x1D, 0x00, 0xE0, 0x6D, 0x1E, 0x13,
0x68, 0xDB, 0x07, 0x01, 0xD1, 0x00, 0x2D, 0xF9, 0xD1, 0x28, 0x4A, 0x08, 0x32, 0x12, 0x68, 0x08, 0x60, 0xDC, 0xF8, 0x00, 0x10, 0x01, 0xF0, 0xBF, 0x01, 0xCC, 0xF8, 0x00, 0x10, 0xDB, 0xF8, 0x00, 0x10, 0x01, 0xF0, 0xBF, 0x01, 0xCB, 0xF8, 0x00,
0x10, 0x20, 0x49, 0x09, 0x1F, 0xC1, 0xF8, 0x00, 0xE0, 0x01, 0x2A, 0x00, 0xDA, 0x01, 0x22, 0x1E, 0x48, 0xD1, 0x17, 0x03, 0x68, 0x10, 0x46, 0xE3, 0xFB, 0x07, 0x01, 0x52, 0x00, 0xD3, 0x17, 0x4F, 0xF7, 0x9F, 0xF9, 0x00, 0xEB, 0x48, 0x01, 0x4F,
0xEA, 0x40, 0x02, 0x91, 0xFB, 0xF2, 0xF1, 0x00, 0xFB, 0x01, 0xF0, 0xB0, 0xEB, 0x08, 0x01, 0x01, 0xD5, 0xA8, 0xEB, 0x00, 0x01, 0xB9, 0xF1, 0x00, 0x0F, 0x01, 0xD0, 0x64, 0x1C, 0x00, 0xE0, 0x64, 0x1E, 0x51, 0x45, 0x03, 0xD2, 0x16, 0xB9, 0x0F,
0x4A, 0x01, 0x20, 0x10, 0x60, 0x51, 0x45, 0x04, 0xD2, 0x1E, 0xB1, 0x0C, 0x48, 0x00, 0x68, 0x00, 0x28, 0x89, 0xD0, 0x01, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x08, 0x08, 0x64, 0x00, 0xF7, 0x03, 0x21, 0x00, 0x38, 0x05, 0x21, 0x00, 0x14, 0x37, 0x42,
0x00, 0xF6, 0x03, 0x21, 0x00, 0x00, 0x04, 0x21, 0x00, 0x80, 0x6F, 0x0D, 0x00, 0x38, 0x34, 0x42, 0x00, 0xD4, 0x02, 0x21, 0x00, 0x04, 0x04, 0x21, 0x00, 0x03, 0x01, 0xE8, 0x01, 0x04, 0x5D, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x2D, 0x48, 0x01,
0x25, 0x00, 0x78, 0x4C, 0xFC, 0xFF, 0x67, 0x74, 0x21, 0x00, 0x02, 0x28, 0x01, 0xD0, 0x01, 0x24, 0x00, 0xE0, 0x00, 0x24, 0x2A, 0x4F, 0x4F, 0xF4, 0x84, 0x06, 0x78, 0x78, 0x07, 0x28, 0x05, 0xD0, 0x71, 0x28, 0x43, 0xD0, 0x00, 0x25, 0x28, 0x46,
0xBD, 0xE8, 0xF0, 0x81, 0xB5, 0xF7, 0xF1, 0xFF, 0x24, 0x49, 0x40, 0xB2, 0x08, 0x70, 0x3C, 0xB9, 0x24, 0x4B, 0x23, 0x4A, 0x19, 0x78, 0xF7, 0x29, 0x50, 0x54, 0x01, 0xD2, 0x49, 0x1C, 0x19, 0x70, 0x97, 0xF9, 0x0E, 0x10, 0x81, 0x42, 0x2A, 0xDC,
0xD6, 0xF8, 0x4C, 0x42, 0x79, 0x89, 0x4F, 0xF4, 0x7A, 0x72, 0x01, 0xF5, 0x7A, 0x41, 0x01, 0xFB, 0x02, 0xF1, 0x1B, 0x4A, 0x13, 0x68, 0x5A, 0x1A, 0x00, 0xD5, 0xCA, 0x1A, 0x19, 0x49, 0x09, 0x68, 0x8A, 0x42, 0x06, 0xD2, 0x18, 0x49, 0x91, 0xF9,
0x00, 0x10, 0x88, 0x42, 0x01, 0xDA, 0xB5, 0xF7, 0xF5, 0xFE, 0x96, 0xF8, 0x38, 0x00, 0x15, 0x49, 0x40, 0x00, 0x40, 0xB2, 0x08, 0x70, 0xA0, 0x42, 0x09, 0xDC, 0x61, 0x42, 0x88, 0x42, 0x06, 0xDB, 0x08, 0x20, 0x78, 0x70, 0x10, 0x48, 0x00, 0x88,
0xB5, 0xF7, 0x3F, 0xFD, 0xBF, 0xE7, 0xB5, 0xF7, 0xE1, 0xFE, 0xBC, 0xE7, 0xD6, 0xF8, 0x38, 0x01, 0x20, 0xF0, 0x03, 0x00, 0xC6, 0xF8, 0x38, 0x01, 0xB5, 0xE7, 0x00, 0x00, 0x8E, 0x00, 0x21, 0x00, 0x38, 0x05, 0x21, 0x00, 0x77, 0x00, 0x21, 0x00,
0x40, 0x04, 0x21, 0x00, 0x90, 0x00, 0x21, 0x00, 0x84, 0x6F, 0x0D, 0x00, 0xA4, 0x6F, 0x0D, 0x00, 0x38, 0x70, 0x0D, 0x00, 0x78, 0x00, 0x21, 0x00, 0xB0, 0x00, 0x21, 0x00, 0x03, 0x01, 0x4C, 0xE8, 0x5D, 0x0D, 0x00, 0x70, 0xB5, 0x10, 0x48, 0x01,
0x25, 0x01, 0x68, 0x21, 0xF0, 0x10, 0x01, 0x01, 0x60, 0x4F, 0xF4, 0x84, 0x04, 0xD4, 0xF8, 0xC0, 0x00, 0x40, 0xF0, 0x10, 0x00, 0x4C, 0xFC, 0xFF, 0x62, 0x75, 0x21, 0x00, 0xC4, 0xF8, 0xC0, 0x00, 0x26, 0x03, 0x30, 0x46, 0x00, 0x21, 0x5A, 0xF7,
0x52, 0xF9, 0x30, 0x46, 0x00, 0x21, 0x5A, 0xF7, 0x18, 0xF9, 0x60, 0x69, 0x40, 0xF0, 0x02, 0x00, 0x60, 0x61, 0x00, 0x20, 0xB5, 0xF7, 0xD5, 0xFD, 0x28, 0x46, 0x70, 0xBD, 0x00, 0x00, 0x1C, 0x37, 0x42, 0x00, 0x03, 0x01, 0x1E, 0x30, 0x5E, 0x0D,
0x00, 0x1C, 0x48, 0x40, 0x78, 0xFF, 0x28, 0x04, 0xD0, 0x1B, 0x48, 0x00, 0x78, 0x18, 0xB1, 0x00, 0x20, 0x70, 0x47, 0x02, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x03, 0x01, 0x1E, 0x4A, 0x5E, 0x0D, 0x00, 0x17, 0x48, 0x00, 0x78, 0x00, 0x28,
0x07, 0xD0, 0xAF, 0xF2, 0x23, 0x01, 0x15, 0x48, 0x41, 0x60, 0x15, 0x49, 0x81, 0x60, 0x45, 0xF7, 0x5A, 0xB8, 0x70, 0x47, 0x03, 0x01, 0x54, 0x64, 0x5E, 0x0D, 0x00, 0x70, 0xB5, 0x4F, 0xF4, 0x48, 0x15, 0xD5, 0xF8, 0xE8, 0x00, 0x00, 0x07, 0x03,
0xD5, 0x4F, 0xF0, 0xFF, 0x30, 0x01, 0x46, 0x70, 0xBD, 0x6E, 0xF7, 0x42, 0xFA, 0x01, 0x46, 0xD5, 0xF8, 0xEC, 0x40, 0xD5, 0xF8, 0xEC, 0x00, 0x84, 0x42, 0xF9, 0xD1, 0x08, 0x46, 0x6E, 0xF7, 0x3C, 0xFA, 0x24, 0xB1, 0x20, 0x46, 0xBD, 0xE8, 0x70,
0x40, 0x42, 0xF7, 0x4A, 0xBE, 0x00, 0x20, 0x01, 0x46, 0x70, 0xBD, 0x38, 0x05, 0x21, 0x00, 0x39, 0x70, 0x0D, 0x00, 0x10, 0x74, 0x0D, 0x00, 0xAD, 0xCB, 0x08, 0x00, 0x03, 0x01, 0x40, 0xB4, 0x5E, 0x0D, 0x00, 0x4F, 0xF4, 0x84, 0x03, 0xD3, 0xF8,
0xCC, 0x11, 0x8A, 0xB2, 0x0A,
0x49, 0x08, 0x80, 0x0A,
0x49, 0x09, 0x88, 0x88, 0x42, 0x01, 0xD3, 0x49, 0x1E, 0x88, 0xB2, 0x00, 0x21, 0xC3, 0xF8, 0xD0, 0x11, 0xC3, 0xF8, 0xD8, 0x11, 0x82, 0x42, 0x03, 0xD0, 0xC3, 0xF8, 0xCC, 0x01, 0xC3, 0x4C, 0xFC, 0xFF, 0x5D, 0x76, 0x21, 0x00, 0xF8, 0xD4, 0x01,
0x01, 0x20, 0x70, 0x47, 0xAA, 0x6F, 0x0D, 0x00, 0xB8, 0x00, 0x21, 0x00, 0x03, 0x01, 0x42, 0xF0, 0x5E, 0x0D, 0x00, 0x14, 0x4A, 0x01, 0x78, 0x11, 0x80, 0x40, 0x78, 0x41, 0xEA, 0x00, 0x20, 0x12, 0x49, 0x10, 0x80, 0x09, 0x88, 0x88, 0x42, 0x00,
0xD9, 0x11, 0x80, 0x4F, 0xF4, 0x84, 0x00, 0x40, 0x69, 0x80, 0x07, 0x0C, 0xD4, 0x0E, 0x48, 0x00, 0x78, 0x30, 0xB1, 0x0D, 0x48, 0x00, 0x68, 0x18, 0xB1, 0x0D, 0x48, 0x40, 0x78, 0x00, 0x28, 0x02, 0xD1, 0x10, 0x88, 0xB5, 0xF7, 0x52, 0xBD, 0x70,
0x47, 0x03, 0x01, 0x2E, 0x2E, 0x5F, 0x0D, 0x00, 0x02, 0x46, 0x10, 0xB5, 0x00, 0x20, 0xF8, 0x2A, 0x03, 0xD1, 0x08, 0x46, 0xFF, 0xF7, 0xD9, 0xFF, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xB6, 0x00, 0x21, 0x00, 0xB8, 0x00, 0x21, 0x00, 0x3A, 0x70,
0x0D, 0x00, 0xC8, 0x03, 0x21, 0x00, 0x38, 0x05, 0x21, 0x00, 0x03, 0x01, 0x68, 0x58, 0x5F, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x14, 0x4E, 0x07, 0x46, 0x30, 0x78, 0x00, 0x28, 0x22, 0xD0, 0x13, 0x48, 0x04, 0x88, 0x4F, 0xF4, 0x84, 0x00, 0x41,
0x69, 0x11, 0x4D, 0x89, 0x07, 0x01, 0xD5, 0x00, 0x24, 0x10, 0xE0, 0x40, 0x69, 0xC0, 0x07, 0x0D, 0xD0, 0x64, 0xB1, 0x28, 0x78, 0x50, 0xB1, 0xB6, 0xF7, 0xC0, 0xF8, 0x38, 0x44, 0x41, 0x08, 0x28, 0x78, 0x84, 0x42, 0x03, 0xD2, 0x72, 0x78, 0x91,
0x42, 0x00, 0xD2, 0x04, 0x46, 0x68, 0x88, 0x84, 0x42, 0x04, 0xD0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xB5, 0xF7, 0x12, 0xBD, 0xBD, 0xE8, 0xF0, 0x81, 0x3A, 0x70, 0x0D, 0x00, 0xB6, 0x00, 0x21, 0x00, 0xA8, 0x6F, 0x0D, 0x00, 0x03, 0x01, 0x20,
0xBC, 0x5F, 0x0D, 0x00, 0x04, 0x28, 0x03, 0xD0, 0x4C, 0xFC, 0xFF, 0x58, 0x77, 0x21, 0x00, 0x03, 0x28, 0x07, 0xD3, 0x56, 0xF7, 0x1D, 0xBA, 0x4F, 0xF4, 0x48, 0x11, 0x4F, 0xF4, 0x00, 0x50, 0xC8, 0x65, 0xF7, 0xE7, 0x70, 0x47, 0x00, 0x00, 0x03,
0x01, 0x72, 0xD8, 0x5F, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x24, 0x48, 0x00, 0x68, 0xC0, 0x07, 0x2E, 0xD0, 0x23, 0x48, 0x01, 0x68, 0x41, 0xF0, 0x01, 0x01, 0x01, 0x60, 0x21, 0x4F, 0x7C, 0x3F, 0x38, 0x68, 0x40, 0xF0, 0x80, 0x00, 0x38, 0x60,
0x1F, 0x4E, 0x01, 0x20, 0x30, 0x60, 0x3D, 0xF7, 0x26, 0xFF, 0x3D, 0x68, 0x25, 0xF0, 0x80, 0x00, 0x38, 0x60, 0x19, 0x48, 0x74, 0x38, 0x01, 0x68, 0x41, 0xF0, 0x20, 0x01, 0x01, 0x60, 0x01, 0x68, 0x21, 0xF0, 0x20, 0x01, 0x01, 0x60, 0x00, 0x24,
0x04, 0xE0, 0x30, 0x20, 0x8D, 0xF7, 0xA3, 0xFB, 0x04, 0xF1, 0x01, 0x04, 0x30, 0x68, 0x80, 0x07, 0x01, 0xD4, 0x32, 0x2C, 0xF5, 0xD3, 0x45, 0xF0, 0x80, 0x00, 0x38, 0x60, 0x00, 0x20, 0x30, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x03, 0x01, 0x42, 0x46,
0x60, 0x0D, 0x00, 0x0D, 0x48, 0x00, 0x78, 0x18, 0xB1, 0x0C, 0x48, 0x40, 0x78, 0xFF, 0x28, 0x0B, 0xD1, 0x06, 0x48, 0x00, 0x68, 0xC0, 0x07, 0x07, 0xD0, 0x05, 0x49, 0x01, 0x20, 0x60, 0x39, 0x08, 0x60, 0x03, 0x49, 0x12, 0x20, 0x7C, 0x39, 0x08,
0x60, 0x70, 0x47, 0x00, 0x00, 0x58, 0x18, 0x20, 0x00, 0x7C, 0x08, 0x64, 0x00, 0xB4, 0x04, 0x32, 0x00, 0x3C, 0x70, 0x0D, 0x00, 0x38, 0x05, 0x21, 0x00, 0x03, 0x01, 0xA0, 0x01, 0x84, 0x60, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x0E, 0x46, 0x20,
0x49, 0x17, 0x46, 0x09, 0x78, 0x01, 0x29, 0x07, 0xD1, 0xB0, 0xF5, 0xE1, 0x3F, 0x07, 0xD0, 0x1D, 0x49, 0x0A,
0x68, 0x42, 0xF0, 0x01, 0x02, 0x0A,
0x60, 0x1B, 0x4C, 0xFC, 0xFF, 0x53, 0x78, 0x21, 0x00, 0x49, 0x88, 0x42, 0x01, 0xD8, 0x1B, 0x49, 0x00, 0xE0, 0x1B, 0x49, 0xB1, 0xFB, 0xF0, 0xF4, 0x10, 0x2C, 0x0C, 0xDB, 0xE0, 0x17, 0x04, 0xEB, 0x10, 0x70, 0x05, 0x11, 0x20, 0xF0, 0x0F, 0x00,
0x24, 0x1A, 0x18, 0x68, 0x20, 0xF0, 0x08, 0x00, 0x40, 0xF0, 0x80, 0x00, 0x06, 0xE0, 0x18, 0x68, 0x25, 0x46, 0x20, 0xF0, 0x80, 0x00, 0x00, 0x24, 0x40, 0xF0, 0x08, 0x00, 0x18, 0x60, 0x68, 0x1E, 0xFE, 0x28, 0x04, 0xD9, 0x79, 0x21, 0x4F, 0xF4,
0x0C, 0x70, 0x6F, 0xF7, 0xD8, 0xF9, 0xC5, 0xF5, 0x80, 0x70, 0x38, 0x60, 0x04, 0xEB, 0xD4, 0x70, 0x40, 0x10, 0x21, 0x1A, 0x41, 0xEA, 0x00, 0x10, 0x30, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0x3D, 0x70, 0x0D, 0x00, 0x1C, 0x04, 0x36, 0x00,
0x60, 0xE3, 0x16, 0x00, 0x00, 0x36, 0x6E, 0x01, 0x00, 0x6C, 0xDC, 0x02, 0x03, 0x01, 0x50, 0x20, 0x61, 0x0D, 0x00, 0x70, 0xB5, 0x15, 0x48, 0x00, 0x78, 0x80, 0x07, 0x09, 0xD5, 0x14, 0x48, 0x00, 0x68, 0x14, 0x4C, 0xC0, 0xF3, 0x81, 0x00, 0x02,
0x28, 0x03, 0xD0, 0x6E, 0xF7, 0x6F, 0xFA, 0x20, 0x60, 0x70, 0xBD, 0x10, 0x4D, 0x68, 0x78, 0x68, 0xB1, 0x6E, 0xF7, 0x68, 0xFA, 0x01, 0x46, 0x20, 0x68, 0x2C, 0xF7, 0xE1, 0xFB, 0x69, 0x78, 0x40, 0xF6, 0x35, 0x42, 0x51, 0x43, 0xC0, 0xEB, 0x81,
0x00, 0x00, 0x28, 0xED, 0xDC, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x20, 0x2C, 0xF7, 0x5F, 0xBC, 0x03, 0x01, 0x24, 0x6C, 0x61, 0x0D, 0x00, 0x4F, 0xF4, 0x16, 0x72, 0x05, 0x49, 0x2C, 0xF7, 0x5E, 0xBD, 0x00, 0x00, 0xC2, 0x1C, 0x20, 0x00, 0x24, 0x04,
0x36, 0x00, 0xE4, 0x6F, 0x0D, 0x00, 0xBC, 0x18, 0x20, 0x00, 0x7F, 0x66, 0x0D, 0x00, 0x03, 0x01, 0x70, 0x8C, 0x61, 0x0D, 0x4C, 0xFC, 0xFF, 0x4E, 0x79, 0x21, 0x00, 0x00, 0x16, 0x4B, 0x10, 0xB5, 0x1A, 0x78, 0x00, 0x21, 0x22, 0xB1, 0x00, 0x22,
0x1A, 0x70, 0x14, 0x4B, 0x1A, 0x60, 0x5A, 0x60, 0x13, 0x4A, 0x13, 0x78, 0xDB, 0x07, 0x02, 0xD0, 0x52, 0x78, 0xD2, 0x07, 0x0B, 0xD1, 0x11, 0x4A, 0x12, 0x78, 0x01, 0x2A, 0x01, 0xD1, 0x04, 0x28, 0x04, 0xD0, 0x03, 0x28, 0x06, 0xD0, 0x01, 0x28,
0x04, 0xD0, 0x00, 0xE0, 0x05, 0x20, 0x36, 0xF7, 0xEF, 0xFC, 0x06, 0xE0, 0x01, 0x2A, 0x02, 0xD0, 0x02, 0x2A, 0x03, 0xD1, 0x04, 0xE0, 0x00, 0xF0, 0x0F, 0xF8, 0x01, 0x46, 0x08, 0x46, 0x10, 0xBD, 0x00, 0xF0, 0x3D, 0xF8, 0xF9, 0xE7, 0x00, 0x00,
0xAC, 0x6F, 0x0D, 0x00, 0xD0, 0x1F, 0x20, 0x00, 0x83, 0x06, 0x20, 0x00, 0x82, 0x06, 0x20, 0x00, 0x03, 0x01, 0x6A, 0xF8, 0x61, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x00, 0x25, 0xE3, 0x4F, 0x03, 0x28, 0x2A, 0xD0, 0x04, 0x24, 0x0E, 0x20, 0x36,
0xF7, 0xA5, 0xFC, 0x06, 0x01, 0x13, 0x20, 0x36, 0xF7, 0xA1, 0xFC, 0x00, 0xF0, 0x0F, 0x00, 0x30, 0x43, 0x64, 0x1E, 0x05, 0xEB, 0x90, 0x05, 0x14, 0xF0, 0xFF, 0x04, 0xEF, 0xD1, 0xA8, 0x08, 0x45, 0xF6, 0xC0, 0x51, 0x48, 0x43, 0x80, 0x0A,
0x78, 0x80, 0x02, 0x20, 0x36, 0xF7, 0xB8, 0xFC, 0x04, 0x46, 0x00, 0x20, 0x36, 0xF7, 0xB4, 0xFC, 0x79, 0x88, 0x4C, 0x43, 0x04, 0xEB, 0x84, 0x01, 0x49, 0x00, 0xB1, 0xFB, 0xF0, 0xF0, 0x09, 0x21, 0xB0, 0xFB, 0xF1, 0xF0, 0x28, 0x30, 0xBD, 0xE8,
0xF0, 0x81, 0x78, 0x88, 0xFB, 0xE7, 0x03, 0x01, 0x8E, 0x02, 0x5E, 0x62, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x00, 0x25, 0xC9, 0x4E, 0x03, 0x28, 0x49, 0xD0, 0x04, 0x24, 0x0D, 0x20, 0x36, 0xF7, 0x72, 0xFC, 0x07, 0x01, 0x12, 0x20, 0x36, 0x4C,
0xFC, 0xFF, 0x49, 0x7A, 0x21, 0x00, 0xF7, 0x6E, 0xFC, 0xC0, 0xF3, 0x03, 0x10, 0x38, 0x43, 0x64, 0x1E, 0x05, 0xEB, 0x90, 0x05, 0x14, 0xF0, 0xFF, 0x04, 0xEF, 0xD1, 0xC0, 0x49, 0xA8, 0x08, 0x48, 0x43, 0x80, 0x0A,
0x40, 0xF6, 0xE4, 0x41, 0x48, 0x43, 0xBD, 0x49, 0xB0, 0xFB, 0xF1, 0xF5, 0x0F, 0x20, 0x36, 0xF7, 0x58, 0xFC, 0x04, 0x01, 0x13, 0x20, 0x36, 0xF7, 0x54, 0xFC, 0xC0, 0xF3, 0x03, 0x10, 0x20, 0x43, 0x6F, 0xF4, 0x89, 0x71, 0x11, 0xEB, 0xD0, 0x07,
0x00, 0xD5, 0x00, 0x27, 0x00, 0x20, 0x36, 0xF7, 0x71, 0xFC, 0x84, 0xB2, 0x02, 0x20, 0x36, 0xF7, 0x6D, 0xFC, 0x82, 0xB2, 0x71, 0x69, 0xC7, 0xF1, 0x1B, 0x00, 0x48, 0x43, 0xF1, 0x68, 0x42, 0xF2, 0x10, 0x73, 0x61, 0x43, 0xB1, 0xFB, 0xF3, 0xF3,
0x00, 0xF5, 0x7A, 0x70, 0x43, 0x43, 0x4F, 0xF4, 0x7A, 0x71, 0xB3, 0xFB, 0xF1, 0xF0, 0xB3, 0x68, 0x2B, 0x44, 0x83, 0x42, 0x03, 0xD9, 0x18, 0x1A, 0x02, 0xE0, 0x70, 0x88, 0xA9, 0xE7, 0x00, 0x20, 0x80, 0xB2, 0x4F, 0xF4, 0x7A, 0x73, 0x58, 0x43,
0x33, 0x69, 0x80, 0xB2, 0xB0, 0xFB, 0xF3, 0xF0, 0x70, 0x80, 0x50, 0x43, 0x90, 0xFB, 0xF1, 0xF2, 0x30, 0x6A, 0x60, 0x43, 0xB0, 0xFB, 0xF1, 0xF3, 0xF0, 0x69, 0x00, 0xEB, 0x40, 0x05, 0xC5, 0xEB, 0xC0, 0x10, 0xC3, 0xEB, 0xC0, 0x03, 0xB0, 0x6A,
0x50, 0x43, 0xB0, 0xFB, 0xF1, 0xF5, 0x70, 0x6A, 0x00, 0xEB, 0x40, 0x07, 0xC7, 0xEB, 0xC0, 0x10, 0xC5, 0xEB, 0xC0, 0x00, 0xB5, 0x69, 0x5D, 0x43, 0x45, 0x43, 0xB5, 0xFB, 0xF1, 0xF0, 0x44, 0x43, 0xB4, 0xFB, 0xF1, 0xF0, 0x4F, 0xF4, 0x7A, 0x71,
0x4A, 0x43, 0xB2, 0xFB, 0xF0, 0xF0, 0xF1, 0x6A, 0x08, 0x44, 0x76, 0xE7, 0x03, 0x01, 0x46, 0x68, 0x63, 0x0D, 0x00, 0x8A, 0x48, 0x10, 0x4C, 0xFC, 0xFF, 0x44, 0x7B, 0x21, 0x00, 0xB5, 0x01, 0x78, 0xC9, 0x07, 0x02, 0xD0, 0x40, 0x78, 0xC0, 0x07,
0x17, 0xD1, 0x87, 0x48, 0x00, 0x78, 0x02, 0x28, 0x13, 0xD1, 0x8B, 0x20, 0x36, 0xF7, 0xE8, 0xFB, 0x81, 0x4A, 0xC0, 0xB2, 0x00, 0xF0, 0x0F, 0x01, 0x13, 0x6B, 0x19, 0x44, 0x01, 0xEB, 0x81, 0x01, 0x49, 0x00, 0x91, 0x60, 0x30, 0x21, 0xA1, 0xEB,
0x10, 0x10, 0x00, 0xEB, 0x80, 0x00, 0x40, 0x00, 0xD0, 0x60, 0x10, 0xBD, 0x03, 0x01, 0x28, 0xAA, 0x63, 0x0D, 0x00, 0x78, 0x48, 0x10, 0xB5, 0x40, 0x78, 0x00, 0x28, 0x0B, 0xD0, 0x79, 0x48, 0x01, 0x78, 0x21, 0xF0, 0x02, 0x01, 0x01, 0x70, 0x31,
0xF7, 0x46, 0xF8, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x20, 0x38, 0xF7, 0xE6, 0xB9, 0x10, 0xBD, 0x03, 0x01, 0x1C, 0xCE, 0x63, 0x0D, 0x00, 0x08, 0xB5, 0x01, 0x20, 0x00, 0x23, 0xAF, 0xF2, 0x2D, 0x02, 0x00, 0x90, 0x6C, 0x48, 0x70, 0x49, 0x40, 0x68,
0x32, 0xF7, 0x0C, 0xF9, 0x08, 0xBD, 0x03, 0x01, 0x9E, 0x01, 0xE6, 0x63, 0x0D, 0x00, 0x70, 0xB5, 0x6E, 0x4E, 0x00, 0x24, 0x25, 0x46, 0x30, 0x78, 0x10, 0xB9, 0x36, 0xF7, 0x77, 0xFC, 0x30, 0x70, 0x67, 0x48, 0x00, 0x78, 0x01, 0x28, 0x06, 0xD9,
0x62, 0x49, 0x00, 0x20, 0x48, 0x70, 0x52, 0x20, 0x36, 0xF7, 0xA5, 0xFB, 0x85, 0xB2, 0x63, 0x48, 0xA9, 0x07, 0x0B, 0xD5, 0x01, 0x78, 0x4F, 0xF4, 0x00, 0x34, 0x41, 0xF0, 0x02, 0x01, 0x01, 0x70, 0x61, 0x48, 0x01, 0x68, 0x41, 0xF0, 0x08, 0x01,
0x01, 0x60, 0x09, 0xE0, 0xE9, 0x07, 0x07, 0xD0, 0x01, 0x78, 0x4F, 0xF4, 0x80, 0x34, 0x21, 0xF0, 0x02, 0x01, 0x01, 0x70, 0x31, 0xF7, 0x07, 0xF8, 0x30, 0x78, 0x03, 0x28, 0x02, 0xD0, 0x01, 0x28, 0x0C, 0xD0, 0x0D, 0xE0, 0x00, 0x20, 0x36, 0xF7,
0x4C, 0xFC, 0xFF, 0x3F, 0x7C, 0x21, 0x00, 0x82, 0xFB, 0x85, 0xB2, 0x25, 0x43, 0x01, 0x20, 0x36, 0xF7, 0x7D, 0xFB, 0x80, 0xB2, 0x45, 0xEA, 0x00, 0x24, 0x01, 0xE0, 0xE8, 0xB2, 0x04, 0x43, 0x50, 0x48, 0x31, 0x78, 0x00, 0xEB, 0x81, 0x00, 0x01,
0x68, 0x00, 0x29, 0x03, 0xD0, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x08, 0x47, 0x70, 0xBD, 0x03, 0x01, 0x82, 0x01, 0x80, 0x64, 0x0D, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x0E, 0x46, 0x14, 0x46, 0x49, 0x48, 0x6C, 0xF7, 0xAF, 0xFA, 0x68, 0x00, 0x4F,
0xF4, 0x59, 0x15, 0x28, 0x60, 0x6C, 0x61, 0x00, 0x20, 0x04, 0xE0, 0x31, 0x5C, 0x05, 0xEB, 0x80, 0x02, 0x40, 0x1C, 0x11, 0x63, 0xA0, 0x42, 0xF8, 0xDB, 0xA8, 0x69, 0x00, 0xF4, 0xFE, 0x70, 0xA8, 0x61, 0x01, 0x26, 0xEE, 0x61, 0x3E, 0x48, 0x6C,
0xF7, 0x9E, 0xFA, 0xEC, 0x69, 0xA0, 0x07, 0xFC, 0xD5, 0x3B, 0x48, 0x6C, 0xF7, 0x92, 0xFA, 0x00, 0x20, 0xE8, 0x61, 0x60, 0x07, 0x05, 0xD5, 0x37, 0x48, 0x6C, 0xF7, 0x91, 0xFA, 0x2D, 0x48, 0x46, 0x70, 0x0E, 0xE0, 0x68, 0x68, 0xA9, 0x68, 0xC0,
0xB2, 0xC9, 0xB2, 0x40, 0xEA, 0x01, 0x24, 0x31, 0x48, 0x6C, 0xF7, 0x85, 0xFA, 0xA4, 0xF1, 0x52, 0x00, 0x00, 0x28, 0x01, 0xDD, 0x8D, 0xF7, 0x3B, 0xF9, 0x00, 0x20, 0x70, 0xBD, 0x03, 0x01, 0xBA, 0x01, 0xFE, 0x64, 0x0D, 0x00, 0x70, 0xB5, 0x04,
0x46, 0x0A,
0x38, 0x21, 0x4E, 0x0D, 0x28, 0x0B, 0xD8, 0x08, 0x20, 0x30, 0x70, 0xBF, 0x20, 0x70, 0x70, 0x02, 0x22, 0x31, 0x46, 0x20, 0x20, 0xFF, 0xF7, 0xB2, 0xFF, 0x50, 0x20, 0x6E, 0xF7, 0x54, 0xF8, 0x1A, 0x4D, 0x0A,
0x2C, 0x01, 0xD1, 0x00, 0x20, 0x68, 0x70, 0x34, 0x70, 0x01, 0x22, 0x16, 0x49, 0x20, 0x20, 0xFF, 0xF7, 0xA4, 0xFF, 0x0A,
0x2C, 0x15, 0x4C, 0xFC, 0xFF, 0x3A, 0x7D, 0x21, 0x00, 0xD1, 0x68, 0x78, 0x18, 0x49, 0x00, 0x28, 0x68, 0x68, 0x09, 0xD0, 0x32, 0xF7, 0xAB, 0xF8, 0x68, 0xB9, 0x44, 0xF6, 0x20, 0x62, 0x13, 0x49, 0x68, 0x68, 0x32, 0xF7, 0x6D, 0xF8, 0x06, 0xE0,
0x32, 0xF7, 0xA1, 0xF8, 0x18, 0xB1, 0x0F, 0x49, 0x68, 0x68, 0x32, 0xF7, 0x8F, 0xF8, 0x0A,
0x48, 0x00, 0x78, 0xC1, 0x07, 0x05, 0xD0, 0x40, 0x07, 0x03, 0xD5, 0x41, 0xF2, 0x88, 0x30, 0x6E, 0xF7, 0x27, 0xF8, 0x01, 0x22, 0x03, 0x49, 0x20, 0x20, 0x9B, 0xF7, 0x70, 0xFB, 0x30, 0x78, 0x70, 0xBD, 0x00, 0x00, 0xB0, 0x6F, 0x0D, 0x00, 0x40,
0x42, 0x0F, 0x00, 0x83, 0x06, 0x20, 0x00, 0x82, 0x06, 0x20, 0x00, 0x87, 0x06, 0x20, 0x00, 0x20, 0x74, 0x0D, 0x00, 0x88, 0x06, 0x20, 0x00, 0x70, 0x08, 0x64, 0x00, 0xB0, 0x3C, 0x20, 0x00, 0x50, 0x1F, 0x20, 0x00, 0x03, 0x01, 0xCE, 0x01, 0xB4,
0x65, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0xDF, 0xF8, 0x50, 0x81, 0x81, 0x46, 0x0E, 0x46, 0x98, 0xF8, 0x00, 0x00, 0xF0, 0xB3, 0xE6, 0xB3, 0xC0, 0x07, 0x3A, 0xD0, 0x71, 0x68, 0x06, 0xF1, 0x08, 0x00, 0xA1, 0xF5, 0xE0, 0x42, 0x84, 0x3A, 0x0F,
0xD1, 0x45, 0x88, 0x04, 0x46, 0x05, 0xF1, 0x09, 0x00, 0x6E, 0xF7, 0x9D, 0xFB, 0x07, 0x46, 0x2A, 0x46, 0x21, 0x1D, 0x09, 0x30, 0x6F, 0xF7, 0x8F, 0xF8, 0x3C, 0x46, 0x47, 0xF2, 0x3F, 0x00, 0x1D, 0xE0, 0xA1, 0xF5, 0xE0, 0x42, 0x41, 0x3A, 0x1F,
0xD1, 0x05, 0x46, 0x6C, 0xF7, 0x1E, 0xFE, 0x07, 0x00, 0x1A, 0xD0, 0x28, 0x78, 0x13, 0x28, 0x17, 0xD0, 0x68, 0x78, 0x00, 0x1D, 0x3A, 0xF7, 0x08, 0xFE, 0x69, 0x78, 0xA0, 0xF1, 0x08, 0x04, 0x89, 0x1C, 0x41, 0x80, 0x20, 0xF8, 0x04, 0x7B, 0x6A,
0x78, 0x29, 0x46, 0x92, 0x1C, 0x4C, 0xFC, 0xFF, 0x35, 0x7E, 0x21, 0x00, 0x6F, 0xF7, 0x6F, 0xF8, 0x47, 0xF2, 0x82, 0x00, 0x60, 0x60, 0x59, 0xF7, 0x4E, 0xF9, 0x21, 0x46, 0x2C, 0xF7, 0x43, 0xFB, 0x00, 0xE0, 0x08, 0xE0, 0x98, 0xF8, 0x00, 0x00,
0x40, 0x07, 0x04, 0xD5, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x6E, 0xF7, 0x62, 0xBC, 0x2D, 0x48, 0x41, 0x79, 0x41, 0xB1, 0x40, 0x78, 0x18, 0xB1, 0x6D, 0xF7, 0xDA, 0xFF, 0x2B, 0x49, 0x08, 0x60, 0x01, 0x20, 0x2C, 0xF7, 0xDD, 0xF9, 0x31, 0x46,
0x09, 0xF1, 0xB0, 0x00, 0xBD, 0xE8, 0xF0, 0x47, 0x8A, 0xF7, 0xDA, 0xBE, 0x03, 0x01, 0x7E, 0x7E, 0x66, 0x0D, 0x00, 0xD0, 0xF8, 0xD8, 0x20, 0x05, 0x46, 0x00, 0x21, 0x90, 0x47, 0x21, 0x4F, 0x23, 0x4C, 0x05, 0xF1, 0xB0, 0x09, 0x48, 0x46, 0x8A,
0xF7, 0x75, 0xFF, 0x06, 0x00, 0x04, 0xD1, 0xD1, 0x21, 0x40, 0xF2, 0x5B, 0x30, 0x6E, 0xF7, 0xFF, 0xFE, 0xB8, 0x78, 0x08, 0xB3, 0x6D, 0xF7, 0x2B, 0xFE, 0x80, 0x46, 0x20, 0x78, 0xC1, 0x06, 0x07, 0xD5, 0x40, 0xF0, 0x08, 0x00, 0x20, 0x70, 0x6D,
0xF7, 0xAE, 0xFF, 0x17, 0x49, 0x08, 0x60, 0x10, 0xE0, 0x40, 0xF0, 0x10, 0x00, 0x20, 0x70, 0x15, 0x48, 0x6E, 0xF7, 0x9E, 0xF8, 0xB9, 0x78, 0x43, 0xF2, 0xD4, 0x00, 0x41, 0x43, 0x11, 0x48, 0x6E, 0xF7, 0x7B, 0xF8, 0x20, 0x78, 0x20, 0xF0, 0x08,
0x00, 0x20, 0x70, 0x40, 0x46, 0x6D, 0xF7, 0x0F, 0xFE, 0xD5, 0xF8, 0xD8, 0x20, 0x31, 0x46, 0x28, 0x46, 0x90, 0x47, 0xCB, 0xE7, 0x03, 0x01, 0x30, 0xF8, 0x66, 0x0D, 0x00, 0x05, 0x48, 0x10, 0xB5, 0x40, 0x79, 0x18, 0xB1, 0x2C, 0xF7, 0x4D, 0xF9,
0x00, 0x28, 0x00, 0xD0, 0x01, 0x20, 0x10, 0xBD, 0x3E, 0x70, 0x0D, 0x00, 0xBC, 0x18, 0x20, 0x00, 0xE4, 0x6F, 0x0D, 0x00, 0xC2, 0x1C, 0x20, 0x4C, 0xFC, 0xFF, 0x30, 0x7F, 0x21, 0x00, 0x00, 0xC8, 0x1C, 0x20, 0x00, 0x10, 0x4F, 0x20, 0x00, 0x03,
0x01, 0x68, 0x24, 0x67, 0x0D, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x00, 0x20, 0x0F, 0x46, 0x28, 0x60, 0x3D, 0xF7, 0x39, 0xFC, 0x3C, 0x68, 0x06, 0x46, 0x40, 0xF2, 0x26, 0x28, 0x0D, 0xB1, 0xAC, 0x42, 0x03, 0xD1, 0x21, 0x21, 0x40, 0x46,
0x6E, 0xF7, 0xAC, 0xFE, 0x1C, 0xB1, 0x0D, 0x48, 0x85, 0x42, 0x0A,
0xD1, 0x2C, 0x60, 0x3D, 0x60, 0x0C, 0xE0, 0x04, 0x46, 0xA8, 0x42, 0x05, 0xD1, 0x30, 0x21, 0x38, 0x46, 0x6E, 0xF7, 0x9E, 0xFE, 0x00, 0xE0, 0x47, 0x46, 0x20, 0x68, 0x00, 0x28, 0xF3, 0xD1, 0x25, 0x60, 0x00, 0x2E, 0x03, 0xD1, 0xBD, 0xE8, 0xF0,
0x41, 0x3D, 0xF7, 0x37, 0xBC, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0xC4, 0x4E, 0x20, 0x00, 0x03, 0x01, 0x40, 0x88, 0x67, 0x0D, 0x00, 0x02, 0x28, 0x11, 0xD0, 0x4F, 0xF4, 0x95, 0x72, 0x0A,
0x62, 0x09, 0x48, 0x09, 0x49, 0x00, 0x68, 0x09, 0x78, 0x00, 0xFB, 0x01, 0xF0, 0x08, 0x49, 0xC0, 0xEB, 0x00, 0x10, 0x4F, 0xEA, 0x40, 0x00, 0x08, 0x60, 0x04, 0xD0, 0x42, 0xF7, 0xAA, 0xBA, 0x4F, 0xF0, 0xAA, 0x02, 0xEC, 0xE7, 0x70, 0x47, 0xD8,
0x18, 0x20, 0x00, 0xD1, 0x18, 0x20, 0x00, 0xDC, 0x18, 0x20, 0x00, 0x03, 0x01, 0x44, 0xC4, 0x67, 0x0D, 0x00, 0x70, 0xB5, 0x0C, 0x49, 0x0A,
0x68, 0x82, 0xB1, 0x01, 0x46, 0xA1, 0xFB, 0x02, 0x05, 0x00, 0x23, 0x03, 0xFB, 0x02, 0x52, 0x01, 0xFB, 0x03, 0x21, 0x07, 0x4A, 0x08, 0x4B, 0x12, 0x68, 0x1B, 0x78, 0x5A, 0x43, 0x00, 0x23, 0x4E, 0xF7, 0xF4, 0xFB, 0x02, 0xE0, 0x1E, 0x21, 0xA0,
0xFB, 0x01, 0x01, 0x00, 0x21, 0x70, 0xBD, 0xDC, 0x18, 0x20, 0x00, 0xD8, 0x18, 0x20, 0x00, 0xD1, 0x4C, 0xFC, 0xFF, 0x2B, 0x80, 0x21, 0x00, 0x18, 0x20, 0x00, 0x10, 0x01, 0x0F, 0x00, 0xF0, 0x3E, 0x04, 0x00, 0x8C, 0xF0, 0x86, 0xB9, 0x00, 0x00,
0x00, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x01, 0x88, 0xEC, 0x03, 0x00, 0x91, 0xF0, 0xBE, 0xBA, 0x00, 0x00, 0x08, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x02, 0x60, 0x33, 0x08, 0x00, 0x4D, 0xF0, 0xD6, 0xB8, 0x00, 0x00, 0x10, 0x05, 0x0D, 0x00,
0x10, 0x01, 0x0F, 0x03, 0xD0, 0xB5, 0x07, 0x00, 0x54, 0xF0, 0xCE, 0xBF, 0x00, 0x00, 0x70, 0x05, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x04, 0xD4, 0xB6, 0x07, 0x00, 0x54, 0xF0, 0x92, 0xBF, 0x00, 0x00, 0xFC, 0x05, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x05,
0xB0, 0xBA, 0x07, 0x00, 0x54, 0xF0, 0xB2, 0xBB, 0x00, 0x00, 0x18, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x06, 0xC0, 0xBD, 0x07, 0x00, 0x54, 0xF0, 0x27, 0xBE, 0x00, 0x00, 0x12, 0x0A,
0x0D, 0x00, 0x10, 0x01, 0x0F, 0x07, 0xA4, 0xBE, 0x07, 0x00, 0x54, 0xF0, 0xA5, 0xBE, 0x00, 0x00, 0xF2, 0x0B, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x08, 0x70, 0xBF, 0x07, 0x00, 0x54, 0xF0, 0x55, 0xB9, 0x00, 0x00, 0x1E, 0x02, 0x0D, 0x00, 0x10, 0x01,
0x0F, 0x09, 0xA0, 0xB9, 0x07, 0x00, 0x55, 0xF0, 0xDB, 0xB9, 0x00, 0x00, 0x5A, 0x0D, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x0A,
0x80, 0xC2, 0x07, 0x00, 0x53, 0xF0, 0xD0, 0xBF, 0x00, 0x00, 0x24, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x0B, 0xE4, 0x42, 0x07, 0x00, 0x5C, 0xF0, 0xB8, 0xBE, 0x00, 0x00, 0x58, 0x10, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x0C, 0xAC, 0x41, 0x07, 0x00,
0x5C, 0xF0, 0x3E, 0xB8, 0x00, 0x00, 0x2C, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x0D, 0xF4, 0xA9, 0x07, 0x00, 0x56, 0xF0, 0x3A, 0xBC, 0x00, 0x00, 0x4C, 0xFC, 0xFF, 0x26, 0x81, 0x21, 0x00, 0x6C, 0x12, 0x0D, 0x00, 0x06, 0x01, 0x04, 0xA0, 0x17,
0x0D, 0x00, 0x10, 0x01, 0x0F, 0x0E, 0x60, 0x8E, 0x07, 0x00, 0x57, 0xF0, 0xEA, 0xB9, 0x00, 0x00, 0x38, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x0F, 0x4C, 0x37, 0x03, 0x00, 0x9E, 0xF0, 0x7C, 0xB8, 0x00, 0x00, 0x48, 0x18, 0x0D, 0x00, 0x10, 0x01,
0x0F, 0x10, 0x50, 0x04, 0x07, 0x00, 0x61, 0xF0, 0x6C, 0xBA, 0x00, 0x00, 0x2C, 0x19, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x11, 0x44, 0x03, 0x07, 0x00, 0x5F, 0xF0, 0x7C, 0xBF, 0x00, 0x00, 0x40, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x12, 0xDC, 0x0F,
0x08, 0x00, 0x50, 0xF0, 0xD2, 0xBC, 0x00, 0x00, 0x84, 0x19, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x13, 0x8C, 0x10, 0x08, 0x00, 0x4F, 0xF0, 0xDC, 0xB8, 0x00, 0x00, 0x48, 0x02, 0x0D, 0x00, 0x06, 0x01, 0x04, 0x5C, 0x1C, 0x0D, 0x00, 0x10, 0x01, 0x0F,
0x14, 0xF0, 0xBA, 0x06, 0x00, 0x64, 0xF0, 0xAE, 0xBB, 0x00, 0x00, 0x50, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x15, 0xFC, 0xBA, 0x06, 0x00, 0x66, 0xF0, 0xDF, 0xB8, 0x00, 0x00, 0xBE, 0x1C, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x16, 0x4C, 0x8C, 0x05,
0x00, 0x77, 0xF0, 0x02, 0xBB, 0x00, 0x00, 0x54, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x17, 0xCC, 0x68, 0x02, 0x00, 0xA9, 0xF0, 0xC6, 0xBC, 0x00, 0x00, 0x5C, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x18, 0x5C, 0x7A, 0x02, 0x00, 0xA8, 0xF0, 0x02,
0xBC, 0x00, 0x00, 0x64, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x19, 0x48, 0xCE, 0x05, 0x00, 0x73, 0xF0, 0x16, 0xBA, 0x00, 0x00, 0x78, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x1A, 0xF4, 0x3A, 0x05, 0x00, 0x7C, 0xF0, 0xC6, 0xBB, 0x00, 0x00, 0x84,
0x02, 0x0D, 0x4C, 0xFC, 0xFF, 0x21, 0x82, 0x21, 0x00, 0x00, 0x10, 0x01, 0x0F, 0x1B, 0x00, 0xC9, 0x02, 0x00, 0xA5, 0xF0, 0xF0, 0xBD, 0x00, 0x00, 0xE4, 0x24, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x1C, 0x64, 0xE6, 0x06, 0x00, 0x63, 0xF0, 0x9A, 0xBF,
0x00, 0x00, 0x9C, 0x25, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x1D, 0xE8, 0x40, 0x00, 0x00, 0x3A, 0x46, 0x84, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x0F, 0x1E, 0x3C, 0x3E, 0x00, 0x00, 0x01, 0x20, 0x20, 0xB9, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x01, 0x0F, 0x1F, 0x34, 0x7A, 0x05, 0x00, 0x78, 0xF0, 0x2E, 0xBC, 0x00, 0x00, 0x94, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x20, 0x10, 0x9E, 0x05, 0x00, 0x78, 0xF0, 0xCE, 0xBD, 0x00, 0x00, 0xB0, 0x29, 0x0D, 0x00, 0x10, 0x01,
0x0F, 0x21, 0xDC, 0x75, 0x06, 0x00, 0x68, 0xF0, 0x5C, 0xBE, 0x00, 0x00, 0x98, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x22, 0xDC, 0x6D, 0x05, 0x00, 0x79, 0xF0, 0x62, 0xBA, 0x00, 0x00, 0xA4, 0x02, 0x0D, 0x00, 0x06, 0x01, 0x04, 0xC2, 0x2C, 0x0D,
0x00, 0x10, 0x01, 0x0F, 0x23, 0xC0, 0x6C, 0x03, 0x00, 0x99, 0xF0, 0xF8, 0xBA, 0x00, 0x00, 0xB4, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x24, 0x58, 0x77, 0x03, 0x00, 0x9B, 0xF0, 0xC3, 0xBA, 0x00, 0x00, 0xE2, 0x2C, 0x0D, 0x00, 0x06, 0x01, 0x04,
0x2C, 0x2E, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x25, 0x54, 0x59, 0x06, 0x00, 0x6D, 0xF0, 0x84, 0xBA, 0x00, 0x00, 0x60, 0x2E, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x26, 0xE8, 0x58, 0x06, 0x00, 0x6A, 0xF0, 0xEC, 0xBC, 0x00, 0x00, 0xC4, 0x02, 0x0D, 0x00,
0x10, 0x01, 0x0F, 0x27, 0xB0, 0x15, 0x03, 0x00, 0x9E, 0xF0, 0x98, 0xBE, 0x00, 0x00, 0xE4, 0x02, 0x0D, 0x00, 0x06, 0x01, 0x4C, 0xFC, 0xFF, 0x1C, 0x83, 0x21, 0x00, 0x04, 0xAE, 0x37, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x28, 0x00, 0x33, 0x05, 0x00,
0x7C, 0xF0, 0xF4, 0xBF, 0x00, 0x00, 0xEC, 0x02, 0x0D, 0x00, 0x06, 0x01, 0x04, 0x16, 0x3B, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x29, 0xA8, 0x4A, 0x02, 0x00, 0xAF, 0xF0, 0x7E, 0xB9, 0x00, 0x00, 0xA8, 0x3D, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x2A, 0x14,
0x97, 0x04, 0x00, 0x86, 0xF0, 0xEE, 0xBD, 0x00, 0x00, 0xF4, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x2B, 0xB8, 0x93, 0x02, 0x00, 0xAA, 0xF0, 0x7A, 0xBD, 0x00, 0x00, 0xB0, 0x3E, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x2C, 0x88, 0x53, 0x03, 0x00, 0x9A,
0xF0, 0xB8, 0xBF, 0x00, 0x00, 0xFC, 0x02, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x2D, 0x88, 0x2C, 0x02, 0x00, 0xB1, 0xF0, 0x76, 0xBC, 0x00, 0x00, 0x78, 0x45, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x2E, 0xD8, 0x48, 0x02, 0x00, 0xAB, 0xF0, 0x16, 0xBD, 0x00,
0x00, 0x08, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x2F, 0x08, 0x3E, 0x01, 0x00, 0xC0, 0xF0, 0x38, 0xBD, 0x00, 0x00, 0x7C, 0x48, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x30, 0x24, 0x3E, 0x01, 0x00, 0xC0, 0xF0, 0x3E, 0xBD, 0x00, 0x00, 0xA4, 0x48, 0x0D,
0x00, 0x10, 0x01, 0x0F, 0x31, 0xA4, 0x50, 0x08, 0x00, 0x4F, 0xF0, 0x1A, 0xBC, 0x00, 0x00, 0xDC, 0x48, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x32, 0xF8, 0x50, 0x08, 0x00, 0x4F, 0xF0, 0x04, 0xBC, 0x00, 0x00, 0x04, 0x49, 0x0D, 0x00, 0x10, 0x01, 0x0F,
0x33, 0x9C, 0x51, 0x08, 0x00, 0x4F, 0xF0, 0xC4, 0xBB, 0x00, 0x00, 0x28, 0x49, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x34, 0x70, 0xCF, 0x01, 0x00, 0xB7, 0xF0, 0xE8, 0xBC, 0x00, 0x00, 0x44, 0x49, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x35, 0x8C, 0x4C, 0xFC,
0xFF, 0x17, 0x84, 0x21, 0x00, 0xD4, 0x01, 0x00, 0xB2, 0xF0, 0x40, 0xBF, 0x00, 0x00, 0x10, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x36, 0x38, 0xB1, 0x02, 0x00, 0xA9, 0xF0, 0x83, 0xBD, 0x00, 0x00, 0x42, 0x4C, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x37,
0x20, 0x48, 0x00, 0x00, 0xD0, 0xF0, 0x98, 0xBA, 0x00, 0x00, 0x54, 0x4D, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x38, 0x3C, 0xA1, 0x02, 0x00, 0xAA, 0xF0, 0x13, 0xBE, 0x00, 0x00, 0x66, 0x4D, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x39, 0x00, 0x61, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x0F, 0x3A, 0xD0, 0x61, 0x07, 0x00, 0x5E, 0xF0, 0x9C, 0xBE, 0x00, 0x00, 0x0C, 0x4F, 0x0D, 0x00, 0x06, 0x01, 0x04, 0x2C, 0x2E, 0x0D, 0x00, 0x06, 0x01, 0x04, 0xAE, 0x37,
0x0D, 0x00, 0x06, 0x01, 0x04, 0xA0, 0x17, 0x0D, 0x00, 0x06, 0x01, 0x04, 0x5C, 0x1C, 0x0D, 0x00, 0x06, 0x01, 0x04, 0xC2, 0x2C, 0x0D, 0x00, 0x06, 0x01, 0x04, 0xE2, 0x50, 0x0D, 0x00, 0x06, 0x01, 0x04, 0x2C, 0x2E, 0x0D, 0x00, 0x06, 0x01, 0x04,
0xAE, 0x37, 0x0D, 0x00, 0x06, 0x01, 0x04, 0xA0, 0x17, 0x0D, 0x00, 0x06, 0x01, 0x04, 0xC2, 0x2C, 0x0D, 0x00, 0x06, 0x01, 0x04, 0x5C, 0x1C, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x3B, 0x44, 0xB6, 0x08, 0x00, 0x4A, 0xF0, 0x1E, 0xB8, 0x00, 0x00, 0x84,
0x56, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x3C, 0xCC, 0xCF, 0x08, 0x00, 0x43, 0xF0, 0xA4, 0xB9, 0x00, 0x00, 0x18, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x3D, 0xAC, 0xCB, 0x08, 0x00, 0x49, 0xF0, 0x5A, 0xB9, 0x00, 0x00, 0x64, 0x5E, 0x0D, 0x00, 0x10,
0x01, 0x0F, 0x3E, 0x94, 0xE3, 0x08, 0x00, 0x41, 0xF0, 0xC4, 0xBF, 0x00, 0x00, 0x20, 0x03, 0x0D, 0x4C, 0xFC, 0xFF, 0x12, 0x85, 0x21, 0x00, 0x00, 0x10, 0x01, 0x0F, 0x3F, 0x9C, 0xD3, 0x08, 0x00, 0x42, 0xF0, 0xC8, 0xBF, 0x00, 0x00, 0x30, 0x03,
0x0D, 0x00, 0x10, 0x01, 0x0F, 0x40, 0xC4, 0x3E, 0x01, 0x00, 0xC2, 0xF0, 0x88, 0xB8, 0x00, 0x00, 0xD8, 0x5F, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x41, 0x20, 0x3F, 0x01, 0x00, 0xC2, 0xF0, 0x91, 0xB8, 0x00, 0x00, 0x46, 0x60, 0x0D, 0x00, 0x10, 0x01,
0x0F, 0x42, 0xDC, 0x46, 0x08, 0x00, 0x4B, 0xF0, 0x30, 0xBE, 0x00, 0x00, 0x40, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x43, 0x6C, 0xF4, 0x07, 0x00, 0x50, 0xF0, 0x6C, 0xBF, 0x00, 0x00, 0x48, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x44, 0x04, 0xFF,
0x07, 0x00, 0x56, 0xF0, 0x32, 0xB9, 0x00, 0x00, 0x6C, 0x61, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x45, 0x00, 0x74, 0x00, 0x00, 0xCE, 0xF0, 0xC4, 0xBE, 0x00, 0x00, 0x8C, 0x61, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x46, 0x14, 0xCD, 0x00, 0x00, 0xC3, 0xF0,
0x20, 0xBB, 0x00, 0x00, 0x58, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x47, 0xFC, 0x1D, 0x07, 0x00, 0x5E, 0xF0, 0xAF, 0xBA, 0x00, 0x00, 0x5E, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x48, 0x58, 0xCB, 0x00, 0x00, 0xC3, 0xF0, 0x05, 0xBC, 0x00, 0x00,
0x66, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x49, 0x10, 0x2D, 0x00, 0x00, 0xCD, 0xF0, 0x2C, 0xBB, 0x00, 0x00, 0x6C, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x4A, 0x08, 0x2A, 0x00, 0x00, 0xCD, 0xF0, 0xB4, 0xBC, 0x00, 0x00, 0x74, 0x03, 0x0D, 0x00,
0x10, 0x01, 0x0F, 0x4B, 0xF8, 0x3F, 0x01, 0x00, 0xBC, 0xF0, 0xC0, 0xB9, 0x00, 0x00, 0x7C, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x4C, 0x9C, 0x8E, 0x01, 0x00, 0xB7, 0xF0, 0x72, 0xBA, 0x00, 0x00, 0x84, 0x03, 0x4C, 0xFC, 0x3F, 0x0D, 0x86, 0x21,
0x00, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x4D, 0x8C, 0x8B, 0x01, 0x00, 0xB7, 0xF0, 0xFE, 0xBB, 0x00, 0x00, 0x8C, 0x03, 0x0D, 0x00, 0x10, 0x01, 0x0F, 0x4E, 0x44, 0x8C, 0x01, 0x00, 0x40, 0xF6, 0xEB, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x01, 0x0F, 0x4F, 0x64, 0xAB, 0x01, 0x00, 0xB5, 0xF0, 0x16, 0xBC, 0x00, 0x00, 0x94, 0x03, 0x0D, 0x00, 0xFE, 0x00, 0x00, 0x4C, 0xFC, 0xFF, 0x18, 0x68, 0x0D, 0x00, 0xE8, 0x1B, 0x20, 0x00, 0xE0, 0x1B, 0x20, 0x00, 0xD8, 0x1B, 0x20, 0x00, 0x30,
0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0xD3, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x03, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x32, 0x02, 0x00, 0x7D, 0x32, 0x02, 0x00, 0x25, 0x3E, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x33, 0xA9, 0x50, 0x02, 0x4F,
0x68, 0x74, 0x00, 0xE0, 0x2E, 0x00, 0x00, 0x60, 0x08, 0x9E, 0x03, 0xFC, 0xE2, 0xB5, 0x00, 0xC8, 0x32, 0x00, 0x00, 0xBD, 0x33, 0xEB, 0x03, 0x3C, 0x0B, 0xC5, 0x00, 0x40, 0x38, 0x00, 0x00, 0x40, 0x3D, 0x57, 0x04, 0x95, 0x43, 0xDA, 0x00, 0x00,
0x3C, 0x00, 0x00, 0x66, 0x52, 0xA1, 0x04, 0x9F, 0xD0, 0xE8, 0x00, 0x48, 0x3F, 0x00, 0x00, 0xE8, 0x24, 0xE2, 0x04, 0x08, 0x8C, 0xF5, 0x00, 0xA0, 0x41, 0x00, 0x00, 0x20, 0x72, 0x10, 0x05, 0x2E, 0xA4, 0xFE, 0x00, 0x50, 0x46, 0x00, 0x00, 0x90,
0x0C, 0x6D, 0x05, 0x7B, 0xD4, 0x10, 0x01, 0x00, 0x4B, 0x00, 0x00, 0x00, 0xA7, 0xC9, 0x05, 0xC7, 0x04, 0x23, 0x01, 0xF0, 0x4B, 0x00, 0x00, 0x49, 0x2C, 0xDC, 0x05, 0x0A,
0xA8, 0x26, 0x01, 0xE0, 0x4C, 0x00, 0x00, 0x93, 0xB1, 0xEE, 0x05, 0x4C, 0x4B, 0x2A, 0x01, 0x58, 0x4D, 0x00, 0x00, 0x38, 0xF4, 0xF7, 0x05, 0xED, 0x1C, 0x2C, 0x01, 0x20, 0x4E, 0x00, 0x00, 0x4A, 0x63, 0x07, 0x06, 0xFA, 0x24, 0x2F, 0x01, 0xC0,
0x5D, 0x00, 0x00, 0xC0, 0x10, 0x3C, 0x07, 0xF9, 0xC5, 0x6B, 0x4C, 0xFC, 0xFF, 0x13, 0x69, 0x0D, 0x00, 0x01, 0x90, 0x65, 0x00, 0x00, 0x7A, 0x67, 0xD6, 0x07, 0x79, 0x16, 0x8A, 0x01, 0x18, 0x92, 0x00, 0x00, 0xA2, 0x22, 0x46, 0x0B, 0x4F, 0xE1,
0x36, 0x02, 0x00, 0x96, 0x00, 0x00, 0x00, 0x4E, 0x93, 0x0B, 0x8F, 0x09, 0x46, 0x02, 0x40, 0x9C, 0x00, 0x00, 0x95, 0xC6, 0x0E, 0x0C, 0xF5, 0x49, 0x5E, 0x02, 0x20, 0xCB, 0x00, 0x00, 0xF5, 0xCE, 0xAC, 0x0F, 0xF2, 0x2C, 0x14, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0x93, 0x02, 0x00, 0xE5, 0x93,
0x02, 0x00, 0x11, 0x94, 0x02, 0x00, 0x3B, 0x94, 0x02, 0x00, 0x53, 0x94, 0x02, 0x00, 0xCF, 0x3E, 0x0D, 0x00, 0xAF, 0x96, 0x02, 0x00, 0x2B, 0x97, 0x02, 0x00, 0x33, 0x98, 0x02, 0x00, 0x89, 0x99, 0x02, 0x00, 0xA1, 0x99, 0x02, 0x00, 0x70, 0x01,
0x65, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x65, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x04, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x4A, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x01, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0xAF,
0x02, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0xFC, 0xFF, 0x0E, 0x6A, 0x0D, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x60,
0x00, 0x40, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x60, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x04, 0x41, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x60, 0x00, 0x30, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x60,
0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x4B, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x02, 0x60, 0x00, 0x40, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x04, 0x41, 0x00, 0xBA, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x04, 0x41, 0x00, 0xC0, 0x50, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x4A, 0x0D,
0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x34, 0x06, 0x41, 0x00, 0x80, 0x18, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x60, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x04, 0x41, 0x00, 0xE9, 0x02, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x06, 0x41, 0x00, 0xF1, 0x82, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x04, 0x41,
0x00, 0x21, 0x00, 0x00, 0x00, 0xFF, 0x4C, 0xFC, 0xFF, 0x09, 0x6B, 0x0D, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x04, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x4B, 0x0D, 0x00,
0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x15, 0x4C, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x83, 0x4B, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43,
0x00, 0x00, 0x00, 0x00, 0x9C, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x02, 0x60, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC8, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x02, 0x60, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9B, 0x4A, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xB0, 0x02, 0x00, 0x4C, 0xFC, 0xFF, 0x04, 0x6C, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00,
0x00, 0x00, 0x00, 0xF0, 0x00, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x64, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x64, 0x00, 0x30,
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x60, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1C, 0x00, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x0D, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x60, 0x00, 0xFF,
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x04, 0x41, 0x00, 0x19, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x02, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x01, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x4A, 0x0D, 0x00, 0xBC,
0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00,
0x00, 0x00, 0x4C, 0xFC, 0xFF, 0xFF, 0x6C, 0x0D, 0x00, 0x00, 0x60, 0x01, 0x65, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0x65, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF8, 0x00, 0x64, 0x00, 0xDF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x64, 0x00, 0x18, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x60, 0x00, 0xBE, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x14, 0x00, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x60, 0x00, 0x30, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x04, 0x60, 0x00, 0x08, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x04, 0x41, 0x00, 0x02, 0xC2, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x64, 0x04, 0x41, 0x00, 0xBA, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x06, 0x41, 0x00, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x02, 0x60, 0x00, 0x45, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x4B, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x4C, 0xFC, 0xFF, 0xFA, 0x6D, 0x0D, 0x00, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x15, 0x4C, 0x0D, 0x00, 0xBC, 0xBC, 0xBC,
0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x73, 0x4A, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x4A, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00,
0x00, 0xB9, 0xAF, 0x02, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x69, 0x4C, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x04, 0x41, 0x00, 0x21, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x4C, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x4B, 0x0D, 0x00, 0xBC, 0xBC, 0xBC, 0xBC, 0x43, 0x43, 0x43, 0x43, 0x00, 0x00, 0x00,
0x00, 0xF0, 0x00, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x64, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x64, 0x00, 0x30, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x9E, 0x02, 0x00, 0x41, 0x4A, 0x0D, 0x00, 0x55, 0x9E, 0x02, 0x00, 0x73, 0x9E, 0x02,
0x00, 0xEF, 0x9E, 0x02, 0x00, 0x97, 0x9F, 0x02, 0x00, 0xD1, 0x9F, 0x02, 0x00, 0xE1, 0xA0, 0x02, 0x00, 0x61, 0x3D, 0x0D, 0x00, 0x0A,
0x00, 0x06, 0x00, 0x81, 0x1E, 0x0D, 0x00, 0x0A,
0x00, 0x06, 0x00, 0xBD, 0x20, 0x0D, 0x00, 0x06, 0x4C, 0xFC, 0xFF, 0xF5, 0x6E, 0x0D, 0x00, 0x00, 0x06, 0x00, 0x5D, 0x21, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x1F, 0x0D, 0x00, 0x03, 0x00, 0x00, 0x00, 0x49, 0x20, 0x0D, 0x00, 0x0C, 0x00,
0x06, 0x00, 0x79, 0x20, 0x0D, 0x00, 0x21, 0x00, 0x26, 0x00, 0x9D, 0x20, 0x0D, 0x00, 0x00, 0x00, 0x06, 0x00, 0xF7, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0xE3, 0x1F, 0x0D, 0x00, 0x0D, 0x00, 0x06, 0x00, 0xB9, 0x21, 0x0D, 0x00, 0x11, 0x00,
0x00, 0x00, 0xED, 0x22, 0x0D, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x24, 0x0D, 0x00, 0x06, 0x00, 0x08, 0x00, 0xB3, 0xD9, 0x01, 0x00, 0x04, 0x00, 0x06, 0x00, 0xC7, 0xD9, 0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0xC9, 0x26, 0x0D, 0x00, 0x06, 0x00,
0x09, 0x00, 0x5F, 0x27, 0x0D, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x24, 0x0D, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x55, 0x24, 0x0D, 0x00, 0x23, 0x00, 0x00, 0x00, 0xAD, 0x51, 0x0D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x8A, 0xE1, 0x00, 0x00, 0xC5, 0x00, 0xC5, 0x00, 0x00, 0x00, 0x0D, 0xE1, 0x00, 0x00, 0x86, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xC3, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x07, 0x04, 0x4C, 0xFC, 0x32, 0xF0, 0x6F, 0x0D, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01,
0x52, 0x66, 0xFC, 0xFC, 0x3E, 0x52, 0xFD, 0xFD, 0x2A, 0x3E, 0xFE, 0xFE, 0x16, 0x2A, 0xFF, 0xFF, 0x02, 0x16, 0x00, 0x00, 0xEE, 0x02, 0x01, 0x01, 0xDA, 0xEE, 0x02, 0x02, 0xC6, 0xDA, 0x03, 0x03, 0xB2, 0xC6, 0x04, 0x04, 0x4C, 0xFC, 0x23, 0x20,
0x70, 0x0D, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4E, 0xFC, 0x04, 0xFF, 0xFF, 0xFF,
0xFF, 0x00
};
const int brcm_patch_ram_length = sizeof(brcm_patchram_buf);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
NAME := lib_mico_ble_firmware
# Use Firmware images which are already present
ifeq ($(BT_CHIP_XTAL_FREQUENCY),)
$(NAME)_SOURCES := $(BT_CHIP)$(BT_CHIP_REVISION)/bt_firmware_image.c
else
$(NAME)_SOURCES := $(BT_CHIP)$(BT_CHIP_REVISION)/$(BT_CHIP_XTAL_FREQUENCY)/bt_firmware_image.c
endif

View file

@ -0,0 +1,189 @@
#!/bin/perl
#
# This is a tool to convert a configuration data image from intel hex format to patch ram format
# format suitable for direct transmission to a device for 2045B1
# it will strip all unnecessary hex from the intel hex file and just keep the data portion,
# The hex file ***.prm will be used to modify bcm2045_prm.c BCM2045_PatchRam array to define internal build patch
#
#
# The Proprietary format is as follows:
#
####################################################################################################
# script body
####################################################################################################
{
# extract and check the inputs
my $inputsOk = 1;
if( @ARGV != 1 )
{
$inputsOk = 0;
}
my $inputFileName = shift ARGV;
$_ = $inputFileName;
if( !/(.*)(\.hex)/ )
{
$inputsOk = 0;
}
my $outFileName = $1.".prm";
if( !$inputsOk )
{
print "Usage: IncBD_ADDR.pl InputFileName.hex\n\n";
print "The output file will be InputFileName.prm for hex file.\n";
exit 0;
}
# parse the input file
ParseHexFile( \@inputRecords, $inputFileName ); # note: \@ is a reference, akin to & in C++
# open the output file
open( OutputFile, ">$outFileName") || die "Can't open $outFileName for output\n";
my $num = 0;
foreach $record (@inputRecords)
{
my @data = @{$record->{"data"}};
if($record->{"len"} != ($#data + 1))
{
die "Internal error: record length field should not mismatch data array length\n";
}
if ($record->{"type"} == 0) {
my $line;
my $append;
foreach $byte (@data)
{
$num = $num + 1;
$append = sprintf "0x%02X, ", $byte;
$line .= $append;
if ($num == 16)
{
$append = sprintf "\n";
$line .= $append;
$num = 0;
}
}
print OutputFile $line;
}
}
close OutputFile;
}
####################################################################################################
sub ParseHexFile()
####################################################################################################
{
my $recordArrayRef = shift @_;
my $filename = shift @_;
my $line;
open( inputFile, $filename ) || die "Can't open $filename\n";
while( $line = <inputFile> )
{
# get a line of the file
chomp $line;
my $record = {};
# extract the colon, length of the hex record
$_ = $line;
if(! /:([\dA-Fa-f]{2})([\dA-Fa-f]{4})([\dA-Fa-f]{2})/ )
{
# doesn't match
die "Invalid hex input file $filename\n";
}
if( defined($`) && ($` ne "") )
{
# nothing should be before the colon
die "Invalid hex input file $filename\n";
}
$record->{"len"} = hex $1;
$record->{"addr"} = hex $2;
$record->{"type"} = hex $3;
if( ( ($record->{"type"} != 2) || ($record->{"addr"} < 0x8000) ||
($record->{"len"} > 16) ) && ($record->{"type"} != 1) )
{
# die "Invalid input file $filename (input file must contain only hex records in\n".
# "bank 1/type code 2, with addresses >= 0x8000 and len <= 16 for each hex\n".
# "record)\n";
}
$remainder = $';
# extract the remaining bytes, including the checksum
my @data = ();
my $byteIndex;
my $checksum = $record->{"len"} + ($record->{"addr"}>>8) + $record->{"addr"} +
$record->{"type"};
foreach $byteIndex ( 1 .. ($record->{"len"}+1) )
{
$_ = $remainder;
if(! /([\dA-Fa-f]{2})/ )
{
# doesn't match
die "Invalid hex input file $filename\n";
}
if( defined($`) && ($` ne "") )
{
# nothing should be before the data byte
die "Invalid hex input file $filename\n";
}
my $byte = hex $1;
$checksum += $byte;
push @data, $byte;
$remainder = $';
}
# validate the checksum
if( ($checksum&0xFF) != 0)
{
# nothing should be before the data byte
die "Invalid hex input file $filename\n";
}
# remove the checksum from the data array
pop @data;
# there should be nothing remaining on the line
if( defined($remainder) && ($remainder ne "") )
{
# nothing should be before the data byte
die "Invalid hex input file $filename\n";
}
if( $record->{"type"} != 1 )
{
# store the data array in the record
$record->{"data"} = \@data; # note: \@ obtains a reference to the data array
# store the record
push @$recordArrayRef , $record; # note: using a hash with $ appears to obtain a
# reference despite the appearance of using it
# as a scalar
}
else
{
close file;
return;
}
}
# should never get here
die "Invalid hex input file $filename\n";
}

View file

@ -0,0 +1,174 @@
#!/bin/perl
use strict;
use warnings;
my $help = 0;
my $done_popping_opts = 0;
my $download_minidriver_prefix = 1;
my $uart_pkt_type_ind = 0;
my $no_hci_header = 0;
my $outBinFileName;
while(@ARGV && !$done_popping_opts)
{
if($ARGV[0] eq '-h' || $ARGV[0] eq '--help')
{
shift @ARGV;
$help = 1;
}
elsif($ARGV[0] eq '-n' || $ARGV[0] eq '--nodownloadminidriver')
{
shift @ARGV;
$download_minidriver_prefix = 0;
}
elsif($ARGV[0] eq '-u' || $ARGV[0] eq '--adduartpkttypeindicators')
{
shift @ARGV;
$uart_pkt_type_ind = 1;
}
elsif($ARGV[0] eq '-s' || $ARGV[0] eq '--nohciheader')
{
shift @ARGV;
$no_hci_header = 1;
$download_minidriver_prefix = 0;
}
else
{
$done_popping_opts = 1;
}
}
if(@ARGV != 1)
{
$help = 1;
}
if($help)
{
printf( "\n".
"USAGE: hcd2c.pl [OPTIONS] INFILE\n".
" output is to STDOUT.\n".
" OPTIONS:\n".
" -n | --nodownloadminidriver ".
"excludes Download_Minidriver\n".
" -u | --adduartpkttypeindicators ".
"adds UART packet type indicators\n".
" -s | --nohciheader ".
"excludes hci header\n".
"\n" );
exit -1;
}
open( INFILE, '<', $ARGV[0] ) || die;
binmode INFILE;
## generate BIN file for -s option
if ($no_hci_header)
{
$outBinFileName = $ARGV[0].".bin";
open( OUTFILE, ">$outBinFileName" ) || die;
binmode OUTFILE;
}
printf("unsigned char ConfigData[] =\n");
printf("{\n");
if($download_minidriver_prefix)
{
printf("/* Download_Minidriver */\n");
if($uart_pkt_type_ind)
{
printf("0x01, ");
}
printf("0x2E, 0xFC, 0x00,\n\n");
}
printf("/* Configuration Data Records (Write_RAM) */\n");
my $done = 0;
my $eor = pack( "CCCCCCC", 0x4E, 0xFC, 0x04, 0xFF, 0xFF, 0xFF, 0xFF );
my $record_prefix = pack( "CC", 0x4C, 0xFC );
while(!$done)
{
my $header;
my $result = read( INFILE, $header, 7 );
($result == 7) || die;
if($header eq $eor)
{
$done = 1;
}
else
{
(substr( $header, 0, 2 ) eq $record_prefix) || die;
my $data_length = ExtractUINT8( $header, 2 ) - 4;
my $addr = ExtractUINT32LittleEndian( $header, 3 );
my $data;
$result = read( INFILE, $data, $data_length );
($result == $data_length) || die;
my $column = 0;
if($uart_pkt_type_ind)
{
printf("0x01, ");
$column = 6;
}
if ($no_hci_header eq 0)
{
printf( "0x4C, 0xFC, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X,",
$data_length+4,
($addr) & 0xFF,
($addr >> 8) & 0xFF,
($addr >> 16) & 0xFF,
($addr >> 24) & 0xFF );
$column += 7*6-1;
}
my $data_pos = 0;
while($data_pos < $data_length)
{
my $byte_val = unpack( "C", substr( $data, $data_pos, 1 ) );
if ($no_hci_header)
{
my $byte_bin = pack("C", $byte_val);
print OUTFILE $byte_bin;
}
if($column + 6 > 80)
{
printf("\n ");
$column = 5;
}
printf( " 0x%02X,", $byte_val );
$column += 6;
$data_pos++;
}
printf("\n");
}
}
printf("\n/* Commit configuration data, reboot firmware (Launch_RAM) */\n");
if($uart_pkt_type_ind)
{
printf("0x01, ");
}
if ($no_hci_header eq 0)
{
printf("0x4E, 0xFC, 0x04, 0xFF, 0xFF, 0xFF, 0xFF\n");
}
else
{
close OUTFILE;
}
printf("};\n");
sub ExtractUINT8
{
return unpack( "C", substr( $_[0], $_[1], 1 ) );
}
sub ExtractUINT32LittleEndian
{
return unpack( "L", substr( $_[0], $_[1], 4 ) );
}

View file

@ -0,0 +1,27 @@
How to download 2045B patch ram
There are two ways user can download 2045B patch ram, one is compiled into code, another one is download from a binary file.
In order to prepare the hex and binary download file. here is the step need to follow.
1) First use Bluetool to generate intel hex file from cgs file. Yon can import Burn_2045B_Runtime_RAM_Hex_Image.btp in
hcis/patchram directory as template to BuleTool.Setting SS location to 0x00000000 to generate the right bin file.
2) Run Hex2Prm.pl in hcis/patchram directory to generate prm file from the intel hex file.
This perl script will strip all unnecessary hex from the intel hex file and just keep the data portion.
The hex file ***.prm contained the hex code for patch ram, you can use this to
modify BCM2045_PatchRam array in bcm2045_prm.c to define internal build patch hex array.
3) Run HEX2BIN.EXE in hcis/patchram directory to generate bin file from the intel hex file
The bin file ***.bin is the bin download patch which can be used by BTA to fetch and download.
4) the lower layer patch ram api bcm2045_prm_api.c provide lower layer download function. For example, BCM2045_PRM_Init can
be used to download patch, you can define this as BTM_APP_DEV_INIT to download patch when BT device is starting up.
5) the high lever BTA api bta_prm_api.c provide high level support so that you can chose to download patch from a bin file.
NOTE: the latest Bluetool generate hcd download file from cgs file, so in order to convert hcd file into build-in c array and
binary file, following that step
1) First use Bluetool to generate hcd file from cgs file. Yon can import Burn_2045B_Runtime_RAM_Hex_Image.btp in
hcis/patchram directory as template to BuleTool.S etting SS location to 0x00000000 to generate the right hcd burn image file.
2) Run hcd2c.pl -s <hcd file> in hcis/patchram directory. The STDOUT is the build-in C array and it will also generate ***.bin
file which can be used by BTA to fetch and download.
NOTE: To download hcd format, hcd file is converted c array with HCI header.
1) Generate hcd file from cgs file with proper SS location by using Bluetool
2) Run hcd2c.pl -n <hcd file> to generate C code without mini driver download.
3) The bcm2045_patchram_format must be BTE_PRM_FORMAT_HCD. (BTE_PRM_FORMAT_BIN must be used for bin format)

View file

@ -0,0 +1,14 @@
src =Split('''
''')
component =aos_component('lib_mico_ble_firmware', src)
BT_CHIP = aos_global_config.get('BT_CHIP')
BT_CHIP_REVISION = aos_global_config.get('BT_CHIP_REVISION')
BT_CHIP_XTAL_FREQUENCY = aos_global_config.get('BT_CHIP_XTAL_FREQUENCY')
if BT_CHIP_XTAL_FREQUENCY == None:
src.add_sources( BT_CHIP+BT_CHIP_REVISION+'/bt_firmware_image.c')
else:
src.add_sources( BT_CHIP+BT_CHIP_REVISION+'/'+BT_CHIP_XTAL_FREQUENCY+'/bt_firmware_image.c')

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,659 @@
#ifndef BT_TYPES_H
#define BT_TYPES_H
#include "data_types.h"
#ifdef _WIN32
#ifdef BLUESTACK_TESTER
#include "bte_stack_entry.h"
#endif
#endif
/* READ WELL !!
**
** This section defines global events. These are events that cross layers.
** Any event that passes between layers MUST be one of these events. Tasks
** can use their own events internally, but a FUNDAMENTAL design issue is
** that global events MUST be one of these events defined below.
**
** The convention used is the the event name contains the layer that the
** event is going to.
*/
#define BT_EVT_MASK 0xFF00
#define BT_SUB_EVT_MASK 0x00FF
/* To Bluetooth Upper Layers */
/************************************/
#define BT_EVT_TO_BTU_L2C_EVT 0x0900 /* L2CAP event */
#define BT_EVT_TO_BTU_HCI_EVT 0x1000 /* HCI Event */
#define BT_EVT_TO_BTU_HCI_BR_EDR_EVT (0x0000 | BT_EVT_TO_BTU_HCI_EVT) /* event from BR/EDR controller */
#define BT_EVT_TO_BTU_HCI_ACL 0x1100 /* ACL Data from HCI */
#define BT_EVT_TO_BTU_HCI_SCO 0x1200 /* SCO Data from HCI */
#define BT_EVT_TO_BTU_HCIT_ERR 0x1300 /* HCI Transport Error */
#define BT_EVT_TO_BTU_SP_EVT 0x1400 /* Serial Port Event */
#define BT_EVT_TO_BTU_SP_DATA 0x1500 /* Serial Port Data */
#define BT_EVT_TO_BTU_HCI_CMD 0x1600 /* HCI command from upper layer */
#define BT_EVT_TO_BTU_L2C_SEG_XMIT 0x1900 /* L2CAP segment(s) transmitted */
#define BT_EVT_PROXY_INCOMING_MSG 0x1A00 /* BlueStackTester event: incoming message from target */
#define BT_EVT_BTSIM 0x1B00 /* Insight BTSIM event */
#define BT_EVT_BTISE 0x1C00 /* Insight Script Engine event */
/* To LM */
/************************************/
#define BT_EVT_TO_LM_HCI_CMD 0x2000 /* HCI Command */
#define BT_EVT_TO_LM_HCI_ACL 0x2100 /* HCI ACL Data */
#define BT_EVT_TO_LM_HCI_SCO 0x2200 /* HCI SCO Data */
#define BT_EVT_TO_LM_HCIT_ERR 0x2300 /* HCI Transport Error */
#define BT_EVT_TO_LM_LC_EVT 0x2400 /* LC event */
#define BT_EVT_TO_LM_LC_LMP 0x2500 /* LC Received LMP command frame */
#define BT_EVT_TO_LM_LC_ACL 0x2600 /* LC Received ACL data */
#define BT_EVT_TO_LM_LC_SCO 0x2700 /* LC Received SCO data (not used) */
#define BT_EVT_TO_LM_LC_ACL_TX 0x2800 /* LMP data transmit complete */
#define BT_EVT_TO_LM_LC_LMPC_TX 0x2900 /* LMP Command transmit complete */
#define BT_EVT_TO_LM_LOCAL_ACL_LB 0x2a00 /* Data to be locally loopbacked */
#define BT_EVT_TO_LM_HCI_ACL_ACK 0x2b00 /* HCI ACL Data ack (not used) */
#define BT_EVT_TO_LM_DIAG 0x2c00 /* LM Diagnostics commands */
#define BT_EVT_TO_BTM_CMDS 0x2f00
#define BT_EVT_TO_BTM_PM_MDCHG_EVT (0x0001 | BT_EVT_TO_BTM_CMDS)
#define BT_EVT_TO_OBX_CL_MSG 0x3100
#define BT_EVT_TO_OBX_SR_MSG 0x3200
/* Obex Over L2CAP */
#define BT_EVT_TO_OBX_CL_L2C_MSG 0x3400
#define BT_EVT_TO_OBX_SR_L2C_MSG 0x3500
/* ftp events */
#define BT_EVT_TO_FTP_SRVR_CMDS 0x3600
#define BT_EVT_TO_FTP_CLNT_CMDS 0x3700
#define BT_EVT_TO_BTU_SAP 0x3800 /* SIM Access Profile events */
/* opp events */
#define BT_EVT_TO_OPP_SRVR_CMDS 0x3900
#define BT_EVT_TO_OPP_CLNT_CMDS 0x3a00
/* gap events */
#define BT_EVT_TO_GAP_MSG 0x3b00
/* start timer */
#define BT_EVT_TO_START_TIMER 0x3c00
/* stop timer */
#define BT_EVT_TO_STOP_TIMER 0x3d00
/* start quick timer */
#define BT_EVT_TO_START_QUICK_TIMER 0x3e00
/* for NFC */
/************************************/
#define BT_EVT_TO_NFC_NCI 0x4000 /* NCI Command, Notification or Data*/
#define BT_EVT_TO_NFC_NCI_VS 0x4200 /* Vendor specific message */
#define BT_EVT_TO_NFC_MSGS 0x4300 /* messages between NFC and NCI task */
#define BT_EVT_TO_LLCP_MSGS 0x4400 /* messages for LLCP */
#define BT_EVT_TO_NFCCSIM_NCI 0x4a00 /* events to NFCC simulation (NCI packets) */
/* HCISU Events */
#define BT_EVT_HCISU 0x5000
#define BT_EVT_TO_HCISU_LP_APP_SLEEPING_EVT (0x0005 | BT_EVT_HCISU)
#define BT_EVT_TO_HCISU_LP_ALLOW_BT_SLEEP_EVT (0x0006 | BT_EVT_HCISU)
#define BT_EVT_TO_HCISU_LP_WAKEUP_HOST_EVT (0x0007 | BT_EVT_HCISU)
#define BT_EVT_TO_HCISU_LP_RCV_H4IBSS_EVT (0x0008 | BT_EVT_HCISU)
#define BT_EVT_TO_HCISU_H5_RESET_EVT (0x0009 | BT_EVT_HCISU)
#define BT_EVT_HCISU_START_QUICK_TIMER (0x000a | BT_EVT_HCISU)
/* HSP Events */
#define BT_EVT_BTU_HSP2 0x6000
#define BT_EVT_TO_BTU_HSP2_EVT (0x0001 | BT_EVT_BTU_HSP2)
/* BPP Events */
#define BT_EVT_TO_BPP_PR_CMDS 0x6100 /* Printer Events */
#define BT_EVT_TO_BPP_SND_CMDS 0x6200 /* BPP Sender Events */
/* BIP Events */
#define BT_EVT_TO_BIP_CMDS 0x6300
#define BT_EVT_BTU_HFP 0x8000
#define BT_EVT_TO_BTU_HFP_EVT (0x0001 | BT_EVT_BTU_HFP)
#define BT_EVT_BTU_IPC_EVT 0x9000
#define BT_EVT_BTU_IPC_LOGMSG_EVT (0x0000 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_ACL_EVT (0x0001 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_BTU_EVT (0x0002 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_L2C_EVT (0x0003 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_L2C_MSG_EVT (0x0004 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_BTM_EVT (0x0005 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_AVDT_EVT (0x0006 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_SLIP_EVT (0x0007 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_MGMT_EVT (0x0008 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_BTTRC_EVT (0x0009 | BT_EVT_BTU_IPC_EVT)
#define BT_EVT_BTU_IPC_BURST_EVT (0x000A | BT_EVT_BTU_IPC_EVT)
/* Define the header of each buffer used in the Bluetooth stack.
*/
typedef struct {
UINT16 event;
UINT16 len;
UINT16 offset;
UINT16 layer_specific;
} BT_HDR;
#define BT_HDR_SIZE (sizeof (BT_HDR))
#define BT_PSM_SDP 0x0001 /* Service Discovery Protocol) */
#define BT_PSM_RFCOMM 0x0003 /* RFCOMM with TS 07.10 */
#define BT_PSM_TCS 0x0005 /* (deprecated) */
#define BT_PSM_CTP 0x0007 /* (deprecated) */
#define BT_PSM_BNEP 0x000F /* Bluetooth Network Encapsulation Protocol */
#define BT_PSM_HIDC 0x0011 /* Human Interface Device (Control) */
#define BT_PSM_HIDI 0x0013 /* Human Interface Device (Interrupt) */
#define BT_PSM_UPNP 0x0015 /* Universal PlugNPlay */
#define BT_PSM_AVCTP 0x0017 /* Audio/Video Control Transport Protocol */
#define BT_PSM_AVDTP 0x0019 /* Audio/Video Distribution Transport Protocol */
#define BT_PSM_AVCTP_13 0x001B /* Advanced Control - Browsing */
#define BT_PSM_UDI_CP 0x001D /* Unrestricted Digital Information C-Plane */
#define BT_PSM_ATT 0x001F /* Attribute Protocol */
#define BT_PSM_3DS 0x0021 /* 3D sync */
#define BT_LE_PSM_IPSP 0x0023 /* Internet Protocol Support (IPv6/6LoWPAN) */
/* These macros extract the HCI opcodes from a buffer
*/
#define HCI_GET_CMD_HDR_OPCODE(p) (UINT16)((*((UINT8 *)((p) + 1) + p->offset) + \
(*((UINT8 *)((p) + 1) + p->offset + 1) << 8)))
#define HCI_GET_CMD_HDR_PARAM_LEN(p) (UINT8) (*((UINT8 *)((p) + 1) + p->offset + 2))
#define HCI_GET_EVT_HDR_OPCODE(p) (UINT8)(*((UINT8 *)((p) + 1) + p->offset))
#define HCI_GET_EVT_HDR_PARAM_LEN(p) (UINT8) (*((UINT8 *)((p) + 1) + p->offset + 1))
/********************************************************************************
** Macros to get and put bytes to and from a stream (Little Endian format).
*/
#define UINT128_TO_STREAM(p, u128) {*(p)++ = (UINT8)(u128); *(p)++ = (UINT8)((u128) >> 8);*(p)++ = (UINT8)((u128) >> 16); *(p)++ = (UINT8)((u128) >> 24); \
*(p)++ = (UINT8)((u128) >> 32); *(p)++ = (UINT8)((u128) >> 40);*(p)++ = (UINT8)((u128) >> 48); *(p)++ = (UINT8)((u128) >> 56); \
*(p)++ = (UINT8)((u128) >> 64); *(p)++ = (UINT8)((u128) >> 72);*(p)++ = (UINT8)((u128) >> 80); *(p)++ = (UINT8)((u128) >> 88); \
*(p)++ = (UINT8)((u128) >> 96); *(p)++ = (UINT8)((u128) >> 104);*(p)++ = (UINT8)((u128) >> 112); *(p)++ = (UINT8)((u128) >> 120); }
#define UINT64_TO_STREAM(p, u64) {*(p)++ = (UINT8)(u64); *(p)++ = (UINT8)((u64) >> 8);*(p)++ = (UINT8)((u64) >> 16); *(p)++ = (UINT8)((u64) >> 24); \
*(p)++ = (UINT8)((u64) >> 32); *(p)++ = (UINT8)((u64) >> 40);*(p)++ = (UINT8)((u64) >> 48); *(p)++ = (UINT8)((u64) >> 56);}
#define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);}
#define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);}
#define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);}
#define UINT8_TO_STREAM(p, u8) {*(p)++ = (UINT8)(u8);}
#define INT8_TO_STREAM(p, u8) {*(p)++ = (INT8)(u8);}
#define ARRAY32_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 32; ijk++) *(p)++ = (UINT8) a[31 - ijk];}
#define ARRAY16_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 16; ijk++) *(p)++ = (UINT8) a[15 - ijk];}
#define ARRAY8_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 8; ijk++) *(p)++ = (UINT8) a[7 - ijk];}
#define BDADDR_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *(p)++ = (UINT8) a[BD_ADDR_LEN - 1 - ijk];}
#define LAP_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < LAP_LEN; ijk++) *(p)++ = (UINT8) a[LAP_LEN - 1 - ijk];}
#define DEVCLASS_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < DEV_CLASS_LEN;ijk++) *(p)++ = (UINT8) a[DEV_CLASS_LEN - 1 - ijk];}
#define ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
#define REVERSE_ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - 1 - ijk];}
#define STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;}
#define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;}
#define STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) ); (p) += 3;}
#define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;}
#define STREAM_TO_BDADDR(a, p) {register int ijk; register UINT8 *pbda = (UINT8 *)a + BD_ADDR_LEN - 1; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *p++;}
#define STREAM_TO_ARRAY32(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 31; for (ijk = 0; ijk < 32; ijk++) *_pa-- = *p++;}
#define STREAM_TO_ARRAY16(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 15; for (ijk = 0; ijk < 16; ijk++) *_pa-- = *p++;}
#define STREAM_TO_ARRAY8(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 7; for (ijk = 0; ijk < 8; ijk++) *_pa-- = *p++;}
#define STREAM_TO_DEVCLASS(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + DEV_CLASS_LEN - 1; for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *p++;}
#define STREAM_TO_LAP(a, p) {register int ijk; register UINT8 *plap = (UINT8 *)a + LAP_LEN - 1; for (ijk = 0; ijk < LAP_LEN; ijk++) *plap-- = *p++;}
#define STREAM_TO_ARRAY(a, p, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
#define REVERSE_STREAM_TO_ARRAY(a, p, len) {register int ijk; register UINT8 *_pa = (UINT8 *)a + len - 1; for (ijk = 0; ijk < len; ijk++) *_pa-- = *p++;}
/********************************************************************************
** Macros to get and put bytes to and from a field (Little Endian format).
** These are the same as to stream, except the pointer is not incremented.
*/
#define UINT32_TO_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)(u32); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+3) = (UINT8)((u32) >> 24);}
#define UINT24_TO_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)(u24); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u24) >> 16);}
#define UINT16_TO_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)(u16); *((UINT8 *)(p)+1) = (UINT8)((u16) >> 8);}
#define UINT8_TO_FIELD(p, u8) {*(UINT8 *)(p) = (UINT8)(u8);}
/********************************************************************************
** Macros to get and put bytes to and from a stream (Big Endian format)
*/
#define UINT128_TO_BE_STREAM(p, u128) {*(p)++ = (UINT8)(u128)>> 120; *(p)++ = (UINT8)((u128) >> 112);*(p)++ = (UINT8)((u128) >> 104); *(p)++ = (UINT8)((u128) >> 96); \
*(p)++ = (UINT8)((u128) >> 88); *(p)++ = (UINT8)((u128) >> 80);*(p)++ = (UINT8)((u128) >> 72); *(p)++ = (UINT8)((u128) >> 64); \
*(p)++ = (UINT8)((u128) >> 56); *(p)++ = (UINT8)((u128) >> 48);*(p)++ = (UINT8)((u128) >> 40); *(p)++ = (UINT8)((u128) >> 32); \
*(p)++ = (UINT8)((u128) >> 24); *(p)++ = (UINT8)((u128) >> 16);*(p)++ = (UINT8)((u128) >> 8); *(p)++ = (UINT8)(u128); }
#define UINT64_TO_BE_STREAM(p, u64) {*(p)++ = (UINT8)((u64) >> 56); *(p)++ = (UINT8)((u64) >> 48);*(p)++ = (UINT8)((u64) >> 40); *(p)++ = (UINT8)((u64) >> 32); \
*(p)++ = (UINT8)((u64) >> 24); *(p)++ = (UINT8)((u64) >> 16);*(p)++ = (UINT8)((u64) >> 8); *(p)++ = (UINT8)(u64); }
#define UINT32_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 24); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
#define UINT24_TO_BE_STREAM(p, u24) {*(p)++ = (UINT8)((u24) >> 16); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)(u24);}
#define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);}
#define UINT8_TO_BE_STREAM(p, u8) {*(p)++ = (UINT8)(u8);}
#define ARRAY_TO_BE_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
#define BE_STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;}
#define BE_STREAM_TO_UINT16(u16, p) {u16 = (UINT16)(((UINT16)(*(p)) << 8) + (UINT16)(*((p) + 1))); (p) += 2;}
#define BE_STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*((p) + 2))) + ((UINT32)(*((p) + 1)) << 8) + ((UINT32)(*(p)) << 16)); (p) += 3;}
#define BE_STREAM_TO_UINT32(u32, p) {u32 = ((UINT32)(*((p) + 3)) + ((UINT32)(*((p) + 2)) << 8) + ((UINT32)(*((p) + 1)) << 16) + ((UINT32)(*(p)) << 24)); (p) += 4;}
#define BE_STREAM_TO_UINT64(u64, p) {u64 = ((UINT64)(*((p) + 7)) + ((UINT64)(*((p) + 6)) << 8) + ((UINT64)(*((p) + 5)) << 16) + ((UINT64)(*((p) + 4)) << 24) + \
((UINT64)(*((p) + 3)) << 32) + ((UINT64)(*((p) + 2)) << 40) + ((UINT64)(*((p) + 1)) << 48) + ((UINT64)(*(p)) << 56)); (p) += 8;}
#define BE_STREAM_TO_ARRAY(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
/********************************************************************************
** Macros to get and put bytes to and from a field (Big Endian format).
** These are the same as to stream, except the pointer is not incremented.
*/
#define UINT32_TO_BE_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)((u32) >> 24); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+3) = (UINT8)(u32); }
#define UINT24_TO_BE_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)((u24) >> 16); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)(u24);}
#define UINT16_TO_BE_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)((u16) >> 8); *((UINT8 *)(p)+1) = (UINT8)(u16);}
#define UINT8_TO_BE_FIELD(p, u8) {*(UINT8 *)(p) = (UINT8)(u8);}
/* Common Bluetooth field definitions */
#define BD_ADDR_LEN 6 /* Device address length */
typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */
typedef UINT8 *BD_ADDR_PTR; /* Pointer to Device Address */
#define BT_OCTET8_LEN 8
typedef UINT8 BT_OCTET8[BT_OCTET8_LEN]; /* octet array: size 8 */
#define LINK_KEY_LEN 16
typedef UINT8 LINK_KEY[LINK_KEY_LEN]; /* Link Key */
#define BT_OCTET16_LEN 16
typedef UINT8 BT_OCTET16[BT_OCTET16_LEN]; /* octet array: size 16 */
#define BT_OCTET32_LEN 32
typedef UINT8 BT_OCTET32[BT_OCTET32_LEN]; /* octet array: size 32 */
#define PIN_CODE_LEN 16
typedef UINT8 PIN_CODE[PIN_CODE_LEN]; /* Pin Code (upto 128 bits) MSB is 0 */
typedef UINT8 *PIN_CODE_PTR; /* Pointer to Pin Code */
#define DEV_CLASS_LEN 3
typedef UINT8 DEV_CLASS[DEV_CLASS_LEN]; /* Device class */
typedef UINT8 *DEV_CLASS_PTR; /* Pointer to Device class */
#define EXT_INQ_RESP_LEN 3
typedef UINT8 EXT_INQ_RESP[EXT_INQ_RESP_LEN];/* Extended Inquiry Response */
typedef UINT8 *EXT_INQ_RESP_PTR; /* Pointer to Extended Inquiry Response */
#define BD_NAME_LEN 248
typedef UINT8 BD_NAME[BD_NAME_LEN + 1]; /* Device name */
typedef UINT8 *BD_NAME_PTR; /* Pointer to Device name */
#define BD_FEATURES_LEN 8
typedef UINT8 BD_FEATURES[BD_FEATURES_LEN]; /* LMP features supported by device */
#define BT_EVENT_MASK_LEN 8
typedef UINT8 BT_EVENT_MASK[BT_EVENT_MASK_LEN]; /* Event Mask */
#define LAP_LEN 3
typedef UINT8 LAP[LAP_LEN]; /* IAC as passed to Inquiry (LAP) */
typedef UINT8 INQ_LAP[LAP_LEN]; /* IAC as passed to Inquiry (LAP) */
#define RAND_NUM_LEN 16
typedef UINT8 RAND_NUM[RAND_NUM_LEN];
#define ACO_LEN 12
typedef UINT8 ACO[ACO_LEN]; /* Authenticated ciphering offset */
#define COF_LEN 12
typedef UINT8 COF[COF_LEN]; /* ciphering offset number */
typedef struct {
UINT8 qos_flags; /* TBD */
UINT8 service_type; /* see below */
UINT32 token_rate; /* bytes/second */
UINT32 token_bucket_size; /* bytes */
UINT32 peak_bandwidth; /* bytes/second */
UINT32 latency; /* microseconds */
UINT32 delay_variation; /* microseconds */
} FLOW_SPEC;
/* Values for service_type */
#define NO_TRAFFIC 0
#define BEST_EFFORT 1
#define GUARANTEED 2
/* Service class of the CoD */
#define SERV_CLASS_NETWORKING (1 << 1)
#define SERV_CLASS_RENDERING (1 << 2)
#define SERV_CLASS_CAPTURING (1 << 3)
#define SERV_CLASS_OBJECT_TRANSFER (1 << 4)
#define SERV_CLASS_OBJECT_AUDIO (1 << 5)
#define SERV_CLASS_OBJECT_TELEPHONY (1 << 6)
#define SERV_CLASS_OBJECT_INFORMATION (1 << 7)
/* Second byte */
#define SERV_CLASS_LIMITED_DISC_MODE (0x20)
/* Field size definitions. Note that byte lengths are rounded up. */
#define ACCESS_CODE_BIT_LEN 72
#define ACCESS_CODE_BYTE_LEN 9
#define SHORTENED_ACCESS_CODE_BIT_LEN 68
typedef UINT8 ACCESS_CODE[ACCESS_CODE_BYTE_LEN];
#define SYNTH_TX 1 /* want synth code to TRANSMIT at this freq */
#define SYNTH_RX 2 /* want synth code to RECEIVE at this freq */
#define SYNC_REPS 1 /* repeats of sync word transmitted to start of burst */
/* Bluetooth CLK27 */
#define BT_CLK27 (2 << 26)
/* Bluetooth CLK12 is 1.28 sec */
#define BT_CLK12_TO_MS(x) ((x) * 1280)
#define BT_MS_TO_CLK12(x) ((x) / 1280)
#define BT_CLK12_TO_SLOTS(x) ((x) << 11)
/* Bluetooth CLK is 0.625 msec */
#define BT_CLK_TO_MS(x) (((x) * 5 + 3) / 8)
#define BT_MS_TO_CLK(x) (((x) * 8 + 2) / 5)
#define BT_CLK_TO_MICROSECS(x) (((x) * 5000 + 3) / 8)
#define BT_MICROSECS_TO_CLK(x) (((x) * 8 + 2499) / 5000)
/* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */
#define MAX_UUID_SIZE 16
typedef struct {
#define LEN_UUID_16 2
#define LEN_UUID_32 4
#define LEN_UUID_128 16
UINT16 len;
union {
UINT16 uuid16;
UINT32 uuid32;
UINT8 uuid128[MAX_UUID_SIZE];
} uu;
} tBT_UUID;
#define BT_EIR_FLAGS_TYPE 0x01
#define BT_EIR_MORE_16BITS_UUID_TYPE 0x02
#define BT_EIR_COMPLETE_16BITS_UUID_TYPE 0x03
#define BT_EIR_MORE_32BITS_UUID_TYPE 0x04
#define BT_EIR_COMPLETE_32BITS_UUID_TYPE 0x05
#define BT_EIR_MORE_128BITS_UUID_TYPE 0x06
#define BT_EIR_COMPLETE_128BITS_UUID_TYPE 0x07
#define BT_EIR_SHORTENED_LOCAL_NAME_TYPE 0x08
#define BT_EIR_COMPLETE_LOCAL_NAME_TYPE 0x09
#define BT_EIR_TX_POWER_LEVEL_TYPE 0x0A
#define BT_EIR_OOB_BD_ADDR_TYPE 0x0C
#define BT_EIR_OOB_COD_TYPE 0x0D
#define BT_EIR_OOB_SSP_HASH_C_TYPE 0x0E
#define BT_EIR_OOB_SSP_RAND_R_TYPE 0x0F
#define BT_EIR_OOB_SSP_HASH_C_256_TYPE 0x1D
#define BT_EIR_OOB_SSP_RAND_R_256_TYPE 0x1E
#define BT_EIR_3D_SYNC_TYPE 0x3D
#define BT_EIR_MANUFACTURER_SPECIFIC_TYPE 0xFF
#define BT_OOB_COD_SIZE 3
#define BT_OOB_HASH_C_SIZE 16
#define BT_OOB_RAND_R_SIZE 16
#define BT_OOB_HASH_C_256_SIZE 16
#define BT_OOB_RAND_R_256_SIZE 16
/* Broadcom proprietary UUIDs and reserved PSMs
**
** The lowest 4 bytes byte of the UUID or GUID depends on the feature. Typically,
** the value of those bytes will be the PSM or SCN, but it is up to the features.
*/
#define BRCM_PROPRIETARY_UUID_BASE 0xDA, 0x23, 0x41, 0x02, 0xA3, 0xBB, 0xC1, 0x71, 0xBA, 0x09, 0x6f, 0x21
#define BRCM_PROPRIETARY_GUID_BASE 0xda23, 0x4102, 0xa3, 0xbb, 0xc1, 0x71, 0xba, 0x09, 0x6f, 0x21
#define BRCM_RESERVED_PSM_START 0x5AE1
#define BRCM_RESERVED_PSM_END 0x5AFF
#define BRCM_UTILITY_SERVICE_PSM 0x5AE1
#define BRCM_MATCHER_PSM 0x5AE3
/* Connection statistics
*/
/* Structure to hold connection stats */
#ifndef BT_CONN_STATS_DEFINED
#define BT_CONN_STATS_DEFINED
/* These bits are used in the bIsConnected field */
#define BT_CONNECTED_USING_BREDR 1
typedef struct {
UINT32 is_connected;
INT32 rssi;
UINT32 bytes_sent;
UINT32 bytes_rcvd;
UINT32 duration;
} tBT_CONN_STATS;
#endif
/*****************************************************************************
** Low Energy definitions
**
** Address types
*/
#define BLE_ADDR_PUBLIC 0x00
#define BLE_ADDR_RANDOM 0x01
#define BLE_ADDR_PUBLIC_ID 0x02
#define BLE_ADDR_RANDOM_ID 0x03
typedef UINT8 tBLE_ADDR_TYPE;
#define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC)
#define BT_TRANSPORT_BR_EDR 1
#define BT_TRANSPORT_LE 2
typedef UINT8 tBT_TRANSPORT;
#define BLE_ADDR_IS_STATIC(x) ((x[0] & 0xC0) == 0xC0)
typedef struct {
tBLE_ADDR_TYPE type;
BD_ADDR bda;
} tBLE_BD_ADDR;
/* Device Types
*/
#define BT_DEVICE_TYPE_BREDR 0x01
#define BT_DEVICE_TYPE_BLE 0x02
#define BT_DEVICE_TYPE_DUMO 0x03
typedef UINT8 tBT_DEVICE_TYPE;
/*****************************************************************************/
/* Define trace levels */
#define BT_TRACE_LEVEL_NONE 0 /* No trace messages to be generated */
#define BT_TRACE_LEVEL_ERROR 1 /* Error condition trace messages */
#define BT_TRACE_LEVEL_WARNING 2 /* Warning condition trace messages */
#define BT_TRACE_LEVEL_API 3 /* API traces */
#define BT_TRACE_LEVEL_EVENT 4 /* Debug messages for events */
#define BT_TRACE_LEVEL_DEBUG 5 /* Full debug messages */
#define MAX_TRACE_LEVEL 5
/* Define New Trace Type Definition */
/* TRACE_CTRL_TYPE 0x^^000000*/
#define TRACE_CTRL_MASK 0xff000000
#define TRACE_GET_CTRL(x) ((((UINT32)(x)) & TRACE_CTRL_MASK) >> 24)
#define TRACE_CTRL_GENERAL 0x00000000
#define TRACE_CTRL_STR_RESOURCE 0x01000000
#define TRACE_CTRL_SEQ_FLOW 0x02000000
#define TRACE_CTRL_MAX_NUM 3
/* LAYER SPECIFIC 0x00^^0000*/
#define TRACE_LAYER_MASK 0x00ff0000
#define TRACE_GET_LAYER(x) ((((UINT32)(x)) & TRACE_LAYER_MASK) >> 16)
#define TRACE_LAYER_NONE 0x00000000
#define TRACE_LAYER_USB 0x00010000
#define TRACE_LAYER_SERIAL 0x00020000
#define TRACE_LAYER_SOCKET 0x00030000
#define TRACE_LAYER_RS232 0x00040000
#define TRACE_LAYER_TRANS_MAX_NUM 5
#define TRACE_LAYER_TRANS_ALL 0x007f0000
#define TRACE_LAYER_LC 0x00050000
#define TRACE_LAYER_LM 0x00060000
#define TRACE_LAYER_HCI 0x00070000
#define TRACE_LAYER_L2CAP 0x00080000
#define TRACE_LAYER_RFCOMM 0x00090000
#define TRACE_LAYER_SDP 0x000a0000
#define TRACE_LAYER_OBEX 0x000b0000
#define TRACE_LAYER_BTM 0x000c0000
#define TRACE_LAYER_GAP 0x000d0000
#define TRACE_LAYER_DUN 0x000e0000
#define TRACE_LAYER_GOEP 0x000f0000
#define TRACE_LAYER_HSP2 0x00100000
#define TRACE_LAYER_SPP 0x00110000
#define TRACE_LAYER_BPP 0x00120000
#define TRACE_LAYER_FTP 0x00130000
#define TRACE_LAYER_OPP 0x00140000
#define TRACE_LAYER_BTU 0x00150000
#define TRACE_LAYER_GKI 0x00160000 /*it's overwritten in nfc_types.h*/
#define TRACE_LAYER_BNEP 0x00170000
#define TRACE_LAYER_PAN 0x00180000
#define TRACE_LAYER_HFP 0x00190000
#define TRACE_LAYER_HID 0x001a0000
#define TRACE_LAYER_BIP 0x001b0000
#define TRACE_LAYER_AVP 0x001c0000
#define TRACE_LAYER_A2D 0x001d0000
#define TRACE_LAYER_SAP 0x001e0000
#define TRACE_LAYER_MCA 0x001f0000
#define TRACE_LAYER_ATT 0x00200000
#define TRACE_LAYER_SMP 0x00210000
#define TRACE_LAYER_NFC 0x00220000
#define TRACE_LAYER_NCI 0x00230000 /*it's overwritten in nfc_types.h*/
#define TRACE_LAYER_LLCP 0x00240000
#define TRACE_LAYER_NDEF 0x00250000
#define TRACE_LAYER_RW 0x00260000
#define TRACE_LAYER_CE 0x00270000
#define TRACE_LAYER_P2P 0x00280000
#define TRACE_LAYER_SNEP 0x00290000
#define TRACE_LAYER_CHO 0x002a0000
#define TRACE_LAYER_NFA 0x002b0000
#define TRACE_LAYER_HAL 0x002c0000 /*it's overwritten in nfc_types.h*/
#define TRACE_LAYER_MAX_NUM 0x002d
/* TRACE_ORIGINATOR 0x0000^^00*/
#define TRACE_ORG_MASK 0x0000ff00
#define TRACE_GET_ORG(x) ((((UINT32)(x)) & TRACE_ORG_MASK) >> 8)
#define TRACE_ORG_STACK 0x00000000
#define TRACE_ORG_HCI_TRANS 0x00000100
#define TRACE_ORG_PROTO_DISP 0x00000200
#define TRACE_ORG_RPC 0x00000300
#define TRACE_ORG_GKI 0x00000400
#define TRACE_ORG_APPL 0x00000500
#define TRACE_ORG_SCR_WRAPPER 0x00000600
#define TRACE_ORG_SCR_ENGINE 0x00000700
#define TRACE_ORG_USER_SCR 0x00000800
#define TRACE_ORG_TESTER 0x00000900
#define TRACE_ORG_MAX_NUM 10 /* 32-bit mask; must be < 32 */
#define TRACE_LITE_ORG_MAX_NUM 6
#define TRACE_ORG_ALL 0x03ff
#define TRACE_ORG_RPC_TRANS 0x04
#define TRACE_ORG_REG 0x00000909
#define TRACE_ORG_REG_SUCCESS 0x0000090a
/* TRACE_TYPE 0x000000^^*/
#define TRACE_TYPE_MASK 0x000000ff
#define TRACE_GET_TYPE(x) (((UINT32)(x)) & TRACE_TYPE_MASK)
#define TRACE_TYPE_ERROR 0x00000000
#define TRACE_TYPE_WARNING 0x00000001
#define TRACE_TYPE_API 0x00000002
#define TRACE_TYPE_EVENT 0x00000003
#define TRACE_TYPE_DEBUG 0x00000004
#define TRACE_TYPE_STACK_ONLY_MAX TRACE_TYPE_DEBUG
#define TRACE_TYPE_TX 0x00000005
#define TRACE_TYPE_RX 0x00000006
#define TRACE_TYPE_DEBUG_ASSERT 0x00000007
#define TRACE_TYPE_GENERIC 0x00000008
#define TRACE_TYPE_REG 0x00000009
#define TRACE_TYPE_REG_SUCCESS 0x0000000a
#define TRACE_TYPE_CMD_TX 0x0000000b
#define TRACE_TYPE_EVT_TX 0x0000000c
#define TRACE_TYPE_ACL_TX 0x0000000d
#define TRACE_TYPE_CMD_RX 0x0000000e
#define TRACE_TYPE_EVT_RX 0x0000000f
#define TRACE_TYPE_ACL_RX 0x00000010
#define TRACE_TYPE_TARGET_TRACE 0x00000011
#define TRACE_TYPE_SCO_TX 0x00000012
#define TRACE_TYPE_SCO_RX 0x00000013
#define TRACE_TYPE_MAX_NUM 20
#define TRACE_TYPE_ALL 0xffff
/* Define color for script type */
#define SCR_COLOR_DEFAULT 0
#define SCR_COLOR_TYPE_COMMENT 1
#define SCR_COLOR_TYPE_COMMAND 2
#define SCR_COLOR_TYPE_EVENT 3
#define SCR_COLOR_TYPE_SELECT 4
/* Define protocol trace flag values */
#define SCR_PROTO_TRACE_HCI_SUMMARY 0x00000001
#define SCR_PROTO_TRACE_HCI_DATA 0x00000002
#define SCR_PROTO_TRACE_L2CAP 0x00000004
#define SCR_PROTO_TRACE_RFCOMM 0x00000008
#define SCR_PROTO_TRACE_SDP 0x00000010
#define SCR_PROTO_TRACE_OBEX 0x00000040
#define SCR_PROTO_TRACE_OAPP 0x00000080 /* OBEX Application Profile */
#define SCR_PROTO_TRACE_BNEP 0x00000200
#define SCR_PROTO_TRACE_AVP 0x00000400
#define SCR_PROTO_TRACE_MCA 0x00000800
#define SCR_PROTO_TRACE_ATT 0x00001000
#define SCR_PROTO_TRACE_SMP 0x00002000
#define SCR_PROTO_TRACE_NCI 0x00004000
#define SCR_PROTO_TRACE_LLCP 0x00008000
#define SCR_PROTO_TRACE_NDEF 0x00010000
#define SCR_PROTO_TRACE_RW 0x00020000
#define SCR_PROTO_TRACE_CE 0x00040000
#define SCR_PROTO_TRACE_SNEP 0x00080000
#define SCR_PROTO_TRACE_CHO 0x00100000
#define SCR_PROTO_TRACE_ALL 0x001fffff
#define SCR_PROTO_TRACE_HCI_LOGGING_VSE 0x0800 /* Brcm vs event for logmsg and protocol traces */
#define MAX_SCRIPT_TYPE 5
/* Define PSMs HID uses */
#define HID_PSM_CONTROL BT_PSM_HIDC
#define HID_PSM_INTERRUPT BT_PSM_HIDI
#if defined(UCD_HID_INCLUDED) && (UCD_HID_INCLUDED == TRUE)
#define UCD_PSM_MIN 0x8001
#define UCD_PSM_MAX 0x8003
#define UCD_PSM_HID_CTRL 0x8001
#define UCD_PSM_HID_INTR 0x8003
#endif
#if defined(HIDH_UCD_INCLUDED) && (HIDH_UCD_INCLUDED == TRUE)
#define HID_UCD_PSM_CONTROL 0x8001
#define HID_UCD_PSM_INTERRUPT 0x8003
#endif
/* Define a function for logging */
typedef void (BT_LOG_FUNC) (int trace_type, const char *fmt_str, ...);
#endif

View file

@ -0,0 +1,68 @@
#ifndef DATA_TYPES_H
#define DATA_TYPES_H
#ifndef NULL
#define NULL 0
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned long UINT32;
typedef unsigned long long int UINT64;
typedef signed long INT32;
typedef signed char INT8;
typedef signed short INT16;
typedef unsigned char BOOLEAN;
typedef UINT32 UINTPTR;
typedef UINT32 TIME_STAMP;
#ifndef TRUE
#define TRUE (!FALSE)
#endif
typedef unsigned char UBYTE;
#ifdef __arm
#define PACKED __packed
#define INLINE __inline
#else
#define PACKED
#define INLINE
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN FALSE
#endif
#define UINT16_LOW_BYTE(x) ((x) & 0xff)
#define UINT16_HI_BYTE(x) ((x) >> 8)
/* MACRO definitions for safe string functions */
/* Replace standard string functions with safe functions if available */
#define BCM_STRCAT_S(x1,x2,x3) strcat((x1),(x3))
#define BCM_STRNCAT_S(x1,x2,x3,x4) strncat((x1),(x3),(x4))
#define BCM_STRCPY_S(x1,x2,x3) strcpy((x1),(x3))
#define BCM_STRNCPY_S(x1,x2,x3,x4) strncpy((x1),(x3),(x4))
#define BCM_SPRINTF_S(x1,x2,x3,x4) sprintf((x1),(x3),(x4))
#define BCM_VSPRINTF_S(x1,x2,x3,x4) vsprintf((x1),(x3),(x4))
#define BT_MEMCPY(a,b,c) memcpy( (a), (b), (c) )
#define BT_MEMSET(a,b,c) memset( (a), (b), (c) )
#define BT_STRLEN(a) strlen( (a) )
#define BT_MEMCMP(a,b,c) memcmp( (a), (b), (c) )
#define BT_MEMCMP_OK 0 // memcmp success
/* Timer list entry callback type
*/
typedef void (TIMER_CBACK)(void *p_tle);
#ifndef TIMER_PARAM_TYPE
#define TIMER_PARAM_TYPE UINT32
#endif
#endif

View file

@ -0,0 +1,176 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
/****************************************************************************/
/* */
/* Name: gattdefs.h */
/* */
/* Function this file contains internally used ATT definitions */
/*****************************************************************************/
#ifndef _GATTDEFS_H
#define _GATTDEFS_H
#define GATT_ILLEGAL_UUID 0
/* GATT attribute types
*/
#define GATT_UUID_PRI_SERVICE 0x2800
#define GATT_UUID_SEC_SERVICE 0x2801
#define GATT_UUID_INCLUDE_SERVICE 0x2802
#define GATT_UUID_CHAR_DECLARE 0x2803 /* Characteristic Declaration*/
#define GATT_UUID_CHAR_EXT_PROP 0x2900 /* Characteristic Extended Properties */
#define GATT_UUID_CHAR_DESCRIPTION 0x2901 /* Characteristic User Description*/
#define GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */
#define GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */
#define GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/
#define GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/
#define GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */
#define GATT_UUID_EXT_RPT_REF_DESCR 0x2907
#define GATT_UUID_RPT_REF_DESCR 0x2908
/* GAP Profile Attributes
*/
#define GATT_UUID_GAP_DEVICE_NAME 0x2A00
#define GATT_UUID_GAP_ICON 0x2A01
#define GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04
#define GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6
/* Attribute Profile Attribute UUID */
#define GATT_UUID_GATT_SRV_CHGD 0x2A05
/* Attribute Protocol Test */
/* Link Loss Service */
#define GATT_UUID_ALERT_LEVEL 0x2A06 /* Alert Level */
#define GATT_UUID_TX_POWER_LEVEL 0x2A07 /* TX power level */
/* Time Profile */
/* Current Time Service */
#define GATT_UUID_CURRENT_TIME 0x2A2B /* Current Time */
#define GATT_UUID_LOCAL_TIME_INFO 0x2A0F /* Local time info */
#define GATT_UUID_REF_TIME_INFO 0x2A14 /* reference time information */
/* NwA Profile */
#define GATT_UUID_NW_STATUS 0x2A18 /* network availability status */
#define GATT_UUID_NW_TRIGGER 0x2A1A /* Network availability trigger */
/* phone alert */
#define GATT_UUID_ALERT_STATUS 0x2A3F /* alert status */
#define GATT_UUID_RINGER_CP 0x2A40 /* ringer control point */
#define GATT_UUID_RINGER_SETTING 0x2A41 /* ringer setting */
/* Glucose Service */
#define GATT_UUID_GM_MEASUREMENT 0x2A18
#define GATT_UUID_GM_CONTEXT 0x2A34
#define GATT_UUID_GM_CONTROL_POINT 0x2A52
#define GATT_UUID_GM_FEATURE 0x2A51
/* device infor characteristic */
#define GATT_UUID_SYSTEM_ID 0x2A23
#define GATT_UUID_MODEL_NUMBER_STR 0x2A24
#define GATT_UUID_SERIAL_NUMBER_STR 0x2A25
#define GATT_UUID_FW_VERSION_STR 0x2A26
#define GATT_UUID_HW_VERSION_STR 0x2A27
#define GATT_UUID_SW_VERSION_STR 0x2A28
#define GATT_UUID_MANU_NAME 0x2A29
#define GATT_UUID_IEEE_DATA 0x2A2A
#define GATT_UUID_PNP_ID 0x2A50
/* HID characteristics */
#define GATT_UUID_HID_INFORMATION 0x2A4A
#define GATT_UUID_HID_REPORT_MAP 0x2A4B
#define GATT_UUID_HID_CONTROL_POINT 0x2A4C
#define GATT_UUID_HID_REPORT 0x2A4D
#define GATT_UUID_HID_PROTO_MODE 0x2A4E
#define GATT_UUID_HID_BT_KB_INPUT 0x2A22
#define GATT_UUID_HID_BT_KB_OUTPUT 0x2A32
#define GATT_UUID_HID_BT_MOUSE_INPUT 0x2A33
/* Battery Service char */
#define GATT_UUID_BATTERY_LEVEL 0x2A19
#define GATT_UUID_SC_CONTROL_POINT 0x2A55
#define GATT_UUID_SENSOR_LOCATION 0x2A5D
/* RUNNERS SPEED AND CADENCE SERVICE */
#define GATT_UUID_RSC_MEASUREMENT 0x2A53
#define GATT_UUID_RSC_FEATURE 0x2A54
/* CYCLING SPEED AND CADENCE SERVICE */
#define GATT_UUID_CSC_MEASUREMENT 0x2A5B
#define GATT_UUID_CSC_FEATURE 0x2A5C
/* CYCLING POWER SERVICE (Temp for IOP) */
#define GATT_UUID_CP_MEASUREMENT 0x2A63
#define GATT_UUID_CP_VECTOR 0x2A64
#define GATT_UUID_CP_FEATURE 0x2A65
#define GATT_UUID_CP_CONTROL_POINT 0x2A66
/* LOCATION AND NAVIGATION SERVICE (Temp for IOP) */
#define GATT_UUID_LN_LOC_AND_SPEED 0x2A67
#define GATT_UUID_LN_NAVIGATION 0x2A68
#define GATT_UUID_LN_POSITION_QUALITY 0x2A69
#define GATT_UUID_LN_FEATURE 0x2A6A
#define GATT_UUID_LN_CONTROL_POINT 0x2A6B
/* HTTP Proxy Service */
#define GATT_UUID_HPS_URI 0x7F11
#define GATT_UUID_HPS_HEADERS 0x7F12
#define GATT_UUID_HPS_STATUS_CODE 0x7F13
#define GATT_UUID_HPS_ENTITY_BODY 0x7F14
#define GATT_UUID_HPS_CONTROL_POINT 0x7F15
#define GATT_UUID_HPS_SERCURITY 0x7F16
/* Scan Parameter charatceristics */
#define GATT_UUID_SCAN_INT_WINDOW 0x2A4F
#define GATT_UUID_SCAN_REFRESH 0x2A31
/* GATT appearance definitions */
enum gatt_appearance_e {
APPEARANCE_GENERIC_PHONE = 64,
APPEARANCE_GENERIC_COMPUTER = 128,
APPEARANCE_GENERIC_WATCH = 192,
APPEARANCE_WATCH_SPORTS = 193,
APPEARANCE_GENERIC_CLOCK = 256,
APPEARANCE_GENERIC_DISPLAY = 320,
APPEARANCE_GENERIC_REMOTE_CONTROL = 384,
APPEARANCE_GENERIC_EYE_GLASSES = 448,
APPEARANCE_GENERIC_TAG = 512,
APPEARANCE_GENERIC_KEYRING = 576,
APPEARANCE_GENERIC_MEDIA_PLAYER = 640,
APPEARANCE_GENERIC_BARCODE_SCANNER = 704,
APPEARANCE_GENERIC_THERMOMETER = 768,
APPEARANCE_THERMOMETER_EAR = 769,
APPEARANCE_GENERIC_HEART_RATE_SENSOR = 832,
APPEARANCE_HEART_RATE_BELT = 833,
APPEARANCE_GENERIC_BLOOD_PRESSURE = 896,
APPEARANCE_BLOOD_PRESSURE_ARM = 897,
APPEARANCE_BLOOD_PRESSURE_WRIST = 898,
APPEARANCE_GENERIC_HID_DEVICE = 960,
APPEARANCE_HID_KEYBOARD = 961,
APPEARANCE_HID_MOUSE = 962,
APPEARANCE_HID_JOYSTICK = 963,
APPEARANCE_HID_GAMEPAD = 964,
APPEARANCE_HID_DIGITIZER_TABLET = 965,
APPEARANCE_HID_CARD_READER = 966,
APPEARANCE_HID_DIGITAL_PEN = 967,
APPEARANCE_HID_BARCODE_SCANNER = 968,
APPEARANCE_GENERIC_GLUCOSE_METER = 1024,
APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR = 1088,
APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE = 1089,
APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE = 1090,
APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP = 1091,
APPEARANCE_GENERIC_CYCLING = 1152,
APPEARANCE_CYCLING_COMPUTER = 1153,
APPEARANCE_CYCLING_SPEED_SENSOR = 1154,
APPEARANCE_CYCLING_CADENCE_SENSOR = 1155,
APPEARANCE_CYCLING_POWER_SENSOR = 1156,
APPEARANCE_CYCLING_SPEED_AND_CADENCE_SENSOR = 1157,
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,325 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
/****************************************************************************
**
** Name: l2cdefs.h
**
** Function: This file contains L2CAP protocol definitions
**
**
*****************************************************************************/
#ifndef L2CDEFS_H
#define L2CDEFS_H
/* L2CAP command codes
*/
#define L2CAP_CMD_REJECT 0x01
#define L2CAP_CMD_CONN_REQ 0x02
#define L2CAP_CMD_CONN_RSP 0x03
#define L2CAP_CMD_CONFIG_REQ 0x04
#define L2CAP_CMD_CONFIG_RSP 0x05
#define L2CAP_CMD_DISC_REQ 0x06
#define L2CAP_CMD_DISC_RSP 0x07
#define L2CAP_CMD_ECHO_REQ 0x08
#define L2CAP_CMD_ECHO_RSP 0x09
#define L2CAP_CMD_INFO_REQ 0x0A
#define L2CAP_CMD_INFO_RSP 0x0B
#define L2CAP_CMD_AMP_CONN_REQ 0x0C
#define L2CAP_CMD_AMP_CONN_RSP 0x0D
#define L2CAP_CMD_AMP_MOVE_REQ 0x0E
#define L2CAP_CMD_AMP_MOVE_RSP 0x0F
#define L2CAP_CMD_AMP_MOVE_CFM 0x10
#define L2CAP_CMD_AMP_MOVE_CFM_RSP 0x11
#define L2CAP_CMD_BLE_UPDATE_REQ 0x12
#define L2CAP_CMD_BLE_UPDATE_RSP 0x13
#define L2CAP_CMD_BLE_CONN_REQ 0x14
#define L2CAP_CMD_BLE_CONN_RSP 0x15
#define L2CAP_CMD_BLE_CREDIT 0x16
/* Define some packet and header lengths
*/
#define L2CAP_PKT_OVERHEAD 4 /* Length and CID */
#define L2CAP_CMD_OVERHEAD 4 /* Cmd code, Id and length */
#define L2CAP_CMD_REJECT_LEN 2 /* Reason (data is optional) */
#define L2CAP_CONN_REQ_LEN 4 /* PSM and source CID */
#define L2CAP_CONN_RSP_LEN 8 /* Dest CID, source CID, reason, status */
#define L2CAP_CONFIG_REQ_LEN 4 /* Dest CID, flags (data is optional) */
#define L2CAP_CONFIG_RSP_LEN 6 /* Dest CID, flags, result,data optional*/
#define L2CAP_DISC_REQ_LEN 4 /* Dest CID, source CID */
#define L2CAP_DISC_RSP_LEN 4 /* Dest CID, source CID */
#define L2CAP_ECHO_REQ_LEN 0 /* Data is optional */
#define L2CAP_ECHO_RSP_LEN 0 /* Data is optional */
#define L2CAP_INFO_REQ_LEN 2 /* Info type */
#define L2CAP_INFO_RSP_LEN 4 /* Info type, result (data is optional) */
#define L2CAP_BCST_OVERHEAD 2 /* Additional broadcast packet overhead */
#define L2CAP_UCD_OVERHEAD 2 /* Additional connectionless packet overhead */
#define L2CAP_AMP_CONN_REQ_LEN 5 /* PSM, CID, and remote controller ID */
#define L2CAP_AMP_MOVE_REQ_LEN 3 /* CID and remote controller ID */
#define L2CAP_AMP_MOVE_RSP_LEN 4 /* CID and result */
#define L2CAP_AMP_MOVE_CFM_LEN 4 /* CID and result */
#define L2CAP_AMP_MOVE_CFM_RSP_LEN 2 /* CID */
#define L2CAP_CMD_BLE_UPD_REQ_LEN 8 /* Min and max interval, latency, tout */
#define L2CAP_CMD_BLE_UPD_RSP_LEN 2 /* Result */
#define L2CAP_BLE_CONN_REQ_LEN 10 /* LE_PSM, src CID, MTU, MPS, init credits */
#define L2CAP_BLE_CONN_RSP_LEN 10 /* Dest CID, MTU, MPS, init credits, result */
#define L2CAP_BLE_CONN_CRED_LEN 4 /* Local CID, connection credits to add */
/* Define the packet boundary flags
*/
#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
#define L2CAP_PKT_START_FLUSHABLE 2
#define L2CAP_PKT_START_NON_FLUSHABLE 0
#endif
#define L2CAP_COMPLETE_AMP_PKT 3 /* complete L2CAP packet on AMP HCI */
#define L2CAP_PKT_START 2
#define L2CAP_PKT_CONTINUE 1
#define L2CAP_MASK_FLAG 0x0FFF
#define L2CAP_PKT_TYPE_SHIFT 12
#define L2CAP_PKT_TYPE_MASK 3
#define L2CAP_BLE_CONN_MIN_MPS_SIZE 23
#define L2CAP_BLE_CONN_MAX_MPS_SIZE 65533
#define L2CAP_BLE_CONN_MIN_MTU_SIZE 23
#define L2CAP_BLE_CONN_SDU_LEN_FIELD_SIZE 2
/* Define the L2CAP connection result codes
*/
#define L2CAP_CONN_OK 0
#define L2CAP_CONN_PENDING 1
#define L2CAP_CONN_NO_PSM 2
#define L2CAP_CONN_SECURITY_BLOCK 3
#define L2CAP_CONN_NO_RESOURCES 4
#define L2CAP_CONN_BAD_CTLR_ID 5 /* AMP related */
#define L2CAP_BLE_CONN_BAD_AUTHENT 5 /* BLE L2CAP connections related */
#define L2CAP_BLE_CONN_BAD_AUTHORIZ 6
#define L2CAP_BLE_CONN_BAD_KEY_SIZE 7
#define L2CAP_BLE_CONN_BAD_ENCRYPT 8
/* Add a couple of our own for internal use */
#define L2CAP_CONN_TIMEOUT 0xEEEE
#define L2CAP_BLE_CMD_REJ 253
#define L2CAP_CONN_AMP_FAILED 254
#define L2CAP_CONN_NO_LINK 255
#define L2CAP_CONN_CANCEL 256 /* L2CAP connection cancelled */
/* Define L2CAP Move Channel Response result codes
*/
#define L2CAP_MOVE_OK 0
#define L2CAP_MOVE_PENDING 1
#define L2CAP_MOVE_CTRL_ID_NOT_SUPPORT 2
#define L2CAP_MOVE_SAME_CTRLR_ID 3
#define L2CAP_MOVE_CONFIG_NOT_SUPPORTED 4
#define L2CAP_MOVE_CHAN_COLLISION 5
#define L2CAP_MOVE_NOT_ALLOWED 6
/* Define L2CAP Move Channel Confirmation result codes
*/
#define L2CAP_MOVE_CFM_OK 0
#define L2CAP_MOVE_CFM_REFUSED 1
/* Define the L2CAP command reject reason codes
*/
#define L2CAP_CMD_REJ_NOT_UNDERSTOOD 0
#define L2CAP_CMD_REJ_MTU_EXCEEDED 1
#define L2CAP_CMD_REJ_INVALID_CID 2
/* L2CAP Predefined CIDs
*/
#define L2CAP_SIGNALLING_CID 1
#define L2CAP_CONNECTIONLESS_CID 2
#define L2CAP_AMP_CID 3
#define L2CAP_ATT_CID 4
#define L2CAP_BLE_SIGNALLING_CID 5
#define L2CAP_SMP_CID 6
#define L2CAP_SMP_BR_CID 7
#define L2CAP_AMP_TEST_CID 0x003F
#define L2CAP_BASE_APPL_CID 0x0040
#define L2CAP_BLE_CONN_MAX_CID 0x007F
/* Fixed Channels mask bits
*/
#define L2CAP_FIXED_CHNL_SIG_BIT (1 << L2CAP_SIGNALLING_CID) /* Signal Channel Supported (Mandatory) */
#define L2CAP_FIXED_CHNL_CNCTLESS_BIT (1 << L2CAP_CONNECTIONLESS_CID) /* Connectionless Reception */
#define L2CAP_FIXED_CHNL_AMP_BIT (1 << L2CAP_AMP_CID) /* AMP Manager Supported */
#define L2CAP_FIXED_CHNL_ATT_BIT (1 << L2CAP_ATT_CID) /* Attribute protocol Supported */
#define L2CAP_FIXED_CHNL_BLE_SIG_BIT (1 << L2CAP_BLE_SIGNALLING_CID) /* BLE Signalling Supported */
#define L2CAP_FIXED_CHNL_SMP_BIT (1 << L2CAP_SMP_CID) /* BLE Security Manager Supported */
#define L2CAP_FIXED_CHNL_SMP_BR_BIT (1 << L2CAP_SMP_BR_CID) /* Security Manager over BR Supported */
/* Define the L2CAP configuration result codes
*/
#define L2CAP_CFG_OK 0
#define L2CAP_CFG_UNACCEPTABLE_PARAMS 1
#define L2CAP_CFG_FAILED_NO_REASON 2
#define L2CAP_CFG_UNKNOWN_OPTIONS 3
#define L2CAP_CFG_PENDING 4
#define L2CAP_CFG_FLOW_SPEC_REJECTED 5
/* Define the L2CAP configuration option types
*/
#define L2CAP_CFG_TYPE_MTU 0x01
#define L2CAP_CFG_TYPE_FLUSH_TOUT 0x02
#define L2CAP_CFG_TYPE_QOS 0x03
#define L2CAP_CFG_TYPE_FCR 0x04
#define L2CAP_CFG_TYPE_FCS 0x05
#define L2CAP_CFG_TYPE_EXT_FLOW 0x06
#define L2CAP_CFG_TYPE_EXT_WIN_SIZE 0x07
#define L2CAP_CFG_MTU_OPTION_LEN 2 /* MTU option length */
#define L2CAP_CFG_FLUSH_OPTION_LEN 2 /* Flush option len */
#define L2CAP_CFG_QOS_OPTION_LEN 22 /* QOS option length */
#define L2CAP_CFG_FCR_OPTION_LEN 9 /* FCR option length */
#define L2CAP_CFG_FCS_OPTION_LEN 1 /* FCR option length */
#define L2CAP_CFG_EXT_FLOW_OPTION_LEN 16 /* Extended Flow Spec */
#define L2CAP_CFG_EXT_WIN_SIZE_LEN 2 /* Ext window size length */
#define L2CAP_CFG_OPTION_OVERHEAD 2 /* Type and length */
/* Configuration Cmd/Rsp Flags mask
*/
#define L2CAP_CFG_FLAGS_MASK_CONT 0x0001 /* Flags mask: Continuation */
/* FCS Check Option values
*/
#define L2CAP_CFG_FCS_BYPASS 0 /* Bypass the FCS in streaming or ERTM modes */
#define L2CAP_CFG_FCS_USE 1 /* Use the FCS in streaming or ERTM modes [default] */
/* Default values for configuration
*/
#define L2CAP_NO_AUTOMATIC_FLUSH 0xFFFF
#define L2CAP_NO_RETRANSMISSION 0x0001
#define L2CAP_DEFAULT_MTU (672)
#define L2CAP_DEFAULT_FLUSH_TO L2CAP_NO_AUTOMATIC_FLUSH
#define L2CAP_DEFAULT_SERV_TYPE 1
#define L2CAP_DEFAULT_TOKEN_RATE 0
#define L2CAP_DEFAULT_BUCKET_SIZE 0
#define L2CAP_DEFAULT_PEAK_BANDWIDTH 0
#define L2CAP_DEFAULT_LATENCY 0xFFFFFFFF
#define L2CAP_DEFAULT_DELAY 0xFFFFFFFF
#define L2CAP_DEFAULT_FCS L2CAP_CFG_FCS_USE
/* Define the L2CAP disconnect result codes
*/
#define L2CAP_DISC_OK 0
#define L2CAP_DISC_TIMEOUT 0xEEEE
/* Define the L2CAP info resp result codes
*/
#define L2CAP_INFO_RESP_RESULT_SUCCESS 0
#define L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED 1
/* Define the info-type fields of information request & response
*/
#define L2CAP_CONNLESS_MTU_INFO_TYPE 0x0001
#define L2CAP_EXTENDED_FEATURES_INFO_TYPE 0x0002 /* Used in Information Req/Response */
#define L2CAP_FIXED_CHANNELS_INFO_TYPE 0x0003 /* Used in AMP */
#define L2CAP_CONNLESS_MTU_INFO_SIZE 2 /* Connectionless MTU size */
#define L2CAP_EXTENDED_FEATURES_ARRAY_SIZE 4 /* Extended features array size */
#define L2CAP_FIXED_CHNL_ARRAY_SIZE 8 /* Fixed channel array size */
/* Extended features mask bits
*/
#define L2CAP_EXTFEA_RTRANS 0x00000001 /* Retransmission Mode (Not Supported) */
#define L2CAP_EXTFEA_FC 0x00000002 /* Flow Control Mode (Not Supported) */
#define L2CAP_EXTFEA_QOS 0x00000004
#define L2CAP_EXTFEA_ENH_RETRANS 0x00000008 /* Enhanced retransmission mode */
#define L2CAP_EXTFEA_STREAM_MODE 0x00000010 /* Streaming Mode */
#define L2CAP_EXTFEA_NO_CRC 0x00000020 /* Optional FCS (if set No FCS desired) */
#define L2CAP_EXTFEA_EXT_FLOW_SPEC 0x00000040 /* Extended flow spec */
#define L2CAP_EXTFEA_FIXED_CHNLS 0x00000080 /* Fixed channels */
#define L2CAP_EXTFEA_EXT_WINDOW 0x00000100 /* Extended Window Size */
#define L2CAP_EXTFEA_UCD_RECEPTION 0x00000200 /* Unicast Connectionless Data Reception */
/* Mask for locally supported features used in Information Response (default to none) */
#ifndef L2CAP_EXTFEA_SUPPORTED_MASK
#define L2CAP_EXTFEA_SUPPORTED_MASK 0
#endif
/* Mask for LE supported features used in Information Response (default to none) */
#ifndef L2CAP_BLE_EXTFEA_MASK
#define L2CAP_BLE_EXTFEA_MASK 0
#endif
/* Define a value that tells L2CAP to use the default HCI ACL buffer pool */
#define L2CAP_DEFAULT_ERM_POOL_ID 0xFF
/* Define a value that tells L2CAP to use the default MPS */
#define L2CAP_DEFAULT_ERM_MPS 0x0000
#define L2CAP_FCR_OVERHEAD 2 /* Control word */
#define L2CAP_FCS_LEN 2 /* FCS takes 2 bytes */
#define L2CAP_SDU_LEN_OVERHEAD 2 /* SDU length field is 2 bytes */
#define L2CAP_SDU_LEN_OFFSET 2 /* SDU length offset is 2 bytes */
#define L2CAP_EXT_CONTROL_OVERHEAD 4 /* Extended Control Field */
#define L2CAP_MAX_HEADER_FCS (L2CAP_PKT_OVERHEAD + L2CAP_EXT_CONTROL_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN)
/* length(2), channel(2), control(4), SDU length(2) FCS(2) */
/* Part of L2CAP_MIN_OFFSET that is not part of L2CAP
*/
#define L2CAP_OFFSET_WO_L2HDR (L2CAP_MIN_OFFSET-(L2CAP_PKT_OVERHEAD+L2CAP_FCR_OVERHEAD))
/* SAR bits in the control word
*/
#define L2CAP_FCR_UNSEG_SDU 0x0000 /* Control word to begin with for unsegmented PDU*/
#define L2CAP_FCR_START_SDU 0x4000 /* ...for Starting PDU of a semented SDU */
#define L2CAP_FCR_END_SDU 0x8000 /* ...for ending PDU of a segmented SDU */
#define L2CAP_FCR_CONT_SDU 0xc000 /* ...for continuation PDU of a segmented SDU */
/* Supervisory frame types
*/
#define L2CAP_FCR_SUP_RR 0x0000 /* Supervisory frame - RR */
#define L2CAP_FCR_SUP_REJ 0x0001 /* Supervisory frame - REJ */
#define L2CAP_FCR_SUP_RNR 0x0002 /* Supervisory frame - RNR */
#define L2CAP_FCR_SUP_SREJ 0x0003 /* Supervisory frame - SREJ */
#define L2CAP_FCR_SAR_BITS 0xC000 /* Mask to get the SAR bits from control word */
#define L2CAP_FCR_SAR_BITS_SHIFT 14 /* Bits to shift right to get the SAR bits from ctrl-word */
#define L2CAP_FCR_S_FRAME_BIT 0x0001 /* Mask to check if a PDU is S-frame */
#define L2CAP_FCR_REQ_SEQ_BITS 0x3F00 /* Mask to get the req-seq from control word */
#define L2CAP_FCR_REQ_SEQ_BITS_SHIFT 8 /* Bits to shift right to get the req-seq from ctrl-word */
#define L2CAP_FCR_TX_SEQ_BITS 0x007E /* Mask on get the tx-seq from control word */
#define L2CAP_FCR_TX_SEQ_BITS_SHIFT 1 /* Bits to shift right to get the tx-seq from ctrl-word */
#define L2CAP_FCR_F_BIT 0x0080 /* F-bit in the control word (Sup and I frames) */
#define L2CAP_FCR_P_BIT 0x0010 /* P-bit in the control word (Sup frames only) */
#define L2CAP_FCR_F_BIT_SHIFT 7
#define L2CAP_FCR_P_BIT_SHIFT 4
#define L2CAP_FCR_SEG_BITS 0xC000 /* Mask to get the segmentation bits from ctrl-word */
#define L2CAP_FCR_SUP_SHIFT 2 /* Bits to shift right to get the S-bits from ctrl-word */
#define L2CAP_FCR_SUP_BITS 0x000C /* Mask to get the supervisory bits from ctrl-word */
#define L2CAP_FCR_INIT_CRC 0 /* Initial state of the CRC register */
#define L2CAP_FCR_SEQ_MODULO 0x3F /* Mask for sequence numbers (range 0 - 63) */
/*************************************************************************************************
** The following definitions are only used for internal testing of ERTM at the application level
*************************************************************************************************/
/* L2CA_SetupErtmTest() corruption test types */
#define L2CAP_FCR_TTYPE_CORR_IFRAME 0 /* Corrupt one or more I-frames, based on count */
#define L2CAP_FCR_TTYPE_CORR_SFRAME 1 /* Corrupt an S-frame, (acknowledgement) */
#define L2CAP_FCR_TTYPE_STOP_TEST 2 /* Used when turning off a test */
#define L2CAP_FCR_TTYPE_GET_CID 3 /* Returns RFCOMM cid when '0' is passed in cid argument */
/* L2CA_SetupErtmTest() Freq */
#define L2CAP_FCR_FREQ_NORMAL 0 /* A single test is run */
#define L2CAP_FCR_FREQ_RANDOM 1 /* Randomly loses or corrupts a packet */
#endif

View file

@ -0,0 +1,670 @@
/** @file
*
* MiCO Bluetooth Low Energy (BLE) Functions
*
*/
#pragma once
#include "mico_bt_dev.h"
#define CHNL_MAP_LEN 5
typedef uint8_t mico_bt_ble_chnl_map_t[CHNL_MAP_LEN];
/** Scan modes */
enum mico_bt_ble_scan_mode_e {
BTM_BLE_SCAN_MODE_PASSIVE = 0, /**< Passive scan mode */
BTM_BLE_SCAN_MODE_ACTIVE = 1, /**< Active scan mode */
BTM_BLE_SCAN_MODE_NONE = 0xff /**< None */
};
typedef uint8_t mico_bt_ble_scan_mode_t; /**< scan mode (see #mico_bt_ble_scan_mode_e) */
/** Scan filter policy */
enum mico_bt_ble_scan_filter_policy_e {
BTM_BLE_SCAN_FILTER_POLICY_NONE = 0, /**< Not use White List for Scanning Procedure. */
BTM_BLE_SCAN_FILTER_POLICY_WHITE_LIST = 1, /**< Use White List for Scanning Procedure. */
};
typedef uint8_t mico_bt_ble_scan_filter_policy_t; /**< scan filter policy (see #mico_bt_ble_scan_filter_policy_e) */
/** advertising channel map */
enum mico_bt_ble_advert_chnl_map_e {
BTM_BLE_ADVERT_CHNL_37 = (0x01 << 0), /**< ADV channel */
BTM_BLE_ADVERT_CHNL_38 = (0x01 << 1), /**< ADV channel */
BTM_BLE_ADVERT_CHNL_39 = (0x01 << 2) /**< ADV channel */
};
typedef uint8_t
mico_bt_ble_advert_chnl_map_t; /**< BLE advertisement channel map (see #mico_bt_ble_advert_chnl_map_e) */
/* default advertising channel map */
#ifndef BTM_BLE_DEFAULT_ADVERT_CHNL_MAP
#define BTM_BLE_DEFAULT_ADVERT_CHNL_MAP (BTM_BLE_ADVERT_CHNL_37| BTM_BLE_ADVERT_CHNL_38| BTM_BLE_ADVERT_CHNL_39)
#endif
/** Advertising filter policy */
enum mico_bt_ble_advert_filter_policy_e {
BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ = 0x00, /**< Process scan and connection requests from all devices (i.e., the White List is not in use) (default) */
BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x01, /**< Process connection requests from all devices and only scan requests from devices that are in the White List. */
BTM_BLE_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ = 0x02, /**< Process scan requests from all devices and only connection requests from devices that are in the White List */
BTM_BLE_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x03, /**< Process scan and connection requests only from devices in the White List. */
BTM_BLE_ADVERT_FILTER_MAX
};
typedef uint8_t
mico_bt_ble_advert_filter_policy_t; /**< Advertising filter policy (see #mico_bt_ble_advert_filter_policy_e) */
/* default advertising filter policy */
#define BTM_BLE_ADVERT_FILTER_DEFAULT BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ
/* adv parameter boundary values */
#define BTM_BLE_ADVERT_INTERVAL_MIN 0x0020
#define BTM_BLE_ADVERT_INTERVAL_MAX 0x4000
/* connection parameter boundary values */
#define BTM_BLE_SCAN_INTERVAL_MIN 0x0004
#define BTM_BLE_SCAN_INTERVAL_MAX 0x4000
#define BTM_BLE_SCAN_WINDOW_MIN 0x0004
#define BTM_BLE_SCAN_WINDOW_MAX 0x4000
#define BTM_BLE_CONN_INTERVAL_MIN 0x0006
#define BTM_BLE_CONN_INTERVAL_MAX 0x0C80
#define BTM_BLE_CONN_LATENCY_MAX 500
#define BTM_BLE_CONN_SUP_TOUT_MIN 0x000A
#define BTM_BLE_CONN_SUP_TOUT_MAX 0x0C80
#define BTM_BLE_CONN_PARAM_UNDEF 0xffff /* use this value when a specific value not to be overwritten */
#define BTM_BLE_CONN_SUP_TOUT_DEF 700
/* default connection parameters if not configured, use GAP recommend value for auto/selective connection */
/* default scan interval */
#define BTM_BLE_SCAN_FAST_INTERVAL 96 /* 30 ~ 60 ms (use 60) = 96 *0.625 */
/* default scan window for background connection, applicable for auto connection or selective conenction */
#define BTM_BLE_SCAN_FAST_WINDOW 48 /* 30 ms = 48 *0.625 */
/* default scan paramter used in reduced power cycle (background scanning) */
#define BTM_BLE_SCAN_SLOW_INTERVAL_1 2048 /* 1.28 s = 2048 *0.625 */
#define BTM_BLE_SCAN_SLOW_WINDOW_1 18 /* 11.25 ms = 18 *0.625 */
/* default scan paramter used in reduced power cycle (background scanning) */
#define BTM_BLE_SCAN_SLOW_INTERVAL_2 4096 /* 2.56 s = 4096 *0.625 */
#define BTM_BLE_SCAN_SLOW_WINDOW_2 36 /* 22.5 ms = 36 *0.625 */
/* default connection interval min */
#define BTM_BLE_CONN_INTERVAL_MIN_DEF 24 /* recommended min: 30ms = 24 * 1.25 */
/* default connectino interval max */
#define BTM_BLE_CONN_INTERVAL_MAX_DEF 40 /* recommended max: 50 ms = 56 * 1.25 */
/* default slave latency */
#define BTM_BLE_CONN_SLAVE_LATENCY_DEF 0 /* 0 */
/* default supervision timeout */
#define BTM_BLE_CONN_TIMEOUT_DEF 2000
#define BTM_BLE_DIR_CONN_FALLBACK_UNDIR 1
#define BTM_BLE_DIR_CONN_FALLBACK_NO_ADV 2
#define BTM_BLE_DIR_CONN_FALLBACK BTM_BLE_DIR_CONN_FALLBACK_UNDIR
/** BLE Signature */
#define BTM_BLE_AUTH_SIGNATURE_SIZE 12 /**< BLE data signature length 8 Bytes + 4 bytes counter*/
typedef uint8_t
mico_dev_ble_signature_t[BTM_BLE_AUTH_SIGNATURE_SIZE]; /**< Device address (see #BTM_BLE_AUTH_SIGNATURE_SIZE) */
#define BTM_BLE_POLICY_BLACK_ALL 0x00 /* relevant to both */
#define BTM_BLE_POLICY_ALLOW_SCAN 0x01 /* relevant to advertiser */
#define BTM_BLE_POLICY_ALLOW_CONN 0x02 /* relevant to advertiser */
#define BTM_BLE_POLICY_WHITE_ALL 0x03 /* relevant to both */
/* ADV data flag bit definition used for BTM_BLE_ADVERT_TYPE_FLAG */
#define BTM_BLE_LIMITED_DISCOVERABLE_FLAG (0x01 << 0)
#define BTM_BLE_GENERAL_DISCOVERABLE_FLAG (0x01 << 1)
#define BTM_BLE_BREDR_NOT_SUPPORTED (0x01 << 2)
/* 4.1 spec adv flag for simultaneous BR/EDR+LE connection support (see) */
#define BTM_BLE_SIMULTANEOUS_DUAL_MODE_TO_SAME_DEVICE_CONTROLLER_SUPPORTED (0x01 << 3) /**< Simultaneous LE and BR/EDR to Same Device Capable (Controller). */
#define BTM_BLE_SIMULTANEOUS_DUAL_MODE_TO_SAME_DEVICE_HOST_SUPPORTED (0x01 << 4) /**< Simultaneous LE and BR/EDR to Same Device Capable (Host). */
#define BTM_BLE_NON_LIMITED_DISCOVERABLE_FLAG (0x00 ) /* lowest bit unset */
#define BTM_BLE_ADVERT_FLAG_MASK (BTM_BLE_LIMITED_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED | BTM_BLE_GENERAL_DISCOVERABLE_FLAG)
#define BTM_BLE_LIMITED_DISCOVERABLE_MASK (BTM_BLE_LIMITED_DISCOVERABLE_FLAG )
/** Advertisement Data bit masks */
enum mico_bt_ble_advert_mask_e {
BTM_BLE_ADVERT_BIT_DEV_NAME = (0x00000001 << 0), /**< Device Name */
BTM_BLE_ADVERT_BIT_FLAGS = (0x00000001 << 1), /**< Flags */
BTM_BLE_ADVERT_BIT_MANUFACTURER = (0x00000001 << 2), /**< Manufacturer Specific Data */
BTM_BLE_ADVERT_BIT_TX_POWER = (0x00000001 << 3), /**< Transmit Power Level */
BTM_BLE_ADVERT_BIT_INTERVAL_RANGE = (0x00000001 << 5), /**< Slave preferred connection interval range */
BTM_BLE_ADVERT_BIT_SERVICE = (0x00000001 << 6), /**< Service UUID (16-bit) */
BTM_BLE_ADVERT_BIT_SERVICE_SOLICITATION = (0x00000001 << 7), /**< Service Solicitation (16-bit) */
BTM_BLE_ADVERT_BIT_SERVICE_DATA = (0x00000001 << 8), /**< Service Data */
BTM_BLE_ADVERT_BIT_SIGN_DATA = (0x00000001 << 9), /**< Signed data */
BTM_BLE_ADVERT_BIT_SERVICE_128SOLICITATION = (0x00000001 << 10), /**< Service Solicitation (128-bit) */
BTM_BLE_ADVERT_BIT_APPEARANCE = (0x00000001 << 11), /**< Appearance */
BTM_BLE_ADVERT_BIT_PUBLIC_ADDR = (0x00000001 << 12), /**< Public Target Address */
BTM_BLE_ADVERT_BIT_RANDOM_ADDR = (0x00000001 << 13), /**< Random Target Address */
BTM_BLE_ADVERT_BIT_SERVICE_32 = (0x00000001 << 4), /**< Service UUIDs (32-bit) */
BTM_BLE_ADVERT_BIT_SERVICE_32SOLICITATION = (0x00000001 << 14), /**< Service Solicitation (32-bit) */
BTM_BLE_ADVERT_BIT_PROPRIETARY = (0x00000001 << 15), /**< Priorpietary */
BTM_BLE_ADVERT_BIT_SERVICE_128 = (0x00000001 << 16) /**< Service UUIDs (128-bit) */
};
typedef uint32_t mico_bt_ble_advert_mask_t; /**< BLE advertisement mask (see #mico_bt_ble_advert_mask_e) */
/** Advertisement data types */
enum mico_bt_ble_advert_type_e {
BTM_BLE_ADVERT_TYPE_FLAG = 0x01, /**< Advertisement flags */
BTM_BLE_ADVERT_TYPE_16SRV_PARTIAL = 0x02, /**< List of supported services - 16 bit UUIDs (partial) */
BTM_BLE_ADVERT_TYPE_16SRV_COMPLETE = 0x03, /**< List of supported services - 16 bit UUIDs (complete) */
BTM_BLE_ADVERT_TYPE_32SRV_PARTIAL = 0x04, /**< List of supported services - 32 bit UUIDs (partial) */
BTM_BLE_ADVERT_TYPE_32SRV_COMPLETE = 0x05, /**< List of supported services - 32 bit UUIDs (complete) */
BTM_BLE_ADVERT_TYPE_128SRV_PARTIAL = 0x06, /**< List of supported services - 128 bit UUIDs (partial) */
BTM_BLE_ADVERT_TYPE_128SRV_COMPLETE = 0x07, /**< List of supported services - 128 bit UUIDs (complete) */
BTM_BLE_ADVERT_TYPE_NAME_SHORT = 0x08, /**< Short name */
BTM_BLE_ADVERT_TYPE_NAME_COMPLETE = 0x09, /**< Complete name */
BTM_BLE_ADVERT_TYPE_TX_POWER = 0x0A, /**< TX Power level */
BTM_BLE_ADVERT_TYPE_DEV_CLASS = 0x0D, /**< Device Class */
BTM_BLE_ADVERT_TYPE_SM_TK = 0x10, /**< Security manager TK value */
BTM_BLE_ADVERT_TYPE_SM_OOB_FLAG = 0x11, /**< Security manager Out-of-Band data */
BTM_BLE_ADVERT_TYPE_INTERVAL_RANGE = 0x12, /**< Slave connection interval range */
BTM_BLE_ADVERT_TYPE_SOLICITATION_SRV_UUID = 0x14, /**< List of solicitated services - 16 bit UUIDs */
BTM_BLE_ADVERT_TYPE_128SOLICITATION_SRV_UUID = 0x15, /**< List of solicitated services - 128 bit UUIDs */
BTM_BLE_ADVERT_TYPE_SERVICE_DATA = 0x16, /**< Service data - 16 bit UUID */
BTM_BLE_ADVERT_TYPE_PUBLIC_TARGET = 0x17, /**< Public target address */
BTM_BLE_ADVERT_TYPE_RANDOM_TARGET = 0x18, /**< Random target address */
BTM_BLE_ADVERT_TYPE_APPEARANCE = 0x19, /**< Appearance */
BTM_BLE_ADVERT_TYPE_ADVERT_INTERVAL = 0x1a, /**< Advertising interval */
BTM_BLE_ADVERT_TYPE_32SOLICITATION_SRV_UUID = 0x1b, /**< List of solicitated services - 32 bit UUIDs */
BTM_BLE_ADVERT_TYPE_32SERVICE_DATA = 0x1c, /**< Service data - 32 bit UUID */
BTM_BLE_ADVERT_TYPE_128SERVICE_DATA = 0x1d, /**< Service data - 128 bit UUID */
BTM_BLE_ADVERT_TYPE_MANUFACTURER = 0xFF /**< Manufacturer data */
};
typedef uint8_t mico_bt_ble_advert_type_t; /**< BLE advertisement data type (see #mico_bt_ble_advert_type_e) */
/** security settings used with L2CAP LE COC */
enum mico_bt_ble_sec_flags_e {
BTM_SEC_LE_LINK_ENCRYPTED = 0x01, /**< Link encrypted */
BTM_SEC_LE_LINK_PAIRED_WITHOUT_MITM = 0x02, /**< Paired without man-in-the-middle protection */
BTM_SEC_LE_LINK_PAIRED_WITH_MITM = 0x04 /**< Link with man-in-the-middle protection */
};
/** Slave preferred connection interval range */
typedef struct {
uint16_t low; /**< Preferred low connection interval */
uint16_t hi; /**< Preferred high connection interval */
} mico_bt_ble_int_range_t;
/** Service tag supported in the device */
typedef struct {
uint8_t num_service; /**< Number of services */
mico_bool_t list_cmpl; /**< Complete list or not */
uint16_t *p_uuid; /**< 16-bit UUID data */
} mico_bt_ble_service_t;
/** 32 bits Service supported in the device */
typedef struct {
uint8_t num_service; /**< Number of services */
mico_bool_t list_cmpl; /**< Complete list or not */
uint32_t *p_uuid; /**< 32-bit UUID data */
} mico_bt_ble_32service_t;
/** 128 bits Service supported in the device */
typedef struct {
mico_bool_t list_cmpl; /**< Complete list or not */
uint8_t uuid128[MAX_UUID_SIZE]; /**< 128-bit UUID data */
} mico_bt_ble_128service_t;
/** Manufacturer data supported in the device */
typedef struct {
uint8_t len; /**< Length of manufacturer data */
uint8_t *p_val; /**< Manufacturer data */
} mico_bt_ble_manu_t;
/** Service data supported in the device */
typedef struct {
mico_bt_uuid_t service_uuid; /**< Service UUID data */
uint8_t len; /**< Service UUID length */
uint8_t *p_val; /**< Service data value */
} mico_bt_ble_service_data_t;
/** Proprietary data element supported in the device */
typedef struct {
uint8_t advert_type; /**< Advertisement type */
uint8_t len; /**< Advertisement length */
uint8_t *p_val; /**< Element data */
} mico_bt_ble_prop_elem_t;
/** Proprietary data elements structure supported in the device */
typedef struct {
uint8_t num_elem; /**< Number of elements */
mico_bt_ble_prop_elem_t *p_elem; /**< Proprietary elements */
} mico_bt_ble_proprietary_t;
/** Advertising data */
typedef struct {
mico_bt_ble_int_range_t
int_range; /**< slave preferred connection interval range (BTM_BLE_ADVERT_BIT_INTERVAL_RANGE) */
mico_bt_ble_manu_t *p_manu; /**< manufacturer data (BTM_BLE_ADVERT_BIT_MANUFACTURER) */
mico_bt_ble_service_t
*p_services; /**< list of supported services - 16 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE) */
mico_bt_ble_128service_t
*p_services_128b; /**< list of supported services - 128 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_128) */
mico_bt_ble_32service_t
*p_service_32b; /**< list of supported services - 32 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_32) */
mico_bt_ble_service_t
*p_sol_services; /**< list of solicited services - 16 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_SOLICITATION) */
mico_bt_ble_32service_t
*p_sol_service_32b; /**< list of solicited services - 32 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_32SOLICITATION) */
mico_bt_ble_128service_t
*p_sol_service_128b; /**< list of solicited services - 128 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_128SOLICITATION) */
mico_bt_ble_proprietary_t
*p_proprietary; /**< list of proprietary data elements (BTM_BLE_ADVERT_BIT_PROPRIETARY) */
mico_bt_ble_service_data_t *p_service_data; /**< service data (BTM_BLE_ADVERT_BIT_SERVICE_DATA) */
uint16_t appearance; /**< appearance (BTM_BLE_ADVERT_BIT_APPEARANCE) */
uint8_t flag; /**< flag (BTM_BLE_ADVERT_BIT_FLAGS) */
uint8_t tx_power; /**< transmit power (BTM_BLE_ADVERT_BIT_TX_POWER) */
} mico_bt_ble_advert_data_t;
/** Scan result event type */
enum mico_bt_dev_ble_evt_type_e {
BTM_BLE_EVT_CONNECTABLE_ADVERTISEMENT = 0x00, /**< Connectable advertisement */
BTM_BLE_EVT_CONNECTABLE_DIRECTED_ADVERTISEMENT = 0x01, /**< Connectable Directed advertisement */
BTM_BLE_EVT_SCANNABLE_ADVERTISEMENT = 0x02, /**< Scannable advertisement */
BTM_BLE_EVT_NON_CONNECTABLE_ADVERTISEMENT = 0x03, /**< Non connectable advertisement */
BTM_BLE_EVT_SCAN_RSP = 0x04 /**< Scan response */
};
typedef uint8_t mico_bt_dev_ble_evt_type_t; /**< Scan result event value (see #mico_bt_dev_ble_evt_type_e) */
/** Background connection type */
enum mico_bt_ble_conn_type_e {
BTM_BLE_CONN_NONE, /**< No background connection */
BTM_BLE_CONN_AUTO, /**< Auto connection */
BTM_BLE_CONN_SELECTIVE /**< Selective connection */
};
typedef uint8_t mico_bt_ble_conn_type_t; /**< Connection type (see #mico_bt_ble_conn_type_e) */
/** LE inquiry result type */
typedef struct {
mico_bt_device_address_t remote_bd_addr; /**< Device address */
uint8_t ble_addr_type; /**< LE Address type */
mico_bt_dev_ble_evt_type_t ble_evt_type; /**< Scan result event type */
int8_t
rssi; /**< Set to #BTM_INQ_RES_IGNORE_RSSI, if not valid */
uint8_t flag;
uint8_t length;
} mico_bt_ble_scan_results_t;
/**
* Callback mico_bt_ble_selective_conn_cback_t
*
* Selective connection callback (registered with #mico_bt_ble_set_background_connection_type)
*
* @param remote_bda : remote device
* @param p_remote_name : remote device name
*
* @return
*/
typedef bool (mico_bt_ble_selective_conn_cback_t)(mico_bt_device_address_t remote_bda, uint8_t *p_remote_name,
const uint8_t *p_data, uint8_t length);
/**
* Callback mico_bt_ble_scan_result_cback_t
*
* Scan result callback (from calling #mico_bt_ble_scan)
*
* @param p_scan_result : scan result data (NULL indicates end of scanning)
* @param p_adv_data : Advertisement data (parse using #mico_bt_ble_check_advertising_data)
*
* @return Nothing
*/
typedef void (mico_bt_ble_scan_result_cback_t) (mico_bt_ble_scan_results_t *p_scan_result, uint8_t *p_adv_data);
/******************************************************
* Function Declarations
*
******************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup btm_ble_api_functions BLE (Bluetooth Low Energy)
* @ingroup micobt_DeviceManagement
*
* BLE (Bluetooth Low Energy) Functions.
*
* @{
*/
/**
*
* Function mico_bt_start_advertisements
*
* Start advertising.
*
* Use #mico_bt_ble_set_advertisement_data to configure advertising data
* prior to starting avertisements.
*
* The <b>advert_mode</b> parameter determines what advertising parameters and durations
* to use (as specified by the application configuration).
*
* @param[in] advert_mode : advertisement mode
* @param[in] directed_advertisement_bdaddr_type : BLE_ADDR_PUBLIC or BLE_ADDR_RANDOM (if using directed advertisement mode)
* @param[in] directed_advertisement_bdaddr_ptr : Directed advertisement address (NULL if not using directed advertisement)
*
* @return status
*
*/
mico_bt_result_t mico_bt_start_advertisements(mico_bt_ble_advert_mode_t advert_mode,
mico_bt_ble_address_type_t directed_advertisement_bdaddr_type,
mico_bt_device_address_ptr_t directed_advertisement_bdaddr_ptr);
/**
*
* Function mico_bt_ble_get_current_advert_mode
*
* Get current advertising mode
*
* @return Current advertising mode
*
*/
mico_bt_ble_advert_mode_t mico_bt_ble_get_current_advert_mode(void);
/**
*
* Function mico_bt_ble_set_advertisement_data
*
* Set advertisement data.
*
* @param[in] data_mask : mask of data types to include in the advertisement data
* @param[in] p_data : advertisement data
*
* @return void
*
*/
mico_bt_result_t mico_bt_ble_set_advertisement_data(mico_bt_ble_advert_mask_t data_mask,
mico_bt_ble_advert_data_t *p_data);
/**
*
* Function mico_bt_ble_set_scan_response_data
*
* Set scan response data
*
* @param[in] data_mask : mask of data types to include in the scan response data
* @param[in] p_data : scan response data
*
* @return status of the operation
*
*/
mico_bt_dev_status_t mico_bt_ble_set_scan_response_data(mico_bt_ble_advert_mask_t data_mask,
mico_bt_ble_advert_data_t *p_data);
/**
* Function mico_bt_ble_scan
*
* Start LE scanning
*
* The <b>scan_type</b> parameter determines what scanning parameters and durations
* to use (as specified by the application configuration).
*
* Scan results are notified using <b>p_scan_result_cback</b>
*
* @param[in] scan_type : BTM_BLE_SCAN_TYPE_NONE, BTM_BLE_SCAN_TYPE_HIGH_DUTY, BTM_BLE_SCAN_TYPE_LOW_DUTY
* @param[in] duplicate_filter_enable : TRUE or FALSE to enable or disable duplicate filtering
*
* @param[in] p_scan_result_cback : scan result callback
*
* @return mico_bt_result_t
*
* MICO_BT_PENDING if successfully initiated
* MICO_BT_BUSY if already in progress
* MICO_BT_ILLEGAL_VALUE if parameter(s) are out of range
* MICO_BT_NO_RESOURCES if could not allocate resources to start the command
* MICO_BT_WRONG_MODE if the device is not up.
*/
mico_bt_result_t mico_bt_ble_scan (mico_bt_ble_scan_type_t scan_type, mico_bool_t duplicate_filter_enable,
mico_bt_ble_scan_result_cback_t *p_scan_result_cback);
/**
*
* Function mico_bt_ble_get_current_scan_state
*
* Get current scan state
*
* @return mico_bt_ble_scan_type_t
*
* BTM_BLE_SCAN_TYPE_NONE Not scanning
* BTM_BLE_SCAN_TYPE_HIGH_DUTY High duty cycle scan
* BTM_BLE_SCAN_TYPE_LOW_DUTY Low duty cycle scan
*/
mico_bt_ble_scan_type_t mico_bt_ble_get_current_scan_state(void);
/**
*
* Function mico_bt_ble_security_grant
*
* Grant or deny access. Used in response to an BTM_SECURITY_REQUEST_EVT event.
*
* @param[in] bd_addr : peer device bd address.
* @param[in] res : BTM_SUCCESS to grant access; BTM_REPEATED_ATTEMPTS otherwise
*
* @return <b> None </b>
*
*/
void mico_bt_ble_security_grant(mico_bt_device_address_t bd_addr, uint8_t res);
/**
*
* Function mico_bt_ble_data_signature
*
* Sign the data using AES128 CMAC algorith.
*
* @param[in] bd_addr: target device the data to be signed for.
* @param[in] p_text: signing data
* @param[in] len: length of the signing data
* @param[in] signature: output parameter where data signature is going to be stored
*
* @return TRUE if signing successful, otherwise FALSE.
*
*/
mico_bool_t mico_bt_ble_data_signature (mico_bt_device_address_t bd_addr, uint8_t *p_text, uint16_t len,
mico_dev_ble_signature_t signature);
/**
*
* Function mico_bt_ble_verify_signature
*
* Verify the data signature
*
* @param[in] bd_addr: target device the data to be signed for.
* @param[in] p_orig: original data before signature.
* @param[in] len: length of the signing data
* @param[in] counter: counter used when doing data signing
* @param[in] p_comp: signature to be compared against.
*
* @return TRUE if signature verified correctly; otherwise FALSE.
*
*/
mico_bool_t mico_bt_ble_verify_signature (mico_bt_device_address_t bd_addr, uint8_t *p_orig,
uint16_t len, uint32_t counter,
uint8_t *p_comp);
/**
*
* Function mico_bt_ble_set_background_connection_type
*
* Set BLE background connection procedure type.
*
* @param[in] conn_type: BTM_BLE_CONN_NONE, BTM_BLE_CONN_AUTO, or BTM_BLE_CONN_SELECTIVE
* @param[in] p_select_cback: callback for BTM_BLE_CONN_SELECTIVE
*
* @return TRUE if background connection set
*
*/
mico_bool_t mico_bt_ble_set_background_connection_type (mico_bt_ble_conn_type_t conn_type,
mico_bt_ble_selective_conn_cback_t *p_select_cback);
/**
*
* Function mico_bt_ble_update_background_connection_device
*
* This function is called to add or remove a device into/from
* background connection procedure. The background connection
* procedure is decided by the background connection type, it can be
* auto connection, or selective connection.
*
* @param[in] add_remove: TRUE to add; FALSE to remove.
* @param[in] remote_bda: device address to add/remove.
*
* @return TRUE if successful
*
*/
mico_bool_t mico_bt_ble_update_background_connection_device(mico_bool_t add_remove,
mico_bt_device_address_t remote_bda);
/**
*
* Function mico_bt_ble_get_background_connection_device_size
*
* Get a size of white list for the AUTO or SELECTIVE Connection Procedure.
*
* @param[out] size: white list size
*
* @return MICO_TRUE or MICO_FALSE
*/
mico_bool_t mico_bt_ble_get_background_connection_device_size(uint8_t *size);
/**
*
* Function mico_bt_ble_check_advertising_data
*
* Parse advertising data (returned from scan results callback #mico_bt_ble_scan_result_cback_t).
* Look for specified advertisement data type.
*
* @param[in] p_adv : pointer to advertisement data
* @param[in] type : advertisement data type to look for
* @param[out] p_length : length of advertisement data (if found)
*
* @return pointer to start of requested advertisement data (if found). NULL if requested data type not found.
*
*/
uint8_t *mico_bt_ble_check_advertising_data( uint8_t *p_adv, mico_bt_ble_advert_type_t type, uint8_t *p_length);
/**
*
* Function mico_bt_ble_enable_privacy
*
* This function is called to enable or disable the privacy in
* the local device.
*
* @param[in] enable: TRUE to enable it; FALSE to disable it.
*
* @return void
*
*/
void mico_bt_ble_enable_privacy (mico_bool_t enable);
/**
*
* Function mico_bt_ble_enable_mixed_privacy_mode
*
* This function is called to enabled Mixed mode if privacy 1.2
* is applicable in controller.
*
* @param[in] mixed_on: mixed mode to be used or not.
*
* @return void
*
*/
void mico_bt_ble_enable_mixed_privacy_mode(mico_bool_t mixed_on);
/**
*
* Function mico_bt_ble_get_security_state
*
* Get security mode 1 flags and encryption key size for LE peer.
*
* @param[in] bd_addr : peer address
* @param[out] p_le_sec_flags : security flags (see #mico_bt_ble_sec_flags_e)
* @param[out] p_le_key_size : encryption key size
*
* @return TRUE if successful
*
*/
mico_bool_t mico_bt_ble_get_security_state (mico_bt_device_address_t bd_addr, uint8_t *p_le_sec_flags,
uint8_t *p_le_key_size);
/**
*
* Function mico_bt_ble_update_advertising_white_list
*
* Add or remove device from advertising white list
*
* @param[in] add: TRUE to add; FALSE to remove
* @param[in] remote_bda: remote device address.
*
* @return void
*
*/
mico_bool_t mico_bt_ble_update_advertising_white_list(mico_bool_t add, const mico_bt_device_address_t remote_bda);
/**
*
* Function mico_bt_ble_update_advertisement_filter_policy
*
* Update the filter policy of advertiser.
*
* @param[in] advertising_policy: advertising filter policy
*
* @return void
*/
mico_bool_t mico_bt_ble_update_advertisement_filter_policy(mico_bt_ble_advert_filter_policy_t advertising_policy);
/**
*
* Function mico_bt_ble_get_advertisement_white_list_size
*
* Get advertisement white list size.
*
* @param[out] size: white list size
*
* @return MICO_TRUE or MICO_FALSE
*/
mico_bool_t mico_bt_ble_get_advertisement_white_list_size(uint8_t *size);
/**
*
* Function mico_bt_ble_get_white_list_capability
*
* Get All white list size.
*
* @param[out] size: white list size
*
* @return MICO_TRUE or MICO_FALSE
*/
mico_bool_t mico_bt_ble_get_white_list_capability(uint8_t *size);
/**
*
* Function mico_bt_ble_clear_white_list
*
* Clear white list (Advertisement & background connection).
*
* @param none
*
* @return MICO_TRUE or MICO_FALSE
*/
mico_bool_t mico_bt_ble_clear_white_list(void);
/**@} btm_ble_api_functions */
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,297 @@
/** @file
*
* Runtime Bluetooth configuration parameters
*
*/
#pragma once
#include "data_types.h"
#include "mico_bt_types.h"
#include "mico_bt_dev.h"
#include "mico_bt_ble.h"
#include "mico_bt_gatt.h"
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
* Default configuration values
****************************************************************************/
#define MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL 0x0800 /**< Inquiry scan interval */
#define MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW 0x0012 /**< Inquiry scan window */
#define MICO_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL 0x0800 /**< Page scan interval */
#define MICO_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW 0x0012 /**< Page scan window */
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL 96 /**< High duty scan interval */
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW 48 /**< High duty scan window */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL 2048 /**< Low duty scan interval */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW 18 /**< Low duty scan window */
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL 96 /**< High duty cycle connection scan interval BTM_BLE_SCAN_FAST_INT*/
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW 48 /**< High duty cycle connection scan window BTM_BLE_SCAN_FAST_WIN */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL 2048 /**< Low duty cycle connection scan interval BTM_BLE_SCAN_SLOW_INT_1 */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW 18 /**< Low duty cycle connection scan window BTM_BLE_SCAN_SLOW_WIN_1 */
#define MICO_BT_CFG_DEFAULT_CONN_MIN_INTERVAL 24 /**< Minimum connection event interval */
#define MICO_BT_CFG_DEFAULT_CONN_MAX_INTERVAL 40 /**< Maximum connection event interval */
#define MICO_BT_CFG_DEFAULT_CONN_LATENCY 0 /**< Connection latency */
#define MICO_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT 700 /**< Connection link supervsion timeout */
/* undirected connectable advertisement high/low duty cycle interval default */
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL 48 /**< Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL 48 /**< Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL 2048 /**< Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL 2048 /**< Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */
/* non-connectable advertisement high/low duty cycle advertisement interval default */
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL 160 /**< Tgap(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL 160 /**< Tgap(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL 2048 /**< Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL 2048 /**< Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */
/* directed connectable advertisement high/low duty cycle interval default */
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL 400 /**< Tgap(dir_conn_adv_int_max) = 250 ms = 400 * 0.625 ms */
#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL 800 /**< Tgap(dir_conn_adv_int_min) = 500 ms = 800 * 0.625 ms */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL 48 /**< Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */
#define MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL 48 /**< Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */
/*****************************************************************************
* mico_bt core stack configuration
****************************************************************************/
/** BR/EDR scan settings */
typedef struct {
uint16_t
inquiry_scan_type; /**< Inquiry scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */
uint16_t
inquiry_scan_interval; /**< Inquiry scan interval (default: MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL) */
uint16_t
inquiry_scan_window; /**< Inquiry scan window (default: MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW) */
uint16_t
page_scan_type; /**< Page scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */
uint16_t
page_scan_interval; /**< Page scan interval (default: MICO_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL) */
uint16_t
page_scan_window; /**< Page scan window (default: MICO_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW) */
} mico_bt_cfg_br_edr_scan_settings_t;
extern const mico_bt_cfg_br_edr_scan_settings_t
*mico_bt_cfg_br_edr_scan_settings; /**< BR/EDR Scan settings (NULL to use defaults) */
/** LE Scan settings */
typedef struct {
mico_bt_ble_scan_mode_t
scan_mode; /**< BLE scan mode (BTM_BLE_SCAN_MODE_PASSIVE, BTM_BLE_SCAN_MODE_ACTIVE) */
mico_bt_ble_scan_filter_policy_t
scan_filter_policy; /**< BLE scan filter policy (FILTER_POLICY_NONE or FILTER_POLICY_WHITE_LIST) */
/* Advertisement scan configuration */
uint16_t
high_duty_scan_interval; /**< High duty scan interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL) */
uint16_t
high_duty_scan_window; /**< High duty scan window (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW) */
uint16_t
high_duty_scan_duration; /**< High duty scan duration in seconds (0 for infinite) */
uint16_t
low_duty_scan_interval; /**< Low duty scan interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL) */
uint16_t
low_duty_scan_window; /**< Low duty scan window (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW) */
uint16_t
low_duty_scan_duration; /**< Low duty scan duration in seconds (0 for infinite) */
/* Connection scan configuration */
uint16_t
high_duty_conn_scan_interval; /**< High duty cycle connection scan interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL) */
uint16_t
high_duty_conn_scan_window; /**< High duty cycle connection scan window (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW) */
uint16_t
high_duty_conn_duration; /**< High duty cycle connection duration in seconds (0 for infinite) */
uint16_t
low_duty_conn_scan_interval; /**< Low duty cycle connection scan interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL) */
uint16_t
low_duty_conn_scan_window; /**< Low duty cycle connection scan window (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW) */
uint16_t
low_duty_conn_duration; /**< Low duty cycle connection duration in seconds (0 for infinite) */
/* Connection configuration */
uint16_t
conn_min_interval; /**< Minimum connection interval (default: MICO_BT_CFG_DEFAULT_CONN_MIN_INTERVAL) */
uint16_t
conn_max_interval; /**< Maximum connection interval (default: MICO_BT_CFG_DEFAULT_CONN_MAX_INTERVAL) */
uint16_t
conn_latency; /**< Connection latency (default: MICO_BT_CFG_DEFAULT_CONN_LATENCY) */
uint16_t
conn_supervision_timeout; /**< Connection link supervision timeout (default: MICO_BT_CFG_DEFAULT_ CONN_SUPERVISION_TIMEOUT) */
} mico_bt_cfg_ble_scan_settings_t;
/** Advertising settings */
typedef struct {
mico_bt_ble_advert_chnl_map_t
channel_map; /**< Advertising channel map (mask of BTM_BLE_ADVERT_CHNL_37, BTM_BLE_ADVERT_CHNL_38, BTM_BLE_ADVERT_CHNL_39) */
uint16_t
high_duty_min_interval; /**< High duty undirected connectable advert minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL) */
uint16_t
high_duty_max_interval; /**< High duty undirected connectable advert maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL) */
uint16_t
high_duty_duration; /**< High duty advertising duration in seconds (0 for infinite) */
uint16_t
low_duty_min_interval; /**< Low duty undirected connectable advert minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL) */
uint16_t
low_duty_max_interval; /**< Low duty undirected connectable advert maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL) */
uint16_t
low_duty_duration; /**< Low duty advertising duration in seconds (0 for infinite) */
uint16_t
high_duty_directed_min_interval; /**< high duty directed adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL) */
uint16_t
high_duty_directed_max_interval; /**< high duty directed adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL) */
uint16_t
low_duty_directed_min_interval; /**< Low duty directed adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL) */
uint16_t
low_duty_directed_max_interval; /**< Low duty directed adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL) */
uint16_t
low_duty_directed_duration; /**< Low duty directed advertising duration in seconds (0 for infinite) */
uint16_t
high_duty_nonconn_min_interval; /**< High duty non-connectable adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL) */
uint16_t
high_duty_nonconn_max_interval; /**< High duty non-connectable adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL) */
uint16_t
high_duty_nonconn_duration; /**< High duty non-connectable advertising duration in seconds (0 for infinite) */
uint16_t
low_duty_nonconn_min_interval; /**< Low duty non-connectable adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL) */
uint16_t
low_duty_nonconn_max_interval; /**< Low duty non-connectable adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL) */
uint16_t
low_duty_nonconn_duration; /**< Low duty non-connectable advertising duration in seconds (0 for infinite) */
} mico_bt_cfg_ble_advert_settings_t;
/** GATT settings */
typedef struct {
mico_bt_gatt_appearance_t appearance; /**< GATT appearance (see #gatt_appearance_e) */
uint8_t
client_max_links; /**< Client config: maximum number of servers that local client can connect to */
uint8_t
server_max_links; /**< Server config: maximum number of remote clients connections allowed by the local */
uint16_t
max_attr_len; /**< Maximum attribute length; gki_cfg must have a corresponding buffer pool that can hold this length */
} mico_bt_cfg_gatt_settings_t;
/** Settings for application managed L2CAP protocols (optional) */
typedef struct {
uint8_t
max_links; /**< Maximum number of application-managed l2cap links (BR/EDR and LE) */
/* BR EDR l2cap configuration */
uint8_t
max_psm; /**< Maximum number of application-managed BR/EDR PSMs */
uint8_t
max_channels; /**< Maximum number of application-managed BR/EDR channels */
/* LE L2cap connection-oriented channels configuration */
uint8_t
max_le_psm; /**< Maximum number of application-managed LE PSMs */
uint8_t
max_le_channels; /**< Maximum number of application-managed LE channels */
} mico_bt_cfg_l2cap_application_t;
/** Audio/Video Distribution configuration */
typedef struct {
uint8_t max_links; /**< Maximum simultaneous audio/video links */
} mico_bt_cfg_avdt_t;
/** Audio/Video Remote Control configuration */
typedef struct {
uint8_t
roles; /**< Mask of local roles supported (AVRC_CONN_INITIATOR|AVRC_CONN_ACCEPTOR) */
uint8_t max_links; /**< Maximum simultaneous remote control links */
} mico_bt_cfg_avrc_t;
/* RFCOMM configuration */
typedef struct {
uint8_t
max_links; /**< Maximum number of simultaneous connected remote devices*/
uint8_t max_ports; /**< Maximum number of simultaneous RFCOMM ports */
} mico_bt_cfg_rfcomm_t;
/** Bluetooth stack configuration */
typedef struct {
uint8_t *device_name; /**< Local device name (NULL terminated) */
mico_bt_dev_class_t device_class; /**< Local device class */
uint8_t
security_requirement_mask; /**< Security requirements mask (BTM_SEC_NONE, or combination of BTM_SEC_IN_AUTHENTICATE, BTM_SEC_OUT_AUTHENTICATE, BTM_SEC_ENCRYPT (see #mico_bt_sec_level_e)) */
uint8_t
max_simultaneous_links; /**< Maximum number simultaneous links to different devices */
/* Scan and advertisement configuration */
mico_bt_cfg_br_edr_scan_settings_t br_edr_scan_cfg; /**< BR/EDR scan settings */
mico_bt_cfg_ble_scan_settings_t ble_scan_cfg; /**< BLE scan settings */
mico_bt_cfg_ble_advert_settings_t ble_advert_cfg; /**< BLE advertisement settings */
/* GATT configuration */
mico_bt_cfg_gatt_settings_t gatt_cfg; /**< GATT settings */
/* RFCOMM configuration */
mico_bt_cfg_rfcomm_t rfcomm_cfg; /**< RFCOMM settings */
/* Application managed l2cap protocol configuration */
mico_bt_cfg_l2cap_application_t
l2cap_application; /**< Application managed l2cap protocol configuration */
/* Audio/Video Distribution configuration */
mico_bt_cfg_avdt_t avdt_cfg; /**< Audio/Video Distribution configuration */
/* Audio/Video Remote Control configuration */
mico_bt_cfg_avrc_t avrc_cfg; /**< Audio/Video Remote Control configuration */
/* LE Address Resolution DB size */
uint8_t
addr_resolution_db_size; /**< LE Address Resolution DB settings - effective only for pre 4.2 controller*/
} mico_bt_cfg_settings_t;
/*****************************************************************************
* Buffer pool configuration
*
* Pools must be ordered in increasing buf_size.
* If a pool runs out of buffers, the next pool will be used
*
* Pool usage (4 pools):
* Pool 0: Small Buffer Pool - miscellaneous use (small HCI messages)
* Pool 1: Medium Buffer Pool - HCI & RFCOMM control messages, min recommended buf_size is 360
* Pool 2: Large Buffer Pool - HCI ACL data messages
* Pool 3: Extra Large Buffer Pool - Used for avdt media packets and miscellaneous (if not needed, set buf_count to 0)
*
****************************************************************************/
#define MICO_BT_CFG_NUM_BUF_POOLS (4) /**< mico_bt stack uses 4 pools */
typedef struct {
uint16_t buf_size; /**< size of buffers in the pool */
uint16_t buf_count; /**< number of buffers in the pool */
} mico_bt_cfg_buf_pool_t;
#ifdef __cplusplus
} /* extern "C" */
#endif
#define DEMO_APP_BLE_REPORTER 1
#define DEMO_APP_BLE_MONITOR 2
#define DEMO_APP_RFCOMM_CLT 3
#define DEMO_APP_RFCOMM_SVR 4
#define DEMO_APP_SCAN 5
#define DEMO_APP_FLOOD_BRIDGE 6
//#define DEMO_APP_TYPE DEMO_APP_BLE_REPORTER
//#define DEMO_APP_TYPE DEMO_APP_RFCOMM_SVR
//#define DEMO_APP_TYPE DEMO_APP_RFCOMM_CLT
//#define DEMO_APP_TYPE DEMO_APP_BLE_MONITOR
//#define DEMO_APP_TYPE DEMO_APP_SCAN
#define DEMO_APP_TYPE DEMO_APP_FLOOD_BRIDGE

View file

@ -0,0 +1,115 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
/** @file
* Defines common constants and types for the MBLE Bluetooth Framework
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
#ifndef RESULT_ENUM
#define RESULT_ENUM( prefix, name, value ) prefix ## name = (value)
#endif /* ifndef RESULT_ENUM */
#define BT_RESULT_LIST( prefix ) \
RESULT_ENUM( prefix, SUCCESS, 0 ), /**< Success */ \
RESULT_ENUM( prefix, PARTIAL_RESULTS, 3 ), /**< Partial results */ \
RESULT_ENUM( prefix, BADARG, 5 ), /**< Bad Arguments */ \
RESULT_ENUM( prefix, BADOPTION, 6 ), /**< Mode not supported */ \
RESULT_ENUM( prefix, OUT_OF_HEAP_SPACE, 8 ), /**< Dynamic memory space exhausted */ \
RESULT_ENUM( prefix, UNKNOWN_EVENT, 8029 ), /**< Unknown event is received */ \
RESULT_ENUM( prefix, LIST_EMPTY, 8010 ), /**< List is empty */ \
RESULT_ENUM( prefix, ITEM_NOT_IN_LIST, 8011 ), /**< Item not found in the list */ \
RESULT_ENUM( prefix, PACKET_DATA_OVERFLOW, 8012 ), /**< Data overflow beyond the packet end */ \
RESULT_ENUM( prefix, PACKET_POOL_EXHAUSTED, 8013 ), /**< All packets in the pool is in use */ \
RESULT_ENUM( prefix, PACKET_POOL_FATAL_ERROR, 8014 ), /**< Packet pool fatal error such as permanent packet leak */ \
RESULT_ENUM( prefix, UNKNOWN_PACKET, 8015 ), /**< Unknown packet */ \
RESULT_ENUM( prefix, PACKET_WRONG_OWNER, 8016 ), /**< Packet is owned by another entity */ \
RESULT_ENUM( prefix, BUS_UNINITIALISED, 8017 ), /**< Bluetooth bus isn't initialised */ \
RESULT_ENUM( prefix, MPAF_UNINITIALISED, 8018 ), /**< MPAF framework isn't initialised */ \
RESULT_ENUM( prefix, RFCOMM_UNINITIALISED, 8019 ), /**< RFCOMM protocol isn't initialised */ \
RESULT_ENUM( prefix, STACK_UNINITIALISED, 8020 ), /**< SmartBridge isn't initialised */ \
RESULT_ENUM( prefix, SMART_APPL_UNINITIALISED, 8021 ), /**< Bluetooth stack isn't initialised */ \
RESULT_ENUM( prefix, ATT_CACHE_UNINITIALISED, 8022 ), /**< Attribute cache isn't initialised */ \
RESULT_ENUM( prefix, MAX_CONNECTIONS_REACHED, 8023 ), /**< Maximum number of connections is reached */ \
RESULT_ENUM( prefix, SOCKET_IN_USE, 8024 ), /**< Socket specified is in use */ \
RESULT_ENUM( prefix, SOCKET_NOT_CONNECTED, 8025 ), /**< Socket is not connected or connection failed */ \
RESULT_ENUM( prefix, ENCRYPTION_FAILED, 8026 ), /**< Encryption failed */ \
RESULT_ENUM( prefix, SCAN_IN_PROGRESS, 8027 ), /**< Scan is in progress */ \
RESULT_ENUM( prefix, CONNECT_IN_PROGRESS, 8028 ), /**< Connect is in progress */ \
RESULT_ENUM( prefix, DISCONNECT_IN_PROGRESS, 8029 ), /**< Disconnect is in progress */ \
RESULT_ENUM( prefix, DISCOVER_IN_PROGRESS, 8030 ), /**< Discovery is in progress */ \
RESULT_ENUM( prefix, GATT_TIMEOUT, 8031 ), /**< GATT timeout occured*/ \
RESULT_ENUM( prefix, ATTRIBUTE_VALUE_TOO_LONG, 8032 ), /**< Attribute value too long */ \
RESULT_ENUM( prefix, PENDING, 8100 ), /**< Pending */ \
RESULT_ENUM( prefix, BUSY, 8101 ), /**< Device busy with another command */ \
RESULT_ENUM( prefix, NO_RESOURCES, 8102 ), /**< No resources to issue command */ \
RESULT_ENUM( prefix, UNSUPPORTED, 8103 ), /**< Unsupported function */ \
RESULT_ENUM( prefix, ILLEGAL_VALUE, 8104 ), /**< Illegal parameter value */ \
RESULT_ENUM( prefix, WRONG_MODE, 8105 ), /**< Device in wrong mode for request */ \
RESULT_ENUM( prefix, UNKNOWN_ADDR, 8106 ), /**< Unknown remote BD address */ \
RESULT_ENUM( prefix, TIMEOUT, 8107 ), /**< Timeout */ \
RESULT_ENUM( prefix, BAD_VALUE_RET, 8108 ), /**< A bad value was received from HCI */ \
RESULT_ENUM( prefix, ERROR, 8109 ), /**< Error */ \
RESULT_ENUM( prefix, NOT_AUTHORIZED, 8110 ), /**< Authorization failed */ \
RESULT_ENUM( prefix, DEV_RESET, 8111 ), /**< Device has been reset */ \
RESULT_ENUM( prefix, CMD_STORED, 8112 ), /**< request is stored in control block */ \
RESULT_ENUM( prefix, ILLEGAL_ACTION, 8113 ), /**< state machine gets illegal command */ \
RESULT_ENUM( prefix, DELAY_CHECK, 8114 ), /**< delay the check on encryption */ \
RESULT_ENUM( prefix, SCO_BAD_LENGTH, 8115 ), /**< Bad SCO over HCI data length */ \
RESULT_ENUM( prefix, SUCCESS_NO_SECURITY, 8116 ), /**< security passed, no security set */ \
RESULT_ENUM( prefix, FAILED_ON_SECURITY, 8117 ), /**< security failed */ \
RESULT_ENUM( prefix, REPEATED_ATTEMPTS, 8118 ), /**< repeated attempts for LE security requests */ \
RESULT_ENUM( prefix, MODE4_LEVEL4_NOT_SUPPORTED,8119 ), /**< Connections Only Mode can't be supported */ \
RESULT_ENUM( prefix, USE_DEFAULT_SECURITY, 8120 ), /**< Use default security*/
/******************************************************
* Constants
******************************************************/
/** @cond !ADDTHIS*/
#define MBLE_ADDRESS_BYTE_SIZE 6
/** @endcond */
/******************************************************
* Enumerations
******************************************************/
/**
* MiCO Result Type
*/
typedef enum {
BT_RESULT_LIST ( MICO_BT_ )
} mico_bt_result_t;
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
#ifdef __cplusplus
} /* extern "C" */
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,973 @@
/** @file
*
* MiCO Generic Attribute (GATT) Application Programming Interface
*/
#pragma once
#include "mico.h"
#include "gattdefs.h"
#include "mico_bt_dev.h"
#include "l2cdefs.h"
#include "mico_bt_types.h"
/** GATT Status Codes*/
enum mico_bt_gatt_status_e {
MICO_BT_GATT_SUCCESS = 0x00, /**< Success */
MICO_BT_GATT_INVALID_HANDLE = 0x01, /**< Invalid Handle */
MICO_BT_GATT_READ_NOT_PERMIT = 0x02, /**< Read Not Permitted */
MICO_BT_GATT_WRITE_NOT_PERMIT = 0x03, /**< Write Not permitted */
MICO_BT_GATT_INVALID_PDU = 0x04, /**< Invalid PDU */
MICO_BT_GATT_INSUF_AUTHENTICATION = 0x05, /**< Insufficient Authentication */
MICO_BT_GATT_REQ_NOT_SUPPORTED = 0x06, /**< Request Not Supported */
MICO_BT_GATT_INVALID_OFFSET = 0x07, /**< Invalid Offset */
MICO_BT_GATT_INSUF_AUTHORIZATION = 0x08, /**< Insufficient Authorization */
MICO_BT_GATT_PREPARE_Q_FULL = 0x09, /**< Prepare Queue Full */
MICO_BT_GATT_NOT_FOUND = 0x0a, /**< Not Found */
MICO_BT_GATT_NOT_LONG = 0x0b, /**< Not Long Size */
MICO_BT_GATT_INSUF_KEY_SIZE = 0x0c, /**< Insufficient Key Size */
MICO_BT_GATT_INVALID_ATTR_LEN = 0x0d, /**< Invalid Attribute Length */
MICO_BT_GATT_ERR_UNLIKELY = 0x0e, /**< Error Unlikely */
MICO_BT_GATT_INSUF_ENCRYPTION = 0x0f, /**< Insufficient Encryption */
MICO_BT_GATT_UNSUPPORT_GRP_TYPE = 0x10, /**< Unsupported Group Type */
MICO_BT_GATT_INSUF_RESOURCE = 0x11, /**< Insufficient Resource */
MICO_BT_GATT_ILLEGAL_PARAMETER = 0x87, /**< Illegal Parameter */
MICO_BT_GATT_NO_RESOURCES = 0x80, /**< No Resources */
MICO_BT_GATT_INTERNAL_ERROR = 0x81, /**< Internal Error */
MICO_BT_GATT_WRONG_STATE = 0x82, /**< Wrong State */
MICO_BT_GATT_DB_FULL = 0x83, /**< DB Full */
MICO_BT_GATT_BUSY = 0x84, /**< Busy */
MICO_BT_GATT_ERROR = 0x85, /**< Error */
MICO_BT_GATT_CMD_STARTED = 0x86, /**< Command Started */
MICO_BT_GATT_PENDING = 0x88, /**< Pending */
MICO_BT_GATT_AUTH_FAIL = 0x89, /**< Authentication Fail */
MICO_BT_GATT_MORE = 0x8a, /**< More */
MICO_BT_GATT_INVALID_CFG = 0x8b, /**< Invalid Configuration */
MICO_BT_GATT_SERVICE_STARTED = 0x8c, /**< Service Started */
MICO_BT_GATT_ENCRYPED_MITM = MICO_BT_GATT_SUCCESS, /**< Encrypted MITM */
MICO_BT_GATT_ENCRYPED_NO_MITM = 0x8d, /**< Encrypted No MITM */
MICO_BT_GATT_NOT_ENCRYPTED = 0x8e, /**< Not Encrypted */
MICO_BT_GATT_CONGESTED = 0x8f, /**< Congested */
/* 0xE0 ~ 0xFC reserved for future use */
MICO_BT_GATT_CCC_CFG_ERR = 0xFD, /**< Improper Client Char Configuration */
MICO_BT_GATT_PRC_IN_PROGRESS = 0xFE, /**< Procedure Already in Progress */
MICO_BT_GATT_OUT_OF_RANGE = 0xFF, /**< Value Out of Range */
};
typedef uint8_t mico_bt_gatt_status_t; /**< GATT status (see #mico_bt_gatt_status_e) */
/** GATT Status Codes*/
enum mico_bt_gatt_app_interface_e {
GATT_IF_FIXED_DB_GAP = 0x01,
GATT_IF_FIXED_DB_APP = 0x02,
GATT_IF_CLIENT = 0x03,
};
typedef uint8_t mico_bt_gatt_app_interface_t; /**< GATT status (see #mico_bt_gatt_status_e) */
/** GATT Operation Codes */
#define GATT_RSP_ERROR 0x01 /**< Error Response */
#define GATT_REQ_MTU 0x02 /**< Exchange MTU Request */
#define GATT_RSP_MTU 0x03 /**< Exchange MTU Response */
#define GATT_REQ_FIND_INFO 0x04 /**< Find Information Request */
#define GATT_RSP_FIND_INFO 0x05 /**< Find Information Response */
#define GATT_REQ_FIND_TYPE_VALUE 0x06 /**< Find By Type Value Request */
#define GATT_RSP_FIND_TYPE_VALUE 0x07 /**< Find By Type Value Response */
#define GATT_REQ_READ_BY_TYPE 0x08 /**< Read By Type Request */
#define GATT_RSP_READ_BY_TYPE 0x09 /**< Read By Type Response */
#define GATT_REQ_READ 0x0A /**< Read Request */
#define GATT_RSP_READ 0x0B /**< Read Response */
#define GATT_REQ_READ_BLOB 0x0C /**< Read Blob Request */
#define GATT_RSP_READ_BLOB 0x0D /**< Read Blob Response */
#define GATT_REQ_READ_MULTI 0x0E /**< Read Multiple Request */
#define GATT_RSP_READ_MULTI 0x0F /**< Read Multiple Response */
#define GATT_REQ_READ_BY_GRP_TYPE 0x10 /**< Read By Group Type Request */
#define GATT_RSP_READ_BY_GRP_TYPE 0x11 /**< Read By Group Type Response */
#define GATT_REQ_WRITE 0x12 /**< Write Request */
#define GATT_RSP_WRITE 0x13 /**< Write Request */
#define GATT_CMD_WRITE 0x52 /**< Write Command */
#define GATT_REQ_PREPARE_WRITE 0x16 /**< Prepare Write Request */
#define GATT_RSP_PREPARE_WRITE 0x17 /**< Prepare Write Response */
#define GATT_REQ_EXEC_WRITE 0x18 /**< Execute Write Request */
#define GATT_RSP_EXEC_WRITE 0x19 /**< Execute Write Response */
#define GATT_HANDLE_VALUE_NOTIF 0x1B /**< Handle Value Notification */
#define GATT_HANDLE_VALUE_IND 0x1D /**< Handle Value Indication */
#define GATT_HANDLE_VALUE_CONF 0x1E /**< Handle Value Confirmation */
#define GATT_OP_CODE_MAX (GATT_HANDLE_VALUE_CONF + 1) /**< Maximum opcode value */
#define GATT_SIGN_CMD_WRITE 0xD2 /**< changed in V4.0 1101-0010 (signed write) see write cmd above*/
/** GATT Disconnection reason */
enum mico_bt_gatt_disconn_reason_e {
GATT_CONN_UNKNOWN = 0, /**< Unknown reason */
GATT_CONN_L2C_FAILURE = 1, /**< General L2cap failure */
GATT_CONN_TIMEOUT = HCI_ERR_CONNECTION_TOUT, /**< Connection timeout */
GATT_CONN_TERMINATE_PEER_USER = HCI_ERR_PEER_USER, /**< Connection terminated by peer user */
GATT_CONN_TERMINATE_LOCAL_HOST = HCI_ERR_CONN_CAUSE_LOCAL_HOST, /**< Connection terminated by local host */
GATT_CONN_FAIL_ESTABLISH = HCI_ERR_CONN_FAILED_ESTABLISHMENT, /**< Connection fail to establish */
GATT_CONN_LMP_TIMEOUT = HCI_ERR_LMP_RESPONSE_TIMEOUT, /**< Connection fail due to LMP response tout */
GATT_CONN_CANCEL = L2CAP_CONN_CANCEL /**< L2CAP connection cancelled */
};
typedef uint16_t
mico_bt_gatt_disconn_reason_t; /**< GATT disconnection reason (see #mico_bt_gatt_disconn_reason_e) */
/* default GATT MTU size over LE link
*/
#define GATT_DEF_BLE_MTU_SIZE 23
/* invalid connection ID
*/
#define GATT_INVALID_CONN_ID 0xFFFF
/** characteristic descriptor: client configuration value */
enum mico_bt_gatt_client_char_config_e {
GATT_CLIENT_CONFIG_NONE = 0x0000, /**< Does not allow both notifications and indications */
GATT_CLIENT_CONFIG_NOTIFICATION = 0x0001, /**< Allows notifications */
GATT_CLIENT_CONFIG_INDICATION = 0x0002 /**< Allows indications */
};
typedef uint16_t
mico_bt_gatt_client_char_config_t; /**< GATT client config (see #mico_bt_gatt_client_char_config_e) */
/** characteristic descriptor: server configuration value */
#define GATT_SERVER_CONFIG_NONE 0x0000 /**< No broadcast */
#define GATT_SERVER_CONFIG_BROADCAST 0x0001 /**< Broadcast */
typedef uint16_t
mico_bt_gatt_server_char_config_t; /**< GATT server config (see #mico_bt_gatt_server_char_config_e) */
/** GATT Characteristic Properties Mask */
enum mico_bt_gatt_char_properties_e {
GATT_CHAR_PROPERTIES_BIT_BROADCAST = (1 << 0), /**< bit 0: Broadcast */
GATT_CHAR_PROPERTIES_BIT_READ = (1 << 1), /**< bit 1: Read */
GATT_CHAR_PROPERTIES_BIT_WRITE_NR = (1 << 2), /**< bit 2: Write (No Response) */
GATT_CHAR_PROPERTIES_BIT_WRITE = (1 << 3), /**< bit 3: Write */
GATT_CHAR_PROPERTIES_BIT_NOTIFY = (1 << 4), /**< bit 4: Notify */
GATT_CHAR_PROPERTIES_BIT_INDICATE = (1 << 5), /**< bit 5: Indicate */
GATT_CHAR_PROPERTIES_BIT_AUTH = (1 << 6), /**< bit 6: Authenticate */
GATT_CHAR_PROPERTIES_BIT_EXT_PROP = (1 << 7) /**< bit 7: Extended Properties */
};
typedef uint8_t
mico_bt_gatt_char_properties_t; /**< GATT characteristic properties mask (see #mico_bt_gatt_char_properties_e) */
/*************************************************************************
* Macros for parsing results GATT discovery results
* (while handling GATT_DISCOVERY_RESULT_EVT)
****************************************************************************/
/* Discovery type: GATT_DISCOVER_SERVICES_ALL or GATT_DISCOVER_SERVICES_BY_UUID */
#define GATT_DISCOVERY_RESULT_SERVICE_START_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.s_handle)
#define GATT_DISCOVERY_RESULT_SERVICE_END_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.e_handle)
#define GATT_DISCOVERY_RESULT_SERVICE_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.len)
#define GATT_DISCOVERY_RESULT_SERVICE_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid16)
#define GATT_DISCOVERY_RESULT_SERVICE_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid32)
#define GATT_DISCOVERY_RESULT_SERVICE_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid128)
/* Discovery type: GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS */
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.len)
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid16)
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid32)
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid128)
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_VALUE_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.handle)
/* Discovery type: GATT_DISCOVER_CHARACTERISTICS */
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_VALUE_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.val_handle)
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.len)
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid16)
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid32)
#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid128)
/** Authentication requirement */
enum mico_bt_gatt_auth_req_e {
GATT_AUTH_REQ_NONE = 0, /**< No Authentication Required */
GATT_AUTH_REQ_NO_MITM = 1, /**< Unauthenticated encryption (No MITM) */
GATT_AUTH_REQ_MITM = 2, /**< Authenticated encryption (MITM) */
GATT_AUTH_REQ_SIGNED_NO_MITM = 3, /**< Signed Data (No MITM) */
GATT_AUTH_REQ_SIGNED_MITM = 4 /**< Signed Data (MITM) */
};
typedef uint8_t mico_bt_gatt_auth_req_t; /**< GATT authentication requirement (see #mico_bt_gatt_auth_req_e)*/
/** Attribute value, used for GATT write operations, and read response callbacks */
typedef struct {
uint16_t handle; /**< Attribute handle */
uint16_t
offset; /**< Attribute value offset, ignored if not needed for a command */
uint16_t len; /**< Length of attribute value */
mico_bt_gatt_auth_req_t
auth_req; /**< Authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */
uint8_t
value[1]; /**< The attribute value (actual length is specified by 'len') */
} mico_bt_gatt_value_t;
/** GATT Write Execute request flags */
enum mico_bt_gatt_exec_flag_e {
GATT_PREP_WRITE_CANCEL = 0x00, /**< GATT_PREP_WRITE_CANCEL */
GATT_PREP_WRITE_EXEC = 0x01 /**< GATT_PREP_WRITE_EXEC */
};
typedef uint8_t mico_bt_gatt_exec_flag_t; /**< GATT execute flag (see #mico_bt_gatt_exec_flag_e) */
/** Attribute read request */
typedef struct {
uint16_t handle; /**< Handle of attribute to read */
uint16_t offset; /**< Offset to read */
mico_bool_t is_long; /**< TRUE if long read */
uint16_t *p_val_len; /**< input and output parameter for value length */
uint8_t *p_val; /**< Value pointer */
} mico_bt_gatt_read_t;
/** Attribute write request */
typedef struct {
uint16_t handle; /**< Handle of attribute to read */
mico_bool_t is_prep; /**< TRUE if this is a prepare write request */
uint16_t offset; /**< Offset to write */
uint16_t val_len; /**< Value length */
uint8_t *p_val; /**< Value pointer */
} mico_bt_gatt_write_t;
/** Attribute information for GATT attribute requests */
typedef union {
mico_bt_gatt_read_t read_req; /**< Parameters for GATTS_REQ_TYPE_READ */
mico_bt_gatt_write_t write_req; /**< Parameters for GATTS_REQ_TYPE_WRITE */
uint16_t handle; /**< Parameters for GATTS_REQ_TYPE_CONF */
uint16_t mtu; /**< Parameters for GATTS_REQ_TYPE_MTU */
mico_bt_gatt_exec_flag_t exec_write; /**< Parameters for GATTS_REQ_TYPE_WRITE_EXEC */
} mico_bt_gatt_request_data_t;
/** GATT Attribute Request Type */
enum mico_bt_gatt_request_type_e {
GATTS_REQ_TYPE_READ = 1, /**< Attribute read notification (attribute value internally read from GATT database) */
GATTS_REQ_TYPE_WRITE, /**< Attribute write notification (attribute value internally written to GATT database) */
GATTS_REQ_TYPE_PREP_WRITE, /**< Attribute Prepare Write Notification (Suspending write request before triggering actual execute write ) */
GATTS_REQ_TYPE_WRITE_EXEC, /**< Execute write request */
GATTS_REQ_TYPE_MTU, /**< MTU exchange information */
GATTS_REQ_TYPE_CONF, /**< Value confirmation */
};
typedef uint8_t mico_bt_gatt_request_type_t; /**< GATT Attribute Request Type (see #mico_bt_gatt_request_type_e) */
/** Discovery types */
enum mico_bt_gatt_discovery_type_e {
GATT_DISCOVER_SERVICES_ALL = 1, /**< discover all services */
GATT_DISCOVER_SERVICES_BY_UUID, /**< discover service by UUID */
GATT_DISCOVER_INCLUDED_SERVICES, /**< discover an included service within a service */
GATT_DISCOVER_CHARACTERISTICS, /**< discover characteristics of a service with/without type requirement */
GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS, /**< discover characteristic descriptors of a character */
GATT_DISCOVER_MAX /* maximum discovery types */
};
typedef uint8_t mico_bt_gatt_discovery_type_t; /**< GATT Discovery type (see #mico_bt_gatt_discovery_type_e) */
/** Parameters used in a GATT Discovery */
typedef struct {
mico_bt_uuid_t uuid; /**< Service or Characteristic UUID */
uint16_t s_handle; /**< Start handle for range to search */
uint16_t e_handle; /**< End handle for range to search */
} mico_bt_gatt_discovery_param_t;
/** GATT Read Types */
enum mico_bt_gatt_read_type_e {
GATT_READ_BY_TYPE = 1, /**< Read by Type (service or characteristic UUIDs) */
GATT_READ_BY_HANDLE, /**< Read by Handle */
GATT_READ_MULTIPLE, /**< Read Multiple (array of handles) */
GATT_READ_CHAR_VALUE, /**< Read Characteristic Value */
GATT_READ_PARTIAL, /**< Read Partial */
GATT_READ_MAX
};
typedef uint8_t mico_bt_gatt_read_type_t; /**< GATT read type (see #mico_bt_gatt_read_type_e) */
/** Parameters for GATT_READ_BY_TYPE and GATT_READ_CHAR_VALUE */
typedef struct {
mico_bt_gatt_auth_req_t
auth_req; /**< Authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */
uint16_t s_handle; /**< Starting handle */
uint16_t e_handle; /**< Ending handle */
mico_bt_uuid_t uuid; /**< uuid */
} mico_bt_gatt_read_by_type_t;
#define GATT_MAX_READ_MULTI_HANDLES 10 /**< Max attributes allowed in one GATT_READ_MULTIPLE request */
/** Parameters for GATT_READ_MULTIPLE */
typedef struct {
mico_bt_gatt_auth_req_t
auth_req; /**< authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */
uint16_t num_handles; /**< number of handles to read */
uint16_t handles[GATT_MAX_READ_MULTI_HANDLES]; /**< handles list to be read */
} mico_bt_gatt_read_multi_t;
/** Parameters for GATT_READ_BY_HANDLE */
typedef struct {
mico_bt_gatt_auth_req_t
auth_req; /**< authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */
uint16_t handle; /**< handle */
} mico_bt_gatt_read_by_handle_t;
/** Parameters for GATT_READ_PARTIAL */
typedef struct {
mico_bt_gatt_auth_req_t
auth_req; /**< authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */
uint16_t handle; /**< handle */
uint16_t offset; /**< offset */
} mico_bt_gatt_read_partial_t;
/** Read request parameters - used when calling #mico_bt_gatt_send_read */
typedef union {
mico_bt_gatt_read_by_type_t service; /**< Parameters for GATT_READ_BY_TYPE */
mico_bt_gatt_read_by_type_t char_type; /**< Parameters for GATT_READ_CHAR_VALUE */
mico_bt_gatt_read_multi_t read_multiple; /**< Parameters for GATT_READ_MULTIPLE */
mico_bt_gatt_read_by_handle_t by_handle; /**< Parameters for GATT_READ_BY_HANDLE */
mico_bt_gatt_read_partial_t partial; /**< Parameters for GATT_READ_PARTIAL */
} mico_bt_gatt_read_param_t;
/** Write request types - used when calling #mico_bt_gatt_send_write */
enum mico_bt_gatt_write_type_e {
GATT_WRITE_NO_RSP = 1, /**< Write without response */
GATT_WRITE, /**< Write with response */
GATT_WRITE_PREPARE /**< Prepare to write (call #mico_bt_gatt_send_execute_write to execute the write) */
};
typedef uint8_t mico_bt_gatt_write_type_t; /**< GATT write type (see #mico_bt_gatt_write_type_e) */
/** Response data for read operations */
typedef struct {
uint16_t handle; /**< handle */
uint16_t len; /**< length of response data */
uint16_t offset; /**< offset */
uint8_t *p_data; /**< attribute data */
} mico_bt_gatt_data_t;
/** Client Operation Complete response data (dependent on operation completed) */
typedef union {
mico_bt_gatt_data_t
att_value; /**< Response data for read operations (initiated using #mico_bt_gatt_send_read) */
uint16_t mtu; /**< Response data for configuration operations */
uint16_t
handle; /**< Response data for write operations (initiated using #mico_bt_gatt_send_write) */
} mico_bt_gatt_operation_complete_rsp_t; /**< GATT operation complete response type */
/** GATT client operation type, used in client callback function
*/
enum mico_bt_gatt_optype_e {
GATTC_OPTYPE_NONE = 0, /**< None */
GATTC_OPTYPE_DISCOVERY = 1, /**< Discovery */
GATTC_OPTYPE_READ = 2, /**< Read */
GATTC_OPTYPE_WRITE = 3, /**< Write */
GATTC_OPTYPE_EXE_WRITE = 4, /**< Execute Write */
GATTC_OPTYPE_CONFIG = 5, /**< Configure */
GATTC_OPTYPE_NOTIFICATION = 6, /**< Notification */
GATTC_OPTYPE_INDICATION = 7 /**< Indication */
};
/* GATT Client Operation Codes */
typedef uint8_t mico_bt_gatt_optype_t; /**< GATT operation type (see #mico_bt_gatt_optype_e) */
/** characteristic declaration */
typedef struct {
mico_bt_gatt_char_properties_t
characteristic_properties; /**< characteristic properties (see @link mico_bt_gatt_char_properties_e mico_bt_gatt_char_properties_t @endlink) */
uint16_t val_handle; /**< characteristic value attribute handle */
uint16_t handle; /**< characteristic declaration handle */
mico_bt_uuid_t char_uuid; /**< characteristic UUID type */
} mico_bt_gatt_char_declaration_t;
/** GATT group value */
typedef struct {
mico_bt_uuid_t service_type; /**< group type */
uint16_t s_handle; /**< starting handle of the group */
uint16_t e_handle; /**< ending handle of the group */
} mico_bt_gatt_group_value_t;
/** included service attribute value */
typedef struct {
mico_bt_uuid_t service_type; /**< included service UUID */
uint16_t handle; /**< included service handle */
uint16_t s_handle; /**< starting handle */
uint16_t e_handle; /**< ending handle */
} mico_bt_gatt_included_service_t;
/** characteristic descriptor information */
typedef struct {
mico_bt_uuid_t type; /**< descriptor UUID type */
uint16_t handle; /**< descriptor attribute handle */
} mico_bt_gatt_char_descr_info_t;
/**
* Discovery result data
* Use GATT_DISCOVERY_RESULT_SERVICE_* or GATT_DISCOVERY_RESULT_CHARACTERISTIC_* macros to parse discovery data)
*/
typedef union {
mico_bt_gatt_included_service_t included_service; /**< Result for GATT_DISCOVER_INCLUDED_SERVICES */
mico_bt_gatt_group_value_t
group_value; /**< Result for GATT_DISCOVER_SERVICES_ALL or GATT_DISCOVER_SERVICES_BY_UUID */
mico_bt_gatt_char_declaration_t characteristic_declaration; /**< Result for GATT_DISCOVER_CHARACTERISTICS */
mico_bt_gatt_char_descr_info_t
char_descr_info; /**< Result for GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS */
} mico_bt_gatt_discovery_data_t;
#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP 0 /* start a idle timer for this duration when no application need to use the link */
#define GATT_LINK_NO_IDLE_TIMEOUT 0xFFFF
#define GATT_INVALID_ACL_HANDLE 0xFFFF
#define GATT_HANDLE_IS_VALID(x) ((x) != 0)
typedef uint16_t mico_bt_gatt_appearance_t; /**< GATT appearance (see #gatt_appearance_e) */
/*****************************************************************************
* GATT Database Defintions
*****************************************************************************/
/* The permission bits (see Vol 3, Part F, 3.3.1.1) */
#define LEGATTDB_PERM_NONE (0x00)
#define LEGATTDB_PERM_VARIABLE_LENGTH (0x1 << 0)
#define LEGATTDB_PERM_READABLE (0x1 << 1)
#define LEGATTDB_PERM_WRITE_CMD (0x1 << 2)
#define LEGATTDB_PERM_WRITE_REQ (0x1 << 3)
#define LEGATTDB_PERM_AUTH_READABLE (0x1 << 4)
#define LEGATTDB_PERM_RELIABLE_WRITE (0x1 << 5)
#define LEGATTDB_PERM_AUTH_WRITABLE (0x1 << 6)
#define LEGATTDB_PERM_WRITABLE (LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ| LEGATTDB_PERM_AUTH_WRITABLE)
#define LEGATTDB_PERM_MASK (0x7f) /* All the permission bits. */
#define LEGATTDB_PERM_SERVICE_UUID_128 (0x1 << 7)
/* GATT Characteristic Properties */
#define LEGATTDB_CHAR_PROP_BROADCAST (0x1 << 0)
#define LEGATTDB_CHAR_PROP_READ (0x1 << 1)
#define LEGATTDB_CHAR_PROP_WRITE_NO_RESPONSE (0x1 << 2)
#define LEGATTDB_CHAR_PROP_WRITE (0x1 << 3)
#define LEGATTDB_CHAR_PROP_NOTIFY (0x1 << 4)
#define LEGATTDB_CHAR_PROP_INDICATE (0x1 << 5)
#define LEGATTDB_CHAR_PROP_AUTHD_WRITES (0x1 << 6)
#define LEGATTDB_CHAR_PROP_EXTENDED (0x1 << 7)
/* Conversion macros */
#define BIT16_TO_8( val ) \
(uint8_t)( (val) & 0xff),/* LSB */ \
(uint8_t)(( (val) >> 8 ) & 0xff) /* MSB */
/* UUID lengths */
#define LEGATTDB_UUID16_SIZE 2
#define LEGATTDB_UUID128_SIZE 16
/* Service and Characteristic macros */
#define ATTRIBUTE16( handle, permission, datalen, uuid ) \
BIT16_TO_8(handle), \
(uint8_t)(permission), \
(uint8_t)(datalen + 2), \
BIT16_TO_8(uuid)
#define PRIMARY_SERVICE_UUID16(handle, service) \
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
4, \
BIT16_TO_8((GATT_UUID_PRI_SERVICE)), \
BIT16_TO_8((service))
#define PRIMARY_SERVICE_UUID128(handle, service) \
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
18, \
BIT16_TO_8(GATT_UUID_PRI_SERVICE), \
service
#define SECONDARY_SERVICE_UUID16(handle, service) \
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
4, \
BIT16_TO_8((GATT_UUID_SEC_SERVICE)), \
BIT16_TO_8((service))
#define SECONDARY_SERVICE_UUID128(handle, service) \
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
18, \
BIT16_TO_8(GATT_UUID_SEC_SERVICE), \
service
#define INCLUDE_SERVICE_UUID16(handle, service_handle, end_group_handle, service) \
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
8, \
BIT16_TO_8(GATT_UUID_INCLUDE_SERVICE), \
BIT16_TO_8(service_handle), \
BIT16_TO_8(end_group_handle), \
BIT16_TO_8(service)
#define INCLUDE_SERVICE_UUID128(handle, service_handle, end_group_handle)\
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
6, \
BIT16_TO_8(GATT_UUID_INCLUDE_SERVICE), \
BIT16_TO_8(service_handle), \
BIT16_TO_8(end_group_handle)
#define CHARACTERISTIC_UUID16(handle, handle_value, uuid, properties, permission) \
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
0x07, \
BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \
(uint8_t)(properties), \
BIT16_TO_8((uint16_t)(handle_value)), \
BIT16_TO_8(uuid), \
BIT16_TO_8((uint16_t)(handle_value)), \
(uint8_t)(permission), \
(uint8_t)(LEGATTDB_UUID16_SIZE), \
BIT16_TO_8(uuid)
#define CHARACTERISTIC_UUID128(handle, handle_value, uuid, properties, permission) \
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
21, \
BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \
(uint8_t)(properties), \
BIT16_TO_8((uint16_t)(handle_value)), \
uuid, \
BIT16_TO_8((uint16_t)(handle_value)), \
(uint8_t)(permission | LEGATTDB_PERM_SERVICE_UUID_128), \
(uint8_t)(LEGATTDB_UUID128_SIZE), \
uuid
#define CHARACTERISTIC_UUID16_WRITABLE(handle, handle_value, uuid, properties, permission) \
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
0x07, \
BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \
(uint8_t)(properties), \
BIT16_TO_8((uint16_t)(handle_value)), \
BIT16_TO_8(uuid), \
BIT16_TO_8((uint16_t)(handle_value)), \
(uint8_t)(permission), \
(uint8_t)(LEGATTDB_UUID16_SIZE), \
(uint8_t)(0), \
BIT16_TO_8(uuid)
#define CHARACTERISTIC_UUID128_WRITABLE(handle, handle_value, uuid, properties, permission) \
BIT16_TO_8((uint16_t)(handle)), \
LEGATTDB_PERM_READABLE, \
21, \
BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \
(uint8_t)(properties), \
BIT16_TO_8((uint16_t)(handle_value)), \
uuid, \
BIT16_TO_8((uint16_t)(handle_value)), \
(uint8_t)(permission | LEGATTDB_PERM_SERVICE_UUID_128), \
(uint8_t)(LEGATTDB_UUID128_SIZE), \
(uint8_t)(0), \
uuid
#define CHAR_DESCRIPTOR_UUID16_WRITABLE(handle, uuid, permission) \
BIT16_TO_8((uint16_t)(handle)), \
(uint8_t)(permission), \
(uint8_t)(LEGATTDB_UUID16_SIZE), \
(uint8_t)(0), \
BIT16_TO_8(uuid)
#define CHAR_DESCRIPTOR_UUID16(handle, uuid, permission) \
BIT16_TO_8((uint16_t)(handle)), \
(uint8_t)(permission), \
(uint8_t)(LEGATTDB_UUID16_SIZE), \
BIT16_TO_8(uuid)
/** GATT events */
typedef enum {
GATT_CONNECTION_STATUS_EVT, /**< GATT connection status change. Event data: #mico_bt_gatt_connection_status_t */
GATT_OPERATION_CPLT_EVT, /**< GATT operation complete. Event data: #mico_bt_gatt_event_data_t */
GATT_DISCOVERY_RESULT_EVT, /**< GATT attribute discovery result. Event data: #mico_bt_gatt_discovery_result_t */
GATT_DISCOVERY_CPLT_EVT, /**< GATT attribute discovery complete. Event data: #mico_bt_gatt_event_data_t */
GATT_ATTRIBUTE_REQUEST_EVT /**< GATT attribute request (from remote client). Event data: #mico_bt_gatt_attribute_request_t */
} mico_bt_gatt_evt_t;
/** Discovery result (used by GATT_DISCOVERY_RESULT_EVT notification) */
typedef struct {
uint16_t conn_id; /**< ID of the connection */
mico_bt_gatt_discovery_type_t
discovery_type; /**< Discovery type (see @link mico_bt_gatt_discovery_type_e mico_bt_gatt_discovery_type_t @endlink) */
mico_bt_gatt_discovery_data_t discovery_data; /**< Discovery data */
} mico_bt_gatt_discovery_result_t;
/** Discovery Complete (used by GATT_DISCOVERY_CPLT_EVT notification) */
typedef struct {
uint16_t conn_id; /**< ID of the connection */
mico_bt_gatt_discovery_type_t
disc_type; /**< Discovery type (see @link mico_bt_gatt_discovery_type_e mico_bt_gatt_discovery_type_t @endlink) */
mico_bt_gatt_status_t status; /**< Status of operation */
} mico_bt_gatt_discovery_complete_t;
/** Response to read/write/disc/config operations (used by GATT_OPERATION_CPLT_EVT notification) */
typedef struct {
uint16_t conn_id; /**< ID of the connection */
mico_bt_gatt_optype_t
op; /**< Type of operation completed (see @link mico_bt_gatt_optype_e mico_bt_gatt_optype_t @endlink) */
mico_bt_gatt_status_t status; /**< Status of operation */
mico_bt_gatt_operation_complete_rsp_t response_data; /**< Response data (dependent on optype) */
} mico_bt_gatt_operation_complete_t;
/** GATT connection status (used by GATT_CONNECTION_STATUS_EVT notification) */
typedef struct {
uint8_t *bd_addr; /**< Remote device address */
mico_bt_ble_address_type_t addr_type; /**< Remmote device address type */
uint16_t conn_id; /**< ID of the connection */
mico_bool_t connected; /**< TRUE if connected, FALSE if disconnected */
mico_bt_gatt_disconn_reason_t
reason; /**< Reason code (see @link mico_bt_gatt_disconn_reason_e mico_bt_gatt_disconn_reason_t @endlink) */
mico_bt_transport_t transport; /**< Transport type of the connection */
uint8_t link_role; /**< Link role on this connection */
} mico_bt_gatt_connection_status_t;
/** GATT attribute request (used by GATT_ATTRIBUTE_REQUEST_EVT notification) */
typedef struct {
uint16_t conn_id; /**< ID of the connection */
mico_bt_gatt_request_type_t
request_type; /**< Request type (see @link mico_bt_gatt_request_type_e mico_bt_gatt_request_type_t) */
mico_bt_gatt_request_data_t
data; /**< Information about attribute being request (dependent on request type) */
} mico_bt_gatt_attribute_request_t;
/** Stuctures for GATT event notifications */
typedef union {
mico_bt_gatt_discovery_result_t discovery_result; /**< Data for GATT_DISCOVERY_RESULT_EVT */
mico_bt_gatt_discovery_complete_t discovery_complete; /**< Data for GATT_DISCOVERY_CPLT_EVT */
mico_bt_gatt_operation_complete_t operation_complete; /**< Data for GATT_OPERATION_CPLT_EVT */
mico_bt_gatt_connection_status_t connection_status; /**< Data for GATT_CONNECTION_STATUS_EVT */
mico_bt_gatt_attribute_request_t attribute_request; /**< Data for GATT_ATTRIBUTE_REQUEST_EVT */
} mico_bt_gatt_event_data_t;
/**
* GATT event notification callback
*
* Callback for GATT event notifications
* Registered using mico_bt_gatt_register()
*
* @param event : Event ID
* @param p_event_data : Event data
*
* @return Status of event handling
*/
typedef mico_bt_gatt_status_t mico_bt_gatt_cback_t(mico_bt_gatt_evt_t event, mico_bt_gatt_event_data_t *p_event_data);
/*****************************************************************************
* External Function Declarations
****************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @addtogroup micobt_gatt Generic Attribute (GATT)
* @ingroup micobt
*
* Generic Attribute (GATT) Functions.
*
* @{
*/
/****************************************************************************/
/**
* GATT Profile Server Functions
*
* @addtogroup server_api_functions Server
* @ingroup micobt_gatt
*
* <b> Server API Functions </b> sub module for @b GATT.
*
* @{
*/
/****************************************************************************/
/**
* Function mico_bt_gatt_db_init
*
* Initialize the GATT database
*
* @param[in] p_gatt_db : First element in GATT database array
* @param[in] gatt_db_size : Size (in bytes) of GATT database
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*
*/
mico_bt_gatt_status_t mico_bt_gatt_db_init (const uint8_t *p_gatt_db, uint16_t gatt_db_size);
/**
*
* Function mico_bt_gatt_send_indication
*
* Send a handle value indication to a client
*
* @param[in] conn_id : connection identifier.
* @param[in] attr_handle : Attribute handle of this handle value indication.
* @param[in] val_len : Length of notification value passed, and return the length actually.
* @param[in] p_val : Notification Value.
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*
*/
mico_bt_gatt_status_t mico_bt_gatt_send_indication (uint16_t conn_id, uint16_t attr_handle, uint16_t *val_len,
uint8_t *p_val );
/**
* Function mico_bt_gatt_send_notification
*
* Send a handle value notification to a client.
*
* @param[in] conn_id : connection identifier.
* @param[in] attr_handle : Attribute handle of this handle value indication.
* @param[in] val_len : Length of notification value passed, and return the length actually.
* @param[in] p_val : Notification Value.
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*
*/
mico_bt_gatt_status_t mico_bt_gatt_send_notification (uint16_t conn_id, uint16_t attr_handle, uint16_t *val_len,
uint8_t *p_val );
/**
* Function mico_bt_gatt_send_response
*
* When application receives a Read Request, Write Request or Indication from the
* peer it can reply synchronously or return a MICO_BT_GATT_PENDING result code
* indicating to the stack that the message is not processed yet. In that case
* application should call this function to send data or just a confirmation to
* the peer.
*
* @param[in] status : Status of the operation to be send to the peer
* @param[in] conn_id : Connection handle
* @param[in] attr_handle : Attribute handle
* @param[in] attr_len : Length of the attribute to send
* @param[in] offset : Attribute value offset
* @param[in] p_attr : Attribute Value
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*/
mico_bt_gatt_status_t mico_bt_gatt_send_response(mico_bt_gatt_status_t status, uint16_t conn_id,
uint16_t attr_handle, uint16_t attr_len, uint16_t offset, uint8_t *p_attr);
/**@} server_api_functions */
/*****************************************************************************/
/**
* GATT Profile Client Functions
*
* @addtogroup client_api_functions Client
* @ingroup micobt_gatt
*
* @{
*/
/*****************************************************************************/
/**
* Function mico_bt_gatt_configure_mtu
*
* Configure the ATT MTU size for a connection on an LE
* transport.
*
* @param[in] conn_id : GATT connection handle
* @param[in] mtu : New MTU size
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*/
mico_bt_gatt_status_t mico_bt_gatt_configure_mtu (uint16_t conn_id, uint16_t mtu);
/**
* Function mico_bt_gatt_send_discover
*
* Start an attribute discovery on an ATT server.
* Discovery results are notified using <b> GATT_DISCOVERY_RESULT_EVT </b>;
* completion is notified using <b> GATT_DISCOVERY_CPLT_EVT </b> of #mico_bt_gatt_cback_t.
*
* @param[in] conn_id : GATT connection handle
* @param[in] discovery_type : Discover type
* @param[in] p_discovery_param : Discover parameter
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*/
mico_bt_gatt_status_t mico_bt_gatt_send_discover (uint16_t conn_id,
mico_bt_gatt_discovery_type_t discovery_type,
mico_bt_gatt_discovery_param_t *p_discovery_param );
/**
* Function mico_bt_gatt_send_read
*
* Read from remote ATT server.
* Result is notified using <b> GATT_OPERATION_CPLT_EVT </b> of #mico_bt_gatt_cback_t.
*
* @param[in] conn_id : Connection handle
* @param[in] type : Type of the read
* @param[in] p_read : Pointer to the read request parameters
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*
*/
mico_bt_gatt_status_t mico_bt_gatt_send_read (uint16_t conn_id, mico_bt_gatt_read_type_t type,
mico_bt_gatt_read_param_t *p_read);
/**
* Function mico_bt_gatt_send_write
*
* Write to remote ATT server.
* Result is notified using <b> GATT_OPERATION_CPLT_EVT </b> of #mico_bt_gatt_cback_t.
*
* @param[in] conn_id : Connection handle
* @param[in] type : Type of write
* @param[in] p_write : Pointer to the write parameters
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*/
mico_bt_gatt_status_t mico_bt_gatt_send_write (uint16_t conn_id, mico_bt_gatt_write_type_t type,
mico_bt_gatt_value_t *p_write);
/**
* Function mico_bt_gatt_send_execute_write
*
* Send Execute Write request to remote ATT server.
*
* @param[in] conn_id : Connection handle
* @param[in] is_execute : <b>MICO_BT_TRUE </b> to execute, <b> MICO_BT_FALSE </b> to cancel
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*
*/
mico_bt_gatt_status_t mico_bt_gatt_send_execute_write (uint16_t conn_id, mico_bool_t is_execute);
/**
* Function mico_bt_gatt_send_indication_confirm
*
* Send a handle value confirmation to remote ATT server.
* (in response to <b>GATTC_OPTYPE_INDICATION </b> of #mico_bt_gatt_cback_t)
*
* @param[in] conn_id : Connection handle
* @param[in] handle : Attribute handle
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*/
mico_bt_gatt_status_t mico_bt_gatt_send_indication_confirm (uint16_t conn_id, uint16_t handle);
/**@} client_api_functions */
/*****************************************************************************/
/**
* GATT Profile Common Functions
*
* @addtogroup common_api_functions Common
* @ingroup micobt_gatt
*
* @{
*/
/*****************************************************************************/
/**
* Function mico_bt_gatt_register
*
* Register an application callback for GATT.
*
* @param[in] gatt_if : The GATT application interface
* @param[in] p_gatt_cback : The GATT notification callback
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*
*/
mico_bt_gatt_status_t mico_bt_gatt_register (mico_bt_gatt_app_interface_t gatt_if, mico_bt_gatt_cback_t *p_gatt_cback);
/**
* Function mico_bt_gatt_deregister
*
* Deregister an application callback for GATT.
*
* @param[in] gatt_if : The GATT application interface
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*
*/
mico_bt_gatt_status_t mico_bt_gatt_deregister (mico_bt_gatt_app_interface_t gatt_if);
/**
* Function mico_bt_gatt_le_connect
*
* Open GATT over LE connection to a remote device
* Result is notified using <b> GATT_CONNECTION_STATUS_EVT </b> of #mico_bt_gatt_cback_t.
*
* @param[in] bd_addr : Remote device address
* @param[in] bd_addr_type: Public or random address
* @param[in] conn_mode : connection scan mode
* @param[in] is_direct : Is direct connection or not
*
* @return <b> TRUE </b> : If connection started
* <b> FALSE </b> : If connection start failure
*
*/
mico_bool_t mico_bt_gatt_le_connect (mico_bt_device_address_t bd_addr,
mico_bt_ble_address_type_t bd_addr_type,
mico_bt_ble_conn_mode_t conn_mode,
mico_bool_t is_direct);
/**
* Function mico_bt_gatt_bredr_connect
*
* Open GATT over BR/EDR connection to a remote device
* Result is notified using <b> GATT_CONNECTION_STATUS_EVT </b> of #mico_bt_gatt_cback_t.
*
* @param[in] bd_addr : Remote device address
*
* @return <b> TRUE </b> : If connection started
* <b> FALSE </b> : If connection start failure
*
*/
mico_bool_t mico_bt_gatt_bredr_connect (mico_bt_device_address_t bd_addr);
/**
* Function mico_bt_gatt_cancel_connect
*
* Cancel initiating GATT connecton
*
* @param[in] bd_addr : Remote device addresss
* @param[in] is_direct : Is direct connection or not
*
* @return <b> TRUE </b> : If connection started
* <b> FALSE </b> : If connection start failure
*
*/
mico_bool_t mico_bt_gatt_cancel_connect (mico_bt_device_address_t bd_addr, mico_bool_t is_direct);
/**
* Function mico_bt_gatt_disconnect
*
* Close the specified GATT connection.
* Result is notified using <b> GATT_CONNECTION_STATUS_EVT </b> of #mico_bt_gatt_cback_t.
*
* @param[in] conn_id : GATT connection ID
*
* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink
*
*/
mico_bt_gatt_status_t mico_bt_gatt_disconnect (uint16_t conn_id);
/**
* Function mico_bt_gatt_listen
*
* Start or stop LE advertisement and listen for connection.
*
* @param[in] start : TRUE to add device to whitelist / FALSE to remove
* @param[in] bd_addr : Device to add/remove from whitelist
*
* @return <b> TRUE </b> : Success
* <b> FALSE </b> : Failure
*
*/
mico_bool_t mico_bt_gatt_listen (mico_bool_t start, mico_bt_device_address_t bd_addr);
/**@} common_api_functions*/
#ifdef __cplusplus
}
#endif
/**@} micobt_gatt */

View file

@ -0,0 +1,306 @@
/** @file
*
* Human Interface Device Profile (HID) Device over BLE
*
*/
#pragma once
#include "mico.h"
#include "mico_bt_dev.h"
#include "hiddefs.h"
/******************************************************
* Constants
******************************************************/
/* HID-LE-Device Callback Events */
enum mico_bt_hidd_ble_cback_event_e {
MICO_BT_HIDD_BLE_DEV_EVT_OPEN, /**< Connected to host with Interrupt and Control Data = 1 if Virtual Cable
Channels in OPEN state. pdata = Host BD-Addr.*/
MICO_BT_HIDD_BLE_DEV_EVT_CLOSE, /**< Connection with host is closed. Data=Reason Code. */
MICO_BT_HIDD_BLE_DEV_EVT_GET_REPORT, /**< Host sent GET_REPORT Data=Length pdata=structure
having details of get-report. */
MICO_BT_HIDD_BLE_DEV_EVT_SET_REPORT, /**< Host sent SET_REPORT Data=Length pdata=details. */
MICO_BT_HIDD_BLE_DEV_EVT_GET_PROTO, /**< Host sent GET_PROTOCOL Data=NA */
MICO_BT_HIDD_BLE_DEV_EVT_SET_PROTO, /**< Host sent SET_PROTOCOL Data=1 for Report, 0 for Boot */
MICO_BT_HIDD_BLE_DEV_EVT_DATA /**< General event data */
};
typedef uint8_t mico_bt_hidd_ble_cback_event_t; /**< HIDD BLE callback events */
/* GATT application error code for HID profile */
#define HIDD_LE_RPT_NOT_SUPT 0x8F /**< Report not supported */
/* HIDD type */
#define HIDD_LE_KB_TYPE 0x01 /**< bit 0 */
#define HIDD_LE_MICE_TYPE 0x02 /**< bit 1 */
#define HIDD_LE_OTHER_TYPE 0x80 /**< bit 7 */
typedef uint8_t mico_bt_hidd_ble_dev_t; /**< HIDD BLE device types */
#define HIDD_LE_PROTO_MODE_RPT 0x00 /**< Report protocol */
#define HIDD_LE_PROTO_MODE_BOOT 0x01 /**< Boot protocol */
typedef uint8_t mico_bt_hidd_ble_proto_t; /**< HIDD BLE protocol types */
/* LE HIDD report type */
#define HID_LE_RPT_TYPE_INPUT 0x01 /**< Input reports */
#define HID_LE_RPT_TYPE_OUTPUT 0x02 /**< Output reports */
#define HID_LE_RPT_TYPE_FEATURE 0x03 /**< Feature reports */
#define HID_LE_RPT_TYPE_KB_INPUT 0x04 /**< Keyboard input */
#define HID_LE_RPT_TYPE_KB_OUTPUT 0x05 /**< Keyboard output */
#define HID_LE_RPT_TYPE_MI_INPUT 0x06 /**< Mouse input */
typedef uint8_t mico_bt_hidd_ble_rpt_t; /**< HIDD BLE report types */
#define HID_LE_RPT_TYPE_MAX HID_LE_RPT_TYPE_FEATURE /**< Maximun report type */
/******************************************************
* Type Definitions
******************************************************/
enum mico_bt_hidd_ble_status {
MICO_BT_HIDD_BLE_SUCCESS, /**< Success */
MICO_BT_HIDD_BLE_ERR_NOT_REGISTERED, /**< Not registered */
MICO_BT_HIDD_BLE_ERR_ALREADY_REGISTERED, /**< Alreadu registered */
MICO_BT_HIDD_BLE_ERR_NO_RESOURCES, /**< No resources */
MICO_BT_HIDD_BLE_ERR_NO_CONNECTION, /**< Not connection */
MICO_BT_HIDD_BLE_ERR_INVALID_PARAM, /**< Invalid parameter */
MICO_BT_HIDD_BLE_ERR_UNSUPPORTED, /**< Not supported */
MICO_BT_HIDD_BLE_ERR_UNKNOWN_COMMAND, /**< Unknown command */
MICO_BT_HIDD_BLE_ERR_CONGESTED, /**< Congested */
MICO_BT_HIDD_BLE_ERR_CONN_IN_PROCESS, /**< Connection in process */
MICO_BT_HIDD_BLE_ERR_ALREADY_CONN, /**< Already connected */
MICO_BT_HIDD_BLE_ERR_DISCONNECTING, /**< Disconnecting is process */
MICO_BT_HIDD_BLE_ERR_SET_CONNABLE_FAIL, /**< Set connectable failiure */
/* Device specific error codes */
MICO_BT_HIDD_BLE_ERR_HOST_UNKNOWN, /**< Host unknown */
MICO_BT_HIDD_BLE_ERR_L2CAP_FAILED, /**< L2CAP failed */
MICO_BT_HIDD_BLE_ERR_AUTH_FAILED, /**< Authentication failed */
MICO_BT_HIDD_BLE_ERR_SDP_BUSY, /**< SDP busy */
MICO_BT_HIDD_BLE_ERR_GATT, /**< GATT */
MICO_BT_HIDD_BLE_ERR_INVALID = 0xFF /**< Invalid */
};
typedef uint8_t mico_bt_hidd_ble_status_t; /**< HIDD BLE status codes */
/* report reference descriptor value */
typedef struct {
uint8_t rpt_id; /**< Report ID */
mico_bt_hidd_ble_rpt_t rpt_type; /**< Report type */
} mico_bt_hidd_ble_rpt_ref_t; /**< HIDD BLE report reference */
/* LE HIDD registration information */
typedef struct {
mico_bt_hidd_ble_dev_t dev_type; /**< Device type */
uint8_t num_rpt; /**< Number of reports */
uint16_t battery_handle; /**< Battery handle */
mico_bt_hidd_ble_rpt_ref_t *p_rpt_lst; /**< Pointer to the report reference */
mico_bt_hidd_ble_proto_t proto_cap; /**< Protocol capability */
} mico_bt_hidd_ble_dev_info_t; /**< HIDD BLE device info */
#define HIDD_LE_REMOTE_WAKE 0x01 /**< Remote wake */
#define HIDD_LE_NORMAL_CONN 0x02 /**< Normally connectable */
typedef struct {
uint16_t dl_len; /**< Description length */
uint8_t *dsc_list; /**< Pointer to the description */
} mico_bt_hidd_ble_dscp_info_t; /**< HIDD BLE description info */
/* LE HIDD report map info */
typedef struct {
uint16_t bcdHID; /**< HID info in BCD format */
uint8_t contry_code; /**< Country code */
uint8_t flags; /**< HID info in BCD format */
mico_bt_hidd_ble_dscp_info_t rpt_map; /**< Report map */
} mico_bt_hidd_ble_rpt_map_info_t; /**< HIDD BLE report map info */
#define HIDD_REPT_ID_BOOT_KB 1
#define HIDD_REPT_ID_BOOT_MOUSE 2
typedef struct {
uint16_t event; /**< event */
uint16_t len; /**< length */
uint16_t offset; /**< offset */
uint16_t layer_specific; /**< lay_specific */
} mico_bt_hidd_bt_hdr_t; /**< General data in BT_HDR type */
/* LE HIDD report data */
typedef struct {
mico_bt_hidd_bt_hdr_t hdr; /**< report data, assuming the first byte of data is report ID */
uint8_t rpt_id; /**< report ID */
} mico_bt_hidd_ble_rpt_data_t; /**< HIDD BLE report data */
/* LE HIDD get report data */
typedef struct {
uint8_t rep_type; /**< HIDD BLE report type */
uint8_t rep_id; /**< HIDD BLE report ID */
} mico_bt_hidd_ble_get_rpt_data_t; /**< HIDD BLE get report data */
/* LE HIDD cback data */
typedef union {
mico_bt_device_address_t host_bdaddr; /**< Host BD-ADDR */
mico_bt_hidd_ble_get_rpt_data_t get_rpt; /**< Get report */
mico_bt_hidd_ble_rpt_data_t *p_buffer; /**< General report data */
} mico_bt_hidd_ble_cback_data_t; /**< HIDD BLE callback data */
/**
* HIDD LE callback
*
* Callback for Human Interface Device Profile Device (HIDD)
*
* @param[in] event : Callback event
* @param[in] data : Integer data corresponding to the event
* @param[in] p_data : Callback data
*
* @return void
*/
typedef void (mico_bt_hidd_ble_cback_t) (uint8_t event,
uint32_t data,
mico_bt_hidd_ble_cback_data_t *p_data );
/* HIDD LE registration info */
typedef struct {
mico_bt_device_address_t host_addr; /**< Host BD-ADDR */
mico_bt_hidd_ble_dev_info_t dev_info; /**< Device info */
mico_bt_hidd_ble_cback_t *app_cback; /**< Callback function */
} mico_bt_hidd_ble_reg_info_t; /**< HIDD BLE registration info */
/**
* @addtogroup hidd_le_api_functions HIDD over BLE
* @ingroup micobt
*
* HIDD LE Functions
*
* @{
*/
/******************************************************
* Function Declarations
******************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/**
* Function mico_bt_hidd_ble_init
*
* Initialize HIDD LE control block and trace variable.
*
* @param[in] None
* @param[out] None
*
* @return None
*/
void mico_bt_hidd_ble_init (void);
/**
* Function mico_bt_hidd_ble_register
*
* This function must be called at startup to register info related
* to HIDD over LE.
*
*
* @param[in] p_reg_info : SCO index to remove
* @param[out] None
*
* @return status code (see #mico_bt_hidd_ble_status_t)
*/
mico_bt_hidd_ble_status_t mico_bt_hidd_ble_register(mico_bt_hidd_ble_reg_info_t *p_reg_info);
/**
* Function mico_bt_hidd_ble_deregister
*
* Disable HIDD service.
*
* @param[in] None
* @param[out] None
*
* @return status code (see #mico_bt_hidd_ble_status_t)
*/
mico_bt_hidd_ble_status_t mico_bt_hidd_ble_deregister(void);
/**
* Function mico_bt_hidd_ble_connect
*
* Initiates a connection to the host.
*
* @param[in] None
* @param[out] None
*
* @return status code (see #mico_bt_hidd_ble_status_t)
*/
mico_bt_hidd_ble_status_t mico_bt_hidd_ble_connect(void);
/**
* Function mico_bt_hidd_ble_disconnect
*
* Disconnects from the host.
*
* @param[in] None
* @param[out] None
*
* @return status code (see #mico_bt_hidd_ble_status_t)
*/
mico_bt_hidd_ble_status_t mico_bt_hidd_ble_disconnect(void);
/**
* Function mico_bt_hidd_ble_send_report
*
* Sends report data to the host.
*
* @param[in] rep_type : Report type
* @param[in] rep_id : Report ID
* @param[in] len : Length of the data
* @param[in] offset : Offset of the data
* @param[in] p_rpt : Pointer to the report data
* @param[out] None
*
* @return status code (see #mico_bt_hidd_ble_status_t)
*/
mico_bt_hidd_ble_status_t mico_bt_hidd_ble_send_report(uint8_t rep_type, uint8_t rpt_id,
uint16_t len, uint16_t offset, uint8_t *p_rpt);
/**
* Function mico_bt_hidd_ble_hand_shake
*
* Acks a set report request
*
* @param[in] status code (see #mico_bt_hidd_ble_status_t)
* @param[out] None
*
* @return status code (see #mico_bt_hidd_ble_status_t)
*/
mico_bt_hidd_ble_status_t mico_bt_hidd_ble_hand_shake(mico_bt_hidd_ble_status_t status);
/**
* Function mico_bt_hidd_ble_rsp_get_protocol
*
* Responds to a get protocol mode request
*
* @param[in] cur_mode : Current protocol
* @param[out] None
*
* @return status code (see #mico_bt_hidd_ble_status_t)
*/
mico_bt_hidd_ble_status_t mico_bt_hidd_ble_rsp_get_protocol(mico_bt_hidd_ble_proto_t cur_mode);
/**
* Function mico_bt_hidd_ble_set_rsp_map_info
*
* This function shall be called at startup to configure the
* device HID information and report map
*
*
* @param[in] p_dev_info : Device map info
* @param[out] None
*
* @return status code (see #mico_bt_hidd_ble_status_t)
*/
mico_bt_hidd_ble_status_t mico_bt_hidd_ble_set_rsp_map_info(mico_bt_hidd_ble_rpt_map_info_t *p_dev_info);
#ifdef __cplusplus
}
#endif
/** @} micobt_hidd_ble */

View file

@ -0,0 +1,75 @@
#pragma once
/* MiCO -> BTE Conversion */
#define int8_t INT8
#define int16_t INT16
#define int32_t INT32
#define uint8_t UINT8
#define uint16_t UINT16
#define uint32_t UINT32
#define mico_bool_t BOOLEAN
#define mico_bt_dev_status_t tBTM_STATUS
#define mico_bt_management_evt_t tBTM_EVENT
#define mico_bt_dev_class_t DEV_CLASS
#define mico_bt_device_address_t BD_ADDR
#define mico_bt_device_address_ptr_t BD_ADDR_PTR
#define mico_bt_dev_io_cap_t tBTM_IO_CAP
#define mico_bt_dev_oob_data_t tBTM_OOB_DATA
#define mico_bt_dev_le_auth_req_t tBTM_LE_AUTH_REQ
#define mico_bt_dev_le_key_type_t tBTM_LE_KEY_TYPE
#define mico_bt_dev_auth_req_t tBTM_AUTH_REQ
#define mico_bt_device_type_t tBT_DEVICE_TYPE
#define mico_bt_dev_bonded_device_info_t tBT_BONDED_DEVICE_INFO_TYPE
#define mico_bt_security_key_value_t tBTM_SEC_KEY_VALUE
#define mico_bt_transport_t tBT_TRANSPORT
#define mico_bt_ble_address_t tBLE_BD_ADDR
#define mico_bt_ble_address_type_t tBLE_ADDR_TYPE
#define mico_bt_ble_conn_mode_t tBLE_CONN_MODE
#define mico_bt_dev_passkey_entry_type_t tBTM_SP_KEY_TYPE
#define mico_bt_connection_status_change_cback_t tBTM_ACL_DB_CHANGE_CB /* modified from bte */
#define mico_bt_dev_inq_parms_t tBTM_INQ_PARMS /* modified from bte */
#define mico_bt_dev_inquiry_scan_result_t tBTM_INQ_RESULTS /* modified from bte */
#define mico_bt_inquiry_result_cback_t tBTM_INQ_RESULTS_CB
#define mico_bt_dev_vendor_specific_command_complete_cback_t tBTM_VSC_CMPL_CB
#ifndef mico_bt_dev_vendor_specific_command_complete_params_t
#define mico_bt_dev_vendor_specific_command_complete_params_t tBTM_VSC_CMPL
#endif
#define mico_bt_ble_advert_mask_t tBTM_BLE_AD_MASK
#define mico_bt_ble_advert_data_t tBTM_BLE_ADV_DATA
#define mico_bt_ble_conn_type_t tBTM_BLE_CONN_TYPE
#define mico_bt_ble_selective_conn_cback_t tBTM_BLE_SEL_CBACK
#define mico_bt_ble_scan_type_t tBTM_BLE_SCAN_TYPE /* new */
#define mico_bt_ble_advert_mode_t tBTM_BLE_AVERT_MODE /* new */
#define mico_bt_ble_scan_result_cback_t tBTM_BLE_SCAN_RESULT_CBACK /* new */
#define mico_bt_ble_scan_results_t tBTM_BLE_SCAN_RESULT /* new */
#define mico_bt_ble_scan_mode_t tBTM_BLE_SCAN_MODE
#define mico_bt_ble_advert_chnl_map_t tBTM_BLE_ADV_CHNL_MAP
#define mico_dev_ble_signature_t BLE_SIGNATURE
#define mico_bt_ble_advert_filter_policy_t tBTM_BLE_AFP
#define mico_bt_device_link_keys_t tBTM_PAIRED_DEVICE_LINK_KEYS
#define mico_bt_local_identity_keys_t tBTM_LOCAL_IDENTITY_KEYS
/* l2cap mico-to-bte translation */
#define mico_bt_l2c_appl_info_t tL2CAP_APPL_INFO
#define mico_bt_l2c_fixed_chnl_reg_t tL2CAP_FIXED_CHNL_REG
#define mico_bt_l2cap_le_appl_information_t tL2CAP_LE_APPL_INFO
#define mico_bt_l2c_cfg_info_t tL2CAP_CFG_INFO
#define mico_bt_l2c_ch_cfg_bits_t tL2CAP_CH_CFG_BITS
#define mico_bt_l2cap_ertm_information_t tL2CAP_ERTM_INFO
#define mico_bt_l2cap_chnl_priority_t tL2CAP_CHNL_PRIORITY
#define mico_bt_l2cap_nocp_cback_t tL2CA_NOCP_CB
#define mico_bt_l2cap_chnl_data_rate_t tL2CAP_CHNL_DATA_RATE
#define mico_bt_gatt_appearance_t tGATT_APPEARANCE
#define mico_bt_gatt_status_t tGATT_STATUS
#define mico_bt_gatt_write_t tGATT_WRITE_REQ
#define mico_bt_gatt_read_t tGATT_READ_REQ
#define mico_bt_gatt_exec_flag_t tGATT_EXEC_FLAG
#define mico_bt_hidd_status_t tHID_STATUS
#define mico_bt_hidd_reg_info_t tHID_DEV_REG_INFO
#define mico_bt_hidd_callback_t tHID_DEV_CBACK_DATA
#define mico_bt_sco_enh_esco_params_t tBTM_ENH_ESCO_PARAMS

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,41 @@
/** @file
*
* MiCO Bluetooth Low Energy (BLE) Functions
*
*/
#pragma once
#ifndef OFFSETOF
#define OFFSETOF( type, member ) ( (uintptr_t)&((type *)0)->member )
#endif /* OFFSETOF */
#define MICO_BT_PARA_LOCAL_KEY_DATA 65 /* BTM_SECURITY_LOCAL_KEY_DATA_LEN */
#define MICO_BT_DCT_NAME 249
#define MICO_BT_DCT_MAX_KEYBLOBS 146 /* Maximum size of key blobs to be stored := size of BR-EDR link keys + size of BLE keys*/
#define MICO_BT_DCT_ADDR_FIELD 6
#define MICO_BT_DCT_LENGTH_FIELD 2
#ifndef MICO_BT_DCT_MAX_DEVICES
#define MICO_BT_DCT_MAX_DEVICES 10 /* Maximum number of device records stored in nvram */
#endif
#define MICO_BT_DCT_ADDR_TYPE 1
#define MICO_BT_DCT_DEVICE_TYPE 1
/* Length of BD_ADDR + 2bytes length field */
#define MICO_BT_DCT_ENTRY_HDR_LENGTH (MICO_BT_DCT_ADDR_FIELD + MICO_BT_DCT_LENGTH_FIELD + MICO_BT_DCT_ADDR_TYPE + MICO_BT_DCT_DEVICE_TYPE)
#define MICO_BT_DCT_LOCAL_KEY_OFFSET OFFSETOF( mico_bt_config_t, bluetooth_local_key )
#define MICO_BT_DCT_REMOTE_KEY_OFFSET OFFSETOF( mico_bt_config_t, bluetooth_remote_key )
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,317 @@
/** @file
*
* Bluetooth RFCOMM Application Programming Interface
*
*/
#pragma once
#include "mico.h"
//#include "mico_bt_dev.h"
/******************************************************
* Constants and Type definitions
******************************************************/
/** RFCOMM Port Event Masks */
typedef enum mico_bt_rfcomm_port_event_e {
MICO_BT_RFCOMM_EV_RXCHAR = 0x00000001, /**< Any Character received */
MICO_BT_RFCOMM_EV_RXFLAG = 0x00000002, /**< Received certain character */
MICO_BT_RFCOMM_EV_TXEMPTY = 0x00000004, /**< Transmitt Queue Empty */
MICO_BT_RFCOMM_EV_CTS = 0x00000008, /**< CTS changed state */
MICO_BT_RFCOMM_EV_DSR = 0x00000010, /**< DSR changed state */
MICO_BT_RFCOMM_EV_RLSD = 0x00000020, /**< RLSD changed state */
MICO_BT_RFCOMM_EV_BREAK = 0x00000040, /**< BREAK received */
MICO_BT_RFCOMM_EV_ERR = 0x00000080, /**< Line status error occurred */
MICO_BT_RFCOMM_EV_RING = 0x00000100, /**< Ring signal detected */
MICO_BT_RFCOMM_EV_CTSS = 0x00000400, /**< CTS state */
MICO_BT_RFCOMM_EV_DSRS = 0x00000800, /**< DSR state */
MICO_BT_RFCOMM_EV_RLSDS = 0x00001000, /**< RLSD state */
MICO_BT_RFCOMM_EV_OVERRUN = 0x00002000, /**< receiver buffer overrun */
MICO_BT_RFCOMM_EV_TXCHAR = 0x00004000, /**< Any character transmitted */
MICO_BT_RFCOMM_EV_CONNECTED = 0x00000200, /**< RFCOMM connection established */
MICO_BT_RFCOMM_EV_CONNECT_ERR = 0x00008000, /**< Was not able to establish connection or disconnected */
MICO_BT_RFCOMM_EV_FC = 0x00010000, /**< data flow enabled flag changed by remote */
MICO_BT_RFCOMM_EV_FCS = 0x00020000, /**< data flow enable status true = enabled */
} mico_bt_rfcomm_port_event_t;
#define MICO_BT_RFCOMM_MASK_ALL (MICO_BT_RFCOMM_EV_RXCHAR | MICO_BT_RFCOMM_EV_TXEMPTY | MICO_BT_RFCOMM_EV_CTS | \
MICO_BT_RFCOMM_EV_DSR | MICO_BT_RFCOMM_EV_RLSD | MICO_BT_RFCOMM_EV_BREAK | \
MICO_BT_RFCOMM_EV_ERR | MICO_BT_RFCOMM_EV_RING | MICO_BT_RFCOMM_EV_CONNECT_ERR | \
MICO_BT_RFCOMM_EV_DSRS | MICO_BT_RFCOMM_EV_CTSS | MICO_BT_RFCOMM_EV_RLSDS | \
MICO_BT_RFCOMM_EV_RXFLAG | MICO_BT_RFCOMM_EV_TXCHAR | MICO_BT_RFCOMM_EV_OVERRUN | \
MICO_BT_RFCOMM_EV_FC | MICO_BT_RFCOMM_EV_FCS | MICO_BT_RFCOMM_EV_CONNECTED)
/** RFCOMM Result Codes */
enum mico_bt_rfcomm_result_e {
MICO_BT_RFCOMM_SUCCESS, /**< Success */
MICO_BT_RFCOMM_ERROR, /**< Error */
MICO_BT_RFCOMM_ALREADY_OPENED, /**< Already Opened */
MICO_BT_RFCOMM_CMD_PENDING, /**< Command Pending */
MICO_BT_RFCOMM_APP_NOT_REGISTERED, /**< App Not Registered */
MICO_BT_RFCOMM_NO_MEM, /**< No Memory */
MICO_BT_RFCOMM_NO_RESOURCES, /**< No Resources */
MICO_BT_RFCOMM_BAD_BD_ADDR, /**< Bad BD Address */
MICO_BT_RFCOMM_RESULT_RESERVED0,
MICO_BT_RFCOMM_BAD_HANDLE, /**< Bad Handle */
MICO_BT_RFCOMM_NOT_OPENED, /**< Not Opened */
MICO_BT_RFCOMM_LINE_ERR, /**< Line Error */
MICO_BT_RFCOMM_START_FAILED, /**< Start Failed */
MICO_BT_RFCOMM_PAR_NEG_FAILED,
MICO_BT_RFCOMM_RFCOMM_NEG_FAILED,
MICO_BT_RFCOMM_SEC_FAILED,
MICO_BT_RFCOMM_PEER_CONNECTION_FAILED, /**< Peer Connection Failed */
MICO_BT_RFCOMM_PEER_FAILED, /**< Peer Failed */
MICO_BT_RFCOMM_PEER_TIMEOUT, /**< Peer Timeout */
MICO_BT_RFCOMM_CLOSED, /**< Closed */
MICO_BT_RFCOMM_TX_FULL,
MICO_BT_RFCOMM_LOCAL_CLOSED, /**< Local Closed */
MICO_BT_RFCOMM_LOCAL_TIMEOUT, /**< Local Timeout */
MICO_BT_RFCOMM_TX_QUEUE_DISABLED,
MICO_BT_RFCOMM_PAGE_TIMEOUT, /**< Page Timeout */
MICO_BT_RFCOMM_INVALID_SCN /**< Invalid SCN */
};
typedef int mico_bt_rfcomm_result_t; /**< RFCOMM result code (see #mico_bt_rfcomm_result_e) */
/** RFCOMM Signals */
enum mico_bt_rfcomm_signal_e {
MICO_BT_RFCOMM_SET_DTRDSR = 0x01, /** DTRDSR set */
MICO_BT_RFCOMM_CLR_DTRDSR, /** DTRDSR clear */
MICO_BT_RFCOMM_SET_CTSRTS, /** CTSRTS set */
MICO_BT_RFCOMM_CLR_CTSRTS, /** CTSRTS clear */
MICO_BT_RFCOMM_SET_RI, /** RI set (DCE only) */
MICO_BT_RFCOMM_CLR_RI, /** RI clear (DCE only) */
MICO_BT_RFCOMM_SET_DCD, /** DCD set (DCE only) */
MICO_BT_RFCOMM_CLR_DCD, /** DCD clear (DCE only) */
MICO_BT_RFCOMM_BREAK, /** BRK */
};
typedef uint8_t mico_bt_rfcomm_signal_t; /**< RFCOMM Signals (see #mico_bt_rfcomm_signal_e) */
/**
* Define the callback function prototypes for mico_bt_rfcomm_data_cback_t
*
* @param port_handle : A 16-bit unsigned integer returned by @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink.
* @param *p_data : A pointer to the array of bytes received from the peer device.
* @param len : The length of the data received.
*/
typedef int (mico_bt_rfcomm_data_cback_t) (uint16_t port_handle, void *p_data, uint16_t len);
/**
* Port management callback
*
* @param code : Result code
* @param port_handle : Port handle from @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink.
*/
typedef void (mico_bt_port_mgmt_cback_t) (mico_bt_rfcomm_result_t code, uint16_t port_handle);
/**
* Port event callback
*
* @param event : A 32-bit event code that contains a bit-mask of one or more events the caller would like to register.
* @param port_handle : Port handle from @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink.
*/
typedef void (mico_bt_port_event_cback_t) (mico_bt_rfcomm_port_event_t event, uint16_t port_handle);
/**
* @addtogroup rfcomm_api_functions RFCOMM
* @ingroup micobt
*
* RFCOMM Functions
*
* @{
*/
/******************************************************
* Function Declarations
******************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/**
* Establish serial port connection to the peer device, or allow
* RFCOMM to accept a connection from peer devices.
*
* @note
* Server can call this function with the same scn parameter multiple times if
* it is ready to accept multiple simulteneous connections.
*
* DLCI for the connection is (scn * 2 + 1) if client originates connection on
* existing none initiator multiplexer channel. Otherwise it is (scn * 2).
* For the server DLCI can be changed later if client will be calling it using
* (scn * 2 + 1) dlci.
*
* @param[in] uuid : The Universal Unique Identifier (UUID) of the
* Class ID of the service being opened
* @param[in] scn : The Service Channel Number(SCN) as registered
* with the SDP (server) or obtained using SDP from
* the peer device (client)
* @param[in] is_server : TRUE if requesting application is a server
* @param[in] mtu : The maximum number of bytes transferred per frame
* If 0, a default size of L2CAP_MTU_SIZE minus
* 5 bytes is used
* @param[in] bd_addr : BD_ADDR of the peer (if client), NULL if server
* @param[in] p_mgmt_cb : Pointer to callback function to receive connection
* up/down events
* @param[out] p_handle : A pointer to the handle set by RFCOMM to be used in
* consecutive calls for this connection
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_ALREADY_OPENED </b> : If the client tries to establish a connection to the same BD_ADDR
* <b> MICO_BT_RFCOMM_NO_RESOURCES </b> : If there is not enough memory to allocate a control block structure
* <b> MICO_BT_RFCOMM_INVALID_SCN </b> : If Server Channel Number(SCN) is out of in range 1...30
*/
mico_bt_rfcomm_result_t mico_bt_rfcomm_create_connection (uint16_t uuid, uint8_t scn,
mico_bool_t is_server, uint16_t mtu,
mico_bt_device_address_t bd_addr,
uint16_t *p_handle,
mico_bt_port_mgmt_cback_t *p_mgmt_cb);
/**
* Close the specified connection.
*
* @param[in] handle : The connection handle returned by
* @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink.
* @param[in] remove_server : (for server only) If TRUE, then also remove server; otherwise server remains enabled
* after connection is closed.
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_BAD_HANDLE </b> : If the handle is out of range
* <b> MICO_BT_RFCOMM_NOT_OPENED </b> : If the connection is not opened
*/
mico_bt_rfcomm_result_t mico_bt_rfcomm_remove_connection (uint16_t handle, mico_bool_t remove_server);
/**
* Set event callback the specified connection.
*
* @param[in] port_handle : A 16-bit unsigned integer returned by
* @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink
* @param[in] p_port_cb : Address of the callback function which should
* be called from the RFCOMM when an event
* specified in the mask occurs
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_BAD_HANDLE </b> : If the handle is out of range
* <b> MICO_BT_RFCOMM_NOT_OPENED </b> : If the connection is not opened
*/
mico_bt_rfcomm_result_t mico_bt_rfcomm_set_event_callback (uint16_t port_handle, mico_bt_port_event_cback_t *p_port_cb);
/**
* Set event data callback the specified connection.
*
* @param[in] port_handle : A 16-bit unsigned integer returned by
* @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink
* @param[in] p_cb : Address of the callback function which should
* be called from the RFCOMM when a data
* packet is received
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_BAD_HANDLE </b> : If the handle is out of range
* <b> MICO_BT_RFCOMM_NOT_OPENED </b> : If the connection is not opened
*/
mico_bt_rfcomm_result_t mico_bt_rfcomm_set_data_callback (uint16_t port_handle, mico_bt_rfcomm_data_cback_t *p_cb);
/**
* Set events for which to be notified
*
* @param[in] port_handle : A 16-bit unsigned integer returned by
* @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink
* @param[in] mask : Event mask
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_BAD_HANDLE </b> : If the handle is out of range
* <b> MICO_BT_RFCOMM_NOT_OPENED </b> : If the connection is not opened
*/
mico_bt_rfcomm_result_t mico_bt_rfcomm_set_event_mask (uint16_t port_handle, mico_bt_rfcomm_port_event_t mask);
/**
* Send control signal to the peer device.
*
* @param[in] handle : The connection handle returned by
* @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink
* @param[in] signal : Signal to send (see #mico_bt_rfcomm_signal_e)
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_BAD_HANDLE </b> : If the handle is out of range
* <b> MICO_BT_RFCOMM_NOT_OPENED </b> : If the connection is not opened
*/
mico_bt_rfcomm_result_t mico_bt_rfcomm_control (uint16_t handle, mico_bt_rfcomm_signal_t signal);
/**
* This function directs a specified connection to pass flow control message to the peer device.
* Enable flag passed shows if port can accept more data.
*
* @param[in] handle : The connection handle returned by
* @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink
* @param[in] enable : Flow control setting
* TRUE Enable data flow
* FALSE Disable data flow
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_BAD_HANDLE </b> : If the handle is out of range
* <b> MICO_BT_RFCOMM_NOT_OPENED </b> : If the connection is not opened
*/
mico_bt_rfcomm_result_t mico_bt_rfcomm_flow_control (uint16_t handle, mico_bool_t enable);
/**
* This function directs a specified connection to pass flow control message to the peer device.
* Enable flag passed shows if port can accept more data.
*
* @param[in] handle : The connection handle returned by
* @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink
* @param[in] p_data : Data to write
* @param[in] max_len : Byte count to write
* @param[out] p_len : Bytes written
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_BAD_HANDLE </b> : If the handle is out of range
* <b> MICO_BT_RFCOMM_NOT_OPENED </b> : If the connection is not opened
*/
mico_bt_rfcomm_result_t mico_bt_rfcomm_write_data (uint16_t handle, char *p_data, uint16_t max_len, uint16_t *p_len);
/**
* This function checks connection referenced by handle is up and running.
*
* @param[in] handle : The connection handle returned by
* @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink
* @param[out] bd_addr : Peer BD Address
* @param[out] p_lcid : L2CAP's LCID
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_LINE_ERR </b> : If connection is not up and running
*/
//mico_bt_rfcomm_result_t mico_bt_rfcomm_check_connection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid);
#ifdef MPAF_CUSTOM_STACK
/**
* This function allocates private pool to be used by RFCOMM.
*
* @param[in] buffer_size : size of buffer
* @param[out] buffer_cnt : buffers
*
* @return <b> MICO_BT_RFCOMM_SUCCESS </b> : If successful
* <b> MICO_BT_RFCOMM_ERROR </b> : If pool allocation fails
*/
mico_bt_rfcomm_result_t mico_bt_rfcomm_init(uint32_t buffer_size, uint32_t buffer_cnt);
/**
* This function enables flow control based on ACL buffer availability
*
* @param[in] peer_addr : Peer BD Address
*
* @return <b> MICO_TRUE </b> : If successful
* <b> MICO_FALSE </b> : If fails
*/
mico_bool_t mico_bt_rfcomm_control_data_flow(BD_ADDR peer_bda);
#endif
#ifdef __cplusplus
}
#endif
/**@} */

View file

@ -0,0 +1,126 @@
/** @file
*
* Bluetooth Synchronous Connection Oriented Channel Application Programming Interface
*
*/
#ifdef SCO_ENABLE //oscar for mindray
#pragma once
#include "mico.h"
#include "mico_bt_dev.h"
/******************************************************
* Constants
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/* Subset for the enhanced setup/accept synchronous connection paramters
* See BT 4.1 or later HCI spec for details */
typedef struct {
uint16_t max_latency; /**< Maximum latency (0x4-0xFFFE in msecs) */
uint16_t packet_types; /**< Packet Types */
uint8_t retrans_effort; /**< 0x00-0x02, 0xFF don't care */
mico_bool_t use_wbs; /**< True to use wide band, False to use narrow band */
} mico_bt_sco_params_t;
/**
* @addtogroup sco_api_functions Synchronous Connection Oriented (SCO) Channel
* @ingroup micobt
*
* SCO Functions
*
* @{
*/
/******************************************************
* Function Declarations
******************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/**
* Function mico_bt_sco_create_as_initiator
*
* Creates a synchronous connection oriented connection as initiator.
*
* @param[in] bd_addr : Peer bd_addr
* @param[in] p_params : Pointer to the SCO parameter structure
* @param[out] p_sco_index : SCO index returned
*
* @return <b> MICO_BT_UNKNOWN_ADDR </b> : Create connection failed, ACL connection is not up
* <b> MICO_BT_BUSY </b> : Create connection failed, another SCO is being
* conncted to the same BD address
* <b> MICO_BT_WRONG_MODE </b> : Create connection failed, wrong mode
* <b> MICO_BT_NO_RESOURCES </b> : Create connection failed, max SCO limit has been
* reached
* <b> BTM_CMD_STARTED </b> : Create connection successfully, "p_sco_index" is returned
*/
mico_bt_dev_status_t mico_bt_sco_create_as_initiator (mico_bt_device_address_t bd_addr,
uint16_t *p_sco_index,
mico_bt_sco_params_t *p_params);
/**
* Function mico_bt_sco_create_as_acceptor
*
* Creates a synchronous connection oriented connection as acceptor.
*
* @param[out] p_sco_index : SCO index returned
*
* @return <b> MICO_BT_UNKNOWN_ADDR </b> : Create connection failed, ACL connection is not up or
* address is invalid
* <b> MICO_BT_BUSY </b> : Create connection failed, a SCO connection is already
* conncted to the same BD address
* <b> MICO_BT_WRONG_MODE </b> : Create connection failed, link in park mode or
* automatic un-park is not supported
* <b> MICO_BT_NO_RESOURCES </b> : Create connection failed, max SCO limit has been
* reached
* <b> BTM_CMD_STARTED </b> : Create connection successfully, "p_sco_index" is returned
*/
mico_bt_dev_status_t mico_bt_sco_create_as_acceptor (uint16_t *p_sco_index);
/**
* Function mico_bt_sco_remove
*
* Removes a specific synchronous connection oriented connection.
*
* @param[in] sco_index : SCO index to remove
*
* @return <b> MICO_BT_UNKNOWN_ADDR </b> : Remove connection failed, invalid SCO index
* <b> MICO_BT_NO_RESOURCES </b> : Remove connection failed, no resource
* <b> MICO_BT_SUCCESS </b> : Remove connection successfully, device is still
* listening for incoming connection
* <b> BTM_CMD_STARTED </b> : Remove connection successfully
*/
mico_bt_dev_status_t mico_bt_sco_remove (uint16_t sco_index);
/**
* Function mico_bt_sco_accept_connection
*
* Called to handle (e)SCO connection request event (mico_bt_sco_connect_request_event).
*
*
* @param[in] sco_index : SCO index to remove
*
* @param[in] HCI status code : HCI_SUCCESS 0x00
* HCI_ERR_HOST_REJECT_RESOURCES 0x0D
* HCI_ERR_HOST_REJECT_SECURITY 0x0E
* HCI_ERR_HOST_REJECT_DEVICE 0x0F
* @param[in] p_params : Pointer to the SCO parameter structure
*
*/
void mico_bt_sco_accept_connection (uint16_t sco_index, uint8_t hci_status,
mico_bt_sco_params_t *p_params);
#ifdef __cplusplus
}
#endif
/** @} micobt_sco */
#endif

View file

@ -0,0 +1,520 @@
/** @file
*
* Bluetooth SDP Application Programming Interface
*
*/
#pragma once
#include "mico_bt_dev.h"
#include "sdpdefs.h"
/*****************************************************************************
* Constants
****************************************************************************/
/** SDP result - Success code and error codes */
enum mico_bt_sdp_result_t {
MICO_BT_SDP_SUCCESS = MICO_BT_SUCCESS, /**< SDP - Result: Success */
MICO_BT_SDP_INVALID_VERSION = 0x0001, /**< SDP - invalid version */
MICO_BT_SDP_INVALID_SERV_REC_HDL = 0x0002, /**< SDP - invalid service record */
MICO_BT_SDP_INVALID_REQ_SYNTAX = 0x0003, /**< SDP - invalid request syntax */
MICO_BT_SDP_INVALID_PDU_SIZE = 0x0004, /**< SDP - invalid PDU size */
MICO_BT_SDP_INVALID_CONT_STATE = 0x0005, /**< SDP - invalid controller state */
MICO_BT_SDP_NO_RESOURCES = 0x0006, /**< SDP - no resources */
MICO_BT_SDP_DI_REG_FAILED = 0x0007, /**< SDP - registration failed */
MICO_BT_SDP_DI_DISC_FAILED = 0x0008, /**< SDP - discovery failed */
MICO_BT_SDP_NO_DI_RECORD_FOUND = 0x0009, /**< SDP - no record found */
MICO_BT_SDP_ERR_ATTR_NOT_PRESENT = 0x000A, /**< SDP - no attribute present */
MICO_BT_SDP_ILLEGAL_PARAMETER = 0x000B, /**< SDP - Illegal parameter */
MICO_BT_SDP_NO_RECS_MATCH = 0xFFF0, /**< SDP - No records match */
MICO_BT_SDP_CONN_FAILED = 0xFFF1, /**< SDP - Connection failed */
MICO_BT_SDP_CFG_FAILED = 0xFFF2, /**< SDP - Configuration failed */
MICO_BT_SDP_GENERIC_ERROR = 0xFFF3, /**< SDP - Generic error */
MICO_BT_SDP_DB_FULL = 0xFFF4, /**< SDP - DB full */
MICO_BT_SDP_INVALID_PDU = 0xFFF5, /**< SDP - Invalid PDU */
MICO_BT_SDP_SECURITY_ERR = 0xFFF6, /**< SDP - Security Error */
MICO_BT_SDP_CONN_REJECTED = 0xFFF7, /**< SDP - Connection rejected */
MICO_BT_SDP_CANCEL = 0xFFF8 /**< SDP - cancel */
};
/* Define the PSM that SDP uses */
#define SDP_PSM 0x0001
/* Masks for attr_value field of mico_bt_sdp_discovery_attribute_t */
#define SDP_DISC_ATTR_LEN_MASK 0x0FFF
#define SDP_DISC_ATTR_TYPE(len_type) (len_type >> 12)
#define SDP_DISC_ATTR_LEN(len_type) (len_type & SDP_DISC_ATTR_LEN_MASK)
/* Maximum number of protocol list items (list_elem in mico_bt_sdp_protocol_elem_t) */
#define SDP_MAX_LIST_ELEMS 3
/*****************************************************************************
* Type Definitions
****************************************************************************/
/**
* Function mico_bt_sdp_discovery_complete_cback_t
*
* Service discovery complete callback.
*
* If discovery was successful, the discovery results database (provided when #mico_bt_sdp_service_search_request
* or #mico_bt_sdp_service_search_attribute_request was called) will be filled.
*
* Use the mico_bt_sdp_find_* utility functions to parse the results.
*
* @param[in] sdp_result : SDP result code (see #mico_bt_sdp_result_t)
*
* @return Nothing
*
*/
typedef void (mico_bt_sdp_discovery_complete_cback_t) (uint16_t sdp_result);
/** Attribute value */
typedef struct {
union {
uint8_t u8; /**< 8-bit integer */
uint16_t u16; /**< 16-bit integer */
uint32_t u32; /**< 32-bit integer */
uint8_t array[4]; /**< Variable length field */
struct t_sdp_discovery_attr *p_sub_attr; /**< Addr of first sub-attr (list)*/
} v;
} mico_bt_sdp_discovery_attribute_value_t;
/** SDP Attribute */
typedef struct t_sdp_discovery_attr {
struct t_sdp_disc_attr *p_next_attr; /**< Addr of next linked attr */
uint16_t attr_id; /**< Attribute ID */
uint16_t attr_len_type; /**< Length and type fields */
mico_bt_sdp_discovery_attribute_value_t attr_value; /**< Variable length entry data */
} mico_bt_sdp_discovery_attribute_t;
/** Discovery record from SDP search result */
typedef struct sdp_discovery_record_t {
mico_bt_sdp_discovery_attribute_t *p_first_attr; /**< First attribute of record */
struct sdp_discovery_record_t *p_next_rec; /**< Addr of next linked record */
uint32_t time_read; /**< The time the record was read */
mico_bt_device_address_t remote_bd_addr; /**< Remote BD address */
} mico_bt_sdp_discovery_record_t;
/** Discovery database (used for performing service searches and holding search results) */
typedef struct {
uint32_t mem_size; /**< Memory size of the DB */
uint32_t mem_free; /**< Memory still available */
mico_bt_sdp_discovery_record_t *p_first_rec; /**< Addr of first record in DB */
uint16_t num_uuid_filters; /**< Number of UUIds to filter */
mico_bt_uuid_t uid_filters[SDP_MAX_UUID_FILTERS]; /**< UUIDs to filter */
uint16_t num_attr_filters; /**< Number of attribute filters */
uint16_t attr_filters[SDP_MAX_ATTR_FILTERS]; /**< Attributes to filter */
uint8_t *p_free_mem; /**< Pointer to free memory */
} mico_bt_sdp_discovery_db_t;
/** This structure is used to add protocol lists and find protocol elements */
typedef struct {
uint16_t protocol_uuid; /**< The protocol uuid */
uint16_t num_params; /**< Number of parameters */
uint16_t params[SDP_MAX_PROTOCOL_PARAMS]; /**< Contents of protocol parameters */
} mico_bt_sdp_protocol_elem_t;
/*****************************************************************************
* SDP Server Database Macros
****************************************************************************/
#define SDP_UINT1(value) (value)
#define SDP_UINT2(value) (value) >> 8, (value) & 0xff
#define SDP_UINT4(value) (value) >> 24, ((value) >> 16) & 0xff, ((value) >> 8) & 0xff, (value) & 0xff
#define SDP_UINT8(value) (value) >> 56, ((value) >> 48) & 0xff, ((value >> 40) >> 8) & 0xff, \
(value >> 32) & 0xff, ((value) >> 24) & 0xff, ((value) >> 16) & 0xff, \
((value) >> 8) & 0xff, (value) & 0xff
#define SDP_BOOLEAN SDP_UINT1
#define SDP_ATTR_VALUE_UINT1(value) (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE, SDP_UINT1(value)
#define SDP_ATTR_VALUE_UINT2(value) (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES, SDP_UINT2(value)
#define SDP_ATTR_VALUE_UINT4(value) (UINT_DESC_TYPE << 3) | SIZE_FOUR_BYTES, SDP_UINT4(value)
#define SDP_ATTR_VALUE_UINT8(value) (UINT_DESC_TYPE << 3) | SIZE_EIGHT_BYTES, SDP_UINT8(value)
#define SDP_ATTR_VALUE_BOOLEAN(value) (BOOLEAN_DESC_TYPE << 3), SDP_UINT1(value)
#define SDP_ATTR_VALUE_TEXT (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE
#define SDP_ATTR_UINT1(id, value) SDP_ATTR_ID(id), SDP_ATTR_VALUE_UINT1(value)
#define SDP_ATTR_UINT2(id, value) SDP_ATTR_ID(id), SDP_ATTR_VALUE_UINT2(value)
#define SDP_ATTR_UINT4(id, value) SDP_ATTR_ID(id), SDP_ATTR_VALUE_UINT4(value)
#define SDP_ATTR_UINT8(id, value) SDP_ATTR_ID(id), SDP_ATTR_VALUE_UINT8(value)
#define SDP_ATTR_BOOLEAN(id, value) SDP_ATTR_ID(id), SDP_ATTR_VALUE_BOOLEAN(value)
#define SDP_ATTR_ID SDP_ATTR_VALUE_UINT2
#define SDP_ATTR_UUID16(uuid) ((UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES), SDP_UINT2(uuid)
#define SDP_ATTR_UUID128(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) \
((UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES), \
x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16
#define SDP_ATTR_TEXT(id, len) SDP_ATTR_ID(id), SDP_ATTR_VALUE_TEXT, (len)
#define SDP_ATTR_SEQUENCE_1(length) ((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE), (length)
#define SDP_ATTR_SEQUENCE_2(length) ((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD), SDP_UINT2(length)
#define SDP_ATTR_SEQUENCE_4(length) ((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_LONG), SDP_UINT4(length)
/* Service Record Handle 0x0000 */
#define SDP_ATTR_RECORD_HANDLE(handle) SDP_ATTR_UINT4(ATTR_ID_SERVICE_RECORD_HDL, handle)
/* Service Class ID List 0x0001 */
#define SDP_ATTR_CLASS_ID(uuid) \
SDP_ATTR_ID(ATTR_ID_SERVICE_CLASS_ID_LIST), SDP_ATTR_SEQUENCE_1(3), \
SDP_ATTR_UUID16(uuid)
#define SDP_ATTR_CLASS_ID128(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) \
SDP_ATTR_ID(ATTR_ID_SERVICE_CLASS_ID_LIST), SDP_ATTR_SEQUENCE_1(17), \
SDP_ATTR_UUID128(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)
/* Service Record State 0x0002 */
#define SDP_ATTR_SERVICE_RECORD_STATE(state) \
SDP_ATTR_UINT4(ATTR_ID_SERVICE_RECORD_STATE, state)
/* Service ID 0x0003 */
#define SDP_ATTR_SERVICE_ID(uuid) \
SDP_ATTR_ID(ATTR_ID_SERVICE_ID), SDP_ATTR_SEQUENCE_1(3), \
SDP_ATTR_UUID16(uuid)
/* Protocol Descriptor List 0x0004 for L2CAP */
#define SDP_ATTR_PROTOCOL_DESC_LIST(l2cap_chan) \
SDP_ATTR_ID(ATTR_ID_PROTOCOL_DESC_LIST), SDP_ATTR_SEQUENCE_1(13), \
SDP_ATTR_SEQUENCE_1(6), \
SDP_ATTR_UUID16(UUID_PROTOCOL_L2CAP), \
SDP_ATTR_VALUE_UINT2(1), \
SDP_ATTR_SEQUENCE_1(3), \
SDP_ATTR_UUID16(l2cap_chan)
/* Protocol Descriptor List 0x0004 for RFCOMM */
#define SDP_ATTR_RFCOMM_PROTOCOL_DESC_LIST(scn) \
SDP_ATTR_ID(ATTR_ID_PROTOCOL_DESC_LIST), SDP_ATTR_SEQUENCE_1(12), \
SDP_ATTR_SEQUENCE_1(3), \
SDP_ATTR_UUID16(UUID_PROTOCOL_L2CAP), \
SDP_ATTR_SEQUENCE_1(5), \
SDP_ATTR_UUID16(UUID_PROTOCOL_RFCOMM), \
SDP_ATTR_VALUE_UINT1(scn)
/* Browse Group List 0x0005 */
#define SDP_ATTR_BROWSE_LIST \
SDP_ATTR_ID(ATTR_ID_BROWSE_GROUP_LIST), SDP_ATTR_SEQUENCE_1(3), \
SDP_ATTR_UUID16(UUID_SERVCLASS_PUBLIC_BROWSE_GROUP)
/* Language Base 0x0006 */
#define SDP_ATTR_LANGUAGE_BASE_ATTR_ID_LIST \
SDP_ATTR_ID(ATTR_ID_LANGUAGE_BASE_ATTR_ID_LIST), SDP_ATTR_SEQUENCE_1(9), \
SDP_ATTR_VALUE_UINT2(LANG_ID_CODE_ENGLISH), \
SDP_ATTR_VALUE_UINT2(LANG_ID_CHAR_ENCODE_UTF8), \
SDP_ATTR_VALUE_UINT2(LANGUAGE_BASE_ID)
/* Service Info Time to Live 0x0007 */
#define SDP_ATTR_SERVICE_INFO_TIME_TO_LIVE(seconds) \
SDP_ATTR_UINT4(ATTR_ID_SERVICE_INFO_TIME_TO_LIVE, seconds)
/* Service Availability 0x0008 */
#define SDP_ATTR_SERVICE_AVAILABILITY(availability) \
SDP_ATTR_UINT1(ATTR_ID_SERVICE_AVAILABILITY, availability)
/* BT Profile Descriptor List 0x0009 */
#define SDP_ATTR_PROFILE_DESC_LIST(uuid, version) \
SDP_ATTR_ID(ATTR_ID_BT_PROFILE_DESC_LIST), SDP_ATTR_SEQUENCE_1(8), \
SDP_ATTR_SEQUENCE_1(6), \
SDP_ATTR_UUID16(uuid), \
SDP_ATTR_VALUE_UINT2(version)
/* Documentation URL 0x000A */
#define SDP_ATTR_DOCUMENTATION_URL(len) \
SDP_ATTR_TEXT(ATTR_ID_DOCUMENTATION_URL, len)
/* Client Executable URL 0x000B */
#define SDP_ATTR_CLIENT_EXECUTABLE_URL(len) \
SDP_ATTR_TEXT(ATTR_ID_CLIENT_EXE_URL, len)
/* Icon URL 0x000C */
#define SDP_ATTR_ICON_URL(len) \
SDP_ATTR_TEXT(ATTR_ID_ICON_URL, len)
/* Service Name LANGUAGE_BASE_ID (0x0100) + 0x0000 = 0x0100 */
#define SDP_ATTR_SERVICE_NAME(len) \
SDP_ATTR_TEXT(ATTR_ID_SERVICE_NAME, len)
/* Service Description LANGUAGE_BASE_ID (0x0100) + 0x0001 = 0x0101 */
#define SDP_ATTR_SERVICE_DESCRIPTION(len) \
SDP_ATTR_TEXT(ATTR_ID_SERVICE_DESCRIPTION, len)
/* Provider Name LANGUAGE_BASE_ID (0x0100) + 0x0002 = 0x0102 */
#define SDP_ATTR_PROVIDER_NAME(len) \
SDP_ATTR_TEXT(ATTR_ID_PROVIDER_NAME, len)
/* Group ID 0x0200 */
#define SDP_ATTR_GROUP_ID(uuid) \
SDP_ATTR_ID(ATTR_ID_GROUP_ID), SDP_ATTR_SEQUENCE_1(3), \
SDP_ATTR_UUID16(uuid)
/* Version Number List 0x0200 */
#define SDP_ATTR_VERSION_NUMBER_LIST(version) \
SDP_ATTR_UINT2(ATTR_ID_SPECIFICATION_ID, version)
/* Service Database State 0x0201 */
#define SDP_ATTR_SERVICE_DATABASE_STATE(state) \
SDP_ATTR_UINT4(ATTR_ID_VENDOR_ID, state)
/*************************************************************************//**
* @addtogroup sdp_api_functions Service Discovery (SDP)
* @ingroup micobt
*
* Service Discovery (SDP) Functions.
*
* @{
****************************************************************************/
/******************************************************
* Function Declarations
******************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/* SDP Server APIs */
/**
*
* Function mico_bt_sdp_db_init
*
* Initialize local SDP server database (database generated using
* MiCO Smart/SmartReady Designer)
*
* @param[in] p_sdp_db: First element in database array
* @param[in] size: size (in bytes) of SDP database
*
* @return TRUE if successful, FALSE otherwise
*
**/
mico_bool_t mico_bt_sdp_db_init (uint8_t *p_sdp_db, uint16_t size);
/* SDP Client APIs */
/**
*
* Function mico_bt_sdp_init_discovery_db
*
* Initialize discovery database prior to performing service
* discovery (using #mico_bt_sdp_service_search_request or
* #mico_bt_sdp_service_search_request).
*
* Provides a list of UUIDs and/or attribute IDs to search for.
*
* @param[in] p_db : Discovery database to initialize
* @param[in] len : size of discovery database
* @param[in] num_uuid : Number of UUIDs in p_uuid_list
* @param[in] p_uuid_list : UUIDs to add to discovery database
* @param[in] num_attr : Number of attributes in p_attr_list
* @param[in] p_attr_list : Attributes to add to discovery database
*
* @return TRUE if successful, FALSE if one or more parameters are bad
*
**/
mico_bool_t mico_bt_sdp_init_discovery_db (mico_bt_sdp_discovery_db_t *p_db, uint32_t len,
uint16_t num_uuid,
mico_bt_uuid_t *p_uuid_list,
uint16_t num_attr,
uint16_t *p_attr_list);
/**
*
* Function mico_bt_sdp_cancel_service_search
*
* Cancel service search request
*
* @param[in] p_db : Discovery database of the request being cancelled
*
* @return TRUE if discovery cancelled, FALSE if a matching activity is not found.
*
**/
mico_bool_t mico_bt_sdp_cancel_service_search (mico_bt_sdp_discovery_db_t *p_db);
/**
*
* Function mico_bt_sdp_service_search_request
*
* Initiate service search on remote device
*
* @param[in] p_bd_addr : Remote device address
* @param[in] p_db : Discovery database of UUIDs and attribute IDs to search for (intialized using #mico_bt_sdp_init_discovery_db)
* @param[in] p_cb : Callback for discovery results
*
* @return TRUE if discovery started, FALSE if failed.
*
**/
mico_bool_t mico_bt_sdp_service_search_request (uint8_t *p_bd_addr,
mico_bt_sdp_discovery_db_t *p_db,
mico_bt_sdp_discovery_complete_cback_t *p_cb);
/**
*
* Function mico_bt_sdp_service_search_attribute_request
*
* Initiate combined service search and attribute request on remote device
*
* @param[in] p_bd_addr : Remote device address
* @param[in] p_db : Discovery database of UUIDs and attribute IDs to search for (intialized using #mico_bt_sdp_init_discovery_db)
* @param[in] p_cb : Callback for discovery results
*
* @return TRUE if discovery started, FALSE if failed.
*
**/
mico_bool_t mico_bt_sdp_service_search_attribute_request (uint8_t *p_bd_addr,
mico_bt_sdp_discovery_db_t *p_db,
mico_bt_sdp_discovery_complete_cback_t *p_cb);
/* API of utilities to find data in the local discovery database */
/**
*
* Function mico_bt_sdp_find_attribute_in_db
*
* Parse results from service search. Look next record in discovery database
* containing attribute ID.
*
* @param[in] p_db : Discovery results database
* @param[in] attr_id : Attribute ID to find
* @param[in] p_start_rec : Starting record to search from (if NULL, start from beginning of database)
*
* @return Pointer to matching record, or NULL
*
**/
mico_bt_sdp_discovery_record_t *mico_bt_sdp_find_attribute_in_db (mico_bt_sdp_discovery_db_t *p_db,
uint16_t attr_id,
mico_bt_sdp_discovery_record_t *p_start_rec);
/**
*
* Function mico_bt_sdp_find_attribute_in_rec
*
* Parse SDP record. Look for requested attribute in the service record.
*
* @param[in] p_rec : Service record
* @param[in] attr_id : Attribute ID to find
*
* @return Pointer to matching attribute entry, or NULL
*
**/
mico_bt_sdp_discovery_attribute_t *mico_bt_sdp_find_attribute_in_rec (mico_bt_sdp_discovery_record_t *p_rec,
uint16_t attr_id);
/**
*
* Function mico_bt_sdp_find_service_in_db
*
* Parse results from service search. Look next record in discovery database
* containing requested service UUID (specified using uint16_t)
*
* @param[in] p_db : Discovery results database
* @param[in] service_uuid: Service to find
* @param[in] p_start_rec : Starting record to search from (if NULL, start from beginning of database)
*
* @return Pointer to matching record, or NULL
*
**/
mico_bt_sdp_discovery_record_t *mico_bt_sdp_find_service_in_db (mico_bt_sdp_discovery_db_t *p_db,
uint16_t service_uuid,
mico_bt_sdp_discovery_record_t *p_start_rec);
/**
*
* Function mico_bt_sdp_find_service_uuid_in_db
*
* Parse results from service search. Look next record in discovery database
* containing requested service UUID (specified using mico_bt_uuid_t structure)
*
* @param[in] p_db : Discovery results database
* @param[in] p_uuid : Service to find
* @param[in] p_start_rec : Starting record to search from (if NULL, start from beginning of database)
*
* @return Pointer to matching record, or NULL
*
**/
mico_bt_sdp_discovery_record_t *mico_bt_sdp_find_service_uuid_in_db (mico_bt_sdp_discovery_db_t *p_db,
mico_bt_uuid_t *p_uuid,
mico_bt_sdp_discovery_record_t *p_start_rec);
/**
*
* Function mico_bt_sdp_find_protocol_list_elem_in_rec
*
* Parse SDP record. Look for requested protocol list element in the service record.
*
* @param[in] p_rec : Service record
* @param[in] layer_uuid : protocol list element to find
* @param[out] p_elem : protocol list element (if found)
*
* @return TRUE if found, else FALSE
*
**/
mico_bool_t mico_bt_sdp_find_protocol_list_elem_in_rec (mico_bt_sdp_discovery_record_t *p_rec,
uint16_t layer_uuid,
mico_bt_sdp_protocol_elem_t *p_elem);
/**
*
* Function mico_bt_sdp_find_protocol_lists_elem_in_rec
*
* Parse SDP record. Look for requested protocol lists element in the service record.
*
* @param[in] p_rec : Service record
* @param[in] layer_uuid : protocol lists element to find
* @param[out] p_elem : protocol lists element (if found)
*
* @return TRUE if found, else FALSE
*
**/
mico_bool_t mico_bt_sdp_find_protocol_lists_elem_in_rec (mico_bt_sdp_discovery_record_t *p_rec,
uint16_t layer_uuid,
mico_bt_sdp_protocol_elem_t *p_elem);
/**
*
* Function mico_bt_sdp_find_profile_version_in_rec
*
* Parse SDP record. Look for version of requested profile.
*
* @param[in] p_rec : Service record
* @param[in] profile_uuid: Profile to find
* @param[out] p_version : Major/minor version of profile (if found)
*
* @return TRUE if found, FALSE if not
*
**/
mico_bool_t mico_bt_sdp_find_profile_version_in_rec (mico_bt_sdp_discovery_record_t *p_rec,
uint16_t profile_uuid,
uint16_t *p_version);
/**
*
* Function mico_bt_sdp_find_service_uuid_in_rec
*
* Parse SDP record. Look for service UUID
*
* @param[in] p_rec : Service record
* @param[out] p_uuid : Service UUID of the record
*
* @return TRUE if found, FALSE if not
*
**/
mico_bool_t mico_bt_sdp_find_service_uuid_in_rec(mico_bt_sdp_discovery_record_t *p_rec, mico_bt_uuid_t *p_uuid);
#ifdef __cplusplus
}
#endif
/**@} sdp_api_functions */

View file

@ -0,0 +1,79 @@
/** @file
*
* Bluetooth Management (BTM) Application Programming Interface
*
* The BTM consists of several management entities:
* 1. Device Control - controls the local device
* 2. Device Discovery - manages inquiries, discover database
* 3. ACL Channels - manages ACL connections (BR/EDR and LE)
* 4. SCO Channels - manages SCO connections
* 5. Security - manages all security functionality
* 6. Power Management - manages park, sniff, hold, etc.
*
* @defgroup micobt Bluetooth
*
* MiCO Bluetooth Framework Functions
*/
#pragma once
#include "mico_bt_dev.h"
#include "mico_bt_cfg.h"
/******************************************************
* Function Declarations
******************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************************/
/**
* Framework Management Functions
*
* @addtogroup micobt_Framework Framework
* @ingroup micobt
*
* @{
*/
/****************************************************************************/
/**
* Function mico_bt_stack_init
*
* Initialize the Bluetooth controller and stack; register
* callback for Bluetooth event notification.
*
* @param[in] p_bt_management_cback : Callback for receiving Bluetooth management events
* @param[in] p_bt_cfg_settings : Bluetooth stack configuration
* @param[in] mico_bt_cfg_buf_pools : Buffer pool configuration
*
* @return MICO_BT_SUCCESS : on success;
* MICO_BT_FAILED : if an error occurred
*/
mico_bt_result_t mico_bt_stack_init(mico_bt_management_cback_t *p_bt_management_cback,
const mico_bt_cfg_settings_t *p_bt_cfg_settings,
const mico_bt_cfg_buf_pool_t mico_bt_cfg_buf_pools[MICO_BT_CFG_NUM_BUF_POOLS]);
/**
* Function mico_bt_stack_deinit
*
* De-initialize the Bluetooth controller and stack.
*
* @return MICO_BT_SUCCESS : on success;
* MICO_BT_ERROR : if an error occurred
*/
OSStatus mico_bt_stack_deinit(void);
/**@} micobt_Framework */
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,114 @@
/** @file
*
* Generic types
*
*/
#pragma once
#include "common.h"
#include "data_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BD_ADDR_LEN 6
typedef uint8_t mico_bt_device_address_t[BD_ADDR_LEN]; /**< Device address length */
typedef uint8_t *mico_bt_device_address_ptr_t; /**< Device address Pointer */
#define DEV_CLASS_LEN 3
typedef uint8_t mico_bt_dev_class_t[DEV_CLASS_LEN]; /**< Device class */
#define MAX_UUID_SIZE 16 /**< Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */
/** UUID Type */
typedef struct {
#define LEN_UUID_16 2
#define LEN_UUID_32 4
#define LEN_UUID_128 16
uint16_t len; /**< UUID length */
union {
uint16_t uuid16; /**< 16-bit UUID */
uint32_t uuid32; /**< 32-bit UUID */
uint8_t uuid128[MAX_UUID_SIZE]; /**< 128-bit UUID */
} uu;
} mico_bt_uuid_t;
#define BT_OCTET16_LEN 16 /**< length: 16 */
typedef uint8_t BT_OCTET16[BT_OCTET16_LEN]; /**< octet array: size 16 */
#define BT_OCTET32_LEN 32
typedef uint8_t BT_OCTET32[BT_OCTET32_LEN]; /* octet array: size 32 */
/** Bluetooth QoS defintions */
typedef struct {
uint8_t qos_flags; /**< TBD */
uint8_t service_type; /**< service type (NO_TRAFFIC, BEST_EFFORT, or GUARANTEED) */
uint32_t token_rate; /**< token rate (bytes/second) */
uint32_t token_bucket_size; /**< token bucket size (bytes) */
uint32_t peak_bandwidth; /**< peak bandwidth (bytes/second) */
uint32_t latency; /**< latency (microseconds) */
uint32_t delay_variation; /**< delay variation (microseconds) */
} mico_bt_flow_spec_t;
/* Values for smico_bt_flow_spec_t service_type */
#define NO_TRAFFIC 0
#define BEST_EFFORT 1
#define GUARANTEED 2
/**
* @anchor MICO_BT_TRANSPORT_TYPE
* @name Transport types
* @{
*/
#define BT_TRANSPORT_BR_EDR 1 /**< BR/EDR transport */
#define BT_TRANSPORT_LE 2 /**< BLE transport */
typedef uint8_t mico_bt_transport_t; /**< Transport type (see @ref MICO_BT_TRANSPORT_TYPE "BT Transport Types") */
/**
* @anchor MICO_BT_DEVICE_TYPE
* @name Device Types
* @{
*/
#define BT_DEVICE_TYPE_BREDR 0x01 /**< BR/EDR device */
#define BT_DEVICE_TYPE_BLE 0x02 /**< LE device */
#define BT_DEVICE_TYPE_BREDR_BLE 0x03 /**< Dual Mode device */
typedef uint8_t
mico_bt_device_type_t; /**< Bluetooth device type (see @ref MICO_BT_DEVICE_TYPE "BT Device Types") */
/** @} MICO_BT_DEVICE_TYPE */
/**
* @anchor MICO_BT_ADDR_TYPE
* @name Address Types
* @{
*/
#define BLE_ADDR_PUBLIC 0x00 /**< Public address */
#define BLE_ADDR_RANDOM 0x01 /**< Random address */
#define BLE_ADDR_PUBLIC_ID 0x02 /**< Public ID */
#define BLE_ADDR_RANDOM_ID 0x03 /**< Random ID */
typedef uint8_t
mico_bt_ble_address_type_t; /**< BLE device address type (see @ref MICO_BT_ADDR_TYPE "BT Address Types")*/
#define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC)
/** @} MICO_BT_ADDR_TYPE */
typedef struct {
mico_bt_ble_address_type_t type;
mico_bt_device_address_t bda;
} mico_bt_ble_address_t;
#define LINK_KEY_LEN 16
typedef uint8_t mico_bt_link_key_t[LINK_KEY_LEN];
#define BT_ROLE_MASTER 0x00
#define BT_ROLE_SLAVE 0x01
typedef uint8_t mico_bt_ble_link_role_t;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,341 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
/****************************************************************************
**
** Name: sdp_defs.h
**
** Function this file contains the definitions for the SDP API
**
******************************************************************************/
#ifndef SDP_DEFS_H
#define SDP_DEFS_H
/* Define the service attribute IDs.
*/
#define ATTR_ID_SERVICE_RECORD_HDL 0x0000
#define ATTR_ID_SERVICE_CLASS_ID_LIST 0x0001
#define ATTR_ID_SERVICE_RECORD_STATE 0x0002
#define ATTR_ID_SERVICE_ID 0x0003
#define ATTR_ID_PROTOCOL_DESC_LIST 0x0004
#define ATTR_ID_BROWSE_GROUP_LIST 0x0005
#define ATTR_ID_LANGUAGE_BASE_ATTR_ID_LIST 0x0006
#define ATTR_ID_SERVICE_INFO_TIME_TO_LIVE 0x0007
#define ATTR_ID_SERVICE_AVAILABILITY 0x0008
#define ATTR_ID_BT_PROFILE_DESC_LIST 0x0009
#define ATTR_ID_DOCUMENTATION_URL 0x000A
#define ATTR_ID_CLIENT_EXE_URL 0x000B
#define ATTR_ID_ICON_URL 0x000C
#define ATTR_ID_ADDITION_PROTO_DESC_LISTS 0x000D
#define LANGUAGE_BASE_ID 0x0100
#define ATTR_ID_SERVICE_NAME LANGUAGE_BASE_ID + 0x0000
#define ATTR_ID_SERVICE_DESCRIPTION LANGUAGE_BASE_ID + 0x0001
#define ATTR_ID_PROVIDER_NAME LANGUAGE_BASE_ID + 0x0002
/* Device Identification (DI)
*/
#define ATTR_ID_SPECIFICATION_ID 0x0200
#define ATTR_ID_VENDOR_ID 0x0201
#define ATTR_ID_PRODUCT_ID 0x0202
#define ATTR_ID_PRODUCT_VERSION 0x0203
#define ATTR_ID_PRIMARY_RECORD 0x0204
#define ATTR_ID_VENDOR_ID_SOURCE 0x0205
#define BLUETOOTH_DI_SPECIFICATION 0x0103 /* 1.3 */
#define DI_VENDOR_ID_DEFAULT 0xFFFF
#define DI_VENDOR_ID_SOURCE_BTSIG 0x0001
#define DI_VENDOR_ID_SOURCE_USBIF 0x0002
#define ATTR_ID_IP_SUBNET 0x0200 /* PAN Profile (***) */
#define ATTR_ID_VERSION_NUMBER_LIST 0x0200
#define ATTR_ID_GROUP_ID 0x0200
#define ATTR_ID_SERVICE_DATABASE_STATE 0x0201
#define ATTR_ID_SERVICE_VERSION 0x0300
#define ATTR_ID_HCRP_1284ID 0x0300
#define ATTR_ID_SUPPORTED_DATA_STORES 0x0301
#define ATTR_ID_NETWORK 0x0301
#define ATTR_ID_EXTERNAL_NETWORK 0x0301
#define ATTR_ID_FAX_CLASS_1_SUPPORT 0x0302
#define ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL 0x0302
#define ATTR_ID_DEVICE_NAME 0x0302
#define ATTR_ID_SUPPORTED_FORMATS_LIST 0x0303
#define ATTR_ID_FAX_CLASS_2_0_SUPPORT 0x0303
#define ATTR_ID_FAX_CLASS_2_SUPPORT 0x0304
#define ATTR_ID_FRIENDLY_NAME 0x0304
#define ATTR_ID_AUDIO_FEEDBACK_SUPPORT 0x0305
#define ATTR_ID_NETWORK_ADDRESS 0x0306
#define ATTR_ID_DEVICE_LOCATION 0x0306
#define ATTR_ID_WAP_GATEWAY 0x0307
#define ATTR_ID_HOME_PAGE_URL 0x0308
#define ATTR_ID_WAP_STACK_TYPE 0x0309
#define ATTR_ID_IMG_SUPPORTED_CAPABILITIES 0x0310 /* Imaging Profile */
#define ATTR_ID_SUPPORTED_FEATURES 0x0311 /* HFP, BIP */
#define ATTR_ID_IMG_SUPPORTED_FUNCTIONS 0x0312 /* Imaging Profile */
#define ATTR_ID_IMG_TOT_DATA_CAPABILITY 0x0313 /* Imaging Profile */
#define ATTR_ID_SUPPORTED_REPOSITORIES 0x0314 /* Phone book access Profile */
#define ATTR_ID_INSTANCE_ID 0x0315 /* MAP, CTN profile */
#define ATTR_ID_SUPPORTED_MSG_TYPE 0x0316 /* MAP profile */
/* MAP 1.2 uses this, but PBAP 1.2 and GPP, and
** other profiles can also use this generic 32-bit mask
*/
#define ATTR_ID_SUPPORTED_FEATURES_32 0x0317 /* 32-bit supported features */
/* These values are for the BPP profile */
#define ATTR_ID_DOCUMENT_FORMATS_SUPPORTED 0x0350
#define ATTR_ID_CHARACTER_REPERTOIRES_SUPPORTED 0x0352
#define ATTR_ID_XHTML_IMAGE_FORMATS_SUPPORTED 0x0354
#define ATTR_ID_COLOR_SUPPORTED 0x0356
#define ATTR_ID_1284ID 0x0358
#define ATTR_ID_PRINTER_NAME 0x035A
#define ATTR_ID_PRINTER_LOCATION 0x035C
#define ATTR_ID_DUPLEX_SUPPORTED 0x035E
#define ATTR_ID_MEDIA_TYPES_SUPPORTED 0x0360
#define ATTR_ID_MAX_MEDIA_WIDTH 0x0362
#define ATTR_ID_MAX_MEDIA_LENGTH 0x0364
#define ATTR_ID_ENHANCED_LAYOUT_SUPPORTED 0x0366
#define ATTR_ID_RUI_FORMATS_SUPPORTED 0x0368
#define ATTR_ID_RUI_REF_PRINTING_SUPPORTED 0x0370 /* Boolean */
#define ATTR_ID_RUI_DIRECT_PRINTING_SUPPORTED 0x0372 /* Boolean */
#define ATTR_ID_REF_PRINTING_TOP_URL 0x0374
#define ATTR_ID_DIRECT_PRINTING_TOP_URL 0x0376
#define ATTR_ID_PRINTER_ADMIN_RUI_TOP_URL 0x0378
#define ATTR_ID_BPP_DEVICE_NAME 0x037A
/* These values are for the PAN profile */
#define ATTR_ID_SECURITY_DESCRIPTION 0x030A
#define ATTR_ID_NET_ACCESS_TYPE 0x030B
#define ATTR_ID_MAX_NET_ACCESS_RATE 0x030C
#define ATTR_ID_IPV4_SUBNET 0x030D
#define ATTR_ID_IPV6_SUBNET 0x030E
#define ATTR_ID_PAN_SECURITY 0x0400
/* These values are for HID profile */
#define ATTR_ID_HID_DEVICE_RELNUM 0x0200
#define ATTR_ID_HID_PARSER_VERSION 0x0201
#define ATTR_ID_HID_DEVICE_SUBCLASS 0x0202
#define ATTR_ID_HID_COUNTRY_CODE 0x0203
#define ATTR_ID_HID_VIRTUAL_CABLE 0x0204
#define ATTR_ID_HID_RECONNECT_INITIATE 0x0205
#define ATTR_ID_HID_DESCRIPTOR_LIST 0x0206
#define ATTR_ID_HID_LANGUAGE_ID_BASE 0x0207
#define ATTR_ID_HID_SDP_DISABLE 0x0208
#define ATTR_ID_HID_BATTERY_POWER 0x0209
#define ATTR_ID_HID_REMOTE_WAKE 0x020A
#define ATTR_ID_HID_PROFILE_VERSION 0x020B
#define ATTR_ID_HID_LINK_SUPERVISION_TO 0x020C
#define ATTR_ID_HID_NORMALLY_CONNECTABLE 0x020D
#define ATTR_ID_HID_BOOT_DEVICE 0x020E
#define ATTR_ID_HID_SSR_HOST_MAX_LAT 0x020F
#define ATTR_ID_HID_SSR_HOST_MIN_TOUT 0x0210
/* These values are for the HDP profile */
#define ATTR_ID_HDP_SUP_FEAT_LIST 0x0200 /* Supported features list */
#define ATTR_ID_HDP_DATA_EXCH_SPEC 0x0301 /* Data exchange specification */
#define ATTR_ID_HDP_MCAP_SUP_PROC 0x0302 /* MCAP supported procedures */
/* These values are for GOEP */
#define ATTR_ID_OBX_OVR_L2CAP_PSM 0x0200
/* MultiProfile Attribute IDs */
#define BTA_MPS_UUID_MPSD_SCENARIOS ((UINT16) 0x200)
#define BTA_MPS_UUID_MPMD_SCENARIOS ((UINT16) 0x201)
#define BTA_MPS_UUID_PPD_SUPPORTED ((UINT16) 0x202)
/* Define common 16-bit protocol UUIDs
*/
#define UUID_PROTOCOL_SDP 0x0001
#define UUID_PROTOCOL_UDP 0x0002
#define UUID_PROTOCOL_RFCOMM 0x0003
#define UUID_PROTOCOL_TCP 0x0004
#define UUID_PROTOCOL_TCS_BIN 0x0005
#define UUID_PROTOCOL_TCS_AT 0x0006
#define UUID_PROTOCOL_OBEX 0x0008
#define UUID_PROTOCOL_IP 0x0009
#define UUID_PROTOCOL_FTP 0x000A
#define UUID_PROTOCOL_HTTP 0x000C
#define UUID_PROTOCOL_WSP 0x000E
#define UUID_PROTOCOL_BNEP 0x000F
#define UUID_PROTOCOL_UPNP 0x0010
#define UUID_PROTOCOL_HIDP 0x0011
#define UUID_PROTOCOL_HCRP_CTRL 0x0012
#define UUID_PROTOCOL_HCRP_DATA 0x0014
#define UUID_PROTOCOL_HCRP_NOTIF 0x0016
#define UUID_PROTOCOL_AVCTP 0x0017
#define UUID_PROTOCOL_AVDTP 0x0019
#define UUID_PROTOCOL_CMTP 0x001B
#define UUID_PROTOCOL_UDI 0x001D
#define UUID_PROTOCOL_MCAP_CTRL 0x001E
#define UUID_PROTOCOL_MCAP_DATA 0x001F
#define UUID_PROTOCOL_L2CAP 0x0100
#define UUID_PROTOCOL_ATT 0x0007
/* Define common 16-bit service class UUIDs
*/
#define UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER 0X1000
#define UUID_SERVCLASS_BROWSE_GROUP_DESCRIPTOR 0X1001
#define UUID_SERVCLASS_PUBLIC_BROWSE_GROUP 0X1002
#define UUID_SERVCLASS_SERIAL_PORT 0X1101
#define UUID_SERVCLASS_LAN_ACCESS_USING_PPP 0X1102
#define UUID_SERVCLASS_DIALUP_NETWORKING 0X1103
#define UUID_SERVCLASS_IRMC_SYNC 0X1104
#define UUID_SERVCLASS_OBEX_OBJECT_PUSH 0X1105
#define UUID_SERVCLASS_OBEX_FILE_TRANSFER 0X1106
#define UUID_SERVCLASS_IRMC_SYNC_COMMAND 0X1107
#define UUID_SERVCLASS_HEADSET 0X1108
#define UUID_SERVCLASS_CORDLESS_TELEPHONY 0X1109
#define UUID_SERVCLASS_AUDIO_SOURCE 0X110A
#define UUID_SERVCLASS_AUDIO_SINK 0X110B
#define UUID_SERVCLASS_AV_REM_CTRL_TARGET 0X110C /* Audio/Video Control profile */
#define UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION 0X110D /* Advanced Audio Distribution profile */
#define UUID_SERVCLASS_AV_REMOTE_CONTROL 0X110E /* Audio/Video Control profile */
#define UUID_SERVCLASS_AV_REM_CTRL_CONTROL 0X110F /* Audio/Video Control profile */
#define UUID_SERVCLASS_INTERCOM 0X1110
#define UUID_SERVCLASS_FAX 0X1111
#define UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY 0X1112
#define UUID_SERVCLASS_WAP 0X1113
#define UUID_SERVCLASS_WAP_CLIENT 0X1114
#define UUID_SERVCLASS_PANU 0X1115 /* PAN profile */
#define UUID_SERVCLASS_NAP 0X1116 /* PAN profile */
#define UUID_SERVCLASS_GN 0X1117 /* PAN profile */
#define UUID_SERVCLASS_DIRECT_PRINTING 0X1118 /* BPP profile */
#define UUID_SERVCLASS_REFERENCE_PRINTING 0X1119 /* BPP profile */
#define UUID_SERVCLASS_IMAGING 0X111A /* Imaging profile */
#define UUID_SERVCLASS_IMAGING_RESPONDER 0X111B /* Imaging profile */
#define UUID_SERVCLASS_IMAGING_AUTO_ARCHIVE 0X111C /* Imaging profile */
#define UUID_SERVCLASS_IMAGING_REF_OBJECTS 0X111D /* Imaging profile */
#define UUID_SERVCLASS_HF_HANDSFREE 0X111E /* Handsfree profile */
#define UUID_SERVCLASS_AG_HANDSFREE 0X111F /* Handsfree profile */
#define UUID_SERVCLASS_DIR_PRT_REF_OBJ_SERVICE 0X1120 /* BPP profile */
#define UUID_SERVCLASS_REFLECTED_UI 0X1121 /* BPP profile */
#define UUID_SERVCLASS_BASIC_PRINTING 0X1122 /* BPP profile */
#define UUID_SERVCLASS_PRINTING_STATUS 0X1123 /* BPP profile */
#define UUID_SERVCLASS_HUMAN_INTERFACE 0X1124 /* HID profile */
#define UUID_SERVCLASS_CABLE_REPLACEMENT 0X1125 /* HCRP profile */
#define UUID_SERVCLASS_HCRP_PRINT 0X1126 /* HCRP profile */
#define UUID_SERVCLASS_HCRP_SCAN 0X1127 /* HCRP profile */
#define UUID_SERVCLASS_COMMON_ISDN_ACCESS 0X1128 /* CAPI Message Transport Protocol*/
#define UUID_SERVCLASS_VIDEO_CONFERENCING_GW 0X1129 /* Video Conferencing profile */
#define UUID_SERVCLASS_UDI_MT 0X112A /* Unrestricted Digital Information profile */
#define UUID_SERVCLASS_UDI_TA 0X112B /* Unrestricted Digital Information profile */
#define UUID_SERVCLASS_VCP 0X112C /* Video Conferencing profile */
#define UUID_SERVCLASS_SAP 0X112D /* SIM Access profile */
#define UUID_SERVCLASS_PBAP_PCE 0X112E /* Phonebook Access - PCE */
#define UUID_SERVCLASS_PBAP_PSE 0X112F /* Phonebook Access - PSE */
#define UUID_SERVCLASS_PHONE_ACCESS 0x1130
#define UUID_SERVCLASS_HEADSET_HS 0x1131 /* Headset - HS, from HSP v1.2 */
#define UUID_SERVCLASS_MAP_PROFILE 0X1134 /* MAP profile UUID */
#define UUID_SERVCLASS_MESSAGE_ACCESS 0X1132 /* Message Access Service UUID */
#define UUID_SERVCLASS_MESSAGE_NOTIFICATION 0X1133 /* Message Notification Service UUID */
#define UUID_SERVCLASS_3DD 0x1137 /* 3D Sync (Display role) */
#define UUID_SERVCLASS_3DG 0x1138 /* 3D Sync (Glasses role) */
#define UUID_SERVCLASS_3DS 0x1139 /* 3D Sync Profile */
#define UUID_PROFILE_MULTIPROFILE 0X113A /* Multiprofile Profile UUID */
#define UUID_SERVCLASS_MULTIPROFILE 0X113B /* Multiprofile Service UUID */
#define UUID_SERVCLASS_CAS 0x113C /* CTN Access Service */
#define UUID_SERVCLASS_CNS 0x113D /* CTN Notification Service */
#define UUID_SERVCLASS_CTN 0x113E /* Calendar Tasks and Notes Profile (CTN) */
#define UUID_SERVCLASS_PNP_INFORMATION 0X1200 /* Device Identification */
#define UUID_SERVCLASS_GENERIC_NETWORKING 0X1201
#define UUID_SERVCLASS_GENERIC_FILETRANSFER 0X1202
#define UUID_SERVCLASS_GENERIC_AUDIO 0X1203
#define UUID_SERVCLASS_GENERIC_TELEPHONY 0X1204
#define UUID_SERVCLASS_UPNP_SERVICE 0X1205 /* UPNP_Service [ESDP] */
#define UUID_SERVCLASS_UPNP_IP_SERVICE 0X1206 /* UPNP_IP_Service [ESDP] */
#define UUID_SERVCLASS_ESDP_UPNP_IP_PAN 0X1300 /* UPNP_IP_PAN [ESDP] */
#define UUID_SERVCLASS_ESDP_UPNP_IP_LAP 0X1301 /* UPNP_IP_LAP [ESDP] */
#define UUID_SERVCLASS_ESDP_UPNP_IP_L2CAP 0X1302 /* UPNP_L2CAP [ESDP] */
#define UUID_SERVCLASS_VIDEO_SOURCE 0X1303 /* Video Distribution Profile (VDP) */
#define UUID_SERVCLASS_VIDEO_SINK 0X1304 /* Video Distribution Profile (VDP) */
#define UUID_SERVCLASS_VIDEO_DISTRIBUTION 0X1305 /* Video Distribution Profile (VDP) */
#define UUID_SERVCLASS_HDP_PROFILE 0X1400 /* Health Device profile (HDP) */
#define UUID_SERVCLASS_HDP_SOURCE 0X1401 /* Health Device profile (HDP) */
#define UUID_SERVCLASS_HDP_SINK 0X1402 /* Health Device profile (HDP) */
#define UUID_SERVCLASS_GAP_SERVER 0x1800
#define UUID_SERVCLASS_GATT_SERVER 0x1801
#define UUID_SERVCLASS_IMMEDIATE_ALERT 0x1802 /* immediate alert */
#define UUID_SERVCLASS_LINKLOSS 0x1803 /* Link Loss Alert */
#define UUID_SERVCLASS_TX_POWER 0x1804 /* TX power */
#define UUID_SERVCLASS_CURRENT_TIME 0x1805 /* Link Loss Alert */
#define UUID_SERVCLASS_DST_CHG 0x1806 /* DST Time change */
#define UUID_SERVCLASS_REF_TIME_UPD 0x1807 /* reference time update */
#define UUID_SERVCLASS_THERMOMETER 0x1809 /* Thermometer UUID */
#define UUID_SERVCLASS_DEVICE_INFO 0x180A /* device info service */
#define UUID_SERVCLASS_NWA 0x180B /* Network availability */
#define UUID_SERVCLASS_HEART_RATE 0x180D /* Heart Rate service */
#define UUID_SERVCLASS_PHALERT 0x180E /* phone alert service */
#define UUID_SERVCLASS_BATTERY 0x180F /* battery service */
#define UUID_SERVCLASS_BPM 0x1810 /* blood pressure service */
#define UUID_SERVCLASS_ALERT_NOTIFICATION 0x1811 /* alert notification service */
#define UUID_SERVCLASS_LE_HID 0x1812 /* HID over LE */
#define UUID_SERVCLASS_SCAN_PARAM 0x1813 /* Scan Parameter service */
#define UUID_SERVCLASS_GLUCOSE 0x1808 /* Glucose Meter Service */
#define UUID_SERVCLASS_RSC 0x1814 /* Runners Speed and Cadence Service */
#define UUID_SERVCLASS_CSC 0x1816 /* Cycling Speed and Cadence Service */
#define UUID_SERVCLASS_CP 0x1818 /* Cycling Power Service (pre-Adoption IOP) */
#define UUID_SERVCLASS_LN 0x1819 /* Location and Navigation Service (pre-Adoption IOP) */
#define UUID_SERVCLASS_HPS 0x7F10 /* HTTP Proxy Service */
#define UUID_SERVCLASS_TEST_SERVER 0x9000 /* Test Group UUID */
#if (BTM_WBS_INCLUDED == TRUE )
#define UUID_CODEC_CVSD 0x0001 /* CVSD */
#define UUID_CODEC_MSBC 0x0002 /* mSBC */
#endif
#define UUID_HF_IND_EDS 0x0001 /* HF indicator for enhanced driver safety */
/* Define all the 'Descriptor Type' values.
*/
#define NULL_DESC_TYPE 0
#define UINT_DESC_TYPE 1
#define TWO_COMP_INT_DESC_TYPE 2
#define UUID_DESC_TYPE 3
#define TEXT_STR_DESC_TYPE 4
#define BOOLEAN_DESC_TYPE 5
#define DATA_ELE_SEQ_DESC_TYPE 6
#define DATA_ELE_ALT_DESC_TYPE 7
#define URL_DESC_TYPE 8
/* Define all the "Descriptor Size" values.
*/
#define SIZE_ONE_BYTE 0
#define SIZE_TWO_BYTES 1
#define SIZE_FOUR_BYTES 2
#define SIZE_EIGHT_BYTES 3
#define SIZE_SIXTEEN_BYTES 4
#define SIZE_IN_NEXT_BYTE 5
#define SIZE_IN_NEXT_WORD 6
#define SIZE_IN_NEXT_LONG 7
/* Language Encoding Constants */
#define LANG_ID_CODE_ENGLISH ((UINT16) 0x656e) /* "en" */
#define LANG_ID_CHAR_ENCODE_UTF8 ((UINT16) 0x006a) /* UTF-8 */
/* Constants used for display purposes only. These define ovelapping attribute values */
#define ATTR_ID_VERS_OR_GRP_OR_DRELNUM_OR_IPSUB_OR_SPECID_OR_MPSD 0x0200
#define ATTR_ID_VEND_ID_OR_SERVICE_DB_STATE_OR_PARSE_VER_OR_MPMD 0x0201
#define ATTR_ID_PROD_ID_OR_HID_DEV_SUBCLASS_OR_MPSPP 0x0202
#define ATTR_ID_PROD_VER_OR_HID_COUNTRY_CODE 0x0203
#define ATTR_ID_PRIMARY_REC_OR_HID_VIRTUAL_CABLE 0x0204
#define ATTR_ID_DI_VENDOR_ID_SOURCE_OR_HID_INIT_RECONNECT 0x0205
#define ATTR_ID_SERV_VERS_OR_1284ID 0x0300
#define ATTR_ID_DATA_STORES_OR_NETWORK 0x0301
#define ATTR_ID_FAX_1_OR_AUD_VOL_OR_DEV_NAME 0x0302
#define ATTR_ID_FORMATS_OR_FAX_2_0 0x0303
#define ATTR_ID_FAX_CLASS_2_OR_FRIENDLY_NAME 0x0304
#define ATTR_ID_NETADDRESS_OR_DEVLOCATION 0x0306
#endif

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