mirror of
https://github.com/DrHo1y/orangepi-build.git
synced 2026-11-05 23:37:21 +07:00
First Commit
This commit is contained in:
20
external/cache/sources/brcm_patchram_plus/Makefile
vendored
Executable file
20
external/cache/sources/brcm_patchram_plus/Makefile
vendored
Executable file
@@ -0,0 +1,20 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# Makefile for building tapp
|
||||
#
|
||||
#
|
||||
|
||||
CFLAGS = -Wall -O2
|
||||
CC = gcc
|
||||
INSTALL = install
|
||||
|
||||
TARGET = brcm_patchram_plus
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): brcm_patchram_plus.c
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
clean distclean:
|
||||
rm -rf *.o $(TARGET)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
.PHONY: $(PHONY) install clean distclean
|
||||
890
external/cache/sources/brcm_patchram_plus/brcm_patchram_plus.c
vendored
Executable file
890
external/cache/sources/brcm_patchram_plus/brcm_patchram_plus.c
vendored
Executable file
@@ -0,0 +1,890 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2011 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
**
|
||||
** Name: brcm_patchram_plus.c
|
||||
**
|
||||
** Description: This program downloads a patchram files in the HCD format
|
||||
** to Broadcom Bluetooth based silicon and combo chips and
|
||||
** and other utility functions.
|
||||
**
|
||||
** It can be invoked from the command line in the form
|
||||
** <-d> to print a debug log
|
||||
** <--patchram patchram_file>
|
||||
** <--baudrate baud_rate>
|
||||
** <--bd_addr bd_address>
|
||||
** <--enable_lpm>
|
||||
** <--enable_hci>
|
||||
** <--use_baudrate_for_download>
|
||||
** <--scopcm=sco_routing,pcm_interface_rate,frame_type,
|
||||
** sync_mode,clock_mode,lsb_first,fill_bits,
|
||||
** fill_method,fill_num,right_justify>
|
||||
**
|
||||
** Where
|
||||
**
|
||||
** sco_routing is 0 for PCM, 1 for Transport,
|
||||
** 2 for Codec and 3 for I2S,
|
||||
**
|
||||
** pcm_interface_rate is 0 for 128KBps, 1 for
|
||||
** 256 KBps, 2 for 512KBps, 3 for 1024KBps,
|
||||
** and 4 for 2048Kbps,
|
||||
**
|
||||
** frame_type is 0 for short and 1 for long,
|
||||
**
|
||||
** sync_mode is 0 for slave and 1 for master,
|
||||
**
|
||||
** clock_mode is 0 for slabe and 1 for master,
|
||||
**
|
||||
** lsb_first is 0 for false aand 1 for true,
|
||||
**
|
||||
** fill_bits is the value in decimal for unused bits,
|
||||
**
|
||||
** fill_method is 0 for 0's and 1 for 1's, 2 for
|
||||
** signed and 3 for programmable,
|
||||
**
|
||||
** fill_num is the number or bits to fill,
|
||||
**
|
||||
** right_justify is 0 for false and 1 for true
|
||||
**
|
||||
** <--i2s=i2s_enable,is_master,sample_rate,clock_rate>
|
||||
**
|
||||
** Where
|
||||
**
|
||||
** i2s_enable is 0 for disable and 1 for enable,
|
||||
**
|
||||
** is_master is 0 for slave and 1 for master,
|
||||
**
|
||||
** sample_rate is 0 for 8KHz, 1 for 16Khz and
|
||||
** 2 for 4 KHz,
|
||||
**
|
||||
** clock_rate is 0 for 128KHz, 1 for 256KHz, 3 for
|
||||
** 1024 KHz and 4 for 2048 KHz.
|
||||
**
|
||||
** <--no2bytes skips waiting for two byte confirmation
|
||||
** before starting patchram download. Newer chips
|
||||
** do not generate these two bytes.>
|
||||
** <--tosleep=number of microsseconds to sleep before
|
||||
** patchram download begins.>
|
||||
** uart_device_name
|
||||
**
|
||||
** For example:
|
||||
**
|
||||
** brcm_patchram_plus -d --patchram \
|
||||
** BCM2045B2_002.002.011.0348.0349.hcd /dev/ttyHS0
|
||||
**
|
||||
** It will return 0 for success and a number greater than 0
|
||||
** for any errors.
|
||||
**
|
||||
** For Android, this program invoked using a
|
||||
** "system(2)" call from the beginning of the bt_enable
|
||||
** function inside the file
|
||||
** system/bluetooth/bluedroid/bluetooth.c.
|
||||
**
|
||||
** If the Android system property "ro.bt.bcm_bdaddr_path" is
|
||||
** set, then the bd_addr will be read from this path.
|
||||
** This is overridden by --bd_addr on the command line.
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
// TODO: Integrate BCM support into Bluez hciattach
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <termios.h>
|
||||
#else
|
||||
#include <sys/termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <cutils/properties.h>
|
||||
#define LOG_TAG "brcm_patchram_plus"
|
||||
#include <cutils/log.h>
|
||||
#undef printf
|
||||
#define printf ALOGD
|
||||
#undef fprintf
|
||||
#define fprintf(x, ...) \
|
||||
{ if(x==stderr) ALOGE(__VA_ARGS__); else fprintf(x, __VA_ARGS__); }
|
||||
|
||||
#endif //ANDROID
|
||||
|
||||
#ifndef N_HCI
|
||||
#define N_HCI 15
|
||||
#endif
|
||||
|
||||
#define HCIUARTSETPROTO _IOW('U', 200, int)
|
||||
#define HCIUARTGETPROTO _IOR('U', 201, int)
|
||||
#define HCIUARTGETDEVICE _IOR('U', 202, int)
|
||||
|
||||
#define HCI_UART_H4 0
|
||||
#define HCI_UART_BCSP 1
|
||||
#define HCI_UART_3WIRE 2
|
||||
#define HCI_UART_H4DS 3
|
||||
#define HCI_UART_LL 4
|
||||
|
||||
typedef unsigned char uchar;
|
||||
|
||||
int uart_fd = -1;
|
||||
int hcdfile_fd = -1;
|
||||
int termios_baudrate = 0;
|
||||
int bdaddr_flag = 0;
|
||||
int enable_lpm = 0;
|
||||
int enable_hci = 0;
|
||||
int use_baudrate_for_download = 0;
|
||||
int debug = 0;
|
||||
int scopcm = 0;
|
||||
int i2s = 0;
|
||||
int no2bytes = 0;
|
||||
int tosleep = 0;
|
||||
|
||||
struct termios termios;
|
||||
uchar buffer[1024];
|
||||
|
||||
uchar hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 };
|
||||
|
||||
uchar hci_download_minidriver[] = { 0x01, 0x2e, 0xfc, 0x00 };
|
||||
|
||||
uchar hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
uchar hci_write_bd_addr[] = { 0x01, 0x01, 0xfc, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
uchar hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc, 0x0c,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00 };
|
||||
|
||||
uchar hci_write_sco_pcm_int[] =
|
||||
{ 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
uchar hci_write_pcm_data_format[] =
|
||||
{ 0x01, 0x1e, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
uchar hci_write_i2spcm_interface_param[] =
|
||||
{ 0x01, 0x6d, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
#ifdef SAMSUNG_BLUETOOTH
|
||||
char* get_samsung_bluetooth_type()
|
||||
{
|
||||
char buf[10];
|
||||
int fd = open("/data/.cid.info", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "couldn't open file /data/.cid.info for reading\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (read(fd, buf, sizeof(buf)) < 0) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
if (strncmp(buf, "murata", 6) == 0)
|
||||
return "_murata";
|
||||
|
||||
if (strncmp(buf, "semcove", 7) == 0)
|
||||
return "_semcove";
|
||||
|
||||
if (strncmp(buf, "semcosh", 7) == 0)
|
||||
return "_semcosh";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
parse_patchram(char *optarg)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!(p = strrchr(optarg, '.'))) {
|
||||
fprintf(stderr, "file %s not an HCD file\n", optarg);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
p++;
|
||||
|
||||
if (strcasecmp("hcd", p) != 0) {
|
||||
fprintf(stderr, "file %s not an HCD file\n", optarg);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
#ifdef SAMSUNG_BLUETOOTH
|
||||
char optarg2[256];
|
||||
char* type = get_samsung_bluetooth_type();
|
||||
char* fext = ".hcd";
|
||||
|
||||
if (type != NULL) {
|
||||
memset(optarg2, 0, 256);
|
||||
strncpy(optarg2, optarg, strlen(optarg) - 4);
|
||||
strcpy(optarg2 + strlen(optarg2), type);
|
||||
strcpy(optarg2 + strlen(optarg2), fext);
|
||||
optarg = optarg2;
|
||||
fprintf(stderr, "using %s as hcdfile\n", optarg);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((hcdfile_fd = open(optarg, O_RDONLY)) == -1) {
|
||||
fprintf(stderr, "file %s could not be opened, error %d\n", optarg, errno);
|
||||
exit(5);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
BRCM_encode_baud_rate(uint baud_rate, uchar *encoded_baud)
|
||||
{
|
||||
if(baud_rate == 0 || encoded_baud == NULL) {
|
||||
fprintf(stderr, "Baudrate not supported!");
|
||||
return;
|
||||
}
|
||||
|
||||
encoded_baud[3] = (uchar)(baud_rate >> 24);
|
||||
encoded_baud[2] = (uchar)(baud_rate >> 16);
|
||||
encoded_baud[1] = (uchar)(baud_rate >> 8);
|
||||
encoded_baud[0] = (uchar)(baud_rate & 0xFF);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int baud_rate;
|
||||
int termios_value;
|
||||
} tBaudRates;
|
||||
|
||||
tBaudRates baud_rates[] = {
|
||||
{ 115200, B115200 },
|
||||
{ 230400, B230400 },
|
||||
{ 460800, B460800 },
|
||||
{ 500000, B500000 },
|
||||
{ 576000, B576000 },
|
||||
{ 921600, B921600 },
|
||||
{ 1000000, B1000000 },
|
||||
{ 1152000, B1152000 },
|
||||
{ 1500000, B1500000 },
|
||||
{ 2000000, B2000000 },
|
||||
{ 2500000, B2500000 },
|
||||
{ 3000000, B3000000 },
|
||||
#ifndef __CYGWIN__
|
||||
{ 3500000, B3500000 },
|
||||
{ 4000000, B4000000 }
|
||||
#endif
|
||||
};
|
||||
|
||||
int
|
||||
validate_baudrate(int baud_rate, int *value)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < (sizeof(baud_rates) / sizeof(tBaudRates)); i++) {
|
||||
if (baud_rates[i].baud_rate == baud_rate) {
|
||||
*value = baud_rates[i].termios_value;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_baudrate(char *optarg)
|
||||
{
|
||||
int baudrate = atoi(optarg);
|
||||
|
||||
if (validate_baudrate(baudrate, &termios_baudrate)) {
|
||||
BRCM_encode_baud_rate(baudrate, &hci_update_baud_rate[6]);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_bdaddr(char *optarg)
|
||||
{
|
||||
int bd_addr[6];
|
||||
int i;
|
||||
|
||||
sscanf(optarg, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
&bd_addr[5], &bd_addr[4], &bd_addr[3],
|
||||
&bd_addr[2], &bd_addr[1], &bd_addr[0]);
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
hci_write_bd_addr[4 + i] = bd_addr[i];
|
||||
}
|
||||
|
||||
bdaddr_flag = 1;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_enable_lpm(char *optarg)
|
||||
{
|
||||
enable_lpm = 1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_use_baudrate_for_download(char *optarg)
|
||||
{
|
||||
use_baudrate_for_download = 1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_enable_hci(char *optarg)
|
||||
{
|
||||
enable_hci = 1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_scopcm(char *optarg)
|
||||
{
|
||||
int param[10];
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = sscanf(optarg, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
|
||||
¶m[0], ¶m[1], ¶m[2], ¶m[3], ¶m[4],
|
||||
¶m[5], ¶m[6], ¶m[7], ¶m[8], ¶m[9]);
|
||||
|
||||
if (ret != 10) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
scopcm = 1;
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
hci_write_sco_pcm_int[4 + i] = param[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
hci_write_pcm_data_format[4 + i] = param[5 + i];
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_i2s(char *optarg)
|
||||
{
|
||||
int param[4];
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = sscanf(optarg, "%d,%d,%d,%d", ¶m[0], ¶m[1], ¶m[2],
|
||||
¶m[3]);
|
||||
|
||||
if (ret != 4) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
i2s = 1;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
hci_write_i2spcm_interface_param[4 + i] = param[i];
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_no2bytes(char *optarg)
|
||||
{
|
||||
no2bytes = 1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
parse_tosleep(char *optarg)
|
||||
{
|
||||
tosleep = atoi(optarg);
|
||||
|
||||
if (tosleep <= 0) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
usage(char *argv0)
|
||||
{
|
||||
printf("Usage %s:\n", argv0);
|
||||
printf("\t<-d> to print a debug log\n");
|
||||
printf("\t<--patchram patchram_file>\n");
|
||||
printf("\t<--baudrate baud_rate>\n");
|
||||
printf("\t<--bd_addr bd_address>\n");
|
||||
printf("\t<--enable_lpm>\n");
|
||||
printf("\t<--enable_hci>\n");
|
||||
printf("\t<--use_baudrate_for_download> - Uses the\n");
|
||||
printf("\t\tbaudrate for downloading the firmware\n");
|
||||
printf("\t<--scopcm=sco_routing,pcm_interface_rate,frame_type,\n");
|
||||
printf("\t\tsync_mode,clock_mode,lsb_first,fill_bits,\n");
|
||||
printf("\t\tfill_method,fill_num,right_justify>\n");
|
||||
printf("\n\t\tWhere\n");
|
||||
printf("\n\t\tsco_routing is 0 for PCM, 1 for Transport,\n");
|
||||
printf("\t\t2 for Codec and 3 for I2S,\n");
|
||||
printf("\n\t\tpcm_interface_rate is 0 for 128KBps, 1 for\n");
|
||||
printf("\t\t256 KBps, 2 for 512KBps, 3 for 1024KBps,\n");
|
||||
printf("\t\tand 4 for 2048Kbps,\n");
|
||||
printf("\n\t\tframe_type is 0 for short and 1 for long,\n");
|
||||
printf("\t\tsync_mode is 0 for slave and 1 for master,\n");
|
||||
printf("\n\t\tclock_mode is 0 for slabe and 1 for master,\n");
|
||||
printf("\n\t\tlsb_first is 0 for false aand 1 for true,\n");
|
||||
printf("\n\t\tfill_bits is the value in decimal for unused bits,\n");
|
||||
printf("\n\t\tfill_method is 0 for 0's and 1 for 1's, 2 for\n");
|
||||
printf("\t\tsigned and 3 for programmable,\n");
|
||||
printf("\n\t\tfill_num is the number or bits to fill,\n");
|
||||
printf("\n\t\tright_justify is 0 for false and 1 for true\n");
|
||||
printf("\n\t<--i2s=i2s_enable,is_master,sample_rate,clock_rate>\n");
|
||||
printf("\n\t\tWhere\n");
|
||||
printf("\n\t\ti2s_enable is 0 for disable and 1 for enable,\n");
|
||||
printf("\n\t\tis_master is 0 for slave and 1 for master,\n");
|
||||
printf("\n\t\tsample_rate is 0 for 8KHz, 1 for 16Khz and\n");
|
||||
printf("\t\t2 for 4 KHz,\n");
|
||||
printf("\n\t\tclock_rate is 0 for 128KHz, 1 for 256KHz, 3 for\n");
|
||||
printf("\t\t1024 KHz and 4 for 2048 KHz.\n\n");
|
||||
printf("\t<--no2bytes skips waiting for two byte confirmation\n");
|
||||
printf("\t\tbefore starting patchram download. Newer chips\n");
|
||||
printf("\t\tdo not generate these two bytes.>\n");
|
||||
printf("\t<--tosleep=microseconds>\n");
|
||||
printf("\tuart_device_name\n");
|
||||
}
|
||||
|
||||
int
|
||||
parse_cmd_line(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int ret = 0;
|
||||
|
||||
typedef int (*PFI)();
|
||||
|
||||
PFI parse[] = { parse_patchram, parse_baudrate,
|
||||
parse_bdaddr, parse_enable_lpm, parse_enable_hci,
|
||||
parse_use_baudrate_for_download,
|
||||
parse_scopcm, parse_i2s, parse_no2bytes, parse_tosleep};
|
||||
|
||||
while (1) {
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"patchram", 1, 0, 0},
|
||||
{"baudrate", 1, 0, 0},
|
||||
{"bd_addr", 1, 0, 0},
|
||||
{"enable_lpm", 0, 0, 0},
|
||||
{"enable_hci", 0, 0, 0},
|
||||
{"use_baudrate_for_download", 0, 0, 0},
|
||||
{"scopcm", 1, 0, 0},
|
||||
{"i2s", 1, 0, 0},
|
||||
{"no2bytes", 0, 0, 0},
|
||||
{"tosleep", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long_only (argc, argv, "d", long_options,
|
||||
&option_index);
|
||||
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 0:
|
||||
if (debug) {
|
||||
printf ("option %s",
|
||||
long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
ret = (*parse[option_index])(optarg);
|
||||
|
||||
break;
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
//nobreak
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
if (debug)
|
||||
printf ("%s \n", argv[optind]);
|
||||
if ((uart_fd = open(argv[optind], O_RDWR | O_NOCTTY)) == -1) {
|
||||
fprintf(stderr, "port %s could not be opened, error %d\n",
|
||||
argv[optind], errno);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
init_uart()
|
||||
{
|
||||
#ifdef BCM_INIT_DELAY
|
||||
usleep(150*1000);
|
||||
#endif
|
||||
tcflush(uart_fd, TCIOFLUSH);
|
||||
tcgetattr(uart_fd, &termios);
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
cfmakeraw(&termios);
|
||||
#else
|
||||
termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
|
||||
| INLCR | IGNCR | ICRNL | IXON);
|
||||
termios.c_oflag &= ~OPOST;
|
||||
termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||
termios.c_cflag &= ~(CSIZE | PARENB);
|
||||
termios.c_cflag |= CS8;
|
||||
#endif
|
||||
|
||||
termios.c_cflag |= CRTSCTS;
|
||||
tcsetattr(uart_fd, TCSANOW, &termios);
|
||||
tcflush(uart_fd, TCIOFLUSH);
|
||||
tcsetattr(uart_fd, TCSANOW, &termios);
|
||||
tcflush(uart_fd, TCIOFLUSH);
|
||||
tcflush(uart_fd, TCIOFLUSH);
|
||||
cfsetospeed(&termios, B115200);
|
||||
cfsetispeed(&termios, B115200);
|
||||
tcsetattr(uart_fd, TCSANOW, &termios);
|
||||
}
|
||||
|
||||
void
|
||||
dump(uchar *out, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i && !(i % 16)) {
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "%02x ", out[i]);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
read_event(int fd, uchar *buffer)
|
||||
{
|
||||
int i = 0;
|
||||
int len = 3;
|
||||
int count;
|
||||
|
||||
while ((count = read(fd, &buffer[i], len)) < len) {
|
||||
i += count;
|
||||
len -= count;
|
||||
}
|
||||
|
||||
i += count;
|
||||
len = buffer[2];
|
||||
|
||||
while ((count = read(fd, &buffer[i], len)) < len) {
|
||||
i += count;
|
||||
len -= count;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
count += i;
|
||||
|
||||
fprintf(stderr, "received %d\n", count);
|
||||
dump(buffer, count);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hci_send_cmd(uchar *buf, int len)
|
||||
{
|
||||
if (debug) {
|
||||
fprintf(stderr, "writing\n");
|
||||
dump(buf, len);
|
||||
}
|
||||
|
||||
write(uart_fd, buf, len);
|
||||
}
|
||||
|
||||
void
|
||||
expired(int sig)
|
||||
{
|
||||
hci_send_cmd(hci_reset, sizeof(hci_reset));
|
||||
alarm(4);
|
||||
}
|
||||
|
||||
void
|
||||
proc_reset()
|
||||
{
|
||||
signal(SIGALRM, expired);
|
||||
|
||||
|
||||
hci_send_cmd(hci_reset, sizeof(hci_reset));
|
||||
|
||||
alarm(4);
|
||||
|
||||
read_event(uart_fd, buffer);
|
||||
|
||||
alarm(0);
|
||||
}
|
||||
|
||||
void
|
||||
proc_patchram()
|
||||
{
|
||||
int len;
|
||||
|
||||
hci_send_cmd(hci_download_minidriver, sizeof(hci_download_minidriver));
|
||||
|
||||
read_event(uart_fd, buffer);
|
||||
|
||||
if (!no2bytes) {
|
||||
read(uart_fd, &buffer[0], 2);
|
||||
}
|
||||
|
||||
if (tosleep) {
|
||||
usleep(tosleep);
|
||||
}
|
||||
|
||||
while (read(hcdfile_fd, &buffer[1], 3)) {
|
||||
buffer[0] = 0x01;
|
||||
|
||||
len = buffer[3];
|
||||
|
||||
read(hcdfile_fd, &buffer[4], len);
|
||||
|
||||
hci_send_cmd(buffer, len + 4);
|
||||
|
||||
read_event(uart_fd, buffer);
|
||||
}
|
||||
|
||||
if (use_baudrate_for_download) {
|
||||
cfsetospeed(&termios, B115200);
|
||||
cfsetispeed(&termios, B115200);
|
||||
tcsetattr(uart_fd, TCSANOW, &termios);
|
||||
}
|
||||
proc_reset();
|
||||
}
|
||||
|
||||
void
|
||||
proc_baudrate()
|
||||
{
|
||||
hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate));
|
||||
|
||||
read_event(uart_fd, buffer);
|
||||
|
||||
cfsetospeed(&termios, termios_baudrate);
|
||||
cfsetispeed(&termios, termios_baudrate);
|
||||
tcsetattr(uart_fd, TCSANOW, &termios);
|
||||
|
||||
if (debug) {
|
||||
fprintf(stderr, "Done setting baudrate\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
proc_bdaddr()
|
||||
{
|
||||
hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr));
|
||||
|
||||
read_event(uart_fd, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
proc_enable_lpm()
|
||||
{
|
||||
hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode));
|
||||
|
||||
read_event(uart_fd, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
proc_scopcm()
|
||||
{
|
||||
hci_send_cmd(hci_write_sco_pcm_int,
|
||||
sizeof(hci_write_sco_pcm_int));
|
||||
|
||||
read_event(uart_fd, buffer);
|
||||
|
||||
hci_send_cmd(hci_write_pcm_data_format,
|
||||
sizeof(hci_write_pcm_data_format));
|
||||
|
||||
read_event(uart_fd, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
proc_i2s()
|
||||
{
|
||||
hci_send_cmd(hci_write_i2spcm_interface_param,
|
||||
sizeof(hci_write_i2spcm_interface_param));
|
||||
|
||||
read_event(uart_fd, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
proc_enable_hci()
|
||||
{
|
||||
int i = N_HCI;
|
||||
int proto = HCI_UART_H4;
|
||||
if (ioctl(uart_fd, TIOCSETD, &i) < 0) {
|
||||
fprintf(stderr, "Can't set line discipline\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ioctl(uart_fd, HCIUARTSETPROTO, proto) < 0) {
|
||||
fprintf(stderr, "Can't set hci protocol\n");
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "Done setting line discpline\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
void
|
||||
read_default_bdaddr()
|
||||
{
|
||||
int sz;
|
||||
int fd;
|
||||
|
||||
char path[PROPERTY_VALUE_MAX];
|
||||
|
||||
char bdaddr[18];
|
||||
int len = 17;
|
||||
memset(bdaddr, 0, (len + 1) * sizeof(char));
|
||||
|
||||
property_get("ro.bt.bdaddr_path", path, "");
|
||||
if (path[0] == 0)
|
||||
return;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "open(%s) failed: %s (%d)", path, strerror(errno),
|
||||
errno);
|
||||
return;
|
||||
}
|
||||
|
||||
sz = read(fd, bdaddr, len);
|
||||
if (sz < 0) {
|
||||
fprintf(stderr, "read(%s) failed: %s (%d)", path, strerror(errno),
|
||||
errno);
|
||||
close(fd);
|
||||
return;
|
||||
} else if (sz != len) {
|
||||
fprintf(stderr, "read(%s) unexpected size %d", path, sz);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
printf("Read default bdaddr of %s\n", bdaddr);
|
||||
}
|
||||
|
||||
parse_bdaddr(bdaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
read_default_bdaddr();
|
||||
#endif
|
||||
|
||||
if (parse_cmd_line(argc, argv)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (uart_fd < 0) {
|
||||
exit(2);
|
||||
}
|
||||
|
||||
init_uart();
|
||||
|
||||
proc_reset();
|
||||
|
||||
if (use_baudrate_for_download) {
|
||||
if (termios_baudrate) {
|
||||
proc_baudrate();
|
||||
}
|
||||
}
|
||||
|
||||
if (hcdfile_fd > 0) {
|
||||
proc_patchram();
|
||||
}
|
||||
|
||||
if (termios_baudrate) {
|
||||
proc_baudrate();
|
||||
}
|
||||
|
||||
if (bdaddr_flag) {
|
||||
proc_bdaddr();
|
||||
}
|
||||
|
||||
if (enable_lpm) {
|
||||
proc_enable_lpm();
|
||||
}
|
||||
|
||||
if (scopcm) {
|
||||
proc_scopcm();
|
||||
}
|
||||
|
||||
if (i2s) {
|
||||
proc_i2s();
|
||||
}
|
||||
|
||||
if (enable_hci) {
|
||||
proc_enable_hci();
|
||||
|
||||
while (1) {
|
||||
sleep(UINT_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
95
external/cache/sources/hcitools/Makefile
vendored
Normal file
95
external/cache/sources/hcitools/Makefile
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
#CFLAGS := $(CFLAGS) -g
|
||||
CFLAGS = -I. -Ilib -Wall -DVERSION=\"5.10\" -Wno-strict-aliasing
|
||||
CFLAGS += -Ilib/bluetooth
|
||||
|
||||
# include rule.mk
|
||||
include ./rule.mk
|
||||
|
||||
# define objects collection variable
|
||||
lib = \
|
||||
lib/bluetooth.o \
|
||||
lib/hci.o \
|
||||
lib/sdp.o
|
||||
|
||||
hciattach_objs = \
|
||||
hciattach.o \
|
||||
hciattach_ath3k.o \
|
||||
hciattach_bcm43xx.o \
|
||||
hciattach_intel.o \
|
||||
hciattach_qualcomm.o \
|
||||
hciattach_st.o \
|
||||
hciattach_ti.o \
|
||||
hciattach_tialt.o \
|
||||
hciattach_rtk.o \
|
||||
hciattach_xr.o \
|
||||
hciattach_sprd.o
|
||||
|
||||
hciconfig_objs = \
|
||||
hciconfig.o \
|
||||
csr.o
|
||||
|
||||
hcitool_objs = \
|
||||
hcitool.o
|
||||
|
||||
btmon_objs = \
|
||||
monitor/main.o \
|
||||
monitor/mainloop.o \
|
||||
monitor/display.o \
|
||||
monitor/hcidump.o \
|
||||
monitor/btsnoop.o \
|
||||
monitor/control.o \
|
||||
monitor/packet.o \
|
||||
monitor/vendor.o \
|
||||
monitor/lmp.o \
|
||||
monitor/l2cap.o \
|
||||
monitor/uuid.o \
|
||||
monitor/sdp.o \
|
||||
monitor/crc.o \
|
||||
monitor/ll.o
|
||||
|
||||
# add your target(s) to all
|
||||
.PHONY: all
|
||||
all: hciattach_opi hciconfig hcitool btmon
|
||||
|
||||
# directory
|
||||
hciattach_opi: $(hciattach_objs) $(lib)
|
||||
$(LINK_MSG)
|
||||
$(LINKX)
|
||||
|
||||
hciconfig: $(hciconfig_objs) $(lib)
|
||||
$(LINK_MSG)
|
||||
$(LINKX)
|
||||
|
||||
hcitool: $(hcitool_objs) $(lib)
|
||||
$(LINK_MSG)
|
||||
$(LINKX)
|
||||
|
||||
btmon: $(btmon_objs) $(lib)
|
||||
$(LINK_MSG)
|
||||
$(LINKX)
|
||||
|
||||
# change objs to your objects collection variable
|
||||
$(hciattach_objs): %.o: %.c
|
||||
$(COMPILE_MSG)
|
||||
$(COMPILEX)
|
||||
|
||||
$(hciconfig_objs): %.o: %.c
|
||||
$(COMPILE_MSG)
|
||||
$(COMPILEX)
|
||||
|
||||
$(hcitool_objs): %.o: %.c
|
||||
$(COMPILE_MSG)
|
||||
$(COMPILEX)
|
||||
|
||||
$(btmon_objs): %.o: %.c
|
||||
$(COMPILE_MSG)
|
||||
$(COMPILEX)
|
||||
|
||||
# clean temp files
|
||||
clean:
|
||||
-rm -rf $(hciattach_objs) $(hciattach_objs:.o=.d)
|
||||
-rm -rf $(hciconfig_objs) $(hciconfig_objs:.o=.d)
|
||||
-rm -rf $(hcitool_objs) $(hcitool_objs:.o=.d)
|
||||
-rm -rf $(lib) $(lib:.o=.d)
|
||||
-rm -rf $(btmon_objs) $(btmon_objs:.o=.d)
|
||||
#-rm -rf output
|
||||
343
external/cache/sources/hcitools/NOTICE
vendored
Normal file
343
external/cache/sources/hcitools/NOTICE
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
All of these programs are made available under version 2 of the GNU General
|
||||
Public Licence.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
2853
external/cache/sources/hcitools/csr.c
vendored
Normal file
2853
external/cache/sources/hcitools/csr.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
553
external/cache/sources/hcitools/csr.h
vendored
Normal file
553
external/cache/sources/hcitools/csr.h
vendored
Normal file
@@ -0,0 +1,553 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2003-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <termios.h>
|
||||
|
||||
#define CSR_VARID_PS_CLR_ALL 0x000b /* valueless */
|
||||
#define CSR_VARID_PS_FACTORY_SET 0x000c /* valueless */
|
||||
#define CSR_VARID_PS_CLR_ALL_STORES 0x082d /* uint16 */
|
||||
#define CSR_VARID_BC01_STATUS 0x2801 /* uint16 */
|
||||
#define CSR_VARID_BUILDID 0x2819 /* uint16 */
|
||||
#define CSR_VARID_CHIPVER 0x281a /* uint16 */
|
||||
#define CSR_VARID_CHIPREV 0x281b /* uint16 */
|
||||
#define CSR_VARID_INTERFACE_VERSION 0x2825 /* uint16 */
|
||||
#define CSR_VARID_RAND 0x282a /* uint16 */
|
||||
#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c /* uint16 */
|
||||
#define CSR_VARID_CHIPANAREV 0x2836 /* uint16 */
|
||||
#define CSR_VARID_BUILDID_LOADER 0x2838 /* uint16 */
|
||||
#define CSR_VARID_BT_CLOCK 0x2c00 /* uint32 */
|
||||
#define CSR_VARID_PS_NEXT 0x3005 /* complex */
|
||||
#define CSR_VARID_PS_SIZE 0x3006 /* complex */
|
||||
#define CSR_VARID_CRYPT_KEY_LENGTH 0x3008 /* complex */
|
||||
#define CSR_VARID_PICONET_INSTANCE 0x3009 /* complex */
|
||||
#define CSR_VARID_GET_CLR_EVT 0x300a /* complex */
|
||||
#define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */
|
||||
#define CSR_VARID_PS_MEMORY_TYPE 0x3012 /* complex */
|
||||
#define CSR_VARID_READ_BUILD_NAME 0x301c /* complex */
|
||||
#define CSR_VARID_COLD_RESET 0x4001 /* valueless */
|
||||
#define CSR_VARID_WARM_RESET 0x4002 /* valueless */
|
||||
#define CSR_VARID_COLD_HALT 0x4003 /* valueless */
|
||||
#define CSR_VARID_WARM_HALT 0x4004 /* valueless */
|
||||
#define CSR_VARID_INIT_BT_STACK 0x4005 /* valueless */
|
||||
#define CSR_VARID_ACTIVATE_BT_STACK 0x4006 /* valueless */
|
||||
#define CSR_VARID_ENABLE_TX 0x4007 /* valueless */
|
||||
#define CSR_VARID_DISABLE_TX 0x4008 /* valueless */
|
||||
#define CSR_VARID_RECAL 0x4009 /* valueless */
|
||||
#define CSR_VARID_PS_FACTORY_RESTORE 0x400d /* valueless */
|
||||
#define CSR_VARID_PS_FACTORY_RESTORE_ALL 0x400e /* valueless */
|
||||
#define CSR_VARID_PS_DEFRAG_RESET 0x400f /* valueless */
|
||||
#define CSR_VARID_KILL_VM_APPLICATION 0x4010 /* valueless */
|
||||
#define CSR_VARID_HOPPING_ON 0x4011 /* valueless */
|
||||
#define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */
|
||||
#define CSR_VARID_PS_CLR 0x4818 /* uint16 */
|
||||
#define CSR_VARID_MAP_SCO_PCM 0x481c /* uint16 */
|
||||
#define CSR_VARID_SINGLE_CHAN 0x482e /* uint16 */
|
||||
#define CSR_VARID_RADIOTEST 0x5004 /* complex */
|
||||
#define CSR_VARID_PS_CLR_STORES 0x500c /* complex */
|
||||
#define CSR_VARID_NO_VARIABLE 0x6000 /* valueless */
|
||||
#define CSR_VARID_CONFIG_UART 0x6802 /* uint16 */
|
||||
#define CSR_VARID_PANIC_ARG 0x6805 /* uint16 */
|
||||
#define CSR_VARID_FAULT_ARG 0x6806 /* uint16 */
|
||||
#define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */
|
||||
#define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */
|
||||
#define CSR_VARID_PS 0x7003 /* complex */
|
||||
|
||||
#define CSR_PSKEY_BDADDR 0x0001 /* bdaddr / uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */
|
||||
#define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */
|
||||
#define CSR_PSKEY_CLASSOFDEVICE 0x0003 /* bdcod */
|
||||
#define CSR_PSKEY_DEVICE_DRIFT 0x0004 /* uint16 */
|
||||
#define CSR_PSKEY_DEVICE_JITTER 0x0005 /* uint16 */
|
||||
#define CSR_PSKEY_MAX_ACLS 0x000d /* uint16 */
|
||||
#define CSR_PSKEY_MAX_SCOS 0x000e /* uint16 */
|
||||
#define CSR_PSKEY_MAX_REMOTE_MASTERS 0x000f /* uint16 */
|
||||
#define CSR_PSKEY_ENABLE_MASTERY_WITH_SLAVERY 0x0010 /* bool */
|
||||
#define CSR_PSKEY_H_HC_FC_MAX_ACL_PKT_LEN 0x0011 /* uint16 */
|
||||
#define CSR_PSKEY_H_HC_FC_MAX_SCO_PKT_LEN 0x0012 /* uint8 */
|
||||
#define CSR_PSKEY_H_HC_FC_MAX_ACL_PKTS 0x0013 /* uint16 */
|
||||
#define CSR_PSKEY_H_HC_FC_MAX_SCO_PKTS 0x0014 /* uint16 */
|
||||
#define CSR_PSKEY_LC_FC_BUFFER_LOW_WATER_MARK 0x0015 /* lc_fc_lwm */
|
||||
#define CSR_PSKEY_LC_MAX_TX_POWER 0x0017 /* int16 */
|
||||
#define CSR_PSKEY_TX_GAIN_RAMP 0x001d /* uint16 */
|
||||
#define CSR_PSKEY_LC_POWER_TABLE 0x001e /* power_setting[] */
|
||||
#define CSR_PSKEY_LC_PEER_POWER_PERIOD 0x001f /* TIME */
|
||||
#define CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK 0x0020 /* lc_fc_lwm */
|
||||
#define CSR_PSKEY_LC_DEFAULT_TX_POWER 0x0021 /* int16 */
|
||||
#define CSR_PSKEY_LC_RSSI_GOLDEN_RANGE 0x0022 /* uint8 */
|
||||
#define CSR_PSKEY_LC_COMBO_DISABLE_PIO_MASK 0x0028 /* uint16[] */
|
||||
#define CSR_PSKEY_LC_COMBO_PRIORITY_PIO_MASK 0x0029 /* uint16[] */
|
||||
#define CSR_PSKEY_LC_COMBO_DOT11_CHANNEL_PIO_BASE 0x002a /* uint16 */
|
||||
#define CSR_PSKEY_LC_COMBO_DOT11_BLOCK_CHANNELS 0x002b /* uint16 */
|
||||
#define CSR_PSKEY_LC_MAX_TX_POWER_NO_RSSI 0x002d /* int8 */
|
||||
#define CSR_PSKEY_LC_CONNECTION_RX_WINDOW 0x002e /* uint16 */
|
||||
#define CSR_PSKEY_LC_COMBO_DOT11_TX_PROTECTION_MODE 0x0030 /* uint16 */
|
||||
#define CSR_PSKEY_LC_ENHANCED_POWER_TABLE 0x0031 /* enhanced_power_setting[] */
|
||||
#define CSR_PSKEY_LC_WIDEBAND_RSSI_CONFIG 0x0032 /* wideband_rssi_config */
|
||||
#define CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_LEAD 0x0033 /* uint16 */
|
||||
#define CSR_PSKEY_BT_CLOCK_INIT 0x0034 /* uint32 */
|
||||
#define CSR_PSKEY_TX_MR_MOD_DELAY 0x0038 /* uint8 */
|
||||
#define CSR_PSKEY_RX_MR_SYNC_TIMING 0x0039 /* uint16 */
|
||||
#define CSR_PSKEY_RX_MR_SYNC_CONFIG 0x003a /* uint16 */
|
||||
#define CSR_PSKEY_LC_LOST_SYNC_SLOTS 0x003b /* uint16 */
|
||||
#define CSR_PSKEY_RX_MR_SAMP_CONFIG 0x003c /* uint16 */
|
||||
#define CSR_PSKEY_AGC_HYST_LEVELS 0x003d /* agc_hyst_config */
|
||||
#define CSR_PSKEY_RX_LEVEL_LOW_SIGNAL 0x003e /* uint16 */
|
||||
#define CSR_PSKEY_AGC_IQ_LVL_VALUES 0x003f /* IQ_LVL_VAL[] */
|
||||
#define CSR_PSKEY_MR_FTRIM_OFFSET_12DB 0x0040 /* uint16 */
|
||||
#define CSR_PSKEY_MR_FTRIM_OFFSET_6DB 0x0041 /* uint16 */
|
||||
#define CSR_PSKEY_NO_CAL_ON_BOOT 0x0042 /* bool */
|
||||
#define CSR_PSKEY_RSSI_HI_TARGET 0x0043 /* uint8 */
|
||||
#define CSR_PSKEY_PREFERRED_MIN_ATTENUATION 0x0044 /* uint8 */
|
||||
#define CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_OVERRIDE 0x0045 /* bool */
|
||||
#define CSR_PSKEY_LC_MULTISLOT_HOLDOFF 0x0047 /* TIME */
|
||||
#define CSR_PSKEY_FREE_KEY_PIGEON_HOLE 0x00c9 /* uint16 */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR0 0x00ca /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR1 0x00cb /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR2 0x00cc /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR3 0x00cd /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR4 0x00ce /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR5 0x00cf /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR6 0x00d0 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR7 0x00d1 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR8 0x00d2 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR9 0x00d3 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR10 0x00d4 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR11 0x00d5 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR12 0x00d6 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR13 0x00d7 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR14 0x00d8 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LINK_KEY_BD_ADDR15 0x00d9 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */
|
||||
#define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */
|
||||
#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 }*/
|
||||
#define CSR_PSKEY_LM_USE_UNIT_KEY 0x00f0 /* bool */
|
||||
#define CSR_PSKEY_HCI_NOP_DISABLE 0x00f2 /* bool */
|
||||
#define CSR_PSKEY_LM_MAX_EVENT_FILTERS 0x00f4 /* uint8 */
|
||||
#define CSR_PSKEY_LM_USE_ENC_MODE_BROADCAST 0x00f5 /* bool */
|
||||
#define CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE 0x00f6 /* bool */
|
||||
#define CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME 0x00f7 /* uint16 */
|
||||
#define CSR_PSKEY_AFH_ADAPTATION_RESPONSE_TIME 0x00f8 /* uint16 */
|
||||
#define CSR_PSKEY_AFH_OPTIONS 0x00f9 /* uint16 */
|
||||
#define CSR_PSKEY_AFH_RSSI_RUN_PERIOD 0x00fa /* uint16 */
|
||||
#define CSR_PSKEY_AFH_REENABLE_CHANNEL_TIME 0x00fb /* uint16 */
|
||||
#define CSR_PSKEY_NO_DROP_ON_ACR_MS_FAIL 0x00fc /* bool */
|
||||
#define CSR_PSKEY_MAX_PRIVATE_KEYS 0x00fd /* uint8 */
|
||||
#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR0 0x00fe /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR1 0x00ff /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR2 0x0100 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR3 0x0101 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR4 0x0102 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR5 0x0103 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR6 0x0104 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR7 0x0105 /* LM_LINK_KEY_BD_ADDR_T */
|
||||
#define CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS 0x0106 /* uint16[] = { 0xffff, 0x03ff, 0xfffe, 0xffff, 0xffff, 0xffff, 0x0ff3, 0xfff8, 0x003f } */
|
||||
#define CSR_PSKEY_LM_MAX_ABSENCE_INDEX 0x0107 /* uint8 */
|
||||
#define CSR_PSKEY_DEVICE_NAME 0x0108 /* uint16[] */
|
||||
#define CSR_PSKEY_AFH_RSSI_THRESHOLD 0x0109 /* uint16 */
|
||||
#define CSR_PSKEY_LM_CASUAL_SCAN_INTERVAL 0x010a /* uint16 */
|
||||
#define CSR_PSKEY_AFH_MIN_MAP_CHANGE 0x010b /* uint16[] */
|
||||
#define CSR_PSKEY_AFH_RSSI_LP_RUN_PERIOD 0x010c /* uint16 */
|
||||
#define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */
|
||||
#define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */
|
||||
#define CSR_PSKEY_HOLD_ERROR_MESSAGE_NUMBER 0x0113 /* uint16 */
|
||||
#define CSR_PSKEY_DFU_ATTRIBUTES 0x0136 /* uint8 */
|
||||
#define CSR_PSKEY_DFU_DETACH_TO 0x0137 /* uint16 */
|
||||
#define CSR_PSKEY_DFU_TRANSFER_SIZE 0x0138 /* uint16 */
|
||||
#define CSR_PSKEY_DFU_ENABLE 0x0139 /* bool */
|
||||
#define CSR_PSKEY_DFU_LIN_REG_ENABLE 0x013a /* bool */
|
||||
#define CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_MSB 0x015e /* uint16[] */
|
||||
#define CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_LSB 0x015f /* uint16[] */
|
||||
#define CSR_PSKEY_DFUENC_VMAPP_PK_M_DASH 0x0160 /* uint16 */
|
||||
#define CSR_PSKEY_DFUENC_VMAPP_PK_R2N_MSB 0x0161 /* uint16[] */
|
||||
#define CSR_PSKEY_DFUENC_VMAPP_PK_R2N_LSB 0x0162 /* uint16[] */
|
||||
#define CSR_PSKEY_BCSP_LM_PS_BLOCK 0x0192 /* BCSP_LM_PS_BLOCK */
|
||||
#define CSR_PSKEY_HOSTIO_FC_PS_BLOCK 0x0193 /* HOSTIO_FC_PS_BLOCK */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO0 0x0194 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO1 0x0195 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO2 0x0196 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO3 0x0197 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO4 0x0198 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO5 0x0199 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO6 0x019a /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO7 0x019b /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO8 0x019c /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO9 0x019d /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO10 0x019e /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO11 0x019f /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO12 0x01a0 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO13 0x01a1 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO14 0x01a2 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO15 0x01a3 /* PROTOCOL_INFO */
|
||||
#define CSR_PSKEY_HOSTIO_UART_RESET_TIMEOUT 0x01a4 /* TIME */
|
||||
#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN 0x01a5 /* bool */
|
||||
#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN_CCFC 0x01a6 /* bool */
|
||||
#define CSR_PSKEY_HOSTIO_HCI_EXTN_PAYLOAD_SIZE 0x01a7 /* uint16 */
|
||||
#define CSR_PSKEY_BCSP_LM_CNF_CNT_LIMIT 0x01aa /* uint16 */
|
||||
#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab /* bool */
|
||||
#define CSR_PSKEY_HOSTIO_AWKWARD_PCM_SYNC 0x01ac /* bool */
|
||||
#define CSR_PSKEY_HOSTIO_BREAK_POLL_PERIOD 0x01ad /* TIME */
|
||||
#define CSR_PSKEY_HOSTIO_MIN_UART_HCI_SCO_SIZE 0x01ae /* uint16 */
|
||||
#define CSR_PSKEY_HOSTIO_MAP_SCO_CODEC 0x01b0 /* bool */
|
||||
#define CSR_PSKEY_PCM_CVSD_TX_HI_FREQ_BOOST 0x01b1 /* uint16 */
|
||||
#define CSR_PSKEY_PCM_CVSD_RX_HI_FREQ_BOOST 0x01b2 /* uint16 */
|
||||
#define CSR_PSKEY_PCM_CONFIG32 0x01b3 /* uint32 */
|
||||
#define CSR_PSKEY_USE_OLD_BCSP_LE 0x01b4 /* uint16 */
|
||||
#define CSR_PSKEY_PCM_CVSD_USE_NEW_FILTER 0x01b5 /* bool */
|
||||
#define CSR_PSKEY_PCM_FORMAT 0x01b6 /* uint16 */
|
||||
#define CSR_PSKEY_CODEC_OUT_GAIN 0x01b7 /* uint16 */
|
||||
#define CSR_PSKEY_CODEC_IN_GAIN 0x01b8 /* uint16 */
|
||||
#define CSR_PSKEY_CODEC_PIO 0x01b9 /* uint16 */
|
||||
#define CSR_PSKEY_PCM_LOW_JITTER_CONFIG 0x01ba /* uint32 */
|
||||
#define CSR_PSKEY_HOSTIO_SCO_PCM_THRESHOLDS 0x01bb /* uint16[] */
|
||||
#define CSR_PSKEY_HOSTIO_SCO_HCI_THRESHOLDS 0x01bc /* uint16[] */
|
||||
#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM_SLOT 0x01bd /* uint16 */
|
||||
#define CSR_PSKEY_UART_BAUDRATE 0x01be /* uint16 */
|
||||
#define CSR_PSKEY_UART_CONFIG_BCSP 0x01bf /* uint16 */
|
||||
#define CSR_PSKEY_UART_CONFIG_H4 0x01c0 /* uint16 */
|
||||
#define CSR_PSKEY_UART_CONFIG_H5 0x01c1 /* uint16 */
|
||||
#define CSR_PSKEY_UART_CONFIG_USR 0x01c2 /* uint16 */
|
||||
#define CSR_PSKEY_UART_TX_CRCS 0x01c3 /* bool */
|
||||
#define CSR_PSKEY_UART_ACK_TIMEOUT 0x01c4 /* uint16 */
|
||||
#define CSR_PSKEY_UART_TX_MAX_ATTEMPTS 0x01c5 /* uint16 */
|
||||
#define CSR_PSKEY_UART_TX_WINDOW_SIZE 0x01c6 /* uint16 */
|
||||
#define CSR_PSKEY_UART_HOST_WAKE 0x01c7 /* uint16[] */
|
||||
#define CSR_PSKEY_HOSTIO_THROTTLE_TIMEOUT 0x01c8 /* TIME */
|
||||
#define CSR_PSKEY_PCM_ALWAYS_ENABLE 0x01c9 /* bool */
|
||||
#define CSR_PSKEY_UART_HOST_WAKE_SIGNAL 0x01ca /* uint16 */
|
||||
#define CSR_PSKEY_UART_CONFIG_H4DS 0x01cb /* uint16 */
|
||||
#define CSR_PSKEY_H4DS_WAKE_DURATION 0x01cc /* uint16 */
|
||||
#define CSR_PSKEY_H4DS_MAXWU 0x01cd /* uint16 */
|
||||
#define CSR_PSKEY_H4DS_LE_TIMER_PERIOD 0x01cf /* uint16 */
|
||||
#define CSR_PSKEY_H4DS_TWU_TIMER_PERIOD 0x01d0 /* uint16 */
|
||||
#define CSR_PSKEY_H4DS_UART_IDLE_TIMER_PERIOD 0x01d1 /* uint16 */
|
||||
#define CSR_PSKEY_ANA_FTRIM 0x01f6 /* uint16 */
|
||||
#define CSR_PSKEY_WD_TIMEOUT 0x01f7 /* TIME */
|
||||
#define CSR_PSKEY_WD_PERIOD 0x01f8 /* TIME */
|
||||
#define CSR_PSKEY_HOST_INTERFACE 0x01f9 /* phys_bus */
|
||||
#define CSR_PSKEY_HQ_HOST_TIMEOUT 0x01fb /* TIME */
|
||||
#define CSR_PSKEY_HQ_ACTIVE 0x01fc /* bool */
|
||||
#define CSR_PSKEY_BCCMD_SECURITY_ACTIVE 0x01fd /* bool */
|
||||
#define CSR_PSKEY_ANA_FREQ 0x01fe /* uint16 */
|
||||
#define CSR_PSKEY_PIO_PROTECT_MASK 0x0202 /* uint16 */
|
||||
#define CSR_PSKEY_PMALLOC_SIZES 0x0203 /* uint16[] */
|
||||
#define CSR_PSKEY_UART_BAUD_RATE 0x0204 /* uint16 */
|
||||
#define CSR_PSKEY_UART_CONFIG 0x0205 /* uint16 */
|
||||
#define CSR_PSKEY_STUB 0x0207 /* uint16 */
|
||||
#define CSR_PSKEY_TXRX_PIO_CONTROL 0x0209 /* uint16 */
|
||||
#define CSR_PSKEY_ANA_RX_LEVEL 0x020b /* uint16 */
|
||||
#define CSR_PSKEY_ANA_RX_FTRIM 0x020c /* uint16 */
|
||||
#define CSR_PSKEY_PSBC_DATA_VERSION 0x020d /* uint16 */
|
||||
#define CSR_PSKEY_PCM0_ATTENUATION 0x020f /* uint16 */
|
||||
#define CSR_PSKEY_LO_LVL_MAX 0x0211 /* uint16 */
|
||||
#define CSR_PSKEY_LO_ADC_AMPL_MIN 0x0212 /* uint16 */
|
||||
#define CSR_PSKEY_LO_ADC_AMPL_MAX 0x0213 /* uint16 */
|
||||
#define CSR_PSKEY_IQ_TRIM_CHANNEL 0x0214 /* uint16 */
|
||||
#define CSR_PSKEY_IQ_TRIM_GAIN 0x0215 /* uint16 */
|
||||
#define CSR_PSKEY_IQ_TRIM_ENABLE 0x0216 /* iq_trim_enable_flag */
|
||||
#define CSR_PSKEY_TX_OFFSET_HALF_MHZ 0x0217 /* int16 */
|
||||
#define CSR_PSKEY_GBL_MISC_ENABLES 0x0221 /* uint16 */
|
||||
#define CSR_PSKEY_UART_SLEEP_TIMEOUT 0x0222 /* uint16 */
|
||||
#define CSR_PSKEY_DEEP_SLEEP_STATE 0x0229 /* deep_sleep_state */
|
||||
#define CSR_PSKEY_IQ_ENABLE_PHASE_TRIM 0x022d /* bool */
|
||||
#define CSR_PSKEY_HCI_HANDLE_FREEZE_PERIOD 0x0237 /* TIME */
|
||||
#define CSR_PSKEY_MAX_FROZEN_HCI_HANDLES 0x0238 /* uint16 */
|
||||
#define CSR_PSKEY_PAGETABLE_DESTRUCTION_DELAY 0x0239 /* TIME */
|
||||
#define CSR_PSKEY_IQ_TRIM_PIO_SETTINGS 0x023a /* uint8 */
|
||||
#define CSR_PSKEY_USE_EXTERNAL_CLOCK 0x023b /* bool */
|
||||
#define CSR_PSKEY_DEEP_SLEEP_WAKE_CTS 0x023c /* uint16 */
|
||||
#define CSR_PSKEY_FC_HC2H_FLUSH_DELAY 0x023d /* TIME */
|
||||
#define CSR_PSKEY_RX_HIGHSIDE 0x023e /* bool */
|
||||
#define CSR_PSKEY_TX_PRE_LVL 0x0240 /* uint8 */
|
||||
#define CSR_PSKEY_RX_SINGLE_ENDED 0x0242 /* bool */
|
||||
#define CSR_PSKEY_TX_FILTER_CONFIG 0x0243 /* uint32 */
|
||||
#define CSR_PSKEY_CLOCK_REQUEST_ENABLE 0x0246 /* uint16 */
|
||||
#define CSR_PSKEY_RX_MIN_ATTEN 0x0249 /* uint16 */
|
||||
#define CSR_PSKEY_XTAL_TARGET_AMPLITUDE 0x024b /* uint8 */
|
||||
#define CSR_PSKEY_PCM_MIN_CPU_CLOCK 0x024d /* uint16 */
|
||||
#define CSR_PSKEY_HOST_INTERFACE_PIO_USB 0x0250 /* uint16 */
|
||||
#define CSR_PSKEY_CPU_IDLE_MODE 0x0251 /* cpu_idle_mode */
|
||||
#define CSR_PSKEY_DEEP_SLEEP_CLEAR_RTS 0x0252 /* bool */
|
||||
#define CSR_PSKEY_RF_RESONANCE_TRIM 0x0254 /* uint16 */
|
||||
#define CSR_PSKEY_DEEP_SLEEP_PIO_WAKE 0x0255 /* uint16 */
|
||||
#define CSR_PSKEY_DRAIN_BORE_TIMERS 0x0256 /* uint32[] */
|
||||
#define CSR_PSKEY_DRAIN_TX_POWER_BASE 0x0257 /* uint16 */
|
||||
#define CSR_PSKEY_MODULE_ID 0x0259 /* uint32 */
|
||||
#define CSR_PSKEY_MODULE_DESIGN 0x025a /* uint16 */
|
||||
#define CSR_PSKEY_MODULE_SECURITY_CODE 0x025c /* uint16[] */
|
||||
#define CSR_PSKEY_VM_DISABLE 0x025d /* bool */
|
||||
#define CSR_PSKEY_MOD_MANUF0 0x025e /* uint16[] */
|
||||
#define CSR_PSKEY_MOD_MANUF1 0x025f /* uint16[] */
|
||||
#define CSR_PSKEY_MOD_MANUF2 0x0260 /* uint16[] */
|
||||
#define CSR_PSKEY_MOD_MANUF3 0x0261 /* uint16[] */
|
||||
#define CSR_PSKEY_MOD_MANUF4 0x0262 /* uint16[] */
|
||||
#define CSR_PSKEY_MOD_MANUF5 0x0263 /* uint16[] */
|
||||
#define CSR_PSKEY_MOD_MANUF6 0x0264 /* uint16[] */
|
||||
#define CSR_PSKEY_MOD_MANUF7 0x0265 /* uint16[] */
|
||||
#define CSR_PSKEY_MOD_MANUF8 0x0266 /* uint16[] */
|
||||
#define CSR_PSKEY_MOD_MANUF9 0x0267 /* uint16[] */
|
||||
#define CSR_PSKEY_DUT_VM_DISABLE 0x0268 /* bool */
|
||||
#define CSR_PSKEY_USR0 0x028a /* uint16[] */
|
||||
#define CSR_PSKEY_USR1 0x028b /* uint16[] */
|
||||
#define CSR_PSKEY_USR2 0x028c /* uint16[] */
|
||||
#define CSR_PSKEY_USR3 0x028d /* uint16[] */
|
||||
#define CSR_PSKEY_USR4 0x028e /* uint16[] */
|
||||
#define CSR_PSKEY_USR5 0x028f /* uint16[] */
|
||||
#define CSR_PSKEY_USR6 0x0290 /* uint16[] */
|
||||
#define CSR_PSKEY_USR7 0x0291 /* uint16[] */
|
||||
#define CSR_PSKEY_USR8 0x0292 /* uint16[] */
|
||||
#define CSR_PSKEY_USR9 0x0293 /* uint16[] */
|
||||
#define CSR_PSKEY_USR10 0x0294 /* uint16[] */
|
||||
#define CSR_PSKEY_USR11 0x0295 /* uint16[] */
|
||||
#define CSR_PSKEY_USR12 0x0296 /* uint16[] */
|
||||
#define CSR_PSKEY_USR13 0x0297 /* uint16[] */
|
||||
#define CSR_PSKEY_USR14 0x0298 /* uint16[] */
|
||||
#define CSR_PSKEY_USR15 0x0299 /* uint16[] */
|
||||
#define CSR_PSKEY_USR16 0x029a /* uint16[] */
|
||||
#define CSR_PSKEY_USR17 0x029b /* uint16[] */
|
||||
#define CSR_PSKEY_USR18 0x029c /* uint16[] */
|
||||
#define CSR_PSKEY_USR19 0x029d /* uint16[] */
|
||||
#define CSR_PSKEY_USR20 0x029e /* uint16[] */
|
||||
#define CSR_PSKEY_USR21 0x029f /* uint16[] */
|
||||
#define CSR_PSKEY_USR22 0x02a0 /* uint16[] */
|
||||
#define CSR_PSKEY_USR23 0x02a1 /* uint16[] */
|
||||
#define CSR_PSKEY_USR24 0x02a2 /* uint16[] */
|
||||
#define CSR_PSKEY_USR25 0x02a3 /* uint16[] */
|
||||
#define CSR_PSKEY_USR26 0x02a4 /* uint16[] */
|
||||
#define CSR_PSKEY_USR27 0x02a5 /* uint16[] */
|
||||
#define CSR_PSKEY_USR28 0x02a6 /* uint16[] */
|
||||
#define CSR_PSKEY_USR29 0x02a7 /* uint16[] */
|
||||
#define CSR_PSKEY_USR30 0x02a8 /* uint16[] */
|
||||
#define CSR_PSKEY_USR31 0x02a9 /* uint16[] */
|
||||
#define CSR_PSKEY_USR32 0x02aa /* uint16[] */
|
||||
#define CSR_PSKEY_USR33 0x02ab /* uint16[] */
|
||||
#define CSR_PSKEY_USR34 0x02ac /* uint16[] */
|
||||
#define CSR_PSKEY_USR35 0x02ad /* uint16[] */
|
||||
#define CSR_PSKEY_USR36 0x02ae /* uint16[] */
|
||||
#define CSR_PSKEY_USR37 0x02af /* uint16[] */
|
||||
#define CSR_PSKEY_USR38 0x02b0 /* uint16[] */
|
||||
#define CSR_PSKEY_USR39 0x02b1 /* uint16[] */
|
||||
#define CSR_PSKEY_USR40 0x02b2 /* uint16[] */
|
||||
#define CSR_PSKEY_USR41 0x02b3 /* uint16[] */
|
||||
#define CSR_PSKEY_USR42 0x02b4 /* uint16[] */
|
||||
#define CSR_PSKEY_USR43 0x02b5 /* uint16[] */
|
||||
#define CSR_PSKEY_USR44 0x02b6 /* uint16[] */
|
||||
#define CSR_PSKEY_USR45 0x02b7 /* uint16[] */
|
||||
#define CSR_PSKEY_USR46 0x02b8 /* uint16[] */
|
||||
#define CSR_PSKEY_USR47 0x02b9 /* uint16[] */
|
||||
#define CSR_PSKEY_USR48 0x02ba /* uint16[] */
|
||||
#define CSR_PSKEY_USR49 0x02bb /* uint16[] */
|
||||
#define CSR_PSKEY_USB_VERSION 0x02bc /* uint16 */
|
||||
#define CSR_PSKEY_USB_DEVICE_CLASS_CODES 0x02bd /* usbclass */
|
||||
#define CSR_PSKEY_USB_VENDOR_ID 0x02be /* uint16 */
|
||||
#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf /* uint16 */
|
||||
#define CSR_PSKEY_USB_MANUF_STRING 0x02c1 /* unicodestring */
|
||||
#define CSR_PSKEY_USB_PRODUCT_STRING 0x02c2 /* unicodestring */
|
||||
#define CSR_PSKEY_USB_SERIAL_NUMBER_STRING 0x02c3 /* unicodestring */
|
||||
#define CSR_PSKEY_USB_CONFIG_STRING 0x02c4 /* unicodestring */
|
||||
#define CSR_PSKEY_USB_ATTRIBUTES 0x02c5 /* uint8 */
|
||||
#define CSR_PSKEY_USB_MAX_POWER 0x02c6 /* uint16 */
|
||||
#define CSR_PSKEY_USB_BT_IF_CLASS_CODES 0x02c7 /* usbclass */
|
||||
#define CSR_PSKEY_USB_LANGID 0x02c9 /* uint16 */
|
||||
#define CSR_PSKEY_USB_DFU_CLASS_CODES 0x02ca /* usbclass */
|
||||
#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb /* uint16 */
|
||||
#define CSR_PSKEY_USB_PIO_DETACH 0x02ce /* uint16 */
|
||||
#define CSR_PSKEY_USB_PIO_WAKEUP 0x02cf /* uint16 */
|
||||
#define CSR_PSKEY_USB_PIO_PULLUP 0x02d0 /* uint16 */
|
||||
#define CSR_PSKEY_USB_PIO_VBUS 0x02d1 /* uint16 */
|
||||
#define CSR_PSKEY_USB_PIO_WAKE_TIMEOUT 0x02d2 /* uint16 */
|
||||
#define CSR_PSKEY_USB_PIO_RESUME 0x02d3 /* uint16 */
|
||||
#define CSR_PSKEY_USB_BT_SCO_IF_CLASS_CODES 0x02d4 /* usbclass */
|
||||
#define CSR_PSKEY_USB_SUSPEND_PIO_LEVEL 0x02d5 /* uint16 */
|
||||
#define CSR_PSKEY_USB_SUSPEND_PIO_DIR 0x02d6 /* uint16 */
|
||||
#define CSR_PSKEY_USB_SUSPEND_PIO_MASK 0x02d7 /* uint16 */
|
||||
#define CSR_PSKEY_USB_ENDPOINT_0_MAX_PACKET_SIZE 0x02d8 /* uint8 */
|
||||
#define CSR_PSKEY_USB_CONFIG 0x02d9 /* uint16 */
|
||||
#define CSR_PSKEY_RADIOTEST_ATTEN_INIT 0x0320 /* uint16 */
|
||||
#define CSR_PSKEY_RADIOTEST_FIRST_TRIM_TIME 0x0326 /* TIME */
|
||||
#define CSR_PSKEY_RADIOTEST_SUBSEQUENT_TRIM_TIME 0x0327 /* TIME */
|
||||
#define CSR_PSKEY_RADIOTEST_LO_LVL_TRIM_ENABLE 0x0328 /* bool */
|
||||
#define CSR_PSKEY_RADIOTEST_DISABLE_MODULATION 0x032c /* bool */
|
||||
#define CSR_PSKEY_RFCOMM_FCON_THRESHOLD 0x0352 /* uint16 */
|
||||
#define CSR_PSKEY_RFCOMM_FCOFF_THRESHOLD 0x0353 /* uint16 */
|
||||
#define CSR_PSKEY_IPV6_STATIC_ADDR 0x0354 /* uint16[] */
|
||||
#define CSR_PSKEY_IPV4_STATIC_ADDR 0x0355 /* uint32 */
|
||||
#define CSR_PSKEY_IPV6_STATIC_PREFIX_LEN 0x0356 /* uint8 */
|
||||
#define CSR_PSKEY_IPV6_STATIC_ROUTER_ADDR 0x0357 /* uint16[] */
|
||||
#define CSR_PSKEY_IPV4_STATIC_SUBNET_MASK 0x0358 /* uint32 */
|
||||
#define CSR_PSKEY_IPV4_STATIC_ROUTER_ADDR 0x0359 /* uint32 */
|
||||
#define CSR_PSKEY_MDNS_NAME 0x035a /* char[] */
|
||||
#define CSR_PSKEY_FIXED_PIN 0x035b /* uint8[] */
|
||||
#define CSR_PSKEY_MDNS_PORT 0x035c /* uint16 */
|
||||
#define CSR_PSKEY_MDNS_TTL 0x035d /* uint8 */
|
||||
#define CSR_PSKEY_MDNS_IPV4_ADDR 0x035e /* uint32 */
|
||||
#define CSR_PSKEY_ARP_CACHE_TIMEOUT 0x035f /* uint16 */
|
||||
#define CSR_PSKEY_HFP_POWER_TABLE 0x0360 /* uint16[] */
|
||||
#define CSR_PSKEY_DRAIN_BORE_TIMER_COUNTERS 0x03e7 /* uint32[] */
|
||||
#define CSR_PSKEY_DRAIN_BORE_COUNTERS 0x03e6 /* uint32[] */
|
||||
#define CSR_PSKEY_LOOP_FILTER_TRIM 0x03e4 /* uint16 */
|
||||
#define CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK 0x03e3 /* uint32[] */
|
||||
#define CSR_PSKEY_VM_E2_CACHE_LIMIT 0x03e2 /* uint16 */
|
||||
#define CSR_PSKEY_FORCE_16MHZ_REF_PIO 0x03e1 /* uint16 */
|
||||
#define CSR_PSKEY_CDMA_LO_REF_LIMITS 0x03df /* uint16 */
|
||||
#define CSR_PSKEY_CDMA_LO_ERROR_LIMITS 0x03de /* uint16 */
|
||||
#define CSR_PSKEY_CLOCK_STARTUP_DELAY 0x03dd /* uint16 */
|
||||
#define CSR_PSKEY_DEEP_SLEEP_CORRECTION_FACTOR 0x03dc /* int16 */
|
||||
#define CSR_PSKEY_TEMPERATURE_CALIBRATION 0x03db /* temperature_calibration */
|
||||
#define CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA 0x03da /* temperature_calibration[] */
|
||||
#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL 0x03d9 /* temperature_calibration[] */
|
||||
#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB 0x03d8 /* temperature_calibration[] */
|
||||
#define CSR_PSKEY_TEMPERATURE_VS_DELTA_ANA_FTRIM 0x03d7 /* temperature_calibration[] */
|
||||
#define CSR_PSKEY_TEST_DELTA_OFFSET 0x03d6 /* uint16 */
|
||||
#define CSR_PSKEY_RX_DYNAMIC_LVL_OFFSET 0x03d4 /* uint16 */
|
||||
#define CSR_PSKEY_TEST_FORCE_OFFSET 0x03d3 /* bool */
|
||||
#define CSR_PSKEY_RF_TRAP_BAD_DIVISION_RATIOS 0x03cf /* uint16 */
|
||||
#define CSR_PSKEY_RADIOTEST_CDMA_LO_REF_LIMITS 0x03ce /* uint16 */
|
||||
#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd /* int16 */
|
||||
#define CSR_PSKEY_ONCHIP_HCI_CLIENT 0x03cc /* bool */
|
||||
#define CSR_PSKEY_RX_ATTEN_BACKOFF 0x03ca /* uint16 */
|
||||
#define CSR_PSKEY_RX_ATTEN_UPDATE_RATE 0x03c9 /* uint16 */
|
||||
#define CSR_PSKEY_SYNTH_TXRX_THRESHOLDS 0x03c7 /* uint16 */
|
||||
#define CSR_PSKEY_MIN_WAIT_STATES 0x03c6 /* uint16 */
|
||||
#define CSR_PSKEY_RSSI_CORRECTION 0x03c5 /* int8 */
|
||||
#define CSR_PSKEY_SCHED_THROTTLE_TIMEOUT 0x03c4 /* TIME */
|
||||
#define CSR_PSKEY_DEEP_SLEEP_USE_EXTERNAL_CLOCK 0x03c3 /* bool */
|
||||
#define CSR_PSKEY_TRIM_RADIO_FILTERS 0x03c2 /* uint16 */
|
||||
#define CSR_PSKEY_TRANSMIT_OFFSET 0x03c1 /* int16 */
|
||||
#define CSR_PSKEY_USB_VM_CONTROL 0x03c0 /* bool */
|
||||
#define CSR_PSKEY_MR_ANA_RX_FTRIM 0x03bf /* uint16 */
|
||||
#define CSR_PSKEY_I2C_CONFIG 0x03be /* uint16 */
|
||||
#define CSR_PSKEY_IQ_LVL_RX 0x03bd /* uint16 */
|
||||
#define CSR_PSKEY_MR_TX_FILTER_CONFIG 0x03bb /* uint32 */
|
||||
#define CSR_PSKEY_MR_TX_CONFIG2 0x03ba /* uint16 */
|
||||
#define CSR_PSKEY_USB_DONT_RESET_BOOTMODE_ON_HOST_RESET 0x03b9 /* bool */
|
||||
#define CSR_PSKEY_LC_USE_THROTTLING 0x03b8 /* bool */
|
||||
#define CSR_PSKEY_CHARGER_TRIM 0x03b7 /* uint16 */
|
||||
#define CSR_PSKEY_CLOCK_REQUEST_FEATURES 0x03b6 /* uint16 */
|
||||
#define CSR_PSKEY_TRANSMIT_OFFSET_CLASS1 0x03b4 /* int16 */
|
||||
#define CSR_PSKEY_TX_AVOID_PA_CLASS1_PIO 0x03b3 /* uint16 */
|
||||
#define CSR_PSKEY_MR_PIO_CONFIG 0x03b2 /* uint16 */
|
||||
#define CSR_PSKEY_UART_CONFIG2 0x03b1 /* uint8 */
|
||||
#define CSR_PSKEY_CLASS1_IQ_LVL 0x03b0 /* uint16 */
|
||||
#define CSR_PSKEY_CLASS1_TX_CONFIG2 0x03af /* uint16 */
|
||||
#define CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA_CLASS1 0x03ae /* temperature_calibration[] */
|
||||
#define CSR_PSKEY_TEMPERATURE_VS_DELTA_EXTERNAL_PA_CLASS1 0x03ad /* temperature_calibration[] */
|
||||
#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL_MR 0x03ac /* temperature_calibration[] */
|
||||
#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_HEADER 0x03ab /* temperature_calibration[] */
|
||||
#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_PAYLOAD 0x03aa /* temperature_calibration[] */
|
||||
#define CSR_PSKEY_RX_MR_EQ_TAPS 0x03a9 /* uint16[] */
|
||||
#define CSR_PSKEY_TX_PRE_LVL_CLASS1 0x03a8 /* uint8 */
|
||||
#define CSR_PSKEY_ANALOGUE_ATTENUATOR 0x03a7 /* bool */
|
||||
#define CSR_PSKEY_MR_RX_FILTER_TRIM 0x03a6 /* uint16 */
|
||||
#define CSR_PSKEY_MR_RX_FILTER_RESPONSE 0x03a5 /* int16[] */
|
||||
#define CSR_PSKEY_PIO_WAKEUP_STATE 0x039f /* uint16 */
|
||||
#define CSR_PSKEY_MR_TX_IF_ATTEN_OFF_TEMP 0x0394 /* int16 */
|
||||
#define CSR_PSKEY_LO_DIV_LATCH_BYPASS 0x0393 /* bool */
|
||||
#define CSR_PSKEY_LO_VCO_STANDBY 0x0392 /* bool */
|
||||
#define CSR_PSKEY_SLOW_CLOCK_FILTER_SHIFT 0x0391 /* uint16 */
|
||||
#define CSR_PSKEY_SLOW_CLOCK_FILTER_DIVIDER 0x0390 /* uint16 */
|
||||
#define CSR_PSKEY_USB_ATTRIBUTES_POWER 0x03f2 /* bool */
|
||||
#define CSR_PSKEY_USB_ATTRIBUTES_WAKEUP 0x03f3 /* bool */
|
||||
#define CSR_PSKEY_DFU_ATTRIBUTES_MANIFESTATION_TOLERANT 0x03f4 /* bool */
|
||||
#define CSR_PSKEY_DFU_ATTRIBUTES_CAN_UPLOAD 0x03f5 /* bool */
|
||||
#define CSR_PSKEY_DFU_ATTRIBUTES_CAN_DOWNLOAD 0x03f6 /* bool */
|
||||
#define CSR_PSKEY_UART_CONFIG_STOP_BITS 0x03fc /* bool */
|
||||
#define CSR_PSKEY_UART_CONFIG_PARITY_BIT 0x03fd /* uint16 */
|
||||
#define CSR_PSKEY_UART_CONFIG_FLOW_CTRL_EN 0x03fe /* bool */
|
||||
#define CSR_PSKEY_UART_CONFIG_RTS_AUTO_EN 0x03ff /* bool */
|
||||
#define CSR_PSKEY_UART_CONFIG_RTS 0x0400 /* bool */
|
||||
#define CSR_PSKEY_UART_CONFIG_TX_ZERO_EN 0x0401 /* bool */
|
||||
#define CSR_PSKEY_UART_CONFIG_NON_BCSP_EN 0x0402 /* bool */
|
||||
#define CSR_PSKEY_UART_CONFIG_RX_RATE_DELAY 0x0403 /* uint16 */
|
||||
#define CSR_PSKEY_UART_SEQ_TIMEOUT 0x0405 /* uint16 */
|
||||
#define CSR_PSKEY_UART_SEQ_RETRIES 0x0406 /* uint16 */
|
||||
#define CSR_PSKEY_UART_SEQ_WINSIZE 0x0407 /* uint16 */
|
||||
#define CSR_PSKEY_UART_USE_CRC_ON_TX 0x0408 /* bool */
|
||||
#define CSR_PSKEY_UART_HOST_INITIAL_STATE 0x0409 /* hwakeup_state */
|
||||
#define CSR_PSKEY_UART_HOST_ATTENTION_SPAN 0x040a /* uint16 */
|
||||
#define CSR_PSKEY_UART_HOST_WAKEUP_TIME 0x040b /* uint16 */
|
||||
#define CSR_PSKEY_UART_HOST_WAKEUP_WAIT 0x040c /* uint16 */
|
||||
#define CSR_PSKEY_BCSP_LM_MODE 0x0410 /* uint16 */
|
||||
#define CSR_PSKEY_BCSP_LM_SYNC_RETRIES 0x0411 /* uint16 */
|
||||
#define CSR_PSKEY_BCSP_LM_TSHY 0x0412 /* uint16 */
|
||||
#define CSR_PSKEY_UART_DFU_CONFIG_STOP_BITS 0x0417 /* bool */
|
||||
#define CSR_PSKEY_UART_DFU_CONFIG_PARITY_BIT 0x0418 /* uint16 */
|
||||
#define CSR_PSKEY_UART_DFU_CONFIG_FLOW_CTRL_EN 0x0419 /* bool */
|
||||
#define CSR_PSKEY_UART_DFU_CONFIG_RTS_AUTO_EN 0x041a /* bool */
|
||||
#define CSR_PSKEY_UART_DFU_CONFIG_RTS 0x041b /* bool */
|
||||
#define CSR_PSKEY_UART_DFU_CONFIG_TX_ZERO_EN 0x041c /* bool */
|
||||
#define CSR_PSKEY_UART_DFU_CONFIG_NON_BCSP_EN 0x041d /* bool */
|
||||
#define CSR_PSKEY_UART_DFU_CONFIG_RX_RATE_DELAY 0x041e /* uint16 */
|
||||
#define CSR_PSKEY_AMUX_AIO0 0x041f /* ana_amux_sel */
|
||||
#define CSR_PSKEY_AMUX_AIO1 0x0420 /* ana_amux_sel */
|
||||
#define CSR_PSKEY_AMUX_AIO2 0x0421 /* ana_amux_sel */
|
||||
#define CSR_PSKEY_AMUX_AIO3 0x0422 /* ana_amux_sel */
|
||||
#define CSR_PSKEY_LOCAL_NAME_SIMPLIFIED 0x0423 /* local_name_complete */
|
||||
#define CSR_PSKEY_EXTENDED_STUB 0x2001 /* uint16 */
|
||||
|
||||
char *csr_builddeftostr(uint16_t def);
|
||||
char *csr_buildidtostr(uint16_t id);
|
||||
char *csr_chipvertostr(uint16_t ver, uint16_t rev);
|
||||
char *csr_pskeytostr(uint16_t pskey);
|
||||
char *csr_pskeytoval(uint16_t pskey);
|
||||
|
||||
int csr_open_hci(char *device);
|
||||
int csr_read_hci(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
int csr_write_hci(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
void csr_close_hci(void);
|
||||
|
||||
int csr_open_usb(char *device);
|
||||
int csr_read_usb(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
int csr_write_usb(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
void csr_close_usb(void);
|
||||
|
||||
int csr_open_bcsp(char *device, speed_t bcsp_rate);
|
||||
int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
int csr_write_bcsp(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
void csr_close_bcsp(void);
|
||||
|
||||
int csr_open_h4(char *device);
|
||||
int csr_read_h4(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
int csr_write_h4(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
void csr_close_h4(void);
|
||||
|
||||
int csr_open_3wire(char *device);
|
||||
int csr_read_3wire(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
int csr_write_3wire(uint16_t varid, uint8_t *value, uint16_t length);
|
||||
void csr_close_3wire(void);
|
||||
|
||||
int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid);
|
||||
int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length);
|
||||
int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length);
|
||||
int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value);
|
||||
int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value);
|
||||
int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length);
|
||||
int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length);
|
||||
int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t *value);
|
||||
int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t value);
|
||||
int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t *value);
|
||||
int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t value);
|
||||
|
||||
int psr_put(uint16_t pskey, uint8_t *value, uint16_t size);
|
||||
int psr_get(uint16_t *pskey, uint8_t *value, uint16_t *size);
|
||||
int psr_read(const char *filename);
|
||||
int psr_print(void);
|
||||
1513
external/cache/sources/hcitools/hciattach.c
vendored
Normal file
1513
external/cache/sources/hcitools/hciattach.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
96
external/cache/sources/hcitools/hciattach.h
vendored
Normal file
96
external/cache/sources/hcitools/hciattach.h
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2003-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#include <bluetooth.h>
|
||||
|
||||
#ifndef N_HCI
|
||||
#define N_HCI 15
|
||||
#endif
|
||||
|
||||
#define HCIUARTSETPROTO _IOW('U', 200, int)
|
||||
#define HCIUARTGETPROTO _IOR('U', 201, int)
|
||||
#define HCIUARTGETDEVICE _IOR('U', 202, int)
|
||||
#define HCIUARTSETFLAGS _IOW('U', 203, int)
|
||||
#define HCIUARTGETFLAGS _IOR('U', 204, int)
|
||||
|
||||
#define HCI_UART_H4 0
|
||||
#define HCI_UART_BCSP 1
|
||||
#define HCI_UART_3WIRE 2
|
||||
#define HCI_UART_H4DS 3
|
||||
#define HCI_UART_LL 4
|
||||
#define HCI_UART_ATH3K 5
|
||||
|
||||
#define HCI_UART_RAW_DEVICE 0
|
||||
#define HCI_UART_RESET_ON_INIT 1
|
||||
#define HCI_UART_CREATE_AMP 2
|
||||
|
||||
struct uart_t {
|
||||
char *type;
|
||||
int m_id;
|
||||
int p_id;
|
||||
int proto;
|
||||
int init_speed;
|
||||
int speed;
|
||||
int flags;
|
||||
int pm;
|
||||
char *bdaddr;
|
||||
int (*init) (int fd, struct uart_t *u, struct termios *ti);
|
||||
int (*post) (int fd, struct uart_t *u, struct termios *ti);
|
||||
};
|
||||
|
||||
#define FLOW_CTL 0x0001
|
||||
#define AMP_DEV 0x0002
|
||||
#define ENABLE_PM 1
|
||||
#define DISABLE_PM 0
|
||||
|
||||
int read_hci_event(int fd, unsigned char *buf, int size);
|
||||
int set_speed(int fd, struct termios *ti, int speed);
|
||||
int uart_speed(int speed);
|
||||
|
||||
int texas_init(int fd, int *speed, struct termios *ti);
|
||||
int texas_post(int fd, struct termios *ti);
|
||||
int texasalt_init(int fd, int speed, struct termios *ti);
|
||||
int stlc2500_init(int fd, bdaddr_t *bdaddr);
|
||||
int bgb2xx_init(int dd, bdaddr_t *bdaddr);
|
||||
int ath3k_init(int fd, int speed, int init_speed, char *bdaddr,
|
||||
struct termios *ti);
|
||||
int ath3k_post(int fd, int pm);
|
||||
int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr);
|
||||
int intel_init(int fd, int init_speed, int *speed, struct termios *ti);
|
||||
int bcm43xx_init(int fd, int speed, struct termios *ti, const char *bdaddr);
|
||||
|
||||
//Realtek_add_start
|
||||
//add realtek init and post process for realtek Bluetooth chip
|
||||
int rtk_init(int fd, int proto, int speed, struct termios *ti);
|
||||
int rtk_post(int fd, int proto, struct termios *ti);
|
||||
//Realtek_add_end
|
||||
|
||||
// add xradio init and post process for xradio Bluetooth chip (xr829)
|
||||
int xr_init(int fd, struct uart_t *u, struct termios *ti);
|
||||
int xr_post(int fd, struct uart_t *u, struct termios *ti);
|
||||
|
||||
// add sprd init and post process for sprd Bluetooth chip (UWE5622)
|
||||
int sprd_config_init(int fd, struct uart_t *u, struct termios *ti);
|
||||
int sprd_config_post(int fd, struct uart_t *u, struct termios *ti);
|
||||
1044
external/cache/sources/hcitools/hciattach_ath3k.c
vendored
Normal file
1044
external/cache/sources/hcitools/hciattach_ath3k.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
378
external/cache/sources/hcitools/hciattach_bcm43xx.c
vendored
Normal file
378
external/cache/sources/hcitools/hciattach_bcm43xx.c
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2014 Intel Corporation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
|
||||
#include "hciattach.h"
|
||||
|
||||
#ifndef FIRMWARE_DIR
|
||||
#define FIRMWARE_DIR "/etc/firmware"
|
||||
#endif
|
||||
|
||||
#define FW_EXT ".hcd"
|
||||
|
||||
#define BCM43XX_CLOCK_48 1
|
||||
#define BCM43XX_CLOCK_24 2
|
||||
|
||||
#define CMD_SUCCESS 0x00
|
||||
|
||||
#define CC_MIN_SIZE 7
|
||||
|
||||
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
|
||||
|
||||
static int bcm43xx_read_local_name(int fd, char *name, size_t size)
|
||||
{
|
||||
unsigned char cmd[] = { HCI_COMMAND_PKT, 0x14, 0x0C, 0x00 };
|
||||
unsigned char *resp;
|
||||
unsigned int name_len;
|
||||
|
||||
resp = malloc(size + CC_MIN_SIZE);
|
||||
if (!resp)
|
||||
return -1;
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (write(fd, cmd, sizeof(cmd)) != sizeof(cmd)) {
|
||||
fprintf(stderr, "Failed to write read local name command\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (read_hci_event(fd, resp, size) < CC_MIN_SIZE) {
|
||||
fprintf(stderr, "Failed to read local name, invalid HCI event\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (resp[4] != cmd[1] || resp[5] != cmd[2] || resp[6] != CMD_SUCCESS) {
|
||||
fprintf(stderr, "Failed to read local name, command failure\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
name_len = resp[2] - 1;
|
||||
|
||||
strncpy(name, (char *) &resp[7], MIN(name_len, size));
|
||||
name[size - 1] = 0;
|
||||
|
||||
free(resp);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
free(resp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int bcm43xx_reset(int fd)
|
||||
{
|
||||
unsigned char cmd[] = { HCI_COMMAND_PKT, 0x03, 0x0C, 0x00 };
|
||||
unsigned char resp[CC_MIN_SIZE];
|
||||
|
||||
if (write(fd, cmd, sizeof(cmd)) != sizeof(cmd)) {
|
||||
fprintf(stderr, "Failed to write reset command\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read_hci_event(fd, resp, sizeof(resp)) < CC_MIN_SIZE) {
|
||||
fprintf(stderr, "Failed to reset chip, invalid HCI event\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (resp[4] != cmd[1] || resp[5] != cmd[2] || resp[6] != CMD_SUCCESS) {
|
||||
fprintf(stderr, "Failed to reset chip, command failure\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm43xx_set_bdaddr(int fd, const char *bdaddr)
|
||||
{
|
||||
unsigned char cmd[] =
|
||||
{ HCI_COMMAND_PKT, 0x01, 0xfc, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 };
|
||||
unsigned char resp[CC_MIN_SIZE];
|
||||
|
||||
printf("Set BDADDR UART: %s\n", bdaddr);
|
||||
|
||||
if (str2ba(bdaddr, (bdaddr_t *) (&cmd[4])) < 0) {
|
||||
fprintf(stderr, "Incorrect bdaddr\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (write(fd, cmd, sizeof(cmd)) != sizeof(cmd)) {
|
||||
fprintf(stderr, "Failed to write set bdaddr command\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read_hci_event(fd, resp, sizeof(resp)) < CC_MIN_SIZE) {
|
||||
fprintf(stderr, "Failed to set bdaddr, invalid HCI event\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (resp[4] != cmd[1] || resp[5] != cmd[2] || resp[6] != CMD_SUCCESS) {
|
||||
fprintf(stderr, "Failed to set bdaddr, command failure\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm43xx_set_speed(int fd, uint32_t speed)
|
||||
{
|
||||
unsigned char cmd[] =
|
||||
{ HCI_COMMAND_PKT, 0x18, 0xfc, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 };
|
||||
unsigned char resp[CC_MIN_SIZE];
|
||||
|
||||
printf("Set Controller UART speed to %d bit/s\n", speed);
|
||||
|
||||
cmd[6] = (uint8_t) (speed);
|
||||
cmd[7] = (uint8_t) (speed >> 8);
|
||||
cmd[8] = (uint8_t) (speed >> 16);
|
||||
cmd[9] = (uint8_t) (speed >> 24);
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (write(fd, cmd, sizeof(cmd)) != sizeof(cmd)) {
|
||||
fprintf(stderr, "Failed to write update baudrate command\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read_hci_event(fd, resp, sizeof(resp)) < CC_MIN_SIZE) {
|
||||
fprintf(stderr, "Failed to update baudrate, invalid HCI event\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (resp[4] != cmd[1] || resp[5] != cmd[2] || resp[6] != CMD_SUCCESS) {
|
||||
fprintf(stderr, "Failed to update baudrate, command failure\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm43xx_set_clock(int fd, unsigned char clock)
|
||||
{
|
||||
unsigned char cmd[] = { HCI_COMMAND_PKT, 0x45, 0xfc, 0x01, 0x00 };
|
||||
unsigned char resp[CC_MIN_SIZE];
|
||||
|
||||
printf("Set Controller clock (%d)\n", clock);
|
||||
|
||||
cmd[4] = clock;
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (write(fd, cmd, sizeof(cmd)) != sizeof(cmd)) {
|
||||
fprintf(stderr, "Failed to write update clock command\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read_hci_event(fd, resp, sizeof(resp)) < CC_MIN_SIZE) {
|
||||
fprintf(stderr, "Failed to update clock, invalid HCI event\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (resp[4] != cmd[1] || resp[5] != cmd[2] || resp[6] != CMD_SUCCESS) {
|
||||
fprintf(stderr, "Failed to update clock, command failure\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm43xx_load_firmware(int fd, const char *fw)
|
||||
{
|
||||
unsigned char cmd[] = { HCI_COMMAND_PKT, 0x2e, 0xfc, 0x00 };
|
||||
struct timespec tm_mode = { 0, 50000 };
|
||||
struct timespec tm_ready = { 0, 2000000 };
|
||||
unsigned char resp[CC_MIN_SIZE];
|
||||
unsigned char tx_buf[1024];
|
||||
int len, fd_fw, n;
|
||||
|
||||
printf("Flash firmware %s\n", fw);
|
||||
|
||||
fd_fw = open(fw, O_RDONLY);
|
||||
if (fd_fw < 0) {
|
||||
fprintf(stderr, "Unable to open firmware (%s)\n", fw);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (write(fd, cmd, sizeof(cmd)) != sizeof(cmd)) {
|
||||
fprintf(stderr, "Failed to write download mode command\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (read_hci_event(fd, resp, sizeof(resp)) < CC_MIN_SIZE) {
|
||||
fprintf(stderr, "Failed to load firmware, invalid HCI event\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (resp[4] != cmd[1] || resp[5] != cmd[2] || resp[6] != CMD_SUCCESS) {
|
||||
fprintf(stderr, "Failed to load firmware, command failure\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Wait 50ms to let the firmware placed in download mode */
|
||||
nanosleep(&tm_mode, NULL);
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
while ((n = read(fd_fw, &tx_buf[1], 3))) {
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Failed to read firmware\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
tx_buf[0] = HCI_COMMAND_PKT;
|
||||
|
||||
len = tx_buf[3];
|
||||
|
||||
if (read(fd_fw, &tx_buf[4], len) < 0) {
|
||||
fprintf(stderr, "Failed to read firmware\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (write(fd, tx_buf, len + 4) != (len + 4)) {
|
||||
fprintf(stderr, "Failed to write firmware\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
read_hci_event(fd, resp, sizeof(resp));
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
}
|
||||
|
||||
/* Wait for firmware ready */
|
||||
nanosleep(&tm_ready, NULL);
|
||||
|
||||
close(fd_fw);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
close(fd_fw);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int bcm43xx_locate_patch(const char *dir_name,
|
||||
const char *chip_name, char *location)
|
||||
{
|
||||
DIR *dir;
|
||||
int ret = -1;
|
||||
|
||||
dir = opendir(dir_name);
|
||||
if (!dir) {
|
||||
fprintf(stderr, "Cannot open directory '%s': %s\n",
|
||||
dir_name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Recursively look for a BCM43XX*.hcd */
|
||||
while (1) {
|
||||
struct dirent *entry = readdir(dir);
|
||||
if (!entry)
|
||||
break;
|
||||
|
||||
if (entry->d_type & DT_DIR) {
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (!strcmp(entry->d_name, "..") || !strcmp(entry->d_name, "."))
|
||||
continue;
|
||||
|
||||
snprintf(path, PATH_MAX, "%s/%s", dir_name, entry->d_name);
|
||||
|
||||
ret = bcm43xx_locate_patch(path, chip_name, location);
|
||||
if (!ret)
|
||||
break;
|
||||
} else if (!strncmp(chip_name, entry->d_name, strlen(chip_name))) {
|
||||
unsigned int name_len = strlen(entry->d_name);
|
||||
size_t curs_ext = name_len - sizeof(FW_EXT) + 1;
|
||||
|
||||
if (curs_ext > name_len)
|
||||
break;
|
||||
|
||||
if (strncmp(FW_EXT, &entry->d_name[curs_ext], sizeof(FW_EXT)))
|
||||
break;
|
||||
|
||||
/* found */
|
||||
snprintf(location, PATH_MAX, "%s/%s", dir_name, entry->d_name);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bcm43xx_init(int fd, int speed, struct termios *ti, const char *bdaddr)
|
||||
{
|
||||
char chip_name[20];
|
||||
char fw_path[PATH_MAX];
|
||||
|
||||
printf("bcm43xx_init\n");
|
||||
|
||||
if (bcm43xx_reset(fd))
|
||||
return -1;
|
||||
|
||||
if (bcm43xx_read_local_name(fd, chip_name, sizeof(chip_name)))
|
||||
return -1;
|
||||
|
||||
if (bcm43xx_locate_patch(FIRMWARE_DIR, chip_name, fw_path)) {
|
||||
fprintf(stderr, "Patch not found, continue anyway\n");
|
||||
} else {
|
||||
if (bcm43xx_load_firmware(fd, fw_path))
|
||||
return -1;
|
||||
|
||||
if (bcm43xx_reset(fd))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bdaddr)
|
||||
bcm43xx_set_bdaddr(fd, bdaddr);
|
||||
|
||||
if (speed > 3000000 && bcm43xx_set_clock(fd, BCM43XX_CLOCK_48))
|
||||
return -1;
|
||||
|
||||
if (bcm43xx_set_speed(fd, speed))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
595
external/cache/sources/hcitools/hciattach_intel.c
vendored
Normal file
595
external/cache/sources/hcitools/hciattach_intel.c
vendored
Normal file
@@ -0,0 +1,595 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2012 Intel Corporation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
|
||||
#include "hciattach.h"
|
||||
|
||||
#ifdef INTEL_DEBUG
|
||||
#define DBGPRINT(fmt, args...) printf("DBG: " fmt "\n", ## args)
|
||||
#define PRINT_PACKET(buf, len, msg) { \
|
||||
int i; \
|
||||
printf("%s\n", msg); \
|
||||
for (i = 0; i < len; i++) \
|
||||
printf("%02X ", buf[i]); \
|
||||
printf("\n"); \
|
||||
}
|
||||
#else
|
||||
#define DBGPRINT(fmt, args...)
|
||||
#define PRINT_PACKET(buf, len, msg)
|
||||
#endif
|
||||
|
||||
#define PATCH_SEQ_EXT ".bseq"
|
||||
#define PATCH_FILE_PATH "/lib/firmware/intel/"
|
||||
#define PATCH_MAX_LEN 260
|
||||
#define PATCH_TYPE_CMD 1
|
||||
#define PATCH_TYPE_EVT 2
|
||||
|
||||
#define INTEL_VER_PARAM_LEN 9
|
||||
#define INTEL_MFG_PARAM_LEN 2
|
||||
|
||||
/**
|
||||
* A data structure for a patch entry.
|
||||
*/
|
||||
struct patch_entry {
|
||||
int type;
|
||||
int len;
|
||||
unsigned char data[PATCH_MAX_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* A structure for patch context
|
||||
*/
|
||||
struct patch_ctx {
|
||||
int dev;
|
||||
int fd;
|
||||
int patch_error;
|
||||
int reset_enable_patch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Send HCI command to the controller
|
||||
*/
|
||||
static int intel_write_cmd(int dev, unsigned char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
PRINT_PACKET(buf, len, "<----- SEND CMD: ");
|
||||
|
||||
ret = write(dev, buf, len);
|
||||
if (ret < 0)
|
||||
return -errno;
|
||||
|
||||
if (ret != len)
|
||||
return -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the event from the controller
|
||||
*/
|
||||
static int intel_read_evt(int dev, unsigned char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = read_hci_event(dev, buf, len);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
PRINT_PACKET(buf, ret, "-----> READ EVT: ");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate HCI events
|
||||
*/
|
||||
static int validate_events(struct patch_entry *event,
|
||||
struct patch_entry *entry)
|
||||
{
|
||||
if (event == NULL || entry == NULL) {
|
||||
DBGPRINT("invalid patch entry parameters");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (event->len != entry->len) {
|
||||
DBGPRINT("lengths are mismatched:[%d|%d]",
|
||||
event->len, entry->len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(event->data, entry->data, event->len)) {
|
||||
DBGPRINT("data is mismatched");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the next patch entry one line at a time
|
||||
*/
|
||||
static int get_next_patch_entry(int fd, struct patch_entry *entry)
|
||||
{
|
||||
int size;
|
||||
char rb;
|
||||
|
||||
if (read(fd, &rb, 1) <= 0)
|
||||
return 0;
|
||||
|
||||
entry->type = rb;
|
||||
|
||||
switch (entry->type) {
|
||||
case PATCH_TYPE_CMD:
|
||||
entry->data[0] = HCI_COMMAND_PKT;
|
||||
|
||||
if (read(fd, &entry->data[1], 3) < 0)
|
||||
return -1;
|
||||
|
||||
size = (int)entry->data[3];
|
||||
|
||||
if (read(fd, &entry->data[4], size) < 0)
|
||||
return -1;
|
||||
|
||||
entry->len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE + size;
|
||||
|
||||
break;
|
||||
|
||||
case PATCH_TYPE_EVT:
|
||||
entry->data[0] = HCI_EVENT_PKT;
|
||||
|
||||
if (read(fd, &entry->data[1], 2) < 0)
|
||||
return -1;
|
||||
|
||||
size = (int)entry->data[2];
|
||||
|
||||
if (read(fd, &entry->data[3], size) < 0)
|
||||
return -1;
|
||||
|
||||
entry->len = HCI_TYPE_LEN + HCI_EVENT_HDR_SIZE + size;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "invalid patch entry(%d)\n", entry->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return entry->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download the patch set to the controller and verify the event
|
||||
*/
|
||||
static int intel_download_patch(struct patch_ctx *ctx)
|
||||
{
|
||||
int ret;
|
||||
struct patch_entry entry;
|
||||
struct patch_entry event;
|
||||
|
||||
DBGPRINT("start patch downloading");
|
||||
|
||||
do {
|
||||
ret = get_next_patch_entry(ctx->fd, &entry);
|
||||
if (ret <= 0) {
|
||||
ctx->patch_error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (entry.type) {
|
||||
case PATCH_TYPE_CMD:
|
||||
ret = intel_write_cmd(ctx->dev,
|
||||
entry.data,
|
||||
entry.len);
|
||||
if (ret <= 0) {
|
||||
fprintf(stderr, "failed to send cmd(%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case PATCH_TYPE_EVT:
|
||||
ret = intel_read_evt(ctx->dev, event.data,
|
||||
sizeof(event.data));
|
||||
if (ret <= 0) {
|
||||
fprintf(stderr, "failed to read evt(%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
event.len = ret;
|
||||
|
||||
if (validate_events(&event, &entry) < 0) {
|
||||
DBGPRINT("events are mismatched");
|
||||
ctx->patch_error = 1;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "unknown patch type(%d)\n",
|
||||
entry.type);
|
||||
return -1;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int open_patch_file(struct patch_ctx *ctx, char *fw_ver)
|
||||
{
|
||||
char patch_file[PATH_MAX];
|
||||
|
||||
snprintf(patch_file, PATH_MAX, "%s%s%s", PATCH_FILE_PATH,
|
||||
fw_ver, PATCH_SEQ_EXT);
|
||||
DBGPRINT("PATCH_FILE: %s", patch_file);
|
||||
|
||||
ctx->fd = open(patch_file, O_RDONLY);
|
||||
if (ctx->fd < 0) {
|
||||
DBGPRINT("cannot open patch file. go to post patch");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the controller for patching.
|
||||
*/
|
||||
static int pre_patch(struct patch_ctx *ctx)
|
||||
{
|
||||
int ret, i;
|
||||
struct patch_entry entry;
|
||||
char fw_ver[INTEL_VER_PARAM_LEN * 2];
|
||||
|
||||
DBGPRINT("start pre_patch");
|
||||
|
||||
entry.data[0] = HCI_COMMAND_PKT;
|
||||
entry.data[1] = 0x11;
|
||||
entry.data[2] = 0xFC;
|
||||
entry.data[3] = 0x02;
|
||||
entry.data[4] = 0x01;
|
||||
entry.data[5] = 0x00;
|
||||
entry.len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE + INTEL_MFG_PARAM_LEN;
|
||||
|
||||
ret = intel_write_cmd(ctx->dev, entry.data, entry.len);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to send cmd(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = intel_read_evt(ctx->dev, entry.data, sizeof(entry.data));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to read evt(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
entry.len = ret;
|
||||
|
||||
if (entry.data[6] != 0x00) {
|
||||
DBGPRINT("command failed. status=%02x", entry.data[6]);
|
||||
ctx->patch_error = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry.data[0] = HCI_COMMAND_PKT;
|
||||
entry.data[1] = 0x05;
|
||||
entry.data[2] = 0xFC;
|
||||
entry.data[3] = 0x00;
|
||||
entry.len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE;
|
||||
|
||||
ret = intel_write_cmd(ctx->dev, entry.data, entry.len);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to send cmd(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = intel_read_evt(ctx->dev, entry.data, sizeof(entry.data));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to read evt(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
entry.len = ret;
|
||||
|
||||
if (entry.data[6] != 0x00) {
|
||||
DBGPRINT("command failed. status=%02x", entry.data[6]);
|
||||
ctx->patch_error = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < INTEL_VER_PARAM_LEN; i++)
|
||||
sprintf(&fw_ver[i*2], "%02x", entry.data[7+i]);
|
||||
|
||||
if (open_patch_file(ctx, fw_ver) < 0) {
|
||||
ctx->patch_error = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* check the event is startup event
|
||||
*/
|
||||
static int is_startup_evt(unsigned char *buf)
|
||||
{
|
||||
if (buf[1] == 0xFF && buf[2] == 0x01 && buf[3] == 0x00)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the patch process and reset the controller
|
||||
*/
|
||||
static int post_patch(struct patch_ctx *ctx)
|
||||
{
|
||||
int ret;
|
||||
struct patch_entry entry;
|
||||
|
||||
DBGPRINT("start post_patch");
|
||||
|
||||
entry.data[0] = HCI_COMMAND_PKT;
|
||||
entry.data[1] = 0x11;
|
||||
entry.data[2] = 0xFC;
|
||||
entry.data[3] = 0x02;
|
||||
entry.data[4] = 0x00;
|
||||
if (ctx->reset_enable_patch)
|
||||
entry.data[5] = 0x02;
|
||||
else
|
||||
entry.data[5] = 0x01;
|
||||
|
||||
entry.len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE + INTEL_MFG_PARAM_LEN;
|
||||
|
||||
ret = intel_write_cmd(ctx->dev, entry.data, entry.len);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to send cmd(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = intel_read_evt(ctx->dev, entry.data, sizeof(entry.data));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to read evt(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
entry.len = ret;
|
||||
|
||||
if (entry.data[6] != 0x00) {
|
||||
fprintf(stderr, "cmd failed. st=%02x\n", entry.data[6]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = intel_read_evt(ctx->dev, entry.data,
|
||||
sizeof(entry.data));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to read cmd(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
entry.len = ret;
|
||||
} while (!is_startup_evt(entry.data));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main routine that handles the device patching process.
|
||||
*/
|
||||
static int intel_patch_device(struct patch_ctx *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pre_patch(ctx);
|
||||
if (ret < 0) {
|
||||
if (!ctx->patch_error) {
|
||||
fprintf(stderr, "I/O error: pre_patch failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
DBGPRINT("patch failed. proceed to post patch");
|
||||
goto post_patch;
|
||||
}
|
||||
|
||||
ret = intel_download_patch(ctx);
|
||||
if (ret < 0) {
|
||||
if (!ctx->patch_error) {
|
||||
fprintf(stderr, "I/O error: download_patch failed\n");
|
||||
close(ctx->fd);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
DBGPRINT("patch done");
|
||||
ctx->reset_enable_patch = 1;
|
||||
}
|
||||
|
||||
close(ctx->fd);
|
||||
|
||||
post_patch:
|
||||
ret = post_patch(ctx);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "post_patch failed(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_rts(int dev, int rtsval)
|
||||
{
|
||||
int arg;
|
||||
|
||||
if (ioctl(dev, TIOCMGET, &arg) < 0) {
|
||||
perror("cannot get TIOCMGET");
|
||||
return -errno;
|
||||
}
|
||||
if (rtsval)
|
||||
arg |= TIOCM_RTS;
|
||||
else
|
||||
arg &= ~TIOCM_RTS;
|
||||
|
||||
if (ioctl(dev, TIOCMSET, &arg) == -1) {
|
||||
perror("cannot set TIOCMGET");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned char get_intel_speed(int speed)
|
||||
{
|
||||
switch (speed) {
|
||||
case 9600:
|
||||
return 0x00;
|
||||
case 19200:
|
||||
return 0x01;
|
||||
case 38400:
|
||||
return 0x02;
|
||||
case 57600:
|
||||
return 0x03;
|
||||
case 115200:
|
||||
return 0x04;
|
||||
case 230400:
|
||||
return 0x05;
|
||||
case 460800:
|
||||
return 0x06;
|
||||
case 921600:
|
||||
return 0x07;
|
||||
case 1843200:
|
||||
return 0x08;
|
||||
case 3250000:
|
||||
return 0x09;
|
||||
case 2000000:
|
||||
return 0x0A;
|
||||
case 3000000:
|
||||
return 0x0B;
|
||||
default:
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if it failed to change to new baudrate, it will rollback
|
||||
* to initial baudrate
|
||||
*/
|
||||
static int change_baudrate(int dev, int init_speed, int *speed,
|
||||
struct termios *ti)
|
||||
{
|
||||
int ret;
|
||||
unsigned char br;
|
||||
unsigned char cmd[5];
|
||||
unsigned char evt[7];
|
||||
|
||||
DBGPRINT("start baudrate change");
|
||||
|
||||
ret = set_rts(dev, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to clear RTS\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmd[0] = HCI_COMMAND_PKT;
|
||||
cmd[1] = 0x06;
|
||||
cmd[2] = 0xFC;
|
||||
cmd[3] = 0x01;
|
||||
|
||||
br = get_intel_speed(*speed);
|
||||
if (br == 0xFF) {
|
||||
fprintf(stderr, "speed %d is not supported\n", *speed);
|
||||
return -1;
|
||||
}
|
||||
cmd[4] = br;
|
||||
|
||||
ret = intel_write_cmd(dev, cmd, sizeof(cmd));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to send cmd(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* wait for buffer to be consumed by the controller
|
||||
*/
|
||||
usleep(300000);
|
||||
|
||||
if (set_speed(dev, ti, *speed) < 0) {
|
||||
fprintf(stderr, "can't set to new baud rate\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = set_rts(dev, 1);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to set RTS\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = intel_read_evt(dev, evt, sizeof(evt));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to read evt(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (evt[4] != 0x00) {
|
||||
fprintf(stderr,
|
||||
"failed to change speed. use default speed %d\n",
|
||||
init_speed);
|
||||
*speed = init_speed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* An entry point for Intel specific initialization
|
||||
*/
|
||||
int intel_init(int dev, int init_speed, int *speed, struct termios *ti)
|
||||
{
|
||||
int ret = 0;
|
||||
struct patch_ctx ctx;
|
||||
|
||||
if (change_baudrate(dev, init_speed, speed, ti) < 0)
|
||||
return -1;
|
||||
|
||||
ctx.dev = dev;
|
||||
ctx.patch_error = 0;
|
||||
ctx.reset_enable_patch = 0;
|
||||
|
||||
ret = intel_patch_device(&ctx);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "failed to initialize the device");
|
||||
|
||||
return ret;
|
||||
}
|
||||
273
external/cache/sources/hcitools/hciattach_qualcomm.c
vendored
Normal file
273
external/cache/sources/hcitools/hciattach_qualcomm.c
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
|
||||
#include "hciattach.h"
|
||||
|
||||
#define FAILIF(x, args...) do { \
|
||||
if (x) { \
|
||||
fprintf(stderr, ##args); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef struct {
|
||||
uint8_t uart_prefix;
|
||||
hci_event_hdr hci_hdr;
|
||||
evt_cmd_complete cmd_complete;
|
||||
uint8_t status;
|
||||
uint8_t data[16];
|
||||
} __attribute__((packed)) command_complete_t;
|
||||
|
||||
static int read_command_complete(int fd,
|
||||
unsigned short opcode,
|
||||
unsigned char len)
|
||||
{
|
||||
command_complete_t resp;
|
||||
unsigned char vsevent[512];
|
||||
int n;
|
||||
|
||||
/* Read reply. */
|
||||
n = read_hci_event(fd, vsevent, sizeof(vsevent));
|
||||
FAILIF(n < 0, "Failed to read response");
|
||||
|
||||
FAILIF(vsevent[1] != 0xFF, "Failed to read response");
|
||||
|
||||
n = read_hci_event(fd, (unsigned char *)&resp, sizeof(resp));
|
||||
FAILIF(n < 0, "Failed to read response");
|
||||
|
||||
/* event must be event-complete */
|
||||
FAILIF(resp.hci_hdr.evt != EVT_CMD_COMPLETE,
|
||||
"Error in response: not a cmd-complete event, "
|
||||
"but 0x%02x!\n", resp.hci_hdr.evt);
|
||||
|
||||
FAILIF(resp.hci_hdr.plen < 4, /* plen >= 4 for EVT_CMD_COMPLETE */
|
||||
"Error in response: plen is not >= 4, but 0x%02x!\n",
|
||||
resp.hci_hdr.plen);
|
||||
|
||||
/* cmd-complete event: opcode */
|
||||
FAILIF(resp.cmd_complete.opcode != 0,
|
||||
"Error in response: opcode is 0x%04x, not 0!",
|
||||
resp.cmd_complete.opcode);
|
||||
|
||||
return resp.status == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
static int qualcomm_load_firmware(int fd, const char *firmware, const char *bdaddr_s)
|
||||
{
|
||||
|
||||
int fw = open(firmware, O_RDONLY);
|
||||
|
||||
fprintf(stdout, "Opening firmware file: %s\n", firmware);
|
||||
|
||||
FAILIF(fw < 0,
|
||||
"Could not open firmware file %s: %s (%d).\n",
|
||||
firmware, strerror(errno), errno);
|
||||
|
||||
fprintf(stdout, "Uploading firmware...\n");
|
||||
do {
|
||||
/* Read each command and wait for a response. */
|
||||
unsigned char data[1024];
|
||||
unsigned char cmdp[1 + sizeof(hci_command_hdr)];
|
||||
hci_command_hdr *cmd = (hci_command_hdr *) (cmdp + 1);
|
||||
int nr;
|
||||
|
||||
nr = read(fw, cmdp, sizeof(cmdp));
|
||||
if (!nr)
|
||||
break;
|
||||
|
||||
FAILIF(nr != sizeof(cmdp),
|
||||
"Could not read H4 + HCI header!\n");
|
||||
FAILIF(*cmdp != HCI_COMMAND_PKT,
|
||||
"Command is not an H4 command packet!\n");
|
||||
|
||||
FAILIF(read(fw, data, cmd->plen) != cmd->plen,
|
||||
"Could not read %d bytes of data \
|
||||
for command with opcode %04x!\n",
|
||||
cmd->plen, cmd->opcode);
|
||||
|
||||
if ((data[0] == 1) && (data[1] == 2) && (data[2] == 6)) {
|
||||
bdaddr_t bdaddr;
|
||||
if (bdaddr_s != NULL) {
|
||||
str2ba(bdaddr_s, &bdaddr);
|
||||
memcpy(&data[3], &bdaddr, sizeof(bdaddr_t));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int nw;
|
||||
struct iovec iov_cmd[2];
|
||||
iov_cmd[0].iov_base = cmdp;
|
||||
iov_cmd[0].iov_len = sizeof(cmdp);
|
||||
iov_cmd[1].iov_base = data;
|
||||
iov_cmd[1].iov_len = cmd->plen;
|
||||
nw = writev(fd, iov_cmd, 2);
|
||||
FAILIF(nw != (int) sizeof(cmdp) + cmd->plen,
|
||||
"Could not send entire command \
|
||||
(sent only %d bytes)!\n",
|
||||
nw);
|
||||
}
|
||||
|
||||
/* Wait for response */
|
||||
if (read_command_complete(fd, cmd->opcode, cmd->plen) < 0)
|
||||
return -1;
|
||||
} while (1);
|
||||
fprintf(stdout, "Firmware upload successful.\n");
|
||||
|
||||
close(fw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr)
|
||||
{
|
||||
struct timespec tm = {0, 50000};
|
||||
char cmd[5];
|
||||
unsigned char resp[100]; /* Response */
|
||||
char fw[100];
|
||||
int n;
|
||||
|
||||
memset(resp, 0, 100);
|
||||
|
||||
/* Get Manufacturer and LMP version */
|
||||
cmd[0] = HCI_COMMAND_PKT;
|
||||
cmd[1] = 0x01;
|
||||
cmd[2] = 0x10;
|
||||
cmd[3] = 0x00;
|
||||
|
||||
do {
|
||||
n = write(fd, cmd, 4);
|
||||
if (n < 4) {
|
||||
perror("Failed to write init command");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read reply. */
|
||||
if (read_hci_event(fd, resp, 100) < 0) {
|
||||
perror("Failed to read init response");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait for command complete event for our Opcode */
|
||||
} while (resp[4] != cmd[1] && resp[5] != cmd[2]);
|
||||
|
||||
/* Verify manufacturer */
|
||||
if ((resp[11] & 0xFF) != 0x1d)
|
||||
fprintf(stderr,
|
||||
"WARNING : module's manufacturer is not Qualcomm\n");
|
||||
|
||||
/* Print LMP version */
|
||||
fprintf(stderr,
|
||||
"Qualcomm module LMP version : 0x%02x\n", resp[10] & 0xFF);
|
||||
|
||||
/* Print LMP subversion */
|
||||
{
|
||||
unsigned short lmp_subv = resp[13] | (resp[14] << 8);
|
||||
|
||||
fprintf(stderr, "Qualcomm module LMP sub-version : 0x%04x\n",
|
||||
lmp_subv);
|
||||
}
|
||||
|
||||
/* Get SoC type */
|
||||
cmd[0] = HCI_COMMAND_PKT;
|
||||
cmd[1] = 0x00;
|
||||
cmd[2] = 0xFC;
|
||||
cmd[3] = 0x01;
|
||||
cmd[4] = 0x06;
|
||||
|
||||
do {
|
||||
n = write(fd, cmd, 5);
|
||||
if (n < 5) {
|
||||
perror("Failed to write vendor init command");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read reply. */
|
||||
if ((n = read_hci_event(fd, resp, 100)) < 0) {
|
||||
perror("Failed to read vendor init response");
|
||||
return -1;
|
||||
}
|
||||
|
||||
} while (resp[3] != 0 && resp[4] != 2);
|
||||
|
||||
snprintf(fw, sizeof(fw), "/etc/firmware/%c%c%c%c%c%c_%c%c%c%c.bin",
|
||||
resp[18], resp[19], resp[20], resp[21],
|
||||
resp[22], resp[23],
|
||||
resp[32], resp[33], resp[34], resp[35]);
|
||||
|
||||
/* Wait for command complete event for our Opcode */
|
||||
if (read_hci_event(fd, resp, 100) < 0) {
|
||||
perror("Failed to read init response");
|
||||
return -1;
|
||||
}
|
||||
|
||||
qualcomm_load_firmware(fd, fw, bdaddr);
|
||||
|
||||
/* Reset */
|
||||
cmd[0] = HCI_COMMAND_PKT;
|
||||
cmd[1] = 0x03;
|
||||
cmd[2] = 0x0C;
|
||||
cmd[3] = 0x00;
|
||||
|
||||
do {
|
||||
n = write(fd, cmd, 4);
|
||||
if (n < 4) {
|
||||
perror("Failed to write reset command");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read reply. */
|
||||
if ((n = read_hci_event(fd, resp, 100)) < 0) {
|
||||
perror("Failed to read reset response");
|
||||
return -1;
|
||||
}
|
||||
|
||||
} while (resp[4] != cmd[1] && resp[5] != cmd[2]);
|
||||
|
||||
nanosleep(&tm, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
2563
external/cache/sources/hcitools/hciattach_rtk.c
vendored
Normal file
2563
external/cache/sources/hcitools/hciattach_rtk.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
707
external/cache/sources/hcitools/hciattach_sprd.c
vendored
Normal file
707
external/cache/sources/hcitools/hciattach_sprd.c
vendored
Normal file
@@ -0,0 +1,707 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <limits.h>
|
||||
#include "hciattach.h"
|
||||
|
||||
/******************************************************************************
|
||||
** Constants & Macros
|
||||
******************************************************************************/
|
||||
#define LOG_STR "SPRD Bluetooth"
|
||||
#define DBG_ON 1
|
||||
|
||||
#define SPRD_DBG(fmt, arg...) \
|
||||
do { \
|
||||
if (DBG_ON) \
|
||||
fprintf(stderr, "%s: " fmt "\n" , LOG_STR, ##arg); \
|
||||
} while(0)
|
||||
|
||||
#define SPRD_ERR(fmt, arg...) \
|
||||
do { \
|
||||
fprintf(stderr, "%s ERROR: " fmt "\n", LOG_STR, ##arg);\
|
||||
perror(LOG_STR" ERROR reason"); \
|
||||
} while(0)
|
||||
|
||||
#define SPRD_DUMP(buffer, len) \
|
||||
fprintf(stderr, "%s: ", LOG_STR); \
|
||||
do { \
|
||||
for (int i = 0; i < len; i++) { \
|
||||
if (i && !(i % 16)) { \
|
||||
fprintf(stderr, "\n"); \
|
||||
fprintf(stderr, "%s: ", LOG_STR); \
|
||||
} \
|
||||
fprintf(stderr, "%02x ", buffer[i]); \
|
||||
} \
|
||||
fprintf(stderr, "\n"); \
|
||||
} while (0)
|
||||
|
||||
#define CONF_ITEM_TABLE(ITEM, ACTION, BUF, LEN) \
|
||||
{ #ITEM, ACTION, &(BUF.ITEM), LEN, (sizeof(BUF.ITEM) / LEN) }
|
||||
|
||||
#define UINT8_TO_STREAM(p, u8) \
|
||||
{ *(p)++ = (uint8_t)(u8); }
|
||||
|
||||
#define STREAM_TO_UINT8(u8, p) \
|
||||
{ \
|
||||
(u8) = (uint8_t)(*(p)); \
|
||||
(p) += 1; \
|
||||
}
|
||||
|
||||
#define UINT16_TO_STREAM(p, u16) \
|
||||
{ \
|
||||
*(p)++ = (uint8_t)(u16); \
|
||||
*(p)++ = (uint8_t)((u16) >> 8); \
|
||||
}
|
||||
|
||||
#define STREAM_TO_UINT16(u16, p) \
|
||||
{ \
|
||||
(u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \
|
||||
(p) += 2; \
|
||||
}
|
||||
|
||||
#define UINT32_TO_STREAM(p, u32) \
|
||||
{ \
|
||||
*(p)++ = (uint8_t)(u32); \
|
||||
*(p)++ = (uint8_t)((u32) >> 8); \
|
||||
*(p)++ = (uint8_t)((u32) >> 16); \
|
||||
*(p)++ = (uint8_t)((u32) >> 24); \
|
||||
}
|
||||
|
||||
#define CONF_COMMENT '#'
|
||||
#define CONF_DELIMITERS " =\n\r\t"
|
||||
#define CONF_VALUES_DELIMITERS "=\n\r\t#"
|
||||
#define CONF_VALUES_PARTITION " ,=\n\r\t#"
|
||||
#define CONF_MAX_LINE_LEN 255
|
||||
|
||||
#define HCI_PSKEY 0xFCA0
|
||||
#define HCI_VSC_ENABLE_COMMMAND 0xFCA1
|
||||
#define HCI_RF_PARA 0xFCA2
|
||||
|
||||
#define RESPONSE_LENGTH 100
|
||||
#define HCI_CMD_MAX_LEN 258
|
||||
#define HCI_EVT_CMD_CMPL_OPCODE 3
|
||||
#define HCI_PACKET_TYPE_COMMAND 1
|
||||
#define HCI_CMD_PREAMBLE_SIZE 3
|
||||
|
||||
#define FW_NODE_BYTE 6
|
||||
#define FW_DATE_D_BYTE 8
|
||||
#define FW_DATE_M_BYTE 9
|
||||
#define FW_DATE_Y_BYTE 10
|
||||
|
||||
#define BT_CONFIG_PATH "/lib/firmware"
|
||||
#define BT_HC_HDR_SIZE (sizeof(HC_BT_HDR))
|
||||
#define BT_VND_OP_RESULT_SUCCESS 0
|
||||
#define BT_VND_OP_RESULT_FAIL 1
|
||||
#define MSG_STACK_TO_HC_HCI_CMD 0x2000
|
||||
#define START_STOP_CMD_SIZE 3
|
||||
#define DUAL_MODE 0
|
||||
#define DISABLE_BT 0
|
||||
#define ENABLE_BT 1
|
||||
|
||||
typedef void (*hci_cback)(void *);
|
||||
typedef int (conf_action_t)(char *p_conf_name, char *p_conf_value, void *buf, int len, int size);
|
||||
|
||||
typedef struct {
|
||||
uint16_t event;
|
||||
uint16_t len;
|
||||
uint16_t offset;
|
||||
uint16_t layer_specific;
|
||||
uint8_t data[];
|
||||
} HC_BT_HDR;
|
||||
|
||||
typedef struct {
|
||||
uint32_t device_class;
|
||||
uint8_t feature_set[16];
|
||||
uint8_t device_addr[6];
|
||||
uint16_t comp_id;
|
||||
uint8_t g_sys_uart0_communication_supported;
|
||||
uint8_t cp2_log_mode;
|
||||
uint8_t LogLevel;
|
||||
uint8_t g_central_or_perpheral;
|
||||
uint16_t Log_BitMask;
|
||||
uint8_t super_ssp_enable;
|
||||
uint8_t common_rfu_b3;
|
||||
uint32_t common_rfu_w[2];
|
||||
uint32_t le_rfu_w[2];
|
||||
uint32_t lmp_rfu_w[2];
|
||||
uint32_t lc_rfu_w[2];
|
||||
uint16_t g_wbs_nv_117;
|
||||
uint16_t g_wbs_nv_118;
|
||||
uint16_t g_nbv_nv_117;
|
||||
uint16_t g_nbv_nv_118;
|
||||
uint8_t g_sys_sco_transmit_mode;
|
||||
uint8_t audio_rfu_b1;
|
||||
uint8_t audio_rfu_b2;
|
||||
uint8_t audio_rfu_b3;
|
||||
uint32_t audio_rfu_w[2];
|
||||
uint8_t g_sys_sleep_in_standby_supported;
|
||||
uint8_t g_sys_sleep_master_supported;
|
||||
uint8_t g_sys_sleep_slave_supported;
|
||||
uint8_t power_rfu_b1;
|
||||
uint32_t power_rfu_w[2];
|
||||
uint32_t win_ext;
|
||||
uint8_t edr_tx_edr_delay;
|
||||
uint8_t edr_rx_edr_delay;
|
||||
uint8_t tx_delay;
|
||||
uint8_t rx_delay;
|
||||
uint32_t bb_rfu_w[2];
|
||||
uint8_t agc_mode;
|
||||
uint8_t diff_or_eq;
|
||||
uint8_t ramp_mode;
|
||||
uint8_t modem_rfu_b1;
|
||||
uint32_t modem_rfu_w[2];
|
||||
uint32_t BQB_BitMask_1;
|
||||
uint32_t BQB_BitMask_2;
|
||||
uint16_t bt_coex_threshold[8];
|
||||
uint32_t other_rfu_w[6];
|
||||
} pskey_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t g_GainValue_A[6];
|
||||
uint16_t g_ClassicPowerValue_A[10];
|
||||
uint16_t g_LEPowerValue_A[16];
|
||||
uint16_t g_BRChannelpwrvalue_A[8];
|
||||
uint16_t g_EDRChannelpwrvalue_A[8];
|
||||
uint16_t g_LEChannelpwrvalue_A[8];
|
||||
uint16_t g_GainValue_B[6];
|
||||
uint16_t g_ClassicPowerValue_B[10];
|
||||
uint16_t g_LEPowerValue_B[16];
|
||||
uint16_t g_BRChannelpwrvalue_B[8];
|
||||
uint16_t g_EDRChannelpwrvalue_B[8];
|
||||
uint16_t g_LEChannelpwrvalue_B[8];
|
||||
uint16_t LE_fix_powerword;
|
||||
uint8_t Classic_pc_by_channel;
|
||||
uint8_t LE_pc_by_channel;
|
||||
uint8_t RF_switch_mode;
|
||||
uint8_t Data_Capture_Mode;
|
||||
uint8_t Analog_IQ_Debug_Mode;
|
||||
uint8_t RF_common_rfu_b3;
|
||||
uint32_t RF_common_rfu_w[5];
|
||||
} rf_config_t;
|
||||
|
||||
typedef struct {
|
||||
const char *conf_entry;
|
||||
conf_action_t *p_action;
|
||||
void *buf;
|
||||
int len;
|
||||
int size;
|
||||
} conf_entry_t;
|
||||
|
||||
static uint8_t local_bdaddr[6]={0x10, 0x11, 0x12, 0x13, 0x14, 0x15};
|
||||
static pskey_config_t marlin3_pskey;
|
||||
static rf_config_t marlin3_rf_config;
|
||||
static int s_bt_fd = -1;
|
||||
|
||||
static const conf_entry_t marlin3_pksey_table[] = {
|
||||
CONF_ITEM_TABLE(device_class, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(feature_set, 0, marlin3_pskey, 16),
|
||||
CONF_ITEM_TABLE(device_addr, 0, marlin3_pskey, 6),
|
||||
CONF_ITEM_TABLE(comp_id, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(g_sys_uart0_communication_supported, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(cp2_log_mode, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(LogLevel, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(g_central_or_perpheral, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(Log_BitMask, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(super_ssp_enable, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(common_rfu_b3, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(common_rfu_w, 0, marlin3_pskey, 2),
|
||||
CONF_ITEM_TABLE(le_rfu_w, 0, marlin3_pskey, 2),
|
||||
CONF_ITEM_TABLE(lmp_rfu_w, 0, marlin3_pskey, 2),
|
||||
CONF_ITEM_TABLE(lc_rfu_w, 0, marlin3_pskey, 2),
|
||||
CONF_ITEM_TABLE(g_wbs_nv_117, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(g_wbs_nv_118, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(g_nbv_nv_117, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(g_nbv_nv_118, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(g_sys_sco_transmit_mode, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(audio_rfu_b1, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(audio_rfu_b2, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(audio_rfu_b3, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(audio_rfu_w, 0, marlin3_pskey, 2),
|
||||
CONF_ITEM_TABLE(g_sys_sleep_in_standby_supported, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(g_sys_sleep_master_supported, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(g_sys_sleep_slave_supported, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(power_rfu_b1, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(power_rfu_w, 0, marlin3_pskey, 2),
|
||||
CONF_ITEM_TABLE(win_ext, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(edr_tx_edr_delay, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(edr_rx_edr_delay, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(tx_delay, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(rx_delay, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(bb_rfu_w, 0, marlin3_pskey, 2),
|
||||
CONF_ITEM_TABLE(agc_mode, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(diff_or_eq, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(ramp_mode, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(modem_rfu_b1, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(modem_rfu_w, 0, marlin3_pskey, 2),
|
||||
CONF_ITEM_TABLE(BQB_BitMask_1, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(BQB_BitMask_2, 0, marlin3_pskey, 1),
|
||||
CONF_ITEM_TABLE(bt_coex_threshold, 0, marlin3_pskey, 8),
|
||||
CONF_ITEM_TABLE(other_rfu_w, 0, marlin3_pskey, 6),
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static const conf_entry_t marlin3_rf_table[] = {
|
||||
CONF_ITEM_TABLE(g_GainValue_A, 0, marlin3_rf_config, 6),
|
||||
CONF_ITEM_TABLE(g_ClassicPowerValue_A, 0, marlin3_rf_config, 10),
|
||||
CONF_ITEM_TABLE(g_LEPowerValue_A, 0, marlin3_rf_config, 16),
|
||||
CONF_ITEM_TABLE(g_BRChannelpwrvalue_A, 0, marlin3_rf_config, 8),
|
||||
CONF_ITEM_TABLE(g_EDRChannelpwrvalue_A, 0, marlin3_rf_config, 8),
|
||||
CONF_ITEM_TABLE(g_LEChannelpwrvalue_A, 0, marlin3_rf_config, 8),
|
||||
CONF_ITEM_TABLE(g_GainValue_B, 0, marlin3_rf_config, 6),
|
||||
CONF_ITEM_TABLE(g_ClassicPowerValue_B, 0, marlin3_rf_config, 10),
|
||||
CONF_ITEM_TABLE(g_LEPowerValue_B, 0, marlin3_rf_config, 16),
|
||||
CONF_ITEM_TABLE(g_BRChannelpwrvalue_B, 0, marlin3_rf_config, 8),
|
||||
CONF_ITEM_TABLE(g_EDRChannelpwrvalue_B, 0, marlin3_rf_config, 8),
|
||||
CONF_ITEM_TABLE(g_LEChannelpwrvalue_B, 0, marlin3_rf_config, 8),
|
||||
CONF_ITEM_TABLE(LE_fix_powerword, 0, marlin3_rf_config, 1),
|
||||
CONF_ITEM_TABLE(Classic_pc_by_channel, 0, marlin3_rf_config, 1),
|
||||
CONF_ITEM_TABLE(LE_pc_by_channel, 0, marlin3_rf_config, 1),
|
||||
CONF_ITEM_TABLE(RF_switch_mode, 0, marlin3_rf_config, 1),
|
||||
CONF_ITEM_TABLE(Data_Capture_Mode, 0, marlin3_rf_config, 1),
|
||||
CONF_ITEM_TABLE(Analog_IQ_Debug_Mode, 0, marlin3_rf_config, 1),
|
||||
CONF_ITEM_TABLE(RF_common_rfu_b3, 0, marlin3_rf_config, 1),
|
||||
CONF_ITEM_TABLE(RF_common_rfu_w, 0, marlin3_rf_config, 5),
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void log_bin_to_hexstr(uint8_t *bin, uint8_t binsz, const char *log_tag)
|
||||
{
|
||||
SPRD_DBG("%s", log_tag);
|
||||
SPRD_DUMP(bin, binsz);
|
||||
}
|
||||
|
||||
static void parse_number(char *p_conf_name, char *p_conf_value, void *buf, int len, int size)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)buf;
|
||||
char *sub_value, *p;
|
||||
uint32_t value;
|
||||
(void)p_conf_name;
|
||||
sub_value = strtok_r(p_conf_value, CONF_VALUES_PARTITION, &p);
|
||||
do {
|
||||
if (sub_value == NULL)
|
||||
break;
|
||||
|
||||
if (sub_value[0] == '0' && (sub_value[1] == 'x' || sub_value[1] == 'X'))
|
||||
value = strtoul(sub_value, 0, 16) & 0xFFFFFFFF;
|
||||
else
|
||||
value = strtoul(sub_value, 0, 10) & 0xFFFFFFFF;
|
||||
|
||||
switch (size) {
|
||||
case sizeof(uint8_t):
|
||||
*dest = value & 0xFF;
|
||||
dest += size;
|
||||
break;
|
||||
|
||||
case sizeof(uint16_t):
|
||||
*((uint16_t *)dest) = value & 0xFFFF;
|
||||
dest += size;
|
||||
break;
|
||||
|
||||
case sizeof(uint32_t):
|
||||
*((uint32_t *)dest) = value & 0xFFFFFFFF;
|
||||
dest += size;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sub_value = strtok_r(NULL, CONF_VALUES_PARTITION, &p);
|
||||
} while (--len);
|
||||
}
|
||||
|
||||
static void set_mac_address(uint8_t *addr)
|
||||
{
|
||||
int i = 0;
|
||||
SPRD_DBG("%s", __func__);
|
||||
for (i = 0; i < 6; i++)
|
||||
addr[5-i] = (unsigned char)local_bdaddr[i];
|
||||
}
|
||||
|
||||
static void vnd_load_configure(const char *p_path, const conf_entry_t *entry)
|
||||
{
|
||||
FILE *p_file;
|
||||
char *p_name, *p_value, *p;
|
||||
conf_entry_t *p_entry;
|
||||
char line[CONF_MAX_LINE_LEN + 1]; /* add 1 for \0 char */
|
||||
|
||||
SPRD_DBG("Attempt to load conf from %s", p_path);
|
||||
|
||||
if ((p_file = fopen(p_path, "r")) != NULL) {
|
||||
/* read line by line */
|
||||
while (fgets(line, CONF_MAX_LINE_LEN + 1, p_file) != NULL) {
|
||||
if (line[0] == CONF_COMMENT) continue;
|
||||
|
||||
p_name = strtok_r(line, CONF_DELIMITERS, &p);
|
||||
|
||||
if (NULL == p_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
p_value = strtok_r(NULL, CONF_VALUES_DELIMITERS, &p);
|
||||
|
||||
if (NULL == p_value) {
|
||||
SPRD_DBG("vnd_load_conf: missing value for name: %s", p_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
p_entry = (conf_entry_t*)entry;
|
||||
|
||||
while (p_entry->conf_entry != NULL) {
|
||||
if (strcmp(p_entry->conf_entry, (const char *)p_name) == 0) {
|
||||
if (p_entry->p_action) {
|
||||
p_entry->p_action(p_name, p_value, p_entry->buf, p_entry->len,
|
||||
p_entry->size);
|
||||
} else {
|
||||
SPRD_DBG("%s -> %s", p_name, p_value);
|
||||
parse_number(p_name, p_value, p_entry->buf, p_entry->len,
|
||||
p_entry->size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
p_entry++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(p_file);
|
||||
} else {
|
||||
SPRD_DBG("vnd_load_conf file >%s< not found", p_path);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t H4Protocol_Send(uint8_t type, const uint8_t* data, size_t length)
|
||||
{
|
||||
struct iovec iov[] = {
|
||||
{&type, sizeof(type)},
|
||||
{(uint8_t *)data, length}};
|
||||
|
||||
ssize_t ret = 0;
|
||||
do {
|
||||
ret = writev(s_bt_fd, iov, sizeof(iov) / sizeof(iov[0]));
|
||||
} while (-1 == ret && EAGAIN == errno);
|
||||
|
||||
if (ret == -1) {
|
||||
SPRD_ERR("%s error writing to UART (%s)", __func__, strerror(errno));
|
||||
} else if (ret < length + 1) {
|
||||
SPRD_ERR("%s: %d / %d bytes written - something went wrong...", __func__, ret, length + 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *bt_vendor_alloc(int size)
|
||||
{
|
||||
void *p = (uint8_t *)malloc(size);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void bt_vendor_free(void *buffer)
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static uint8_t bt_vendor_xmit(uint16_t opcode, void* buffer, hci_cback callback)
|
||||
{
|
||||
uint8_t type = HCI_PACKET_TYPE_COMMAND;
|
||||
(void)opcode;
|
||||
HC_BT_HDR* bt_hdr = (HC_BT_HDR *)buffer;
|
||||
H4Protocol_Send(type, bt_hdr->data, bt_hdr->len);
|
||||
return BT_VND_OP_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static uint8_t sprd_vnd_send_hci_vsc(uint16_t cmd, uint8_t *payload, uint8_t len, hci_cback cback)
|
||||
{
|
||||
HC_BT_HDR *p_buf;
|
||||
uint8_t *p, ret;
|
||||
|
||||
p_buf = (HC_BT_HDR *)bt_vendor_alloc(
|
||||
BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + len);
|
||||
if (p_buf) {
|
||||
p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
|
||||
p_buf->offset = 0;
|
||||
p_buf->layer_specific = 0;
|
||||
p_buf->len = HCI_CMD_PREAMBLE_SIZE + len;
|
||||
p = (uint8_t *)(p_buf + 1);
|
||||
|
||||
UINT16_TO_STREAM(p, cmd);
|
||||
*p++ = len;
|
||||
memcpy(p, payload, len);
|
||||
log_bin_to_hexstr((uint8_t *)(p_buf + 1), HCI_CMD_PREAMBLE_SIZE + len, __FUNCTION__);
|
||||
ret = bt_vendor_xmit(cmd, p_buf, cback);
|
||||
bt_vendor_free(p_buf);
|
||||
return ret;
|
||||
}
|
||||
return BT_VND_OP_RESULT_FAIL;
|
||||
}
|
||||
|
||||
static void hw_core_cback(void *p_mem)
|
||||
{
|
||||
uint8_t *p_evt_buf = (uint8_t *)p_mem;
|
||||
uint8_t *p, status;
|
||||
uint16_t opcode, mode;
|
||||
|
||||
p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
|
||||
STREAM_TO_UINT16(opcode,p);
|
||||
STREAM_TO_UINT16(mode,p);
|
||||
STREAM_TO_UINT8(status,p);
|
||||
SPRD_DBG("%s hw_core_cback response: [0x%04X, 0x%04X, 0x%02X]", __func__, opcode, mode, status);
|
||||
bt_vendor_free(p_evt_buf);
|
||||
}
|
||||
|
||||
static void hw_core_enable(unsigned char enable)
|
||||
{
|
||||
uint8_t *p, msg_req[HCI_CMD_MAX_LEN];
|
||||
p = msg_req;
|
||||
UINT16_TO_STREAM(p, DUAL_MODE);
|
||||
UINT8_TO_STREAM(p, enable ? ENABLE_BT : DISABLE_BT);
|
||||
sprd_vnd_send_hci_vsc(HCI_VSC_ENABLE_COMMMAND, msg_req, (uint8_t)(p - msg_req), NULL);
|
||||
}
|
||||
|
||||
static void hw_rf_cback(void *p_mem)
|
||||
{
|
||||
uint8_t *p_evt_buf = (uint8_t *)p_mem, len;
|
||||
uint8_t *p, status;
|
||||
uint16_t opcode, mode = 0;
|
||||
|
||||
p = (uint8_t *)(p_evt_buf + 1) + 1;
|
||||
STREAM_TO_UINT8(len, p);
|
||||
|
||||
p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
|
||||
STREAM_TO_UINT16(opcode, p);
|
||||
if (len == 6)
|
||||
STREAM_TO_UINT16(mode, p);
|
||||
|
||||
STREAM_TO_UINT8(status, p);
|
||||
|
||||
SPRD_DBG("%s hw_rf_cback response: [0x%04X, 0x%04X, 0x%02X]", __func__, opcode, mode, status);
|
||||
/* Must free the RX event buffer */
|
||||
bt_vendor_free(p_evt_buf);
|
||||
}
|
||||
|
||||
static int marlin3_rf_preload()
|
||||
{
|
||||
uint8_t *p, msg_req[HCI_CMD_MAX_LEN];
|
||||
int i;
|
||||
|
||||
SPRD_DBG("yujian.qin %s", __FUNCTION__);
|
||||
p = msg_req;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_GainValue_A[i]);
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_ClassicPowerValue_A[i]);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_LEPowerValue_A[i]);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_BRChannelpwrvalue_A[i]);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_EDRChannelpwrvalue_A[i]);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_LEChannelpwrvalue_A[i]);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_GainValue_B[i]);
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_ClassicPowerValue_B[i]);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_LEPowerValue_B[i]);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_BRChannelpwrvalue_B[i]);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_EDRChannelpwrvalue_B[i]);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.g_LEChannelpwrvalue_B[i]);
|
||||
|
||||
UINT16_TO_STREAM(p, marlin3_rf_config.LE_fix_powerword);
|
||||
|
||||
UINT8_TO_STREAM(p, marlin3_rf_config.Classic_pc_by_channel);
|
||||
UINT8_TO_STREAM(p, marlin3_rf_config.LE_pc_by_channel);
|
||||
UINT8_TO_STREAM(p, marlin3_rf_config.RF_switch_mode);
|
||||
UINT8_TO_STREAM(p, marlin3_rf_config.Data_Capture_Mode);
|
||||
UINT8_TO_STREAM(p, marlin3_rf_config.Analog_IQ_Debug_Mode);
|
||||
UINT8_TO_STREAM(p, marlin3_rf_config.RF_common_rfu_b3);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_rf_config.RF_common_rfu_w[i]);
|
||||
|
||||
sprd_vnd_send_hci_vsc(HCI_RF_PARA, msg_req, (uint8_t)(p - msg_req), NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void marlin3_pskey_cback(void *p_mem)
|
||||
{
|
||||
uint8_t *p_evt_buf = (uint8_t *)p_mem;
|
||||
|
||||
uint16_t opcode, node, year;
|
||||
uint8_t *p, month, day;
|
||||
(void)opcode;
|
||||
|
||||
p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
|
||||
STREAM_TO_UINT16(opcode, p);
|
||||
|
||||
p = (uint8_t *)(p_evt_buf + 1) + FW_NODE_BYTE;
|
||||
STREAM_TO_UINT16(node, p);
|
||||
p = (uint8_t *)(p_evt_buf + 1) + FW_DATE_Y_BYTE;
|
||||
STREAM_TO_UINT16(year, p);
|
||||
p = (uint8_t *)(p_evt_buf + 1) + FW_DATE_M_BYTE;
|
||||
STREAM_TO_UINT8(month, p);
|
||||
p = (uint8_t *)(p_evt_buf + 1) + FW_DATE_D_BYTE;
|
||||
STREAM_TO_UINT8(day, p);
|
||||
|
||||
SPRD_DBG("Bluetooth Firmware Node: %04X Date: %04x-%02x-%02x", node, year, month, day);
|
||||
|
||||
/* Must free the RX event buffer */
|
||||
bt_vendor_free(p_evt_buf);
|
||||
}
|
||||
|
||||
static int marlin3_pskey_preload(void *arg)
|
||||
{
|
||||
uint8_t *p, msg_req[HCI_CMD_MAX_LEN];
|
||||
int i;
|
||||
(void)arg;
|
||||
|
||||
SPRD_DBG("%s", __FUNCTION__);
|
||||
p = msg_req;
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.device_class);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.feature_set[i]);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.device_addr[i]);
|
||||
|
||||
UINT16_TO_STREAM(p, marlin3_pskey.comp_id);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_uart0_communication_supported);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.cp2_log_mode);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.LogLevel);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.g_central_or_perpheral);
|
||||
|
||||
UINT16_TO_STREAM(p, marlin3_pskey.Log_BitMask);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.super_ssp_enable);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.common_rfu_b3);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.common_rfu_w[i]);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.le_rfu_w[i]);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.lmp_rfu_w[i]);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.lc_rfu_w[i]);
|
||||
|
||||
UINT16_TO_STREAM(p, marlin3_pskey.g_wbs_nv_117);
|
||||
UINT16_TO_STREAM(p, marlin3_pskey.g_wbs_nv_118);
|
||||
UINT16_TO_STREAM(p, marlin3_pskey.g_nbv_nv_117);
|
||||
UINT16_TO_STREAM(p, marlin3_pskey.g_nbv_nv_118);
|
||||
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sco_transmit_mode);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.audio_rfu_b1);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.audio_rfu_b2);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.audio_rfu_b3);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.audio_rfu_w[i]);
|
||||
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sleep_in_standby_supported);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sleep_master_supported);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sleep_slave_supported);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.power_rfu_b1);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.power_rfu_w[i]);
|
||||
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.win_ext);
|
||||
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.edr_tx_edr_delay);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.edr_rx_edr_delay);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.tx_delay);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.rx_delay);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.bb_rfu_w[i]);
|
||||
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.agc_mode);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.diff_or_eq);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.ramp_mode);
|
||||
UINT8_TO_STREAM(p, marlin3_pskey.modem_rfu_b1);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.modem_rfu_w[i]);
|
||||
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.BQB_BitMask_1);
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.BQB_BitMask_2);
|
||||
for (i = 0; i < 8; i++)
|
||||
UINT16_TO_STREAM(p, marlin3_pskey.bt_coex_threshold[i]);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
UINT32_TO_STREAM(p, marlin3_pskey.other_rfu_w[i]);
|
||||
|
||||
sprd_vnd_send_hci_vsc(HCI_PSKEY, msg_req, (uint8_t)(p - msg_req), NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sprd_config_init(int fd, struct uart_t *u, struct termios *ti)
|
||||
{
|
||||
uint8_t *recv = NULL;
|
||||
int len = 0;
|
||||
|
||||
s_bt_fd = fd;
|
||||
|
||||
memset(&marlin3_pskey, 0, sizeof(marlin3_pskey));
|
||||
memset(&marlin3_rf_config, 0, sizeof(marlin3_rf_config));
|
||||
vnd_load_configure(BT_CONFIG_PATH "/bt_configure_pskey.ini", &marlin3_pksey_table[0]);
|
||||
vnd_load_configure(BT_CONFIG_PATH "/bt_configure_rf.ini", &marlin3_rf_table[0]);
|
||||
set_mac_address(marlin3_pskey.device_addr);
|
||||
|
||||
marlin3_pskey_preload(NULL);
|
||||
recv = bt_vendor_alloc(RESPONSE_LENGTH);
|
||||
len = read_hci_event(s_bt_fd, recv, RESPONSE_LENGTH);
|
||||
SPRD_DBG("Received event, len: %d", len);
|
||||
SPRD_DUMP(recv, len);
|
||||
marlin3_pskey_cback(recv);
|
||||
|
||||
marlin3_rf_preload();
|
||||
recv = bt_vendor_alloc(RESPONSE_LENGTH);
|
||||
len = read_hci_event(s_bt_fd, recv, RESPONSE_LENGTH);
|
||||
SPRD_DBG("Received event, len: %d", len);
|
||||
SPRD_DUMP(recv, len);
|
||||
hw_rf_cback(recv);
|
||||
|
||||
hw_core_enable(1);
|
||||
recv = bt_vendor_alloc(RESPONSE_LENGTH);
|
||||
len = read_hci_event(s_bt_fd, recv, RESPONSE_LENGTH);
|
||||
SPRD_DBG("Received event, len: %d", len);
|
||||
SPRD_DUMP(recv, len);
|
||||
hw_core_cback(recv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sprd_config_post(int fd, struct uart_t *u, struct termios *ti)
|
||||
{
|
||||
SPRD_DBG("Done setting line discpline");
|
||||
return 0;
|
||||
}
|
||||
|
||||
278
external/cache/sources/hcitools/hciattach_st.c
vendored
Normal file
278
external/cache/sources/hcitools/hciattach_st.c
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
#include "hciattach.h"
|
||||
|
||||
static int debug = 0;
|
||||
|
||||
static int do_command(int fd, uint8_t ogf, uint16_t ocf,
|
||||
uint8_t *cparam, int clen, uint8_t *rparam, int rlen)
|
||||
{
|
||||
//uint16_t opcode = (uint16_t) ((ocf & 0x03ff) | (ogf << 10));
|
||||
unsigned char cp[260], rp[260];
|
||||
int len, size, offset = 3;
|
||||
|
||||
cp[0] = 0x01;
|
||||
cp[1] = ocf & 0xff;
|
||||
cp[2] = ogf << 2 | ocf >> 8;
|
||||
cp[3] = clen;
|
||||
|
||||
if (clen > 0)
|
||||
memcpy(cp + 4, cparam, clen);
|
||||
|
||||
if (debug) {
|
||||
int i;
|
||||
printf("[<");
|
||||
for (i = 0; i < clen + 4; i++)
|
||||
printf(" %02x", cp[i]);
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
if (write(fd, cp, clen + 4) < 0)
|
||||
return -1;
|
||||
|
||||
do {
|
||||
if (read(fd, rp, 1) < 1)
|
||||
return -1;
|
||||
} while (rp[0] != 0x04);
|
||||
|
||||
if (read(fd, rp + 1, 2) < 2)
|
||||
return -1;
|
||||
|
||||
do {
|
||||
len = read(fd, rp + offset, sizeof(rp) - offset);
|
||||
offset += len;
|
||||
} while (offset < rp[2] + 3);
|
||||
|
||||
if (debug) {
|
||||
int i;
|
||||
printf("[>");
|
||||
for (i = 0; i < offset; i++)
|
||||
printf(" %02x", rp[i]);
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
if (rp[0] != 0x04) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (rp[1]) {
|
||||
case 0x0e: /* command complete */
|
||||
if (rp[6] != 0x00)
|
||||
return -ENXIO;
|
||||
offset = 3 + 4;
|
||||
size = rp[2] - 4;
|
||||
break;
|
||||
case 0x0f: /* command status */
|
||||
/* fall through */
|
||||
default:
|
||||
offset = 3;
|
||||
size = rp[2];
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rparam || rlen < size)
|
||||
return -ENXIO;
|
||||
|
||||
memcpy(rparam, rp + offset, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int load_file(int dd, uint16_t version, const char *suffix)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *d;
|
||||
char pathname[PATH_MAX], filename[NAME_MAX], prefix[20];
|
||||
unsigned char cmd[256];
|
||||
unsigned char buf[256];
|
||||
uint8_t seqnum = 0;
|
||||
int fd, size, len, found_fw_file;
|
||||
|
||||
memset(filename, 0, sizeof(filename));
|
||||
|
||||
snprintf(prefix, sizeof(prefix), "STLC2500_R%d_%02d_",
|
||||
version >> 8, version & 0xff);
|
||||
|
||||
strcpy(pathname, "/lib/firmware");
|
||||
dir = opendir(pathname);
|
||||
if (!dir) {
|
||||
strcpy(pathname, ".");
|
||||
dir = opendir(pathname);
|
||||
if (!dir)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
found_fw_file = 0;
|
||||
while (1) {
|
||||
d = readdir(dir);
|
||||
if (!d)
|
||||
break;
|
||||
|
||||
if (strncmp(d->d_name + strlen(d->d_name) - strlen(suffix),
|
||||
suffix, strlen(suffix)))
|
||||
continue;
|
||||
|
||||
if (strncmp(d->d_name, prefix, strlen(prefix)))
|
||||
continue;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/%s",
|
||||
pathname, d->d_name);
|
||||
found_fw_file = 1;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
if (!found_fw_file)
|
||||
return -ENOENT;
|
||||
|
||||
printf("Loading file %s\n", filename);
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("Can't open firmware file");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
size = read(fd, cmd + 1, 254);
|
||||
if (size <= 0)
|
||||
break;
|
||||
|
||||
cmd[0] = seqnum;
|
||||
|
||||
len = do_command(dd, 0xff, 0x002e, cmd, size + 1, buf, sizeof(buf));
|
||||
if (len < 1)
|
||||
break;
|
||||
|
||||
if (buf[0] != seqnum) {
|
||||
fprintf(stderr, "Sequence number mismatch\n");
|
||||
break;
|
||||
}
|
||||
|
||||
seqnum++;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stlc2500_init(int dd, bdaddr_t *bdaddr)
|
||||
{
|
||||
unsigned char cmd[16];
|
||||
unsigned char buf[254];
|
||||
uint16_t version;
|
||||
int len;
|
||||
int err;
|
||||
|
||||
/* Hci_Cmd_Ericsson_Read_Revision_Information */
|
||||
len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
printf("%s\n", buf);
|
||||
|
||||
/* HCI_Read_Local_Version_Information */
|
||||
len = do_command(dd, 0x04, 0x0001, NULL, 0, buf, sizeof(buf));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
version = buf[2] << 8 | buf[1];
|
||||
|
||||
err = load_file(dd, version, ".ptc");
|
||||
if (err < 0) {
|
||||
if (err == -ENOENT)
|
||||
fprintf(stderr, "No ROM patch file loaded.\n");
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = load_file(dd, buf[2] << 8 | buf[1], ".ssf");
|
||||
if (err < 0) {
|
||||
if (err == -ENOENT)
|
||||
fprintf(stderr, "No static settings file loaded.\n");
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = 0xfe;
|
||||
cmd[1] = 0x06;
|
||||
bacpy((bdaddr_t *) (cmd + 2), bdaddr);
|
||||
|
||||
/* Hci_Cmd_ST_Store_In_NVDS */
|
||||
len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
/* HCI_Reset : applies parameters*/
|
||||
len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bgb2xx_init(int dd, bdaddr_t *bdaddr)
|
||||
{
|
||||
unsigned char cmd[16];
|
||||
unsigned char buf[254];
|
||||
int len;
|
||||
|
||||
len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
printf("%s\n", buf);
|
||||
|
||||
cmd[0] = 0xfe;
|
||||
cmd[1] = 0x06;
|
||||
bacpy((bdaddr_t *) (cmd + 2), bdaddr);
|
||||
|
||||
len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
533
external/cache/sources/hcitools/hciattach_ti.c
vendored
Normal file
533
external/cache/sources/hcitools/hciattach_ti.c
vendored
Normal file
@@ -0,0 +1,533 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2005-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
|
||||
#include "hciattach.h"
|
||||
|
||||
#ifdef HCIATTACH_DEBUG
|
||||
#define DPRINTF(x...) printf(x)
|
||||
#else
|
||||
#define DPRINTF(x...)
|
||||
#endif
|
||||
|
||||
#define HCIUARTGETDEVICE _IOR('U', 202, int)
|
||||
|
||||
#define MAKEWORD(a, b) ((uint16_t)(((uint8_t)(a)) | ((uint16_t)((uint8_t)(b))) << 8))
|
||||
|
||||
#define TI_MANUFACTURER_ID 13
|
||||
|
||||
#define FIRMWARE_DIRECTORY "/lib/firmware/ti-connectivity/"
|
||||
|
||||
#define ACTION_SEND_COMMAND 1
|
||||
#define ACTION_WAIT_EVENT 2
|
||||
#define ACTION_SERIAL 3
|
||||
#define ACTION_DELAY 4
|
||||
#define ACTION_RUN_SCRIPT 5
|
||||
#define ACTION_REMARKS 6
|
||||
|
||||
#define BRF_DEEP_SLEEP_OPCODE_BYTE_1 0x0c
|
||||
#define BRF_DEEP_SLEEP_OPCODE_BYTE_2 0xfd
|
||||
#define BRF_DEEP_SLEEP_OPCODE \
|
||||
(BRF_DEEP_SLEEP_OPCODE_BYTE_1 | (BRF_DEEP_SLEEP_OPCODE_BYTE_2 << 8))
|
||||
|
||||
#define FILE_HEADER_MAGIC 0x42535442
|
||||
|
||||
/*
|
||||
* BRF Firmware header
|
||||
*/
|
||||
struct bts_header {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint8_t future[24];
|
||||
uint8_t actions[0];
|
||||
}__attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* BRF Actions structure
|
||||
*/
|
||||
struct bts_action {
|
||||
uint16_t type;
|
||||
uint16_t size;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct bts_action_send {
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct bts_action_wait {
|
||||
uint32_t msec;
|
||||
uint32_t size;
|
||||
uint8_t data[0];
|
||||
}__attribute__ ((packed));
|
||||
|
||||
struct bts_action_delay {
|
||||
uint32_t msec;
|
||||
}__attribute__ ((packed));
|
||||
|
||||
struct bts_action_serial {
|
||||
uint32_t baud;
|
||||
uint32_t flow_control;
|
||||
}__attribute__ ((packed));
|
||||
|
||||
static FILE *bts_load_script(const char *file_name, uint32_t *version)
|
||||
{
|
||||
struct bts_header header;
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(file_name, "rb");
|
||||
if (!fp) {
|
||||
perror("can't open firmware file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (1 != fread(&header, sizeof(struct bts_header), 1, fp)) {
|
||||
perror("can't read firmware file");
|
||||
goto errclose;
|
||||
}
|
||||
|
||||
if (header.magic != FILE_HEADER_MAGIC) {
|
||||
fprintf(stderr, "%s not a legal TI firmware file\n", file_name);
|
||||
goto errclose;
|
||||
}
|
||||
|
||||
if (NULL != version)
|
||||
*version = header.version;
|
||||
|
||||
return fp;
|
||||
|
||||
errclose:
|
||||
fclose(fp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned long bts_fetch_action(FILE *fp, unsigned char *action_buf,
|
||||
unsigned long buf_size, uint16_t *action_type)
|
||||
{
|
||||
struct bts_action action_hdr;
|
||||
unsigned long nread;
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
if (1 != fread(&action_hdr, sizeof(struct bts_action), 1, fp))
|
||||
return 0;
|
||||
|
||||
if (action_hdr.size > buf_size) {
|
||||
fprintf(stderr, "bts_next_action: not enough space to read next action\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
nread = fread(action_buf, sizeof(uint8_t), action_hdr.size, fp);
|
||||
if (nread != (action_hdr.size)) {
|
||||
fprintf(stderr, "bts_next_action: fread failed to read next action\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*action_type = action_hdr.type;
|
||||
|
||||
return nread * sizeof(uint8_t);
|
||||
}
|
||||
|
||||
static void bts_unload_script(FILE *fp)
|
||||
{
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static int is_it_texas(const uint8_t *respond)
|
||||
{
|
||||
uint16_t manufacturer_id;
|
||||
|
||||
manufacturer_id = MAKEWORD(respond[11], respond[12]);
|
||||
|
||||
return TI_MANUFACTURER_ID == manufacturer_id ? 1 : 0;
|
||||
}
|
||||
|
||||
static const char *get_firmware_name(const uint8_t *respond)
|
||||
{
|
||||
static char firmware_file_name[PATH_MAX] = {0};
|
||||
uint16_t version = 0, chip = 0, min_ver = 0, maj_ver = 0;
|
||||
|
||||
version = MAKEWORD(respond[13], respond[14]);
|
||||
chip = (version & 0x7C00) >> 10;
|
||||
min_ver = (version & 0x007F);
|
||||
maj_ver = (version & 0x0380) >> 7;
|
||||
|
||||
if (version & 0x8000)
|
||||
maj_ver |= 0x0008;
|
||||
|
||||
sprintf(firmware_file_name, FIRMWARE_DIRECTORY "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);
|
||||
|
||||
return firmware_file_name;
|
||||
}
|
||||
|
||||
static void brf_delay(struct bts_action_delay *delay)
|
||||
{
|
||||
usleep(1000 * delay->msec);
|
||||
}
|
||||
|
||||
static int brf_set_serial_params(struct bts_action_serial *serial_action,
|
||||
int fd, int *speed, struct termios *ti)
|
||||
{
|
||||
fprintf(stderr, "texas: changing baud rate to %u, flow control to %u\n",
|
||||
serial_action->baud, serial_action->flow_control );
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (serial_action->flow_control)
|
||||
ti->c_cflag |= CRTSCTS;
|
||||
else
|
||||
ti->c_cflag &= ~CRTSCTS;
|
||||
|
||||
if (tcsetattr(fd, TCSANOW, ti) < 0) {
|
||||
perror("Can't set port settings");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (set_speed(fd, ti, serial_action->baud) < 0) {
|
||||
perror("Can't set baud rate");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (speed)
|
||||
*speed = serial_action->baud;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brf_send_command_socket(int fd, struct bts_action_send *send_action)
|
||||
{
|
||||
char response[1024] = {0};
|
||||
hci_command_hdr *cmd = (hci_command_hdr *) send_action->data;
|
||||
uint16_t opcode = cmd->opcode;
|
||||
|
||||
struct hci_request rq;
|
||||
memset(&rq, 0, sizeof(rq));
|
||||
rq.ogf = cmd_opcode_ogf(opcode);
|
||||
rq.ocf = cmd_opcode_ocf(opcode);
|
||||
rq.event = EVT_CMD_COMPLETE;
|
||||
rq.cparam = &send_action->data[3];
|
||||
rq.clen = send_action->data[2];
|
||||
rq.rparam = response;
|
||||
rq.rlen = sizeof(response);
|
||||
|
||||
if (hci_send_req(fd, &rq, 15) < 0) {
|
||||
perror("Cannot send hci command to socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* verify success */
|
||||
if (response[0]) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brf_send_command_file(int fd, struct bts_action_send *send_action,
|
||||
long size)
|
||||
{
|
||||
unsigned char response[1024] = {0};
|
||||
long ret = 0;
|
||||
|
||||
/* send command */
|
||||
if (size != write(fd, send_action, size)) {
|
||||
perror("Texas: Failed to write action command");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read response */
|
||||
ret = read_hci_event(fd, response, sizeof(response));
|
||||
if (ret < 0) {
|
||||
perror("texas: failed to read command response");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* verify success */
|
||||
if (ret < 7 || 0 != response[6]) {
|
||||
fprintf( stderr, "TI init command failed.\n" );
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int brf_send_command(int fd, struct bts_action_send *send_action,
|
||||
long size, int hcill_installed)
|
||||
{
|
||||
int ret = 0;
|
||||
char *fixed_action;
|
||||
|
||||
/* remove packet type when giving to socket API */
|
||||
if (hcill_installed) {
|
||||
fixed_action = ((char *) send_action) + 1;
|
||||
ret = brf_send_command_socket(fd, (struct bts_action_send *) fixed_action);
|
||||
} else {
|
||||
ret = brf_send_command_file(fd, send_action, size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int brf_do_action(uint16_t brf_type, uint8_t *brf_action, long brf_size,
|
||||
int fd, int *speed, struct termios *ti, int hcill_installed)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (brf_type) {
|
||||
case ACTION_SEND_COMMAND:
|
||||
DPRINTF("W");
|
||||
ret = brf_send_command(fd,
|
||||
(struct bts_action_send *) brf_action,
|
||||
brf_size, hcill_installed);
|
||||
break;
|
||||
case ACTION_WAIT_EVENT:
|
||||
DPRINTF("R");
|
||||
break;
|
||||
case ACTION_SERIAL:
|
||||
DPRINTF("S");
|
||||
ret = brf_set_serial_params((struct bts_action_serial *) brf_action, fd, speed, ti);
|
||||
break;
|
||||
case ACTION_DELAY:
|
||||
DPRINTF("D");
|
||||
brf_delay((struct bts_action_delay *) brf_action);
|
||||
break;
|
||||
case ACTION_REMARKS:
|
||||
DPRINTF("C");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "brf_init: unknown firmware action type (%d)\n", brf_type);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* tests whether a given brf action is a HCI_VS_Sleep_Mode_Configurations cmd
|
||||
*/
|
||||
static int brf_action_is_deep_sleep(uint8_t *brf_action, long brf_size,
|
||||
uint16_t brf_type)
|
||||
{
|
||||
uint16_t opcode;
|
||||
|
||||
if (brf_type != ACTION_SEND_COMMAND)
|
||||
return 0;
|
||||
|
||||
if (brf_size < 3)
|
||||
return 0;
|
||||
|
||||
if (brf_action[0] != HCI_COMMAND_PKT)
|
||||
return 0;
|
||||
|
||||
/* HCI data is little endian */
|
||||
opcode = brf_action[1] | (brf_action[2] << 8);
|
||||
|
||||
if (opcode != BRF_DEEP_SLEEP_OPCODE)
|
||||
return 0;
|
||||
|
||||
/* action is deep sleep configuration command ! */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called twice.
|
||||
* The first time it is called, it loads the brf script, and executes its
|
||||
* commands until it reaches a deep sleep command (or its end).
|
||||
* The second time it is called, it assumes HCILL protocol is set up,
|
||||
* and sends rest of brf script via the supplied socket.
|
||||
*/
|
||||
static int brf_do_script(int fd, int *speed, struct termios *ti, const char *bts_file)
|
||||
{
|
||||
int ret = 0, hcill_installed = bts_file ? 0 : 1;
|
||||
uint32_t vers;
|
||||
static FILE *brf_script_file = NULL;
|
||||
static uint8_t brf_action[512];
|
||||
static long brf_size;
|
||||
static uint16_t brf_type;
|
||||
|
||||
/* is it the first time we are called ? */
|
||||
if (0 == hcill_installed) {
|
||||
DPRINTF("Sending script to serial device\n");
|
||||
brf_script_file = bts_load_script(bts_file, &vers );
|
||||
if (!brf_script_file) {
|
||||
fprintf(stderr, "Warning: cannot find BTS file: %s\n",
|
||||
bts_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf( stderr, "Loaded BTS script version %u\n", vers );
|
||||
|
||||
brf_size = bts_fetch_action(brf_script_file, brf_action,
|
||||
sizeof(brf_action), &brf_type);
|
||||
if (brf_size == 0) {
|
||||
fprintf(stderr, "Warning: BTS file is empty !");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DPRINTF("Sending script to bluetooth socket\n");
|
||||
}
|
||||
|
||||
/* execute current action and continue to parse brf script file */
|
||||
while (brf_size != 0) {
|
||||
ret = brf_do_action(brf_type, brf_action, brf_size,
|
||||
fd, speed, ti, hcill_installed);
|
||||
if (ret == -1)
|
||||
break;
|
||||
|
||||
brf_size = bts_fetch_action(brf_script_file, brf_action,
|
||||
sizeof(brf_action), &brf_type);
|
||||
|
||||
/* if this is the first time we run (no HCILL yet) */
|
||||
/* and a deep sleep command is encountered */
|
||||
/* we exit */
|
||||
if (!hcill_installed &&
|
||||
brf_action_is_deep_sleep(brf_action,
|
||||
brf_size, brf_type))
|
||||
return 0;
|
||||
}
|
||||
|
||||
bts_unload_script(brf_script_file);
|
||||
brf_script_file = NULL;
|
||||
DPRINTF("\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int texas_init(int fd, int *speed, struct termios *ti)
|
||||
{
|
||||
struct timespec tm = {0, 50000};
|
||||
char cmd[4];
|
||||
unsigned char resp[100]; /* Response */
|
||||
const char *bts_file;
|
||||
int n;
|
||||
|
||||
memset(resp,'\0', 100);
|
||||
|
||||
/* It is possible to get software version with manufacturer specific
|
||||
HCI command HCI_VS_TI_Version_Number. But the only thing you get more
|
||||
is if this is point-to-point or point-to-multipoint module */
|
||||
|
||||
/* Get Manufacturer and LMP version */
|
||||
cmd[0] = HCI_COMMAND_PKT;
|
||||
cmd[1] = 0x01;
|
||||
cmd[2] = 0x10;
|
||||
cmd[3] = 0x00;
|
||||
|
||||
do {
|
||||
n = write(fd, cmd, 4);
|
||||
if (n < 0) {
|
||||
perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)");
|
||||
return -1;
|
||||
}
|
||||
if (n < 4) {
|
||||
fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read reply. */
|
||||
if (read_hci_event(fd, resp, 100) < 0) {
|
||||
perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait for command complete event for our Opcode */
|
||||
} while (resp[4] != cmd[1] && resp[5] != cmd[2]);
|
||||
|
||||
/* Verify manufacturer */
|
||||
if (! is_it_texas(resp)) {
|
||||
fprintf(stderr,"ERROR: module's manufacturer is not Texas Instruments\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Found a Texas Instruments' chip!\n");
|
||||
|
||||
bts_file = get_firmware_name(resp);
|
||||
fprintf(stderr, "Firmware file : %s\n", bts_file);
|
||||
|
||||
n = brf_do_script(fd, speed, ti, bts_file);
|
||||
|
||||
nanosleep(&tm, NULL);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int texas_post(int fd, struct termios *ti)
|
||||
{
|
||||
int dev_id, dd, ret = 0;
|
||||
|
||||
sleep(1);
|
||||
|
||||
dev_id = ioctl(fd, HCIUARTGETDEVICE, 0);
|
||||
if (dev_id < 0) {
|
||||
perror("cannot get device id");
|
||||
return -1;
|
||||
}
|
||||
|
||||
DPRINTF("\nAdded device hci%d\n", dev_id);
|
||||
|
||||
dd = hci_open_dev(dev_id);
|
||||
if (dd < 0) {
|
||||
perror("HCI device open failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(dd, HCIDEVUP, dev_id) < 0 && errno != EALREADY) {
|
||||
fprintf(stderr, "Can't init device hci%d: %s (%d)", dev_id,
|
||||
strerror(errno), errno);
|
||||
hci_close_dev(dd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = brf_do_script(dd, NULL, ti, NULL);
|
||||
|
||||
hci_close_dev(dd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
242
external/cache/sources/hcitools/hciattach_tialt.c
vendored
Normal file
242
external/cache/sources/hcitools/hciattach_tialt.c
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2005-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
|
||||
#include "hciattach.h"
|
||||
|
||||
#define FAILIF(x, args...) do { \
|
||||
if (x) { \
|
||||
fprintf(stderr, ##args); \
|
||||
return -1; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
typedef struct {
|
||||
uint8_t uart_prefix;
|
||||
hci_event_hdr hci_hdr;
|
||||
evt_cmd_complete cmd_complete;
|
||||
uint8_t status;
|
||||
uint8_t data[16];
|
||||
} __attribute__((packed)) command_complete_t;
|
||||
|
||||
static int read_command_complete(int fd, unsigned short opcode, unsigned char len) {
|
||||
command_complete_t resp;
|
||||
/* Read reply. */
|
||||
FAILIF(read_hci_event(fd, (unsigned char *)&resp, sizeof(resp)) < 0,
|
||||
"Failed to read response");
|
||||
|
||||
/* Parse speed-change reply */
|
||||
FAILIF(resp.uart_prefix != HCI_EVENT_PKT,
|
||||
"Error in response: not an event packet, but 0x%02x!\n",
|
||||
resp.uart_prefix);
|
||||
|
||||
FAILIF(resp.hci_hdr.evt != EVT_CMD_COMPLETE, /* event must be event-complete */
|
||||
"Error in response: not a cmd-complete event, "
|
||||
"but 0x%02x!\n", resp.hci_hdr.evt);
|
||||
|
||||
FAILIF(resp.hci_hdr.plen < 4, /* plen >= 4 for EVT_CMD_COMPLETE */
|
||||
"Error in response: plen is not >= 4, but 0x%02x!\n",
|
||||
resp.hci_hdr.plen);
|
||||
|
||||
/* cmd-complete event: opcode */
|
||||
FAILIF(resp.cmd_complete.opcode != (uint16_t)opcode,
|
||||
"Error in response: opcode is 0x%04x, not 0x%04x!",
|
||||
resp.cmd_complete.opcode, opcode);
|
||||
|
||||
return resp.status == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t uart_prefix;
|
||||
hci_command_hdr hci_hdr;
|
||||
uint32_t speed;
|
||||
} __attribute__((packed)) texas_speed_change_cmd_t;
|
||||
|
||||
static int texas_change_speed(int fd, uint32_t speed)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int texas_load_firmware(int fd, const char *firmware) {
|
||||
|
||||
int fw = open(firmware, O_RDONLY);
|
||||
|
||||
fprintf(stdout, "Opening firmware file: %s\n", firmware);
|
||||
|
||||
FAILIF(fw < 0,
|
||||
"Could not open firmware file %s: %s (%d).\n",
|
||||
firmware, strerror(errno), errno);
|
||||
|
||||
fprintf(stdout, "Uploading firmware...\n");
|
||||
do {
|
||||
/* Read each command and wait for a response. */
|
||||
unsigned char data[1024];
|
||||
unsigned char cmdp[1 + sizeof(hci_command_hdr)];
|
||||
hci_command_hdr *cmd = (hci_command_hdr *)(cmdp + 1);
|
||||
int nr;
|
||||
nr = read(fw, cmdp, sizeof(cmdp));
|
||||
if (!nr)
|
||||
break;
|
||||
FAILIF(nr != sizeof(cmdp), "Could not read H4 + HCI header!\n");
|
||||
FAILIF(*cmdp != HCI_COMMAND_PKT, "Command is not an H4 command packet!\n");
|
||||
|
||||
FAILIF(read(fw, data, cmd->plen) != cmd->plen,
|
||||
"Could not read %d bytes of data for command with opcode %04x!\n",
|
||||
cmd->plen,
|
||||
cmd->opcode);
|
||||
|
||||
{
|
||||
int nw;
|
||||
#if 0
|
||||
fprintf(stdout, "\topcode 0x%04x (%d bytes of data).\n",
|
||||
cmd->opcode,
|
||||
cmd->plen);
|
||||
#endif
|
||||
struct iovec iov_cmd[2];
|
||||
iov_cmd[0].iov_base = cmdp;
|
||||
iov_cmd[0].iov_len = sizeof(cmdp);
|
||||
iov_cmd[1].iov_base = data;
|
||||
iov_cmd[1].iov_len = cmd->plen;
|
||||
nw = writev(fd, iov_cmd, 2);
|
||||
FAILIF(nw != (int) sizeof(cmd) + cmd->plen,
|
||||
"Could not send entire command (sent only %d bytes)!\n",
|
||||
nw);
|
||||
}
|
||||
|
||||
/* Wait for response */
|
||||
if (read_command_complete(fd,
|
||||
cmd->opcode,
|
||||
cmd->plen) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
} while(1);
|
||||
fprintf(stdout, "Firmware upload successful.\n");
|
||||
|
||||
close(fw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int texasalt_init(int fd, int speed, struct termios *ti)
|
||||
{
|
||||
struct timespec tm = {0, 50000};
|
||||
char cmd[4];
|
||||
unsigned char resp[100]; /* Response */
|
||||
int n;
|
||||
|
||||
memset(resp,'\0', 100);
|
||||
|
||||
/* It is possible to get software version with manufacturer specific
|
||||
HCI command HCI_VS_TI_Version_Number. But the only thing you get more
|
||||
is if this is point-to-point or point-to-multipoint module */
|
||||
|
||||
/* Get Manufacturer and LMP version */
|
||||
cmd[0] = HCI_COMMAND_PKT;
|
||||
cmd[1] = 0x01;
|
||||
cmd[2] = 0x10;
|
||||
cmd[3] = 0x00;
|
||||
|
||||
do {
|
||||
n = write(fd, cmd, 4);
|
||||
if (n < 0) {
|
||||
perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)");
|
||||
return -1;
|
||||
}
|
||||
if (n < 4) {
|
||||
fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read reply. */
|
||||
if (read_hci_event(fd, resp, 100) < 0) {
|
||||
perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait for command complete event for our Opcode */
|
||||
} while (resp[4] != cmd[1] && resp[5] != cmd[2]);
|
||||
|
||||
/* Verify manufacturer */
|
||||
if ((resp[11] & 0xFF) != 0x0d)
|
||||
fprintf(stderr,"WARNING : module's manufacturer is not Texas Instrument\n");
|
||||
|
||||
/* Print LMP version */
|
||||
fprintf(stderr, "Texas module LMP version : 0x%02x\n", resp[10] & 0xFF);
|
||||
|
||||
/* Print LMP subversion */
|
||||
{
|
||||
unsigned short lmp_subv = resp[13] | (resp[14] << 8);
|
||||
unsigned short brf_chip = (lmp_subv & 0x7c00) >> 10;
|
||||
static const char *c_brf_chip[8] = {
|
||||
"unknown",
|
||||
"unknown",
|
||||
"brf6100",
|
||||
"brf6150",
|
||||
"brf6300",
|
||||
"brf6350",
|
||||
"unknown",
|
||||
"wl1271"
|
||||
};
|
||||
char fw[100];
|
||||
|
||||
fprintf(stderr, "Texas module LMP sub-version : 0x%04x\n", lmp_subv);
|
||||
|
||||
fprintf(stderr,
|
||||
"\tinternal version freeze: %d\n"
|
||||
"\tsoftware version: %d\n"
|
||||
"\tchip: %s (%d)\n",
|
||||
lmp_subv & 0x7f,
|
||||
((lmp_subv & 0x8000) >> (15-3)) | ((lmp_subv & 0x380) >> 7),
|
||||
((brf_chip > 7) ? "unknown" : c_brf_chip[brf_chip]),
|
||||
brf_chip);
|
||||
|
||||
sprintf(fw, "/etc/firmware/%s.bin", c_brf_chip[brf_chip]);
|
||||
texas_load_firmware(fd, fw);
|
||||
|
||||
texas_change_speed(fd, speed);
|
||||
}
|
||||
nanosleep(&tm, NULL);
|
||||
return 0;
|
||||
}
|
||||
557
external/cache/sources/hcitools/hciattach_xr.c
vendored
Normal file
557
external/cache/sources/hcitools/hciattach_xr.c
vendored
Normal file
@@ -0,0 +1,557 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <limits.h>
|
||||
#include "hciattach.h"
|
||||
|
||||
/******************************************************************************
|
||||
** Constants & Macros
|
||||
******************************************************************************/
|
||||
#define LOG_STR "XRADIO Bluetooth"
|
||||
#define DBG_ON 1
|
||||
|
||||
#define XR_DBG(fmt, arg...) \
|
||||
do { \
|
||||
if (DBG_ON) \
|
||||
fprintf(stderr, "%s: " fmt "\n" , LOG_STR, ##arg); \
|
||||
} while(0)
|
||||
|
||||
#define XR_ERR(fmt, arg...) \
|
||||
do { \
|
||||
fprintf(stderr, "%s ERROR: " fmt "\n", LOG_STR, ##arg);\
|
||||
perror(LOG_STR" ERROR reason"); \
|
||||
} while(0)
|
||||
|
||||
#define XR_DUMP(buffer, len) \
|
||||
fprintf(stderr, "%s: ", LOG_STR); \
|
||||
do { \
|
||||
for (int i = 0; i < len; i++) { \
|
||||
if (i && !(i % 16)) { \
|
||||
fprintf(stderr, "\n"); \
|
||||
fprintf(stderr, "%s: ", LOG_STR); \
|
||||
} \
|
||||
fprintf(stderr, "%02x ", buffer[i]); \
|
||||
} \
|
||||
fprintf(stderr, "\n"); \
|
||||
} while (0)
|
||||
|
||||
#define BT_FW_PATH_NAME "/system/vendor/etc/firmware/fw_xr829_bt.bin"
|
||||
#define BT_FW_LOAD_ADDR 0x0000
|
||||
#define BT_FW_JUMP_ADDR 0x0000
|
||||
#define AW1722 1
|
||||
#define AW1732 2
|
||||
#define CHIP_NAME AW1722
|
||||
|
||||
#define SZ_1K (0x00000400U )
|
||||
#define SZ_16K (0x00004000U )
|
||||
|
||||
#define SWAP16(d) (((d & 0xff) << 8) | ((d & 0xff00) >> 8))
|
||||
#define SWAP32(d) (((d & 0xff) << 24) | ((d & 0xff00) << 8) \
|
||||
| ((d & 0xff0000) >> 8) | ((d & 0xff000000) >> 24))
|
||||
|
||||
#define CMD_ID(group, key) (((group) << 3) | (key))
|
||||
|
||||
/*----------------------------*/
|
||||
/* COMMANDS FORM PC TO MCU */
|
||||
/*----------------------------*/
|
||||
#define CMD_ID_MEMRW 0x00
|
||||
#define CMD_ID_SEQRQ 0x01
|
||||
#define CMD_ID_SYSCTL 0x02
|
||||
#define CMD_ID_FLASH 0x03
|
||||
|
||||
#define CMD_ID_SEQRD CMD_ID(CMD_ID_SEQRQ, 0)
|
||||
#define CMD_ID_SEQWR CMD_ID(CMD_ID_SEQRQ, 1)
|
||||
/* uart commands */
|
||||
#define CMD_ID_SETUART CMD_ID(CMD_ID_SYSCTL, 0)
|
||||
#define CMD_ID_SETPC CMD_ID(CMD_ID_SYSCTL, 3)
|
||||
|
||||
#define CMD_WRITEN 0
|
||||
#define CMD_WRITESEQ 1
|
||||
#define CMD_SETBAUD 2
|
||||
#define CMD_SETPC 3
|
||||
#define DATA_RAW 4
|
||||
|
||||
/******************************************************************************
|
||||
** Type definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* vendor serial control block */
|
||||
typedef struct
|
||||
{
|
||||
int fd; /* fd to Bluetooth device */
|
||||
struct termios *ti; /* serial terminal of BT port */
|
||||
} vnd_userial_cb_t;
|
||||
|
||||
#pragma pack(1)
|
||||
/* command header
|
||||
*
|
||||
* byte 0 byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 -7 byte 8-11
|
||||
* ___________________________________________________________________________________________________
|
||||
* | | | | | | | | |
|
||||
* | 'B' | 'R' | 'O' | 'M' | Flags |Reserved | Checksum | Playload Length |
|
||||
* |_________|_________|_________|_________|_________|_________|__________ ________|___________________|
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t magic[4]; // magic "BROM"
|
||||
#define CMD_BROM_MAGIC "BROM"
|
||||
uint8_t flags;
|
||||
#define CMD_HFLAG_ERROR (0x1U << 0)
|
||||
#define CMD_HFLAG_ACK (0x1U << 1)
|
||||
#define CMD_HFLAG_CHECK (0x1U << 2)
|
||||
#define CMD_HFLAG_RETRY (0x1U << 3)
|
||||
#define CMD_HFLAG_EXE (0x1U << 4)
|
||||
uint8_t version:4;
|
||||
uint8_t reserved:4;
|
||||
uint16_t checksum;
|
||||
uint32_t payload_len;
|
||||
} __attribute__((packed)) cmd_header_t;
|
||||
#define MB_CMD_HEADER_SIZE (sizeof(cmd_header_t))
|
||||
|
||||
/* acknownledge structure */
|
||||
typedef struct {
|
||||
cmd_header_t h;
|
||||
uint8_t err;
|
||||
} __attribute__((packed)) cmd_ack_t;
|
||||
|
||||
/* sequence read/write command structure */
|
||||
typedef struct {
|
||||
cmd_header_t h;
|
||||
uint8_t cmdid;
|
||||
uint32_t addr;
|
||||
uint32_t dlen;
|
||||
uint16_t dcs;
|
||||
} __attribute__((packed)) cmd_seq_wr_t;
|
||||
|
||||
/* io change command structure */
|
||||
typedef struct {
|
||||
cmd_header_t h;
|
||||
uint8_t cmdid;
|
||||
uint32_t val;
|
||||
} __attribute__((packed)) cmd_sys_t;
|
||||
|
||||
typedef struct {
|
||||
cmd_header_t h;
|
||||
uint8_t cmdid;
|
||||
uint32_t lcr;
|
||||
} __attribute__((packed)) cmd_sys_setuart_t;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
static const uint8_t hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 };
|
||||
static const uint8_t hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x04, 0x60, 0xE3, 0x16, 0x00};
|
||||
static vnd_userial_cb_t vnd_userial;
|
||||
|
||||
static int32_t cmd_sync_uart(void);
|
||||
static int32_t cmd_sync_baud(uint32_t lcr);
|
||||
static int32_t cmd_write_seq(uint32_t addr, uint32_t len, uint8_t *data);
|
||||
static int32_t cmd_set_pc(uint32_t pc);
|
||||
static void userial_set_hw_fctrl(uint8_t hw_fctrl);
|
||||
static uint32_t userial_read(uint8_t *p_buffer, uint32_t len, uint32_t timeout);
|
||||
static uint32_t userial_write(const uint8_t *p_data, uint32_t len);
|
||||
|
||||
/******************************************************************************
|
||||
** Functions
|
||||
******************************************************************************/
|
||||
static uint16_t CheckSum16(uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint16_t cs = 0;
|
||||
uint16_t *p = (uint16_t *)data;
|
||||
|
||||
while(len > 1) {
|
||||
cs += *p++;
|
||||
len -= 2;
|
||||
}
|
||||
if (len) {
|
||||
cs += *(uint8_t *)p;
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
static uint64_t time_gettimeofday_us(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (uint64_t)tv.tv_sec * 1000000ULL + (uint64_t)tv.tv_usec;
|
||||
}
|
||||
|
||||
static uint8_t *memsearch(uint8_t *haystack, uint32_t hlen, uint8_t *needle, uint32_t nlen)
|
||||
{
|
||||
while (hlen-- >= nlen) {
|
||||
if (!memcmp(haystack, needle, nlen)) {
|
||||
return haystack;
|
||||
}
|
||||
haystack++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t xr_raw_write(int type, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint8_t buffer[MB_CMD_HEADER_SIZE + 13] = {'B', 'R', 'O', 'M', 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint8_t *psend = data;
|
||||
uint32_t lsend = len;
|
||||
cmd_header_t *hdr = (cmd_header_t *)buffer;;
|
||||
cmd_ack_t *ack = (cmd_ack_t *)buffer;
|
||||
|
||||
if (type != DATA_RAW) {
|
||||
psend = buffer;
|
||||
lsend = MB_CMD_HEADER_SIZE + len;
|
||||
memcpy(buffer + MB_CMD_HEADER_SIZE, data, len);
|
||||
hdr->payload_len = len;
|
||||
#if ENABLE_DCS
|
||||
hdr->flags = CMD_HFLAG_CHECK;
|
||||
#endif
|
||||
hdr->checksum = ~CheckSum16(buffer, MB_CMD_HEADER_SIZE + len);
|
||||
hdr->payload_len = SWAP32(hdr->payload_len);
|
||||
hdr->checksum = SWAP16(hdr->checksum);
|
||||
switch (type) {
|
||||
case CMD_WRITESEQ:
|
||||
{
|
||||
cmd_seq_wr_t *cmd = (cmd_seq_wr_t *)buffer;
|
||||
cmd->addr = SWAP32(cmd->addr);
|
||||
cmd->dlen = SWAP32(cmd->dlen);
|
||||
cmd->dcs = SWAP16(cmd->dcs);
|
||||
}
|
||||
break;
|
||||
case CMD_SETBAUD:
|
||||
{
|
||||
cmd_sys_setuart_t *cmd = (cmd_sys_setuart_t*)buffer;
|
||||
cmd->lcr = SWAP32(cmd->lcr);
|
||||
}
|
||||
break;
|
||||
case CMD_SETPC:
|
||||
{
|
||||
cmd_sys_t *cmd = (cmd_sys_t*)buffer;
|
||||
cmd->val = SWAP32(cmd->val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
XR_ERR("%s: Unsupport type %d", __func__, type);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t ret_w, ret_r;
|
||||
uint64_t t0, t1, t2, t3;
|
||||
|
||||
tcflush(vnd_userial.fd, TCIOFLUSH);
|
||||
|
||||
t0 = time_gettimeofday_us();
|
||||
ret_w = userial_write(psend, lsend);
|
||||
t1 = time_gettimeofday_us();
|
||||
|
||||
memset(buffer, 0, MB_CMD_HEADER_SIZE + 1);
|
||||
|
||||
t2 = time_gettimeofday_us();
|
||||
ret_r = userial_read(buffer, MB_CMD_HEADER_SIZE, 100000);
|
||||
t3 = time_gettimeofday_us();
|
||||
|
||||
XR_DBG("%s, type: %d, write len: %5d, ret: %5d, time: %6lluus, read len: %2d, ret: %2d, %6lluus",
|
||||
__func__, type, lsend, ret_w, t1 - t0, MB_CMD_HEADER_SIZE, ret_r, t3 - t2);
|
||||
|
||||
uint8_t *p = (uint8_t *)memsearch(buffer, MB_CMD_HEADER_SIZE, (uint8_t *)"BROM", 4);
|
||||
if (p != buffer) {
|
||||
if (p == NULL) {
|
||||
XR_ERR("%s: invalid response", __func__);
|
||||
return -1;
|
||||
}
|
||||
uint32_t nowread = buffer + MB_CMD_HEADER_SIZE - p;
|
||||
uint32_t needread = p - buffer;
|
||||
XR_DBG("%s: Index error, re-find header magic", __func__);
|
||||
memcpy(buffer, p, nowread);
|
||||
memset(buffer + nowread, 0x0, needread);
|
||||
userial_read(buffer + nowread, needread, 100000);
|
||||
}
|
||||
|
||||
/* check response */
|
||||
if (ack->h.flags & CMD_HFLAG_ERROR) {
|
||||
userial_read(buffer + MB_CMD_HEADER_SIZE, 1, 100000);
|
||||
XR_ERR("%s: resp error flag, type %d", __func__, ack->err);
|
||||
return -ack->err;
|
||||
}
|
||||
|
||||
if (ack->h.flags & CMD_HFLAG_ACK) {
|
||||
/* convert network byte order to host byte order */
|
||||
ack->h.payload_len = SWAP32(ack->h.payload_len);
|
||||
ack->h.checksum = SWAP16(ack->h.checksum);
|
||||
if (ack->h.payload_len != 0) {
|
||||
XR_ERR("%s: data payload len %d != 0", __func__, ack->h.payload_len);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ack->h.flags & CMD_HFLAG_CHECK) {
|
||||
if (CheckSum16(buffer, MB_CMD_HEADER_SIZE) != 0xffff) {
|
||||
XR_ERR("%s: write data response 0 checksum error", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t cmd_sync_uart(void)
|
||||
{
|
||||
uint8_t sync = 0x55;
|
||||
uint8_t ack[3] = {0};
|
||||
ssize_t ret = -1;
|
||||
uint32_t cnt = 0;
|
||||
|
||||
do {
|
||||
XR_DBG("uart sync count:%d.", cnt);
|
||||
tcflush(vnd_userial.fd, TCIOFLUSH);
|
||||
userial_write(&sync, 1);
|
||||
ret = userial_read(ack, 2, 2000);
|
||||
if (ret == 2 && ((ack[0] == 'O' && ack[1] == 'K') || (ack[0] == 'K' && ack[1] == 'O'))) {
|
||||
XR_DBG("Receive %s, uart Sync done.", ack);
|
||||
return 0;
|
||||
}
|
||||
} while (cnt++ < 50);
|
||||
|
||||
XR_DBG("uart sync fail.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t cmd_sync_baud(uint32_t lcr)
|
||||
{
|
||||
uint8_t buffer[MB_CMD_HEADER_SIZE + 5];
|
||||
cmd_sys_setuart_t *cmd = (cmd_sys_setuart_t*)buffer;
|
||||
|
||||
cmd->cmdid = CMD_ID_SETUART;
|
||||
cmd->lcr = lcr;
|
||||
|
||||
uint8_t cnt = 0;
|
||||
int ret = -1;
|
||||
|
||||
do {
|
||||
XR_DBG("%s count:%d.", __func__, cnt);
|
||||
ret = xr_raw_write(CMD_SETBAUD, buffer + MB_CMD_HEADER_SIZE, 5);
|
||||
if (ret == 0) {
|
||||
set_speed(vnd_userial.fd, vnd_userial.ti, lcr & 0xffffff);
|
||||
return cmd_sync_uart();
|
||||
}
|
||||
} while (cnt++ < 3);
|
||||
|
||||
XR_DBG("cmd_sync_baud fail.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t cmd_write_seq(uint32_t addr, uint32_t len, uint8_t *data)
|
||||
{
|
||||
int ret = -1;
|
||||
uint8_t buffer[MB_CMD_HEADER_SIZE + 13];
|
||||
cmd_seq_wr_t *cmd = (cmd_seq_wr_t *)buffer;
|
||||
|
||||
cmd->cmdid = CMD_ID_SEQWR;
|
||||
cmd->addr = addr;
|
||||
cmd->dlen = len;
|
||||
#if ENABLE_DCS
|
||||
cmd->dcs = ~CheckSum16(data, len);
|
||||
#endif
|
||||
|
||||
ret = xr_raw_write(CMD_WRITESEQ, buffer + MB_CMD_HEADER_SIZE, 11);
|
||||
if (ret == 0) {
|
||||
return xr_raw_write(DATA_RAW, data, len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t cmd_set_pc(uint32_t pc)
|
||||
{
|
||||
uint8_t buffer[MB_CMD_HEADER_SIZE + 5];
|
||||
cmd_sys_t *cmd = (cmd_sys_t*)buffer;
|
||||
|
||||
cmd->cmdid = CMD_ID_SETPC;
|
||||
cmd->val = pc;
|
||||
XR_DBG("set pc %x, val %x", pc, cmd->val);
|
||||
|
||||
return xr_raw_write(CMD_SETPC, buffer + MB_CMD_HEADER_SIZE, 5);
|
||||
}
|
||||
|
||||
static void userial_set_hw_fctrl(uint8_t hw_fctrl)
|
||||
{
|
||||
if (vnd_userial.fd == -1) {
|
||||
XR_ERR("vnd_userial.fd is -1");
|
||||
return;
|
||||
}
|
||||
|
||||
if (hw_fctrl) {
|
||||
XR_DBG("Set HW FlowControl On");
|
||||
vnd_userial.ti->c_cflag |= CRTSCTS;
|
||||
} else {
|
||||
XR_DBG("Set HW FlowControl Off");
|
||||
vnd_userial.ti->c_cflag &= ~CRTSCTS;
|
||||
}
|
||||
tcsetattr(vnd_userial.fd, TCSANOW, vnd_userial.ti);
|
||||
tcflush(vnd_userial.fd, TCIOFLUSH);
|
||||
}
|
||||
|
||||
static uint32_t userial_read(uint8_t *buffer, uint32_t len, uint32_t timeout)
|
||||
{
|
||||
fd_set set;
|
||||
struct timeval tv;
|
||||
int rv;
|
||||
|
||||
FD_ZERO(&set); /* clear the set */
|
||||
FD_SET(vnd_userial.fd, &set); /* add our file descriptor to the set */
|
||||
|
||||
/* there was data to read */
|
||||
ssize_t r;
|
||||
uint8_t *pos = (uint8_t*)buffer;
|
||||
|
||||
while (len > 0) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = timeout;
|
||||
|
||||
rv = select(vnd_userial.fd + 1, &set, NULL, NULL, &tv);
|
||||
if(rv == -1) {
|
||||
XR_ERR("select error"); /* an error accured */
|
||||
break;
|
||||
} else if(rv == 0) {
|
||||
XR_ERR("read timeout"); /* a timeout occured */
|
||||
break;
|
||||
}
|
||||
|
||||
r = read(vnd_userial.fd, pos, len);
|
||||
if (r < 1)
|
||||
break;
|
||||
|
||||
len -= r;
|
||||
pos += r;
|
||||
}
|
||||
|
||||
return pos - buffer;
|
||||
}
|
||||
|
||||
static uint32_t userial_write(const uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
ssize_t r;
|
||||
uint8_t *pos = (uint8_t*)buffer;
|
||||
|
||||
while (len > 0) {
|
||||
r = write(vnd_userial.fd, pos, len);
|
||||
if (r < 1)
|
||||
break;
|
||||
|
||||
len -= r;
|
||||
pos += r;
|
||||
}
|
||||
|
||||
return pos - buffer;
|
||||
}
|
||||
|
||||
static int32_t load_btfirmware(void)
|
||||
{
|
||||
FILE *fwfile_fd = NULL;
|
||||
uint32_t len;
|
||||
uint8_t *data = NULL;
|
||||
uint32_t addr = BT_FW_LOAD_ADDR;
|
||||
uint32_t section = SZ_16K;
|
||||
|
||||
fwfile_fd = fopen(BT_FW_PATH_NAME, "rb");
|
||||
XR_DBG("BT firmware: %s", BT_FW_PATH_NAME);
|
||||
if(!fwfile_fd) {
|
||||
XR_ERR("Unable to open BT firmware %s", BT_FW_PATH_NAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = (uint8_t*)malloc(section);
|
||||
if (data == NULL) {
|
||||
XR_DBG("failed to alloc %d byte memory.", section);
|
||||
fclose(fwfile_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
XR_DBG("load bt firmware starting.");
|
||||
while ((len = fread(data, 1, section, fwfile_fd)) > 0) {
|
||||
cmd_write_seq(addr, len, data);
|
||||
addr += len;
|
||||
}
|
||||
|
||||
free(data);
|
||||
fclose(fwfile_fd);
|
||||
XR_DBG("load firmware done.");
|
||||
|
||||
XR_DBG("Firmware run from address 0x%08X", BT_FW_JUMP_ADDR);
|
||||
cmd_set_pc(BT_FW_JUMP_ADDR);
|
||||
|
||||
if (CHIP_NAME == AW1732) {
|
||||
XR_DBG("second time sync starting....");
|
||||
if (cmd_sync_uart() < 0)
|
||||
return -1;
|
||||
cmd_set_pc(BT_FW_JUMP_ADDR);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
static int hci_cmd_handle(const uint8_t *cmd, uint32_t cmd_len, uint32_t event_len)
|
||||
{
|
||||
uint8_t buffer[256];
|
||||
|
||||
XR_DBG("send hci command");
|
||||
userial_write(cmd, cmd_len);
|
||||
XR_DUMP(cmd, cmd_len);
|
||||
|
||||
if (read_hci_event(vnd_userial.fd, buffer, event_len) != event_len) {
|
||||
XR_ERR("Event read error");
|
||||
return -1;
|
||||
}
|
||||
XR_DBG("Received event");
|
||||
XR_DUMP(buffer, event_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xr_init(int fd, struct uart_t *u, struct termios *ti)
|
||||
{
|
||||
vnd_userial.fd = fd;
|
||||
vnd_userial.ti = ti;
|
||||
|
||||
XR_DBG("uart sync starting....");
|
||||
if (cmd_sync_uart() < 0)
|
||||
goto END;
|
||||
XR_DBG("set bandrate to %d.", u->speed);
|
||||
if (cmd_sync_baud(((u->speed) | (3<<24))) < 0)
|
||||
goto END;
|
||||
if (load_btfirmware() < 0)
|
||||
goto END;
|
||||
XR_DBG("bt firmware is running....");
|
||||
|
||||
XR_DBG("set baudrate to %d", u->init_speed);
|
||||
set_speed(vnd_userial.fd, vnd_userial.ti, u->init_speed);
|
||||
userial_set_hw_fctrl(1);
|
||||
usleep(50000);
|
||||
|
||||
XR_DBG("process hci reset...");
|
||||
if (hci_cmd_handle(hci_reset, sizeof(hci_reset), 7) < 0)
|
||||
goto END;
|
||||
|
||||
XR_DBG("process hci update baud...");
|
||||
if (hci_cmd_handle(hci_update_baud_rate, sizeof(hci_update_baud_rate), 7) < 0)
|
||||
goto END;
|
||||
|
||||
usleep(100000);
|
||||
|
||||
return 0;
|
||||
|
||||
END:
|
||||
XR_DBG("device fd = %d close", fd);
|
||||
close(vnd_userial.fd);
|
||||
vnd_userial.fd = -1;
|
||||
vnd_userial.ti = NULL;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xr_post(int fd, struct uart_t *u, struct termios *ti)
|
||||
{
|
||||
XR_DBG("Done setting line discpline");
|
||||
return 0;
|
||||
}
|
||||
|
||||
2052
external/cache/sources/hcitools/hciconfig.c
vendored
Normal file
2052
external/cache/sources/hcitools/hciconfig.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3122
external/cache/sources/hcitools/hcitool.c
vendored
Normal file
3122
external/cache/sources/hcitools/hcitool.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
149
external/cache/sources/hcitools/lib/a2mp.h
vendored
Normal file
149
external/cache/sources/hcitools/lib/a2mp.h
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2012 Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __A2MP_H
|
||||
#define __A2MP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* A2MP Protocol */
|
||||
|
||||
/* A2MP command codes */
|
||||
|
||||
#define A2MP_COMMAND_REJ 0x01
|
||||
#define A2MP_DISCOVER_REQ 0x02
|
||||
#define A2MP_DISCOVER_RSP 0x03
|
||||
#define A2MP_CHANGE_NOTIFY 0x04
|
||||
#define A2MP_CHANGE_RSP 0x05
|
||||
#define A2MP_INFO_REQ 0x06
|
||||
#define A2MP_INFO_RSP 0x07
|
||||
#define A2MP_ASSOC_REQ 0x08
|
||||
#define A2MP_ASSOC_RSP 0x09
|
||||
#define A2MP_CREATE_REQ 0x0a
|
||||
#define A2MP_CREATE_RSP 0x0b
|
||||
#define A2MP_DISCONN_REQ 0x0c
|
||||
#define A2MP_DISCONN_RSP 0x0d
|
||||
|
||||
struct a2mp_hdr {
|
||||
uint8_t code;
|
||||
uint8_t ident;
|
||||
uint16_t len;
|
||||
} __attribute__ ((packed));
|
||||
#define A2MP_HDR_SIZE 4
|
||||
|
||||
struct a2mp_command_rej {
|
||||
uint16_t reason;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_discover_req {
|
||||
uint16_t mtu;
|
||||
uint16_t mask;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_ctrl {
|
||||
uint8_t id;
|
||||
uint8_t type;
|
||||
uint8_t status;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_discover_rsp {
|
||||
uint16_t mtu;
|
||||
uint16_t mask;
|
||||
struct a2mp_ctrl ctrl_list[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_info_req {
|
||||
uint8_t id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_info_rsp {
|
||||
uint8_t id;
|
||||
uint8_t status;
|
||||
uint32_t total_bw;
|
||||
uint32_t max_bw;
|
||||
uint32_t min_latency;
|
||||
uint16_t pal_caps;
|
||||
uint16_t assoc_size;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_assoc_req {
|
||||
uint8_t id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_assoc_rsp {
|
||||
uint8_t id;
|
||||
uint8_t status;
|
||||
uint8_t assoc_data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_create_req {
|
||||
uint8_t local_id;
|
||||
uint8_t remote_id;
|
||||
uint8_t assoc_data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_create_rsp {
|
||||
uint8_t local_id;
|
||||
uint8_t remote_id;
|
||||
uint8_t status;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_disconn_req {
|
||||
uint8_t local_id;
|
||||
uint8_t remote_id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct a2mp_disconn_rsp {
|
||||
uint8_t local_id;
|
||||
uint8_t remote_id;
|
||||
uint8_t status;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define A2MP_COMMAND_NOT_RECOGNIZED 0x0000
|
||||
|
||||
/* AMP controller status */
|
||||
#define AMP_CTRL_POWERED_DOWN 0x00
|
||||
#define AMP_CTRL_BLUETOOTH_ONLY 0x01
|
||||
#define AMP_CTRL_NO_CAPACITY 0x02
|
||||
#define AMP_CTRL_LOW_CAPACITY 0x03
|
||||
#define AMP_CTRL_MEDIUM_CAPACITY 0x04
|
||||
#define AMP_CTRL_HIGH_CAPACITY 0x05
|
||||
#define AMP_CTRL_FULL_CAPACITY 0x06
|
||||
|
||||
/* A2MP response status */
|
||||
#define A2MP_STATUS_SUCCESS 0x00
|
||||
#define A2MP_STATUS_INVALID_CTRL_ID 0x01
|
||||
#define A2MP_STATUS_UNABLE_START_LINK_CREATION 0x02
|
||||
#define A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS 0x02
|
||||
#define A2MP_STATUS_COLLISION_OCCURED 0x03
|
||||
#define A2MP_STATUS_DISCONN_REQ_RECVD 0x04
|
||||
#define A2MP_STATUS_PHYS_LINK_EXISTS 0x05
|
||||
#define A2MP_STATUS_SECURITY_VIOLATION 0x06
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __A2MP_H */
|
||||
172
external/cache/sources/hcitools/lib/amp.h
vendored
Normal file
172
external/cache/sources/hcitools/lib/amp.h
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2010-2011 Code Aurora Forum. All rights reserved.
|
||||
* Copyright (C) 2012 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AMP_H
|
||||
#define __AMP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AMP_MGR_CID 0x03
|
||||
|
||||
/* AMP manager codes */
|
||||
#define AMP_COMMAND_REJ 0x01
|
||||
#define AMP_DISCOVER_REQ 0x02
|
||||
#define AMP_DISCOVER_RSP 0x03
|
||||
#define AMP_CHANGE_NOTIFY 0x04
|
||||
#define AMP_CHANGE_RSP 0x05
|
||||
#define AMP_INFO_REQ 0x06
|
||||
#define AMP_INFO_RSP 0x07
|
||||
#define AMP_ASSOC_REQ 0x08
|
||||
#define AMP_ASSOC_RSP 0x09
|
||||
#define AMP_LINK_REQ 0x0a
|
||||
#define AMP_LINK_RSP 0x0b
|
||||
#define AMP_DISCONN_REQ 0x0c
|
||||
#define AMP_DISCONN_RSP 0x0d
|
||||
|
||||
typedef struct {
|
||||
uint8_t code;
|
||||
uint8_t ident;
|
||||
uint16_t len;
|
||||
} __attribute__ ((packed)) amp_mgr_hdr;
|
||||
#define AMP_MGR_HDR_SIZE 4
|
||||
|
||||
/* AMP ASSOC structure */
|
||||
typedef struct {
|
||||
uint8_t type_id;
|
||||
uint16_t len;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed)) amp_assoc_tlv;
|
||||
|
||||
typedef struct {
|
||||
uint16_t reason;
|
||||
} __attribute__ ((packed)) amp_cmd_rej_parms;
|
||||
|
||||
typedef struct {
|
||||
uint16_t mtu;
|
||||
uint16_t mask;
|
||||
} __attribute__ ((packed)) amp_discover_req_parms;
|
||||
|
||||
typedef struct {
|
||||
uint16_t mtu;
|
||||
uint16_t mask;
|
||||
uint8_t controller_list[0];
|
||||
} __attribute__ ((packed)) amp_discover_rsp_parms;
|
||||
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
} __attribute__ ((packed)) amp_info_req_parms;
|
||||
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
uint8_t status;
|
||||
uint32_t total_bandwidth;
|
||||
uint32_t max_bandwidth;
|
||||
uint32_t min_latency;
|
||||
uint16_t pal_caps;
|
||||
uint16_t assoc_size;
|
||||
} __attribute__ ((packed)) amp_info_rsp_parms;
|
||||
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
uint8_t status;
|
||||
amp_assoc_tlv assoc;
|
||||
} __attribute__ ((packed)) amp_assoc_rsp_parms;
|
||||
|
||||
typedef struct {
|
||||
uint8_t local_id;
|
||||
uint8_t remote_id;
|
||||
amp_assoc_tlv assoc;
|
||||
} __attribute__ ((packed)) amp_link_req_parms;
|
||||
|
||||
typedef struct {
|
||||
uint8_t local_id;
|
||||
uint8_t remote_id;
|
||||
uint8_t status;
|
||||
} __attribute__ ((packed)) amp_link_rsp_parms;
|
||||
|
||||
typedef struct {
|
||||
uint8_t local_id;
|
||||
uint8_t remote_id;
|
||||
} __attribute__ ((packed)) amp_disconn_req_parms;
|
||||
|
||||
#define A2MP_MAC_ADDR_TYPE 1
|
||||
#define A2MP_PREF_CHANLIST_TYPE 2
|
||||
#define A2MP_CONNECTED_CHAN 3
|
||||
#define A2MP_PAL_CAP_TYPE 4
|
||||
#define A2MP_PAL_VER_INFO 5
|
||||
|
||||
struct amp_tlv {
|
||||
uint8_t type;
|
||||
uint16_t len;
|
||||
uint8_t val[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct amp_pal_ver {
|
||||
uint8_t ver;
|
||||
uint16_t company_id;
|
||||
uint16_t sub_ver;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct amp_country_triplet {
|
||||
union {
|
||||
struct {
|
||||
uint8_t first_channel;
|
||||
uint8_t num_channels;
|
||||
int8_t max_power;
|
||||
} __attribute__ ((packed)) chans;
|
||||
struct {
|
||||
uint8_t reg_extension_id;
|
||||
uint8_t reg_class;
|
||||
uint8_t coverage_class;
|
||||
} __attribute__ ((packed)) ext;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct amp_chan_list {
|
||||
uint8_t country_code[3];
|
||||
struct amp_country_triplet triplets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define AMP_COMMAND_NOT_RECOGNIZED 0x0000
|
||||
|
||||
/* AMP controller status */
|
||||
#define AMP_CT_POWERED_DOWN 0x00
|
||||
#define AMP_CT_BLUETOOTH_ONLY 0x01
|
||||
#define AMP_CT_NO_CAPACITY 0x02
|
||||
#define AMP_CT_LOW_CAPACITY 0x03
|
||||
#define AMP_CT_MEDIUM_CAPACITY 0x04
|
||||
#define AMP_CT_HIGH_CAPACITY 0x05
|
||||
#define AMP_CT_FULL_CAPACITY 0x06
|
||||
|
||||
/* AMP response status */
|
||||
#define AMP_STATUS_SUCCESS 0x00
|
||||
#define AMP_STATUS_INVALID_CTRL_ID 0x01
|
||||
#define AMP_STATUS_UNABLE_START_LINK_CREATION 0x02
|
||||
#define AMP_STATUS_NO_PHYSICAL_LINK_EXISTS 0x02
|
||||
#define AMP_STATUS_COLLISION_OCCURED 0x03
|
||||
#define AMP_STATUS_DISCONN_REQ_RECVD 0x04
|
||||
#define AMP_STATUS_PHYS_LINK_EXISTS 0x05
|
||||
#define AMP_STATUS_SECURITY_VIOLATION 0x06
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __AMP_H */
|
||||
765
external/cache/sources/hcitools/lib/bluetooth.c
vendored
Normal file
765
external/cache/sources/hcitools/lib/bluetooth.c
vendored
Normal file
@@ -0,0 +1,765 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "bluetooth.h"
|
||||
#include "hci.h"
|
||||
|
||||
void baswap(bdaddr_t *dst, const bdaddr_t *src)
|
||||
{
|
||||
register unsigned char *d = (unsigned char *) dst;
|
||||
register const unsigned char *s = (const unsigned char *) src;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
d[i] = s[5-i];
|
||||
}
|
||||
|
||||
char *batostr(const bdaddr_t *ba)
|
||||
{
|
||||
char *str = bt_malloc(18);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
|
||||
ba->b[0], ba->b[1], ba->b[2],
|
||||
ba->b[3], ba->b[4], ba->b[5]);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
bdaddr_t *strtoba(const char *str)
|
||||
{
|
||||
bdaddr_t b;
|
||||
bdaddr_t *ba = bt_malloc(sizeof(*ba));
|
||||
|
||||
if (ba) {
|
||||
str2ba(str, &b);
|
||||
baswap(ba, &b);
|
||||
}
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
||||
int ba2str(const bdaddr_t *ba, char *str)
|
||||
{
|
||||
return sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
|
||||
ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]);
|
||||
}
|
||||
|
||||
int str2ba(const char *str, bdaddr_t *ba)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (bachk(str) < 0) {
|
||||
memset(ba, 0, sizeof(*ba));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 5; i >= 0; i--, str += 3)
|
||||
ba->b[i] = strtol(str, NULL, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ba2oui(const bdaddr_t *ba, char *str)
|
||||
{
|
||||
return sprintf(str, "%2.2X-%2.2X-%2.2X", ba->b[5], ba->b[4], ba->b[3]);
|
||||
}
|
||||
|
||||
int bachk(const char *str)
|
||||
{
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
if (strlen(str) != 17)
|
||||
return -1;
|
||||
|
||||
while (*str) {
|
||||
if (!isxdigit(*str++))
|
||||
return -1;
|
||||
|
||||
if (!isxdigit(*str++))
|
||||
return -1;
|
||||
|
||||
if (*str == 0)
|
||||
break;
|
||||
|
||||
if (*str++ != ':')
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int baprintf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vprintf(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int bafprintf(FILE *stream, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vfprintf(stream, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int basprintf(char *str, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vsnprintf(str, (~0U) >> 1, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int basnprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vsnprintf(str, size, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void *bt_malloc(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void bt_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/* Bluetooth error codes to Unix errno mapping */
|
||||
int bt_error(uint16_t code)
|
||||
{
|
||||
switch (code) {
|
||||
case 0:
|
||||
return 0;
|
||||
case HCI_UNKNOWN_COMMAND:
|
||||
return EBADRQC;
|
||||
case HCI_NO_CONNECTION:
|
||||
return ENOTCONN;
|
||||
case HCI_HARDWARE_FAILURE:
|
||||
return EIO;
|
||||
case HCI_PAGE_TIMEOUT:
|
||||
return EHOSTDOWN;
|
||||
case HCI_AUTHENTICATION_FAILURE:
|
||||
return EACCES;
|
||||
case HCI_PIN_OR_KEY_MISSING:
|
||||
return EINVAL;
|
||||
case HCI_MEMORY_FULL:
|
||||
return ENOMEM;
|
||||
case HCI_CONNECTION_TIMEOUT:
|
||||
return ETIMEDOUT;
|
||||
case HCI_MAX_NUMBER_OF_CONNECTIONS:
|
||||
case HCI_MAX_NUMBER_OF_SCO_CONNECTIONS:
|
||||
return EMLINK;
|
||||
case HCI_ACL_CONNECTION_EXISTS:
|
||||
return EALREADY;
|
||||
case HCI_COMMAND_DISALLOWED:
|
||||
case HCI_TRANSACTION_COLLISION:
|
||||
case HCI_ROLE_SWITCH_PENDING:
|
||||
return EBUSY;
|
||||
case HCI_REJECTED_LIMITED_RESOURCES:
|
||||
case HCI_REJECTED_PERSONAL:
|
||||
case HCI_QOS_REJECTED:
|
||||
return ECONNREFUSED;
|
||||
case HCI_HOST_TIMEOUT:
|
||||
return ETIMEDOUT;
|
||||
case HCI_UNSUPPORTED_FEATURE:
|
||||
case HCI_QOS_NOT_SUPPORTED:
|
||||
case HCI_PAIRING_NOT_SUPPORTED:
|
||||
case HCI_CLASSIFICATION_NOT_SUPPORTED:
|
||||
case HCI_UNSUPPORTED_LMP_PARAMETER_VALUE:
|
||||
case HCI_PARAMETER_OUT_OF_RANGE:
|
||||
case HCI_QOS_UNACCEPTABLE_PARAMETER:
|
||||
return EOPNOTSUPP;
|
||||
case HCI_INVALID_PARAMETERS:
|
||||
case HCI_SLOT_VIOLATION:
|
||||
return EINVAL;
|
||||
case HCI_OE_USER_ENDED_CONNECTION:
|
||||
case HCI_OE_LOW_RESOURCES:
|
||||
case HCI_OE_POWER_OFF:
|
||||
return ECONNRESET;
|
||||
case HCI_CONNECTION_TERMINATED:
|
||||
return ECONNABORTED;
|
||||
case HCI_REPEATED_ATTEMPTS:
|
||||
return ELOOP;
|
||||
case HCI_REJECTED_SECURITY:
|
||||
case HCI_PAIRING_NOT_ALLOWED:
|
||||
case HCI_INSUFFICIENT_SECURITY:
|
||||
return EACCES;
|
||||
case HCI_UNSUPPORTED_REMOTE_FEATURE:
|
||||
return EPROTONOSUPPORT;
|
||||
case HCI_SCO_OFFSET_REJECTED:
|
||||
return ECONNREFUSED;
|
||||
case HCI_UNKNOWN_LMP_PDU:
|
||||
case HCI_INVALID_LMP_PARAMETERS:
|
||||
case HCI_LMP_ERROR_TRANSACTION_COLLISION:
|
||||
case HCI_LMP_PDU_NOT_ALLOWED:
|
||||
case HCI_ENCRYPTION_MODE_NOT_ACCEPTED:
|
||||
return EPROTO;
|
||||
default:
|
||||
return ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
const char *bt_compidtostr(int compid)
|
||||
{
|
||||
switch (compid) {
|
||||
case 0:
|
||||
return "Ericsson Technology Licensing";
|
||||
case 1:
|
||||
return "Nokia Mobile Phones";
|
||||
case 2:
|
||||
return "Intel Corp.";
|
||||
case 3:
|
||||
return "IBM Corp.";
|
||||
case 4:
|
||||
return "Toshiba Corp.";
|
||||
case 5:
|
||||
return "3Com";
|
||||
case 6:
|
||||
return "Microsoft";
|
||||
case 7:
|
||||
return "Lucent";
|
||||
case 8:
|
||||
return "Motorola";
|
||||
case 9:
|
||||
return "Infineon Technologies AG";
|
||||
case 10:
|
||||
return "Cambridge Silicon Radio";
|
||||
case 11:
|
||||
return "Silicon Wave";
|
||||
case 12:
|
||||
return "Digianswer A/S";
|
||||
case 13:
|
||||
return "Texas Instruments Inc.";
|
||||
case 14:
|
||||
return "Ceva, Inc. (formerly Parthus Technologies, Inc.)";
|
||||
case 15:
|
||||
return "Broadcom Corporation";
|
||||
case 16:
|
||||
return "Mitel Semiconductor";
|
||||
case 17:
|
||||
return "Widcomm, Inc";
|
||||
case 18:
|
||||
return "Zeevo, Inc.";
|
||||
case 19:
|
||||
return "Atmel Corporation";
|
||||
case 20:
|
||||
return "Mitsubishi Electric Corporation";
|
||||
case 21:
|
||||
return "RTX Telecom A/S";
|
||||
case 22:
|
||||
return "KC Technology Inc.";
|
||||
case 23:
|
||||
return "NewLogic";
|
||||
case 24:
|
||||
return "Transilica, Inc.";
|
||||
case 25:
|
||||
return "Rohde & Schwarz GmbH & Co. KG";
|
||||
case 26:
|
||||
return "TTPCom Limited";
|
||||
case 27:
|
||||
return "Signia Technologies, Inc.";
|
||||
case 28:
|
||||
return "Conexant Systems Inc.";
|
||||
case 29:
|
||||
return "Qualcomm";
|
||||
case 30:
|
||||
return "Inventel";
|
||||
case 31:
|
||||
return "AVM Berlin";
|
||||
case 32:
|
||||
return "BandSpeed, Inc.";
|
||||
case 33:
|
||||
return "Mansella Ltd";
|
||||
case 34:
|
||||
return "NEC Corporation";
|
||||
case 35:
|
||||
return "WavePlus Technology Co., Ltd.";
|
||||
case 36:
|
||||
return "Alcatel";
|
||||
case 37:
|
||||
return "Philips Semiconductors";
|
||||
case 38:
|
||||
return "C Technologies";
|
||||
case 39:
|
||||
return "Open Interface";
|
||||
case 40:
|
||||
return "R F Micro Devices";
|
||||
case 41:
|
||||
return "Hitachi Ltd";
|
||||
case 42:
|
||||
return "Symbol Technologies, Inc.";
|
||||
case 43:
|
||||
return "Tenovis";
|
||||
case 44:
|
||||
return "Macronix International Co. Ltd.";
|
||||
case 45:
|
||||
return "GCT Semiconductor";
|
||||
case 46:
|
||||
return "Norwood Systems";
|
||||
case 47:
|
||||
return "MewTel Technology Inc.";
|
||||
case 48:
|
||||
return "ST Microelectronics";
|
||||
case 49:
|
||||
return "Synopsis";
|
||||
case 50:
|
||||
return "Red-M (Communications) Ltd";
|
||||
case 51:
|
||||
return "Commil Ltd";
|
||||
case 52:
|
||||
return "Computer Access Technology Corporation (CATC)";
|
||||
case 53:
|
||||
return "Eclipse (HQ Espana) S.L.";
|
||||
case 54:
|
||||
return "Renesas Technology Corp.";
|
||||
case 55:
|
||||
return "Mobilian Corporation";
|
||||
case 56:
|
||||
return "Terax";
|
||||
case 57:
|
||||
return "Integrated System Solution Corp.";
|
||||
case 58:
|
||||
return "Matsushita Electric Industrial Co., Ltd.";
|
||||
case 59:
|
||||
return "Gennum Corporation";
|
||||
case 60:
|
||||
return "Research In Motion";
|
||||
case 61:
|
||||
return "IPextreme, Inc.";
|
||||
case 62:
|
||||
return "Systems and Chips, Inc.";
|
||||
case 63:
|
||||
return "Bluetooth SIG, Inc.";
|
||||
case 64:
|
||||
return "Seiko Epson Corporation";
|
||||
case 65:
|
||||
return "Integrated Silicon Solution Taiwan, Inc.";
|
||||
case 66:
|
||||
return "CONWISE Technology Corporation Ltd";
|
||||
case 67:
|
||||
return "PARROT SA";
|
||||
case 68:
|
||||
return "Socket Mobile";
|
||||
case 69:
|
||||
return "Atheros Communications, Inc.";
|
||||
case 70:
|
||||
return "MediaTek, Inc.";
|
||||
case 71:
|
||||
return "Bluegiga";
|
||||
case 72:
|
||||
return "Marvell Technology Group Ltd.";
|
||||
case 73:
|
||||
return "3DSP Corporation";
|
||||
case 74:
|
||||
return "Accel Semiconductor Ltd.";
|
||||
case 75:
|
||||
return "Continental Automotive Systems";
|
||||
case 76:
|
||||
return "Apple, Inc.";
|
||||
case 77:
|
||||
return "Staccato Communications, Inc.";
|
||||
case 78:
|
||||
return "Avago Technologies";
|
||||
case 79:
|
||||
return "APT Licensing Ltd.";
|
||||
case 80:
|
||||
return "SiRF Technology";
|
||||
case 81:
|
||||
return "Tzero Technologies, Inc.";
|
||||
case 82:
|
||||
return "J&M Corporation";
|
||||
case 83:
|
||||
return "Free2move AB";
|
||||
case 84:
|
||||
return "3DiJoy Corporation";
|
||||
case 85:
|
||||
return "Plantronics, Inc.";
|
||||
case 86:
|
||||
return "Sony Ericsson Mobile Communications";
|
||||
case 87:
|
||||
return "Harman International Industries, Inc.";
|
||||
case 88:
|
||||
return "Vizio, Inc.";
|
||||
case 89:
|
||||
return "Nordic Semiconductor ASA";
|
||||
case 90:
|
||||
return "EM Microelectronic-Marin SA";
|
||||
case 91:
|
||||
return "Ralink Technology Corporation";
|
||||
case 92:
|
||||
return "Belkin International, Inc.";
|
||||
case 93:
|
||||
return "Realtek Semiconductor Corporation";
|
||||
case 94:
|
||||
return "Stonestreet One, LLC";
|
||||
case 95:
|
||||
return "Wicentric, Inc.";
|
||||
case 96:
|
||||
return "RivieraWaves S.A.S";
|
||||
case 97:
|
||||
return "RDA Microelectronics";
|
||||
case 98:
|
||||
return "Gibson Guitars";
|
||||
case 99:
|
||||
return "MiCommand Inc.";
|
||||
case 100:
|
||||
return "Band XI International, LLC";
|
||||
case 101:
|
||||
return "Hewlett-Packard Company";
|
||||
case 102:
|
||||
return "9Solutions Oy";
|
||||
case 103:
|
||||
return "GN Netcom A/S";
|
||||
case 104:
|
||||
return "General Motors";
|
||||
case 105:
|
||||
return "A&D Engineering, Inc.";
|
||||
case 106:
|
||||
return "MindTree Ltd.";
|
||||
case 107:
|
||||
return "Polar Electro OY";
|
||||
case 108:
|
||||
return "Beautiful Enterprise Co., Ltd.";
|
||||
case 109:
|
||||
return "BriarTek, Inc.";
|
||||
case 110:
|
||||
return "Summit Data Communications, Inc.";
|
||||
case 111:
|
||||
return "Sound ID";
|
||||
case 112:
|
||||
return "Monster, LLC";
|
||||
case 113:
|
||||
return "connectBlue AB";
|
||||
case 114:
|
||||
return "ShangHai Super Smart Electronics Co. Ltd.";
|
||||
case 115:
|
||||
return "Group Sense Ltd.";
|
||||
case 116:
|
||||
return "Zomm, LLC";
|
||||
case 117:
|
||||
return "Samsung Electronics Co. Ltd.";
|
||||
case 118:
|
||||
return "Creative Technology Ltd.";
|
||||
case 119:
|
||||
return "Laird Technologies";
|
||||
case 120:
|
||||
return "Nike, Inc.";
|
||||
case 121:
|
||||
return "lesswire AG";
|
||||
case 122:
|
||||
return "MStar Semiconductor, Inc.";
|
||||
case 123:
|
||||
return "Hanlynn Technologies";
|
||||
case 124:
|
||||
return "A & R Cambridge";
|
||||
case 125:
|
||||
return "Seers Technology Co. Ltd";
|
||||
case 126:
|
||||
return "Sports Tracking Technologies Ltd.";
|
||||
case 127:
|
||||
return "Autonet Mobile";
|
||||
case 128:
|
||||
return "DeLorme Publishing Company, Inc.";
|
||||
case 129:
|
||||
return "WuXi Vimicro";
|
||||
case 130:
|
||||
return "Sennheiser Communications A/S";
|
||||
case 131:
|
||||
return "TimeKeeping Systems, Inc.";
|
||||
case 132:
|
||||
return "Ludus Helsinki Ltd.";
|
||||
case 133:
|
||||
return "BlueRadios, Inc.";
|
||||
case 134:
|
||||
return "equinox AG";
|
||||
case 135:
|
||||
return "Garmin International, Inc.";
|
||||
case 136:
|
||||
return "Ecotest";
|
||||
case 137:
|
||||
return "GN ReSound A/S";
|
||||
case 138:
|
||||
return "Jawbone";
|
||||
case 139:
|
||||
return "Topcorn Positioning Systems, LLC";
|
||||
case 140:
|
||||
return "Qualcomm Labs, Inc.";
|
||||
case 141:
|
||||
return "Zscan Software";
|
||||
case 142:
|
||||
return "Quintic Corp.";
|
||||
case 143:
|
||||
return "Stollman E+V GmbH";
|
||||
case 144:
|
||||
return "Funai Electric Co., Ltd.";
|
||||
case 145:
|
||||
return "Advanced PANMOBIL Systems GmbH & Co. KG";
|
||||
case 146:
|
||||
return "ThinkOptics, Inc.";
|
||||
case 147:
|
||||
return "Universal Electronics, Inc.";
|
||||
case 148:
|
||||
return "Airoha Technology Corp.";
|
||||
case 149:
|
||||
return "NEC Lighting, Ltd.";
|
||||
case 150:
|
||||
return "ODM Technology, Inc.";
|
||||
case 151:
|
||||
return "ConnecteDevice Ltd.";
|
||||
case 152:
|
||||
return "zer01.tv GmbH";
|
||||
case 153:
|
||||
return "i.Tech Dynamic Global Distribution Ltd.";
|
||||
case 154:
|
||||
return "Alpwise";
|
||||
case 155:
|
||||
return "Jiangsu Toppower Automotive Electronics Co., Ltd.";
|
||||
case 156:
|
||||
return "Colorfy, Inc.";
|
||||
case 157:
|
||||
return "Geoforce Inc.";
|
||||
case 158:
|
||||
return "Bose Corporation";
|
||||
case 159:
|
||||
return "Suunto Oy";
|
||||
case 160:
|
||||
return "Kensington Computer Products Group";
|
||||
case 161:
|
||||
return "SR-Medizinelektronik";
|
||||
case 162:
|
||||
return "Vertu Corporation Limited";
|
||||
case 163:
|
||||
return "Meta Watch Ltd.";
|
||||
case 164:
|
||||
return "LINAK A/S";
|
||||
case 165:
|
||||
return "OTL Dynamics LLC";
|
||||
case 166:
|
||||
return "Panda Ocean Inc.";
|
||||
case 167:
|
||||
return "Visteon Corporation";
|
||||
case 168:
|
||||
return "ARP Devices Limited";
|
||||
case 169:
|
||||
return "Magneti Marelli S.p.A";
|
||||
case 170:
|
||||
return "CAEN RFID srl";
|
||||
case 171:
|
||||
return "Ingenieur-Systemgruppe Zahn GmbH";
|
||||
case 172:
|
||||
return "Green Throttle Games";
|
||||
case 173:
|
||||
return "Peter Systemtechnik GmbH";
|
||||
case 174:
|
||||
return "Omegawave Oy";
|
||||
case 175:
|
||||
return "Cinetix";
|
||||
case 176:
|
||||
return "Passif Semiconductor Corp";
|
||||
case 177:
|
||||
return "Saris Cycling Group, Inc";
|
||||
case 178:
|
||||
return "Bekey A/S";
|
||||
case 179:
|
||||
return "Clarinox Technologies Pty. Ltd.";
|
||||
case 180:
|
||||
return "BDE Technology Co., Ltd.";
|
||||
case 181:
|
||||
return "Swirl Networks";
|
||||
case 182:
|
||||
return "Meso international";
|
||||
case 183:
|
||||
return "TreLab Ltd";
|
||||
case 184:
|
||||
return "Qualcomm Innovation Center, Inc. (QuIC)";
|
||||
case 185:
|
||||
return "Johnson Controls, Inc.";
|
||||
case 186:
|
||||
return "Starkey Laboratories Inc.";
|
||||
case 187:
|
||||
return "S-Power Electronics Limited";
|
||||
case 188:
|
||||
return "Ace Sensor Inc";
|
||||
case 189:
|
||||
return "Aplix Corporation";
|
||||
case 190:
|
||||
return "AAMP of America";
|
||||
case 191:
|
||||
return "Stalmart Technology Limited";
|
||||
case 192:
|
||||
return "AMICCOM Electronics Corporation";
|
||||
case 193:
|
||||
return "Shenzhen Excelsecu Data Technology Co.,Ltd";
|
||||
case 194:
|
||||
return "Geneq Inc.";
|
||||
case 195:
|
||||
return "adidas AG";
|
||||
case 196:
|
||||
return "LG Electronics";
|
||||
case 197:
|
||||
return "Onset Computer Corporation";
|
||||
case 198:
|
||||
return "Selfly BV";
|
||||
case 199:
|
||||
return "Quuppa Oy.";
|
||||
case 200:
|
||||
return "GeLo Inc";
|
||||
case 201:
|
||||
return "Evluma";
|
||||
case 202:
|
||||
return "MC10";
|
||||
case 203:
|
||||
return "Binauric SE";
|
||||
case 204:
|
||||
return "Beats Electronics";
|
||||
case 205:
|
||||
return "Microchip Technology Inc.";
|
||||
case 206:
|
||||
return "Elgato Systems GmbH";
|
||||
case 207:
|
||||
return "ARCHOS SA";
|
||||
case 209:
|
||||
return "Polar Electro Europe B.V.";
|
||||
case 210:
|
||||
return "Dialog Semiconductor B.V.";
|
||||
case 211:
|
||||
return "Taixingbang Technology (HK) Co,. LTD.";
|
||||
case 212:
|
||||
return "Kawantech";
|
||||
case 213:
|
||||
return "Austco Communication Systems";
|
||||
case 214:
|
||||
return "Timex Group USA, Inc.";
|
||||
case 215:
|
||||
return "Qualcomm Technologies, Inc.";
|
||||
case 216:
|
||||
return "Qualcomm Connected Experiences, Inc.";
|
||||
case 217:
|
||||
return "Voyetra Turtle Beach";
|
||||
case 218:
|
||||
return "txtr GmbH";
|
||||
case 219:
|
||||
return "Biosentronics";
|
||||
case 220:
|
||||
return "Procter & Gamble";
|
||||
case 221:
|
||||
return "Hosiden Corporation";
|
||||
case 222:
|
||||
return "Muzik LLC";
|
||||
case 223:
|
||||
return "Misfit Wearables Corp";
|
||||
case 224:
|
||||
return "Google";
|
||||
case 225:
|
||||
return "Danlers Ltd";
|
||||
case 226:
|
||||
return "Semilink Inc";
|
||||
case 227:
|
||||
return "inMusic Brands, Inc";
|
||||
case 228:
|
||||
return "L.S. Research Inc.";
|
||||
case 229:
|
||||
return "Eden Software Consultants Ltd.";
|
||||
case 230:
|
||||
return "Freshtemp";
|
||||
case 231:
|
||||
return "KS Technologies";
|
||||
case 232:
|
||||
return "ACTS Technologies";
|
||||
case 233:
|
||||
return "Vtrack Systems";
|
||||
case 234:
|
||||
return "Nielsen-Kellerman Company";
|
||||
case 235:
|
||||
return "Server Technology, Inc.";
|
||||
case 236:
|
||||
return "BioResearch Associates";
|
||||
case 237:
|
||||
return "Jolly Logic, LLC";
|
||||
case 238:
|
||||
return "Above Average Outcomes, Inc.";
|
||||
case 239:
|
||||
return "Bitsplitters GmbH";
|
||||
case 240:
|
||||
return "PayPal, Inc.";
|
||||
case 241:
|
||||
return "Witron Technology Limited";
|
||||
case 242:
|
||||
return "Morse Project Inc.";
|
||||
case 243:
|
||||
return "Kent Displays Inc.";
|
||||
case 244:
|
||||
return "Nautilus Inc.";
|
||||
case 245:
|
||||
return "Smartifier Oy";
|
||||
case 246:
|
||||
return "Elcometer Limited";
|
||||
case 247:
|
||||
return "VSN Technologies Inc.";
|
||||
case 248:
|
||||
return "AceUni Corp., Ltd.";
|
||||
case 65535:
|
||||
return "internal use";
|
||||
default:
|
||||
return "not assigned";
|
||||
}
|
||||
}
|
||||
389
external/cache/sources/hcitools/lib/bluetooth/bluetooth.h
vendored
Normal file
389
external/cache/sources/hcitools/lib/bluetooth/bluetooth.h
vendored
Normal file
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __BLUETOOTH_H
|
||||
#define __BLUETOOTH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifndef AF_BLUETOOTH
|
||||
#define AF_BLUETOOTH 31
|
||||
#define PF_BLUETOOTH AF_BLUETOOTH
|
||||
#endif
|
||||
|
||||
#define BTPROTO_L2CAP 0
|
||||
#define BTPROTO_HCI 1
|
||||
#define BTPROTO_SCO 2
|
||||
#define BTPROTO_RFCOMM 3
|
||||
#define BTPROTO_BNEP 4
|
||||
#define BTPROTO_CMTP 5
|
||||
#define BTPROTO_HIDP 6
|
||||
#define BTPROTO_AVDTP 7
|
||||
|
||||
#define SOL_HCI 0
|
||||
#define SOL_L2CAP 6
|
||||
#define SOL_SCO 17
|
||||
#define SOL_RFCOMM 18
|
||||
|
||||
#ifndef SOL_BLUETOOTH
|
||||
#define SOL_BLUETOOTH 274
|
||||
#endif
|
||||
|
||||
#define BT_SECURITY 4
|
||||
struct bt_security {
|
||||
uint8_t level;
|
||||
uint8_t key_size;
|
||||
};
|
||||
#define BT_SECURITY_SDP 0
|
||||
#define BT_SECURITY_LOW 1
|
||||
#define BT_SECURITY_MEDIUM 2
|
||||
#define BT_SECURITY_HIGH 3
|
||||
|
||||
#define BT_DEFER_SETUP 7
|
||||
|
||||
#define BT_FLUSHABLE 8
|
||||
|
||||
#define BT_FLUSHABLE_OFF 0
|
||||
#define BT_FLUSHABLE_ON 1
|
||||
|
||||
#define BT_CHANNEL_POLICY 10
|
||||
|
||||
/* BR/EDR only (default policy)
|
||||
* AMP controllers cannot be used.
|
||||
* Channel move requests from the remote device are denied.
|
||||
* If the L2CAP channel is currently using AMP, move the channel to BR/EDR.
|
||||
*/
|
||||
#define BT_CHANNEL_POLICY_BREDR_ONLY 0
|
||||
|
||||
/* BR/EDR Preferred
|
||||
* Allow use of AMP controllers.
|
||||
* If the L2CAP channel is currently on AMP, move it to BR/EDR.
|
||||
* Channel move requests from the remote device are allowed.
|
||||
*/
|
||||
#define BT_CHANNEL_POLICY_BREDR_PREFERRED 1
|
||||
|
||||
/* AMP Preferred
|
||||
* Allow use of AMP controllers
|
||||
* If the L2CAP channel is currently on BR/EDR and AMP controller
|
||||
* resources are available, initiate a channel move to AMP.
|
||||
* Channel move requests from the remote device are allowed.
|
||||
* If the L2CAP socket has not been connected yet, try to create
|
||||
* and configure the channel directly on an AMP controller rather
|
||||
* than BR/EDR.
|
||||
*/
|
||||
#define BT_CHANNEL_POLICY_AMP_PREFERRED 2
|
||||
|
||||
#define BT_VOICE 11
|
||||
struct bt_voice {
|
||||
uint16_t setting;
|
||||
};
|
||||
|
||||
#define BT_VOICE_TRANSPARENT 0x0003
|
||||
#define BT_VOICE_CVSD_16BIT 0x0060
|
||||
|
||||
/* Connection and socket states */
|
||||
enum {
|
||||
BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
|
||||
BT_OPEN,
|
||||
BT_BOUND,
|
||||
BT_LISTEN,
|
||||
BT_CONNECT,
|
||||
BT_CONNECT2,
|
||||
BT_CONFIG,
|
||||
BT_DISCONN,
|
||||
BT_CLOSED
|
||||
};
|
||||
|
||||
/* Byte order conversions */
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define htobs(d) (d)
|
||||
#define htobl(d) (d)
|
||||
#define htobll(d) (d)
|
||||
#define btohs(d) (d)
|
||||
#define btohl(d) (d)
|
||||
#define btohll(d) (d)
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define htobs(d) bswap_16(d)
|
||||
#define htobl(d) bswap_32(d)
|
||||
#define htobll(d) bswap_64(d)
|
||||
#define btohs(d) bswap_16(d)
|
||||
#define btohl(d) bswap_32(d)
|
||||
#define btohll(d) bswap_64(d)
|
||||
#else
|
||||
#error "Unknown byte order"
|
||||
#endif
|
||||
|
||||
/* Bluetooth unaligned access */
|
||||
#define bt_get_unaligned(ptr) \
|
||||
({ \
|
||||
struct __attribute__((packed)) { \
|
||||
typeof(*(ptr)) __v; \
|
||||
} *__p = (typeof(__p)) (ptr); \
|
||||
__p->__v; \
|
||||
})
|
||||
|
||||
#define bt_put_unaligned(val, ptr) \
|
||||
do { \
|
||||
struct __attribute__((packed)) { \
|
||||
typeof(*(ptr)) __v; \
|
||||
} *__p = (typeof(__p)) (ptr); \
|
||||
__p->__v = (val); \
|
||||
} while(0)
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
static inline uint64_t bt_get_le64(const void *ptr)
|
||||
{
|
||||
return bt_get_unaligned((const uint64_t *) ptr);
|
||||
}
|
||||
|
||||
static inline uint64_t bt_get_be64(const void *ptr)
|
||||
{
|
||||
return bswap_64(bt_get_unaligned((const uint64_t *) ptr));
|
||||
}
|
||||
|
||||
static inline uint32_t bt_get_le32(const void *ptr)
|
||||
{
|
||||
return bt_get_unaligned((const uint32_t *) ptr);
|
||||
}
|
||||
|
||||
static inline uint32_t bt_get_be32(const void *ptr)
|
||||
{
|
||||
return bswap_32(bt_get_unaligned((const uint32_t *) ptr));
|
||||
}
|
||||
|
||||
static inline uint16_t bt_get_le16(const void *ptr)
|
||||
{
|
||||
return bt_get_unaligned((const uint16_t *) ptr);
|
||||
}
|
||||
|
||||
static inline uint16_t bt_get_be16(const void *ptr)
|
||||
{
|
||||
return bswap_16(bt_get_unaligned((const uint16_t *) ptr));
|
||||
}
|
||||
|
||||
static inline void bt_put_le64(uint64_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(val, (uint64_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_be64(uint64_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(bswap_64(val), (uint64_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_le32(uint32_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(val, (uint32_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_be32(uint32_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(bswap_32(val), (uint32_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_le16(uint16_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(val, (uint16_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_be16(uint16_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(bswap_16(val), (uint16_t *) ptr);
|
||||
}
|
||||
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
static inline uint64_t bt_get_le64(const void *ptr)
|
||||
{
|
||||
return bswap_64(bt_get_unaligned((const uint64_t *) ptr));
|
||||
}
|
||||
|
||||
static inline uint64_t bt_get_be64(const void *ptr)
|
||||
{
|
||||
return bt_get_unaligned((const uint64_t *) ptr);
|
||||
}
|
||||
|
||||
static inline uint32_t bt_get_le32(const void *ptr)
|
||||
{
|
||||
return bswap_32(bt_get_unaligned((const uint32_t *) ptr));
|
||||
}
|
||||
|
||||
static inline uint32_t bt_get_be32(const void *ptr)
|
||||
{
|
||||
return bt_get_unaligned((const uint32_t *) ptr);
|
||||
}
|
||||
|
||||
static inline uint16_t bt_get_le16(const void *ptr)
|
||||
{
|
||||
return bswap_16(bt_get_unaligned((const uint16_t *) ptr));
|
||||
}
|
||||
|
||||
static inline uint16_t bt_get_be16(const void *ptr)
|
||||
{
|
||||
return bt_get_unaligned((const uint16_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_le64(uint64_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(bswap_64(val), (uint64_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_be64(uint64_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(val, (uint64_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_le32(uint32_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(bswap_32(val), (uint32_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_be32(uint32_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(val, (uint32_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_le16(uint16_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(bswap_16(val), (uint16_t *) ptr);
|
||||
}
|
||||
|
||||
static inline void bt_put_be16(uint16_t val, const void *ptr)
|
||||
{
|
||||
bt_put_unaligned(val, (uint16_t *) ptr);
|
||||
}
|
||||
#else
|
||||
#error "Unknown byte order"
|
||||
#endif
|
||||
|
||||
/* BD Address */
|
||||
typedef struct {
|
||||
uint8_t b[6];
|
||||
} __attribute__((packed)) bdaddr_t;
|
||||
|
||||
/* BD Address type */
|
||||
#define BDADDR_BREDR 0x00
|
||||
#define BDADDR_LE_PUBLIC 0x01
|
||||
#define BDADDR_LE_RANDOM 0x02
|
||||
|
||||
#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
|
||||
#define BDADDR_ALL (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
|
||||
#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
|
||||
|
||||
/* Copy, swap, convert BD Address */
|
||||
static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2)
|
||||
{
|
||||
return memcmp(ba1, ba2, sizeof(bdaddr_t));
|
||||
}
|
||||
static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src)
|
||||
{
|
||||
memcpy(dst, src, sizeof(bdaddr_t));
|
||||
}
|
||||
|
||||
void baswap(bdaddr_t *dst, const bdaddr_t *src);
|
||||
bdaddr_t *strtoba(const char *str);
|
||||
char *batostr(const bdaddr_t *ba);
|
||||
int ba2str(const bdaddr_t *ba, char *str);
|
||||
int str2ba(const char *str, bdaddr_t *ba);
|
||||
int ba2oui(const bdaddr_t *ba, char *oui);
|
||||
int bachk(const char *str);
|
||||
|
||||
int baprintf(const char *format, ...);
|
||||
int bafprintf(FILE *stream, const char *format, ...);
|
||||
int basprintf(char *str, const char *format, ...);
|
||||
int basnprintf(char *str, size_t size, const char *format, ...);
|
||||
|
||||
void *bt_malloc(size_t size);
|
||||
void bt_free(void *ptr);
|
||||
|
||||
int bt_error(uint16_t code);
|
||||
const char *bt_compidtostr(int id);
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[16];
|
||||
} uint128_t;
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
|
||||
#define ntoh64(x) (x)
|
||||
|
||||
static inline void ntoh128(const uint128_t *src, uint128_t *dst)
|
||||
{
|
||||
memcpy(dst, src, sizeof(uint128_t));
|
||||
}
|
||||
|
||||
static inline void btoh128(const uint128_t *src, uint128_t *dst)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
dst->data[15 - i] = src->data[i];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline uint64_t ntoh64(uint64_t n)
|
||||
{
|
||||
uint64_t h;
|
||||
uint64_t tmp = ntohl(n & 0x00000000ffffffff);
|
||||
|
||||
h = ntohl(n >> 32);
|
||||
h |= tmp << 32;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static inline void ntoh128(const uint128_t *src, uint128_t *dst)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
dst->data[15 - i] = src->data[i];
|
||||
}
|
||||
|
||||
static inline void btoh128(const uint128_t *src, uint128_t *dst)
|
||||
{
|
||||
memcpy(dst, src, sizeof(uint128_t));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define hton64(x) ntoh64(x)
|
||||
#define hton128(x, y) ntoh128(x, y)
|
||||
#define htob128(x, y) btoh128(x, y)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BLUETOOTH_H */
|
||||
153
external/cache/sources/hcitools/lib/bluetooth/bnep.h
vendored
Normal file
153
external/cache/sources/hcitools/lib/bluetooth/bnep.h
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __BNEP_H
|
||||
#define __BNEP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
#ifndef ETH_ALEN
|
||||
#define ETH_ALEN 6 /* from <net/ethernet.h> */
|
||||
#endif
|
||||
|
||||
/* BNEP UUIDs */
|
||||
#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB
|
||||
#define BNEP_UUID16 0x02
|
||||
#define BNEP_UUID32 0x04
|
||||
#define BNEP_UUID128 0x16
|
||||
|
||||
#define BNEP_SVC_PANU 0x1115
|
||||
#define BNEP_SVC_NAP 0x1116
|
||||
#define BNEP_SVC_GN 0x1117
|
||||
|
||||
/* BNEP packet types */
|
||||
#define BNEP_GENERAL 0x00
|
||||
#define BNEP_CONTROL 0x01
|
||||
#define BNEP_COMPRESSED 0x02
|
||||
#define BNEP_COMPRESSED_SRC_ONLY 0x03
|
||||
#define BNEP_COMPRESSED_DST_ONLY 0x04
|
||||
|
||||
/* BNEP control types */
|
||||
#define BNEP_CMD_NOT_UNDERSTOOD 0x00
|
||||
#define BNEP_SETUP_CONN_REQ 0x01
|
||||
#define BNEP_SETUP_CONN_RSP 0x02
|
||||
#define BNEP_FILTER_NET_TYPE_SET 0x03
|
||||
#define BNEP_FILTER_NET_TYPE_RSP 0x04
|
||||
#define BNEP_FILTER_MULT_ADDR_SET 0x05
|
||||
#define BNEP_FILTER_MULT_ADDR_RSP 0x06
|
||||
|
||||
/* BNEP response messages */
|
||||
#define BNEP_SUCCESS 0x00
|
||||
|
||||
#define BNEP_CONN_INVALID_DST 0x01
|
||||
#define BNEP_CONN_INVALID_SRC 0x02
|
||||
#define BNEP_CONN_INVALID_SVC 0x03
|
||||
#define BNEP_CONN_NOT_ALLOWED 0x04
|
||||
|
||||
#define BNEP_FILTER_UNSUPPORTED_REQ 0x01
|
||||
#define BNEP_FILTER_INVALID_RANGE 0x02
|
||||
#define BNEP_FILTER_INVALID_MCADDR 0x02
|
||||
#define BNEP_FILTER_LIMIT_REACHED 0x03
|
||||
#define BNEP_FILTER_DENIED_SECURITY 0x04
|
||||
|
||||
/* L2CAP settings */
|
||||
#define BNEP_MTU 1691
|
||||
#define BNEP_FLUSH_TO 0xffff
|
||||
#define BNEP_CONNECT_TO 15
|
||||
#define BNEP_FILTER_TO 15
|
||||
|
||||
#ifndef BNEP_PSM
|
||||
#define BNEP_PSM 0x0f
|
||||
#endif
|
||||
|
||||
/* BNEP headers */
|
||||
#define BNEP_TYPE_MASK 0x7f
|
||||
#define BNEP_EXT_HEADER 0x80
|
||||
|
||||
struct bnep_setup_conn_req {
|
||||
uint8_t type;
|
||||
uint8_t ctrl;
|
||||
uint8_t uuid_size;
|
||||
uint8_t service[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct bnep_set_filter_req {
|
||||
uint8_t type;
|
||||
uint8_t ctrl;
|
||||
uint16_t len;
|
||||
uint8_t list[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct bnep_control_rsp {
|
||||
uint8_t type;
|
||||
uint8_t ctrl;
|
||||
uint16_t resp;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct bnep_ext_hdr {
|
||||
uint8_t type;
|
||||
uint8_t len;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* BNEP ioctl defines */
|
||||
#define BNEPCONNADD _IOW('B', 200, int)
|
||||
#define BNEPCONNDEL _IOW('B', 201, int)
|
||||
#define BNEPGETCONNLIST _IOR('B', 210, int)
|
||||
#define BNEPGETCONNINFO _IOR('B', 211, int)
|
||||
|
||||
struct bnep_connadd_req {
|
||||
int sock; /* Connected socket */
|
||||
uint32_t flags;
|
||||
uint16_t role;
|
||||
char device[16]; /* Name of the Ethernet device */
|
||||
};
|
||||
|
||||
struct bnep_conndel_req {
|
||||
uint32_t flags;
|
||||
uint8_t dst[ETH_ALEN];
|
||||
};
|
||||
|
||||
struct bnep_conninfo {
|
||||
uint32_t flags;
|
||||
uint16_t role;
|
||||
uint16_t state;
|
||||
uint8_t dst[ETH_ALEN];
|
||||
char device[16];
|
||||
};
|
||||
|
||||
struct bnep_connlist_req {
|
||||
uint32_t cnum;
|
||||
struct bnep_conninfo *ci;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BNEP_H */
|
||||
69
external/cache/sources/hcitools/lib/bluetooth/cmtp.h
vendored
Normal file
69
external/cache/sources/hcitools/lib/bluetooth/cmtp.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CMTP_H
|
||||
#define __CMTP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* CMTP defaults */
|
||||
#define CMTP_MINIMUM_MTU 152
|
||||
#define CMTP_DEFAULT_MTU 672
|
||||
|
||||
/* CMTP ioctl defines */
|
||||
#define CMTPCONNADD _IOW('C', 200, int)
|
||||
#define CMTPCONNDEL _IOW('C', 201, int)
|
||||
#define CMTPGETCONNLIST _IOR('C', 210, int)
|
||||
#define CMTPGETCONNINFO _IOR('C', 211, int)
|
||||
|
||||
#define CMTP_LOOPBACK 0
|
||||
|
||||
struct cmtp_connadd_req {
|
||||
int sock; /* Connected socket */
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct cmtp_conndel_req {
|
||||
bdaddr_t bdaddr;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct cmtp_conninfo {
|
||||
bdaddr_t bdaddr;
|
||||
uint32_t flags;
|
||||
uint16_t state;
|
||||
int num;
|
||||
};
|
||||
|
||||
struct cmtp_connlist_req {
|
||||
uint32_t cnum;
|
||||
struct cmtp_conninfo *ci;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CMTP_H */
|
||||
2418
external/cache/sources/hcitools/lib/bluetooth/hci.h
vendored
Normal file
2418
external/cache/sources/hcitools/lib/bluetooth/hci.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
235
external/cache/sources/hcitools/lib/bluetooth/hci_lib.h
vendored
Normal file
235
external/cache/sources/hcitools/lib/bluetooth/hci_lib.h
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __HCI_LIB_H
|
||||
#define __HCI_LIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct hci_request {
|
||||
uint16_t ogf;
|
||||
uint16_t ocf;
|
||||
int event;
|
||||
void *cparam;
|
||||
int clen;
|
||||
void *rparam;
|
||||
int rlen;
|
||||
};
|
||||
|
||||
struct hci_version {
|
||||
uint16_t manufacturer;
|
||||
uint8_t hci_ver;
|
||||
uint16_t hci_rev;
|
||||
uint8_t lmp_ver;
|
||||
uint16_t lmp_subver;
|
||||
};
|
||||
|
||||
int hci_open_dev(int dev_id);
|
||||
int hci_close_dev(int dd);
|
||||
int hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param);
|
||||
int hci_send_req(int dd, struct hci_request *req, int timeout);
|
||||
|
||||
int hci_create_connection(int dd, const bdaddr_t *bdaddr, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to);
|
||||
int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to);
|
||||
|
||||
int hci_inquiry(int dev_id, int len, int num_rsp, const uint8_t *lap, inquiry_info **ii, long flags);
|
||||
int hci_devinfo(int dev_id, struct hci_dev_info *di);
|
||||
int hci_devba(int dev_id, bdaddr_t *bdaddr);
|
||||
int hci_devid(const char *str);
|
||||
|
||||
int hci_read_local_name(int dd, int len, char *name, int to);
|
||||
int hci_write_local_name(int dd, const char *name, int to);
|
||||
int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to);
|
||||
int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint8_t pscan_rep_mode, uint16_t clkoffset, int len, char *name, int to);
|
||||
int hci_read_remote_name_cancel(int dd, const bdaddr_t *bdaddr, int to);
|
||||
int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, int to);
|
||||
int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to);
|
||||
int hci_read_remote_ext_features(int dd, uint16_t handle, uint8_t page, uint8_t *max_page, uint8_t *features, int to);
|
||||
int hci_read_clock_offset(int dd, uint16_t handle, uint16_t *clkoffset, int to);
|
||||
int hci_read_local_version(int dd, struct hci_version *ver, int to);
|
||||
int hci_read_local_commands(int dd, uint8_t *commands, int to);
|
||||
int hci_read_local_features(int dd, uint8_t *features, int to);
|
||||
int hci_read_local_ext_features(int dd, uint8_t page, uint8_t *max_page, uint8_t *features, int to);
|
||||
int hci_read_bd_addr(int dd, bdaddr_t *bdaddr, int to);
|
||||
int hci_read_class_of_dev(int dd, uint8_t *cls, int to);
|
||||
int hci_write_class_of_dev(int dd, uint32_t cls, int to);
|
||||
int hci_read_voice_setting(int dd, uint16_t *vs, int to);
|
||||
int hci_write_voice_setting(int dd, uint16_t vs, int to);
|
||||
int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to);
|
||||
int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to);
|
||||
int hci_read_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to);
|
||||
int hci_write_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t *key, int to);
|
||||
int hci_delete_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to);
|
||||
int hci_authenticate_link(int dd, uint16_t handle, int to);
|
||||
int hci_encrypt_link(int dd, uint16_t handle, uint8_t encrypt, int to);
|
||||
int hci_change_link_key(int dd, uint16_t handle, int to);
|
||||
int hci_switch_role(int dd, bdaddr_t *bdaddr, uint8_t role, int to);
|
||||
int hci_park_mode(int dd, uint16_t handle, uint16_t max_interval, uint16_t min_interval, int to);
|
||||
int hci_exit_park_mode(int dd, uint16_t handle, int to);
|
||||
int hci_read_inquiry_scan_type(int dd, uint8_t *type, int to);
|
||||
int hci_write_inquiry_scan_type(int dd, uint8_t type, int to);
|
||||
int hci_read_inquiry_mode(int dd, uint8_t *mode, int to);
|
||||
int hci_write_inquiry_mode(int dd, uint8_t mode, int to);
|
||||
int hci_read_afh_mode(int dd, uint8_t *mode, int to);
|
||||
int hci_write_afh_mode(int dd, uint8_t mode, int to);
|
||||
int hci_read_ext_inquiry_response(int dd, uint8_t *fec, uint8_t *data, int to);
|
||||
int hci_write_ext_inquiry_response(int dd, uint8_t fec, uint8_t *data, int to);
|
||||
int hci_read_simple_pairing_mode(int dd, uint8_t *mode, int to);
|
||||
int hci_write_simple_pairing_mode(int dd, uint8_t mode, int to);
|
||||
int hci_read_local_oob_data(int dd, uint8_t *hash, uint8_t *randomizer, int to);
|
||||
int hci_read_inq_response_tx_power_level(int dd, int8_t *level, int to);
|
||||
int hci_read_inquiry_transmit_power_level(int dd, int8_t *level, int to);
|
||||
int hci_write_inquiry_transmit_power_level(int dd, int8_t level, int to);
|
||||
int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to);
|
||||
int hci_read_link_policy(int dd, uint16_t handle, uint16_t *policy, int to);
|
||||
int hci_write_link_policy(int dd, uint16_t handle, uint16_t policy, int to);
|
||||
int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout, int to);
|
||||
int hci_write_link_supervision_timeout(int dd, uint16_t handle, uint16_t timeout, int to);
|
||||
int hci_set_afh_classification(int dd, uint8_t *map, int to);
|
||||
int hci_read_link_quality(int dd, uint16_t handle, uint8_t *link_quality, int to);
|
||||
int hci_read_rssi(int dd, uint16_t handle, int8_t *rssi, int to);
|
||||
int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int to);
|
||||
int hci_read_clock(int dd, uint16_t handle, uint8_t which, uint32_t *clock, uint16_t *accuracy, int to);
|
||||
|
||||
int hci_le_set_scan_enable(int dev_id, uint8_t enable, uint8_t filter_dup, int to);
|
||||
int hci_le_set_scan_parameters(int dev_id, uint8_t type, uint16_t interval,
|
||||
uint16_t window, uint8_t own_type,
|
||||
uint8_t filter, int to);
|
||||
int hci_le_set_advertise_enable(int dev_id, uint8_t enable, int to);
|
||||
int hci_le_create_conn(int dd, uint16_t interval, uint16_t window,
|
||||
uint8_t initiator_filter, uint8_t peer_bdaddr_type,
|
||||
bdaddr_t peer_bdaddr, uint8_t own_bdaddr_type,
|
||||
uint16_t min_interval, uint16_t max_interval,
|
||||
uint16_t latency, uint16_t supervision_timeout,
|
||||
uint16_t min_ce_length, uint16_t max_ce_length,
|
||||
uint16_t *handle, int to);
|
||||
|
||||
int hci_le_conn_update(int dd, uint16_t handle, uint16_t min_interval,
|
||||
uint16_t max_interval, uint16_t latency,
|
||||
uint16_t supervision_timeout, int to);
|
||||
int hci_le_add_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to);
|
||||
int hci_le_rm_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to);
|
||||
int hci_le_read_white_list_size(int dd, uint8_t *size, int to);
|
||||
int hci_le_clear_white_list(int dd, int to);
|
||||
int hci_for_each_dev(int flag, int(*func)(int dd, int dev_id, long arg), long arg);
|
||||
int hci_get_route(bdaddr_t *bdaddr);
|
||||
|
||||
char *hci_bustostr(int bus);
|
||||
char *hci_typetostr(int type);
|
||||
char *hci_dtypetostr(int type);
|
||||
char *hci_dflagstostr(uint32_t flags);
|
||||
char *hci_ptypetostr(unsigned int ptype);
|
||||
int hci_strtoptype(char *str, unsigned int *val);
|
||||
char *hci_scoptypetostr(unsigned int ptype);
|
||||
int hci_strtoscoptype(char *str, unsigned int *val);
|
||||
char *hci_lptostr(unsigned int ptype);
|
||||
int hci_strtolp(char *str, unsigned int *val);
|
||||
char *hci_lmtostr(unsigned int ptype);
|
||||
int hci_strtolm(char *str, unsigned int *val);
|
||||
|
||||
char *hci_cmdtostr(unsigned int cmd);
|
||||
char *hci_commandstostr(uint8_t *commands, char *pref, int width);
|
||||
|
||||
char *hci_vertostr(unsigned int ver);
|
||||
int hci_strtover(char *str, unsigned int *ver);
|
||||
char *lmp_vertostr(unsigned int ver);
|
||||
int lmp_strtover(char *str, unsigned int *ver);
|
||||
char *pal_vertostr(unsigned int ver);
|
||||
int pal_strtover(char *str, unsigned int *ver);
|
||||
|
||||
char *lmp_featurestostr(uint8_t *features, char *pref, int width);
|
||||
|
||||
static inline void hci_set_bit(int nr, void *addr)
|
||||
{
|
||||
*((uint32_t *) addr + (nr >> 5)) |= (1 << (nr & 31));
|
||||
}
|
||||
|
||||
static inline void hci_clear_bit(int nr, void *addr)
|
||||
{
|
||||
*((uint32_t *) addr + (nr >> 5)) &= ~(1 << (nr & 31));
|
||||
}
|
||||
|
||||
static inline int hci_test_bit(int nr, void *addr)
|
||||
{
|
||||
return *((uint32_t *) addr + (nr >> 5)) & (1 << (nr & 31));
|
||||
}
|
||||
|
||||
/* HCI filter tools */
|
||||
static inline void hci_filter_clear(struct hci_filter *f)
|
||||
{
|
||||
memset(f, 0, sizeof(*f));
|
||||
}
|
||||
static inline void hci_filter_set_ptype(int t, struct hci_filter *f)
|
||||
{
|
||||
hci_set_bit((t == HCI_VENDOR_PKT) ? 0 : (t & HCI_FLT_TYPE_BITS), &f->type_mask);
|
||||
}
|
||||
static inline void hci_filter_clear_ptype(int t, struct hci_filter *f)
|
||||
{
|
||||
hci_clear_bit((t == HCI_VENDOR_PKT) ? 0 : (t & HCI_FLT_TYPE_BITS), &f->type_mask);
|
||||
}
|
||||
static inline int hci_filter_test_ptype(int t, struct hci_filter *f)
|
||||
{
|
||||
return hci_test_bit((t == HCI_VENDOR_PKT) ? 0 : (t & HCI_FLT_TYPE_BITS), &f->type_mask);
|
||||
}
|
||||
static inline void hci_filter_all_ptypes(struct hci_filter *f)
|
||||
{
|
||||
memset((void *) &f->type_mask, 0xff, sizeof(f->type_mask));
|
||||
}
|
||||
static inline void hci_filter_set_event(int e, struct hci_filter *f)
|
||||
{
|
||||
hci_set_bit((e & HCI_FLT_EVENT_BITS), &f->event_mask);
|
||||
}
|
||||
static inline void hci_filter_clear_event(int e, struct hci_filter *f)
|
||||
{
|
||||
hci_clear_bit((e & HCI_FLT_EVENT_BITS), &f->event_mask);
|
||||
}
|
||||
static inline int hci_filter_test_event(int e, struct hci_filter *f)
|
||||
{
|
||||
return hci_test_bit((e & HCI_FLT_EVENT_BITS), &f->event_mask);
|
||||
}
|
||||
static inline void hci_filter_all_events(struct hci_filter *f)
|
||||
{
|
||||
memset((void *) f->event_mask, 0xff, sizeof(f->event_mask));
|
||||
}
|
||||
static inline void hci_filter_set_opcode(int opcode, struct hci_filter *f)
|
||||
{
|
||||
f->opcode = opcode;
|
||||
}
|
||||
static inline void hci_filter_clear_opcode(struct hci_filter *f)
|
||||
{
|
||||
f->opcode = 0;
|
||||
}
|
||||
static inline int hci_filter_test_opcode(int opcode, struct hci_filter *f)
|
||||
{
|
||||
return (f->opcode == opcode);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HCI_LIB_H */
|
||||
85
external/cache/sources/hcitools/lib/bluetooth/hidp.h
vendored
Normal file
85
external/cache/sources/hcitools/lib/bluetooth/hidp.h
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2003-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __HIDP_H
|
||||
#define __HIDP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* HIDP defaults */
|
||||
#define HIDP_MINIMUM_MTU 48
|
||||
#define HIDP_DEFAULT_MTU 48
|
||||
|
||||
/* HIDP ioctl defines */
|
||||
#define HIDPCONNADD _IOW('H', 200, int)
|
||||
#define HIDPCONNDEL _IOW('H', 201, int)
|
||||
#define HIDPGETCONNLIST _IOR('H', 210, int)
|
||||
#define HIDPGETCONNINFO _IOR('H', 211, int)
|
||||
|
||||
#define HIDP_VIRTUAL_CABLE_UNPLUG 0
|
||||
#define HIDP_BOOT_PROTOCOL_MODE 1
|
||||
#define HIDP_BLUETOOTH_VENDOR_ID 9
|
||||
|
||||
struct hidp_connadd_req {
|
||||
int ctrl_sock; /* Connected control socket */
|
||||
int intr_sock; /* Connected interrupt socket */
|
||||
uint16_t parser; /* Parser version */
|
||||
uint16_t rd_size; /* Report descriptor size */
|
||||
uint8_t *rd_data; /* Report descriptor data */
|
||||
uint8_t country;
|
||||
uint8_t subclass;
|
||||
uint16_t vendor;
|
||||
uint16_t product;
|
||||
uint16_t version;
|
||||
uint32_t flags;
|
||||
uint32_t idle_to;
|
||||
char name[128]; /* Device name */
|
||||
};
|
||||
|
||||
struct hidp_conndel_req {
|
||||
bdaddr_t bdaddr;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct hidp_conninfo {
|
||||
bdaddr_t bdaddr;
|
||||
uint32_t flags;
|
||||
uint16_t state;
|
||||
uint16_t vendor;
|
||||
uint16_t product;
|
||||
uint16_t version;
|
||||
char name[128];
|
||||
};
|
||||
|
||||
struct hidp_connlist_req {
|
||||
uint32_t cnum;
|
||||
struct hidp_conninfo *ci;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HIDP_H */
|
||||
279
external/cache/sources/hcitools/lib/bluetooth/l2cap.h
vendored
Normal file
279
external/cache/sources/hcitools/lib/bluetooth/l2cap.h
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __L2CAP_H
|
||||
#define __L2CAP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* L2CAP defaults */
|
||||
#define L2CAP_DEFAULT_MTU 672
|
||||
#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
|
||||
|
||||
/* L2CAP socket address */
|
||||
struct sockaddr_l2 {
|
||||
sa_family_t l2_family;
|
||||
unsigned short l2_psm;
|
||||
bdaddr_t l2_bdaddr;
|
||||
unsigned short l2_cid;
|
||||
uint8_t l2_bdaddr_type;
|
||||
};
|
||||
|
||||
/* L2CAP socket options */
|
||||
#define L2CAP_OPTIONS 0x01
|
||||
struct l2cap_options {
|
||||
uint16_t omtu;
|
||||
uint16_t imtu;
|
||||
uint16_t flush_to;
|
||||
uint8_t mode;
|
||||
uint8_t fcs;
|
||||
uint8_t max_tx;
|
||||
uint16_t txwin_size;
|
||||
};
|
||||
|
||||
#define L2CAP_CONNINFO 0x02
|
||||
struct l2cap_conninfo {
|
||||
uint16_t hci_handle;
|
||||
uint8_t dev_class[3];
|
||||
};
|
||||
|
||||
#define L2CAP_LM 0x03
|
||||
#define L2CAP_LM_MASTER 0x0001
|
||||
#define L2CAP_LM_AUTH 0x0002
|
||||
#define L2CAP_LM_ENCRYPT 0x0004
|
||||
#define L2CAP_LM_TRUSTED 0x0008
|
||||
#define L2CAP_LM_RELIABLE 0x0010
|
||||
#define L2CAP_LM_SECURE 0x0020
|
||||
|
||||
/* L2CAP command codes */
|
||||
#define L2CAP_COMMAND_REJ 0x01
|
||||
#define L2CAP_CONN_REQ 0x02
|
||||
#define L2CAP_CONN_RSP 0x03
|
||||
#define L2CAP_CONF_REQ 0x04
|
||||
#define L2CAP_CONF_RSP 0x05
|
||||
#define L2CAP_DISCONN_REQ 0x06
|
||||
#define L2CAP_DISCONN_RSP 0x07
|
||||
#define L2CAP_ECHO_REQ 0x08
|
||||
#define L2CAP_ECHO_RSP 0x09
|
||||
#define L2CAP_INFO_REQ 0x0a
|
||||
#define L2CAP_INFO_RSP 0x0b
|
||||
#define L2CAP_CREATE_REQ 0x0c
|
||||
#define L2CAP_CREATE_RSP 0x0d
|
||||
#define L2CAP_MOVE_REQ 0x0e
|
||||
#define L2CAP_MOVE_RSP 0x0f
|
||||
#define L2CAP_MOVE_CFM 0x10
|
||||
#define L2CAP_MOVE_CFM_RSP 0x11
|
||||
|
||||
/* L2CAP extended feature mask */
|
||||
#define L2CAP_FEAT_FLOWCTL 0x00000001
|
||||
#define L2CAP_FEAT_RETRANS 0x00000002
|
||||
#define L2CAP_FEAT_BIDIR_QOS 0x00000004
|
||||
#define L2CAP_FEAT_ERTM 0x00000008
|
||||
#define L2CAP_FEAT_STREAMING 0x00000010
|
||||
#define L2CAP_FEAT_FCS 0x00000020
|
||||
#define L2CAP_FEAT_EXT_FLOW 0x00000040
|
||||
#define L2CAP_FEAT_FIXED_CHAN 0x00000080
|
||||
#define L2CAP_FEAT_EXT_WINDOW 0x00000100
|
||||
#define L2CAP_FEAT_UCD 0x00000200
|
||||
|
||||
/* L2CAP fixed channels */
|
||||
#define L2CAP_FC_L2CAP 0x02
|
||||
#define L2CAP_FC_CONNLESS 0x04
|
||||
#define L2CAP_FC_A2MP 0x08
|
||||
|
||||
/* L2CAP structures */
|
||||
typedef struct {
|
||||
uint16_t len;
|
||||
uint16_t cid;
|
||||
} __attribute__ ((packed)) l2cap_hdr;
|
||||
#define L2CAP_HDR_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
uint8_t code;
|
||||
uint8_t ident;
|
||||
uint16_t len;
|
||||
} __attribute__ ((packed)) l2cap_cmd_hdr;
|
||||
#define L2CAP_CMD_HDR_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
uint16_t reason;
|
||||
} __attribute__ ((packed)) l2cap_cmd_rej;
|
||||
#define L2CAP_CMD_REJ_SIZE 2
|
||||
|
||||
typedef struct {
|
||||
uint16_t psm;
|
||||
uint16_t scid;
|
||||
} __attribute__ ((packed)) l2cap_conn_req;
|
||||
#define L2CAP_CONN_REQ_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
uint16_t dcid;
|
||||
uint16_t scid;
|
||||
uint16_t result;
|
||||
uint16_t status;
|
||||
} __attribute__ ((packed)) l2cap_conn_rsp;
|
||||
#define L2CAP_CONN_RSP_SIZE 8
|
||||
|
||||
/* connect result */
|
||||
#define L2CAP_CR_SUCCESS 0x0000
|
||||
#define L2CAP_CR_PEND 0x0001
|
||||
#define L2CAP_CR_BAD_PSM 0x0002
|
||||
#define L2CAP_CR_SEC_BLOCK 0x0003
|
||||
#define L2CAP_CR_NO_MEM 0x0004
|
||||
|
||||
/* connect status */
|
||||
#define L2CAP_CS_NO_INFO 0x0000
|
||||
#define L2CAP_CS_AUTHEN_PEND 0x0001
|
||||
#define L2CAP_CS_AUTHOR_PEND 0x0002
|
||||
|
||||
typedef struct {
|
||||
uint16_t dcid;
|
||||
uint16_t flags;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed)) l2cap_conf_req;
|
||||
#define L2CAP_CONF_REQ_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
uint16_t scid;
|
||||
uint16_t flags;
|
||||
uint16_t result;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed)) l2cap_conf_rsp;
|
||||
#define L2CAP_CONF_RSP_SIZE 6
|
||||
|
||||
#define L2CAP_CONF_SUCCESS 0x0000
|
||||
#define L2CAP_CONF_UNACCEPT 0x0001
|
||||
#define L2CAP_CONF_REJECT 0x0002
|
||||
#define L2CAP_CONF_UNKNOWN 0x0003
|
||||
#define L2CAP_CONF_PENDING 0x0004
|
||||
#define L2CAP_CONF_EFS_REJECT 0x0005
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
uint8_t len;
|
||||
uint8_t val[0];
|
||||
} __attribute__ ((packed)) l2cap_conf_opt;
|
||||
#define L2CAP_CONF_OPT_SIZE 2
|
||||
|
||||
#define L2CAP_CONF_MTU 0x01
|
||||
#define L2CAP_CONF_FLUSH_TO 0x02
|
||||
#define L2CAP_CONF_QOS 0x03
|
||||
#define L2CAP_CONF_RFC 0x04
|
||||
#define L2CAP_CONF_FCS 0x05
|
||||
#define L2CAP_CONF_EFS 0x06
|
||||
#define L2CAP_CONF_EWS 0x07
|
||||
|
||||
#define L2CAP_CONF_MAX_SIZE 22
|
||||
|
||||
#define L2CAP_MODE_BASIC 0x00
|
||||
#define L2CAP_MODE_RETRANS 0x01
|
||||
#define L2CAP_MODE_FLOWCTL 0x02
|
||||
#define L2CAP_MODE_ERTM 0x03
|
||||
#define L2CAP_MODE_STREAMING 0x04
|
||||
|
||||
#define L2CAP_SERVTYPE_NOTRAFFIC 0x00
|
||||
#define L2CAP_SERVTYPE_BESTEFFORT 0x01
|
||||
#define L2CAP_SERVTYPE_GUARANTEED 0x02
|
||||
|
||||
typedef struct {
|
||||
uint16_t dcid;
|
||||
uint16_t scid;
|
||||
} __attribute__ ((packed)) l2cap_disconn_req;
|
||||
#define L2CAP_DISCONN_REQ_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
uint16_t dcid;
|
||||
uint16_t scid;
|
||||
} __attribute__ ((packed)) l2cap_disconn_rsp;
|
||||
#define L2CAP_DISCONN_RSP_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
uint16_t type;
|
||||
} __attribute__ ((packed)) l2cap_info_req;
|
||||
#define L2CAP_INFO_REQ_SIZE 2
|
||||
|
||||
typedef struct {
|
||||
uint16_t type;
|
||||
uint16_t result;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed)) l2cap_info_rsp;
|
||||
#define L2CAP_INFO_RSP_SIZE 4
|
||||
|
||||
/* info type */
|
||||
#define L2CAP_IT_CL_MTU 0x0001
|
||||
#define L2CAP_IT_FEAT_MASK 0x0002
|
||||
|
||||
/* info result */
|
||||
#define L2CAP_IR_SUCCESS 0x0000
|
||||
#define L2CAP_IR_NOTSUPP 0x0001
|
||||
|
||||
typedef struct {
|
||||
uint16_t psm;
|
||||
uint16_t scid;
|
||||
uint8_t id;
|
||||
} __attribute__ ((packed)) l2cap_create_req;
|
||||
#define L2CAP_CREATE_REQ_SIZE 5
|
||||
|
||||
typedef struct {
|
||||
uint16_t dcid;
|
||||
uint16_t scid;
|
||||
uint16_t result;
|
||||
uint16_t status;
|
||||
} __attribute__ ((packed)) l2cap_create_rsp;
|
||||
#define L2CAP_CREATE_RSP_SIZE 8
|
||||
|
||||
typedef struct {
|
||||
uint16_t icid;
|
||||
uint8_t id;
|
||||
} __attribute__ ((packed)) l2cap_move_req;
|
||||
#define L2CAP_MOVE_REQ_SIZE 3
|
||||
|
||||
typedef struct {
|
||||
uint16_t icid;
|
||||
uint16_t result;
|
||||
} __attribute__ ((packed)) l2cap_move_rsp;
|
||||
#define L2CAP_MOVE_RSP_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
uint16_t icid;
|
||||
uint16_t result;
|
||||
} __attribute__ ((packed)) l2cap_move_cfm;
|
||||
#define L2CAP_MOVE_CFM_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
uint16_t icid;
|
||||
} __attribute__ ((packed)) l2cap_move_cfm_rsp;
|
||||
#define L2CAP_MOVE_CFM_RSP_SIZE 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __L2CAP_H */
|
||||
99
external/cache/sources/hcitools/lib/bluetooth/rfcomm.h
vendored
Normal file
99
external/cache/sources/hcitools/lib/bluetooth/rfcomm.h
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RFCOMM_H
|
||||
#define __RFCOMM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* RFCOMM defaults */
|
||||
#define RFCOMM_DEFAULT_MTU 127
|
||||
|
||||
#define RFCOMM_PSM 3
|
||||
|
||||
/* RFCOMM socket address */
|
||||
struct sockaddr_rc {
|
||||
sa_family_t rc_family;
|
||||
bdaddr_t rc_bdaddr;
|
||||
uint8_t rc_channel;
|
||||
};
|
||||
|
||||
/* RFCOMM socket options */
|
||||
#define RFCOMM_CONNINFO 0x02
|
||||
struct rfcomm_conninfo {
|
||||
uint16_t hci_handle;
|
||||
uint8_t dev_class[3];
|
||||
};
|
||||
|
||||
#define RFCOMM_LM 0x03
|
||||
#define RFCOMM_LM_MASTER 0x0001
|
||||
#define RFCOMM_LM_AUTH 0x0002
|
||||
#define RFCOMM_LM_ENCRYPT 0x0004
|
||||
#define RFCOMM_LM_TRUSTED 0x0008
|
||||
#define RFCOMM_LM_RELIABLE 0x0010
|
||||
#define RFCOMM_LM_SECURE 0x0020
|
||||
|
||||
/* RFCOMM TTY support */
|
||||
#define RFCOMM_MAX_DEV 256
|
||||
|
||||
#define RFCOMMCREATEDEV _IOW('R', 200, int)
|
||||
#define RFCOMMRELEASEDEV _IOW('R', 201, int)
|
||||
#define RFCOMMGETDEVLIST _IOR('R', 210, int)
|
||||
#define RFCOMMGETDEVINFO _IOR('R', 211, int)
|
||||
|
||||
struct rfcomm_dev_req {
|
||||
int16_t dev_id;
|
||||
uint32_t flags;
|
||||
bdaddr_t src;
|
||||
bdaddr_t dst;
|
||||
uint8_t channel;
|
||||
};
|
||||
#define RFCOMM_REUSE_DLC 0
|
||||
#define RFCOMM_RELEASE_ONHUP 1
|
||||
#define RFCOMM_HANGUP_NOW 2
|
||||
#define RFCOMM_TTY_ATTACHED 3
|
||||
|
||||
struct rfcomm_dev_info {
|
||||
int16_t id;
|
||||
uint32_t flags;
|
||||
uint16_t state;
|
||||
bdaddr_t src;
|
||||
bdaddr_t dst;
|
||||
uint8_t channel;
|
||||
};
|
||||
|
||||
struct rfcomm_dev_list_req {
|
||||
uint16_t dev_num;
|
||||
struct rfcomm_dev_info dev_info[0];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RFCOMM_H */
|
||||
62
external/cache/sources/hcitools/lib/bluetooth/sco.h
vendored
Normal file
62
external/cache/sources/hcitools/lib/bluetooth/sco.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SCO_H
|
||||
#define __SCO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* SCO defaults */
|
||||
#define SCO_DEFAULT_MTU 500
|
||||
#define SCO_DEFAULT_FLUSH_TO 0xFFFF
|
||||
|
||||
#define SCO_CONN_TIMEOUT (HZ * 40)
|
||||
#define SCO_DISCONN_TIMEOUT (HZ * 2)
|
||||
#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
|
||||
|
||||
/* SCO socket address */
|
||||
struct sockaddr_sco {
|
||||
sa_family_t sco_family;
|
||||
bdaddr_t sco_bdaddr;
|
||||
};
|
||||
|
||||
/* set/get sockopt defines */
|
||||
#define SCO_OPTIONS 0x01
|
||||
struct sco_options {
|
||||
uint16_t mtu;
|
||||
};
|
||||
|
||||
#define SCO_CONNINFO 0x02
|
||||
struct sco_conninfo {
|
||||
uint16_t hci_handle;
|
||||
uint8_t dev_class[3];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SCO_H */
|
||||
532
external/cache/sources/hcitools/lib/bluetooth/sdp.h
vendored
Normal file
532
external/cache/sources/hcitools/lib/bluetooth/sdp.h
vendored
Normal file
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2001-2002 Nokia Corporation
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
* Copyright (C) 2002-2003 Stephen Crane <steve.crane@rococosoft.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SDP_H
|
||||
#define __SDP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
#define SDP_UNIX_PATH "/var/run/sdp"
|
||||
#define SDP_RESPONSE_TIMEOUT 20
|
||||
#define SDP_REQ_BUFFER_SIZE 2048
|
||||
#define SDP_RSP_BUFFER_SIZE 65535
|
||||
#define SDP_PDU_CHUNK_SIZE 1024
|
||||
|
||||
/*
|
||||
* All definitions are based on Bluetooth Assigned Numbers
|
||||
* of the Bluetooth Specification
|
||||
*/
|
||||
#define SDP_PSM 0x0001
|
||||
|
||||
/*
|
||||
* Protocol UUIDs
|
||||
*/
|
||||
#define SDP_UUID 0x0001
|
||||
#define UDP_UUID 0x0002
|
||||
#define RFCOMM_UUID 0x0003
|
||||
#define TCP_UUID 0x0004
|
||||
#define TCS_BIN_UUID 0x0005
|
||||
#define TCS_AT_UUID 0x0006
|
||||
#define ATT_UUID 0x0007
|
||||
#define OBEX_UUID 0x0008
|
||||
#define IP_UUID 0x0009
|
||||
#define FTP_UUID 0x000a
|
||||
#define HTTP_UUID 0x000c
|
||||
#define WSP_UUID 0x000e
|
||||
#define BNEP_UUID 0x000f
|
||||
#define UPNP_UUID 0x0010
|
||||
#define HIDP_UUID 0x0011
|
||||
#define HCRP_CTRL_UUID 0x0012
|
||||
#define HCRP_DATA_UUID 0x0014
|
||||
#define HCRP_NOTE_UUID 0x0016
|
||||
#define AVCTP_UUID 0x0017
|
||||
#define AVDTP_UUID 0x0019
|
||||
#define CMTP_UUID 0x001b
|
||||
#define UDI_UUID 0x001d
|
||||
#define MCAP_CTRL_UUID 0x001e
|
||||
#define MCAP_DATA_UUID 0x001f
|
||||
#define L2CAP_UUID 0x0100
|
||||
|
||||
/*
|
||||
* Service class identifiers of standard services and service groups
|
||||
*/
|
||||
#define SDP_SERVER_SVCLASS_ID 0x1000
|
||||
#define BROWSE_GRP_DESC_SVCLASS_ID 0x1001
|
||||
#define PUBLIC_BROWSE_GROUP 0x1002
|
||||
#define SERIAL_PORT_SVCLASS_ID 0x1101
|
||||
#define LAN_ACCESS_SVCLASS_ID 0x1102
|
||||
#define DIALUP_NET_SVCLASS_ID 0x1103
|
||||
#define IRMC_SYNC_SVCLASS_ID 0x1104
|
||||
#define OBEX_OBJPUSH_SVCLASS_ID 0x1105
|
||||
#define OBEX_FILETRANS_SVCLASS_ID 0x1106
|
||||
#define IRMC_SYNC_CMD_SVCLASS_ID 0x1107
|
||||
#define HEADSET_SVCLASS_ID 0x1108
|
||||
#define CORDLESS_TELEPHONY_SVCLASS_ID 0x1109
|
||||
#define AUDIO_SOURCE_SVCLASS_ID 0x110a
|
||||
#define AUDIO_SINK_SVCLASS_ID 0x110b
|
||||
#define AV_REMOTE_TARGET_SVCLASS_ID 0x110c
|
||||
#define ADVANCED_AUDIO_SVCLASS_ID 0x110d
|
||||
#define AV_REMOTE_SVCLASS_ID 0x110e
|
||||
#define AV_REMOTE_CONTROLLER_SVCLASS_ID 0x110f
|
||||
#define INTERCOM_SVCLASS_ID 0x1110
|
||||
#define FAX_SVCLASS_ID 0x1111
|
||||
#define HEADSET_AGW_SVCLASS_ID 0x1112
|
||||
#define WAP_SVCLASS_ID 0x1113
|
||||
#define WAP_CLIENT_SVCLASS_ID 0x1114
|
||||
#define PANU_SVCLASS_ID 0x1115
|
||||
#define NAP_SVCLASS_ID 0x1116
|
||||
#define GN_SVCLASS_ID 0x1117
|
||||
#define DIRECT_PRINTING_SVCLASS_ID 0x1118
|
||||
#define REFERENCE_PRINTING_SVCLASS_ID 0x1119
|
||||
#define IMAGING_SVCLASS_ID 0x111a
|
||||
#define IMAGING_RESPONDER_SVCLASS_ID 0x111b
|
||||
#define IMAGING_ARCHIVE_SVCLASS_ID 0x111c
|
||||
#define IMAGING_REFOBJS_SVCLASS_ID 0x111d
|
||||
#define HANDSFREE_SVCLASS_ID 0x111e
|
||||
#define HANDSFREE_AGW_SVCLASS_ID 0x111f
|
||||
#define DIRECT_PRT_REFOBJS_SVCLASS_ID 0x1120
|
||||
#define REFLECTED_UI_SVCLASS_ID 0x1121
|
||||
#define BASIC_PRINTING_SVCLASS_ID 0x1122
|
||||
#define PRINTING_STATUS_SVCLASS_ID 0x1123
|
||||
#define HID_SVCLASS_ID 0x1124
|
||||
#define HCR_SVCLASS_ID 0x1125
|
||||
#define HCR_PRINT_SVCLASS_ID 0x1126
|
||||
#define HCR_SCAN_SVCLASS_ID 0x1127
|
||||
#define CIP_SVCLASS_ID 0x1128
|
||||
#define VIDEO_CONF_GW_SVCLASS_ID 0x1129
|
||||
#define UDI_MT_SVCLASS_ID 0x112a
|
||||
#define UDI_TA_SVCLASS_ID 0x112b
|
||||
#define AV_SVCLASS_ID 0x112c
|
||||
#define SAP_SVCLASS_ID 0x112d
|
||||
#define PBAP_PCE_SVCLASS_ID 0x112e
|
||||
#define PBAP_PSE_SVCLASS_ID 0x112f
|
||||
#define PBAP_SVCLASS_ID 0x1130
|
||||
#define MAP_MSE_SVCLASS_ID 0x1132
|
||||
#define MAP_MCE_SVCLASS_ID 0x1133
|
||||
#define MAP_SVCLASS_ID 0x1134
|
||||
#define GNSS_SVCLASS_ID 0x1135
|
||||
#define GNSS_SERVER_SVCLASS_ID 0x1136
|
||||
#define PNP_INFO_SVCLASS_ID 0x1200
|
||||
#define GENERIC_NETWORKING_SVCLASS_ID 0x1201
|
||||
#define GENERIC_FILETRANS_SVCLASS_ID 0x1202
|
||||
#define GENERIC_AUDIO_SVCLASS_ID 0x1203
|
||||
#define GENERIC_TELEPHONY_SVCLASS_ID 0x1204
|
||||
#define UPNP_SVCLASS_ID 0x1205
|
||||
#define UPNP_IP_SVCLASS_ID 0x1206
|
||||
#define UPNP_PAN_SVCLASS_ID 0x1300
|
||||
#define UPNP_LAP_SVCLASS_ID 0x1301
|
||||
#define UPNP_L2CAP_SVCLASS_ID 0x1302
|
||||
#define VIDEO_SOURCE_SVCLASS_ID 0x1303
|
||||
#define VIDEO_SINK_SVCLASS_ID 0x1304
|
||||
#define VIDEO_DISTRIBUTION_SVCLASS_ID 0x1305
|
||||
#define HDP_SVCLASS_ID 0x1400
|
||||
#define HDP_SOURCE_SVCLASS_ID 0x1401
|
||||
#define HDP_SINK_SVCLASS_ID 0x1402
|
||||
#define APPLE_AGENT_SVCLASS_ID 0x2112
|
||||
#define GENERIC_ATTRIB_SVCLASS_ID 0x1801
|
||||
|
||||
/*
|
||||
* Standard profile descriptor identifiers; note these
|
||||
* may be identical to some of the service classes defined above
|
||||
*/
|
||||
#define SDP_SERVER_PROFILE_ID SDP_SERVER_SVCLASS_ID
|
||||
#define BROWSE_GRP_DESC_PROFILE_ID BROWSE_GRP_DESC_SVCLASS_ID
|
||||
#define SERIAL_PORT_PROFILE_ID SERIAL_PORT_SVCLASS_ID
|
||||
#define LAN_ACCESS_PROFILE_ID LAN_ACCESS_SVCLASS_ID
|
||||
#define DIALUP_NET_PROFILE_ID DIALUP_NET_SVCLASS_ID
|
||||
#define IRMC_SYNC_PROFILE_ID IRMC_SYNC_SVCLASS_ID
|
||||
#define OBEX_OBJPUSH_PROFILE_ID OBEX_OBJPUSH_SVCLASS_ID
|
||||
#define OBEX_FILETRANS_PROFILE_ID OBEX_FILETRANS_SVCLASS_ID
|
||||
#define IRMC_SYNC_CMD_PROFILE_ID IRMC_SYNC_CMD_SVCLASS_ID
|
||||
#define HEADSET_PROFILE_ID HEADSET_SVCLASS_ID
|
||||
#define CORDLESS_TELEPHONY_PROFILE_ID CORDLESS_TELEPHONY_SVCLASS_ID
|
||||
#define AUDIO_SOURCE_PROFILE_ID AUDIO_SOURCE_SVCLASS_ID
|
||||
#define AUDIO_SINK_PROFILE_ID AUDIO_SINK_SVCLASS_ID
|
||||
#define AV_REMOTE_TARGET_PROFILE_ID AV_REMOTE_TARGET_SVCLASS_ID
|
||||
#define ADVANCED_AUDIO_PROFILE_ID ADVANCED_AUDIO_SVCLASS_ID
|
||||
#define AV_REMOTE_PROFILE_ID AV_REMOTE_SVCLASS_ID
|
||||
#define VIDEO_CONF_PROFILE_ID VIDEO_CONF_SVCLASS_ID
|
||||
#define INTERCOM_PROFILE_ID INTERCOM_SVCLASS_ID
|
||||
#define FAX_PROFILE_ID FAX_SVCLASS_ID
|
||||
#define HEADSET_AGW_PROFILE_ID HEADSET_AGW_SVCLASS_ID
|
||||
#define WAP_PROFILE_ID WAP_SVCLASS_ID
|
||||
#define WAP_CLIENT_PROFILE_ID WAP_CLIENT_SVCLASS_ID
|
||||
#define PANU_PROFILE_ID PANU_SVCLASS_ID
|
||||
#define NAP_PROFILE_ID NAP_SVCLASS_ID
|
||||
#define GN_PROFILE_ID GN_SVCLASS_ID
|
||||
#define DIRECT_PRINTING_PROFILE_ID DIRECT_PRINTING_SVCLASS_ID
|
||||
#define REFERENCE_PRINTING_PROFILE_ID REFERENCE_PRINTING_SVCLASS_ID
|
||||
#define IMAGING_PROFILE_ID IMAGING_SVCLASS_ID
|
||||
#define IMAGING_RESPONDER_PROFILE_ID IMAGING_RESPONDER_SVCLASS_ID
|
||||
#define IMAGING_ARCHIVE_PROFILE_ID IMAGING_ARCHIVE_SVCLASS_ID
|
||||
#define IMAGING_REFOBJS_PROFILE_ID IMAGING_REFOBJS_SVCLASS_ID
|
||||
#define HANDSFREE_PROFILE_ID HANDSFREE_SVCLASS_ID
|
||||
#define HANDSFREE_AGW_PROFILE_ID HANDSFREE_AGW_SVCLASS_ID
|
||||
#define DIRECT_PRT_REFOBJS_PROFILE_ID DIRECT_PRT_REFOBJS_SVCLASS_ID
|
||||
#define REFLECTED_UI_PROFILE_ID REFLECTED_UI_SVCLASS_ID
|
||||
#define BASIC_PRINTING_PROFILE_ID BASIC_PRINTING_SVCLASS_ID
|
||||
#define PRINTING_STATUS_PROFILE_ID PRINTING_STATUS_SVCLASS_ID
|
||||
#define HID_PROFILE_ID HID_SVCLASS_ID
|
||||
#define HCR_PROFILE_ID HCR_SCAN_SVCLASS_ID
|
||||
#define HCR_PRINT_PROFILE_ID HCR_PRINT_SVCLASS_ID
|
||||
#define HCR_SCAN_PROFILE_ID HCR_SCAN_SVCLASS_ID
|
||||
#define CIP_PROFILE_ID CIP_SVCLASS_ID
|
||||
#define VIDEO_CONF_GW_PROFILE_ID VIDEO_CONF_GW_SVCLASS_ID
|
||||
#define UDI_MT_PROFILE_ID UDI_MT_SVCLASS_ID
|
||||
#define UDI_TA_PROFILE_ID UDI_TA_SVCLASS_ID
|
||||
#define AV_PROFILE_ID AV_SVCLASS_ID
|
||||
#define SAP_PROFILE_ID SAP_SVCLASS_ID
|
||||
#define PBAP_PCE_PROFILE_ID PBAP_PCE_SVCLASS_ID
|
||||
#define PBAP_PSE_PROFILE_ID PBAP_PSE_SVCLASS_ID
|
||||
#define PBAP_PROFILE_ID PBAP_SVCLASS_ID
|
||||
#define PNP_INFO_PROFILE_ID PNP_INFO_SVCLASS_ID
|
||||
#define GENERIC_NETWORKING_PROFILE_ID GENERIC_NETWORKING_SVCLASS_ID
|
||||
#define GENERIC_FILETRANS_PROFILE_ID GENERIC_FILETRANS_SVCLASS_ID
|
||||
#define GENERIC_AUDIO_PROFILE_ID GENERIC_AUDIO_SVCLASS_ID
|
||||
#define GENERIC_TELEPHONY_PROFILE_ID GENERIC_TELEPHONY_SVCLASS_ID
|
||||
#define UPNP_PROFILE_ID UPNP_SVCLASS_ID
|
||||
#define UPNP_IP_PROFILE_ID UPNP_IP_SVCLASS_ID
|
||||
#define UPNP_PAN_PROFILE_ID UPNP_PAN_SVCLASS_ID
|
||||
#define UPNP_LAP_PROFILE_ID UPNP_LAP_SVCLASS_ID
|
||||
#define UPNP_L2CAP_PROFILE_ID UPNP_L2CAP_SVCLASS_ID
|
||||
#define VIDEO_SOURCE_PROFILE_ID VIDEO_SOURCE_SVCLASS_ID
|
||||
#define VIDEO_SINK_PROFILE_ID VIDEO_SINK_SVCLASS_ID
|
||||
#define VIDEO_DISTRIBUTION_PROFILE_ID VIDEO_DISTRIBUTION_SVCLASS_ID
|
||||
#define HDP_PROFILE_ID HDP_SVCLASS_ID
|
||||
#define HDP_SOURCE_PROFILE_ID HDP_SOURCE_SVCLASS_ID
|
||||
#define HDP_SINK_PROFILE_ID HDP_SINK_SVCLASS_ID
|
||||
#define APPLE_AGENT_PROFILE_ID APPLE_AGENT_SVCLASS_ID
|
||||
#define GENERIC_ACCESS_PROFILE_ID 0x1800
|
||||
#define GENERIC_ATTRIB_PROFILE_ID GENERIC_ATTRIB_SVCLASS_ID
|
||||
|
||||
/*
|
||||
* Compatibility macros for the old MDP acronym
|
||||
*/
|
||||
#define MDP_SVCLASS_ID HDP_SVCLASS_ID
|
||||
#define MDP_SOURCE_SVCLASS_ID HDP_SOURCE_SVCLASS_ID
|
||||
#define MDP_SINK_SVCLASS_ID HDP_SINK_SVCLASS_ID
|
||||
#define MDP_PROFILE_ID HDP_PROFILE_ID
|
||||
#define MDP_SOURCE_PROFILE_ID HDP_SOURCE_PROFILE_ID
|
||||
#define MDP_SINK_PROFILE_ID HDP_SINK_PROFILE_ID
|
||||
|
||||
/*
|
||||
* Attribute identifier codes
|
||||
*/
|
||||
#define SDP_SERVER_RECORD_HANDLE 0x0000
|
||||
|
||||
/*
|
||||
* Possible values for attribute-id are listed below.
|
||||
* See SDP Spec, section "Service Attribute Definitions" for more details.
|
||||
*/
|
||||
#define SDP_ATTR_RECORD_HANDLE 0x0000
|
||||
#define SDP_ATTR_SVCLASS_ID_LIST 0x0001
|
||||
#define SDP_ATTR_RECORD_STATE 0x0002
|
||||
#define SDP_ATTR_SERVICE_ID 0x0003
|
||||
#define SDP_ATTR_PROTO_DESC_LIST 0x0004
|
||||
#define SDP_ATTR_BROWSE_GRP_LIST 0x0005
|
||||
#define SDP_ATTR_LANG_BASE_ATTR_ID_LIST 0x0006
|
||||
#define SDP_ATTR_SVCINFO_TTL 0x0007
|
||||
#define SDP_ATTR_SERVICE_AVAILABILITY 0x0008
|
||||
#define SDP_ATTR_PFILE_DESC_LIST 0x0009
|
||||
#define SDP_ATTR_DOC_URL 0x000a
|
||||
#define SDP_ATTR_CLNT_EXEC_URL 0x000b
|
||||
#define SDP_ATTR_ICON_URL 0x000c
|
||||
#define SDP_ATTR_ADD_PROTO_DESC_LIST 0x000d
|
||||
|
||||
#define SDP_ATTR_GROUP_ID 0x0200
|
||||
#define SDP_ATTR_IP_SUBNET 0x0200
|
||||
#define SDP_ATTR_VERSION_NUM_LIST 0x0200
|
||||
#define SDP_ATTR_SUPPORTED_FEATURES_LIST 0x0200
|
||||
#define SDP_ATTR_GOEP_L2CAP_PSM 0x0200
|
||||
#define SDP_ATTR_SVCDB_STATE 0x0201
|
||||
|
||||
#define SDP_ATTR_SERVICE_VERSION 0x0300
|
||||
#define SDP_ATTR_EXTERNAL_NETWORK 0x0301
|
||||
#define SDP_ATTR_SUPPORTED_DATA_STORES_LIST 0x0301
|
||||
#define SDP_ATTR_DATA_EXCHANGE_SPEC 0x0301
|
||||
#define SDP_ATTR_NETWORK 0x0301
|
||||
#define SDP_ATTR_FAX_CLASS1_SUPPORT 0x0302
|
||||
#define SDP_ATTR_REMOTE_AUDIO_VOLUME_CONTROL 0x0302
|
||||
#define SDP_ATTR_MCAP_SUPPORTED_PROCEDURES 0x0302
|
||||
#define SDP_ATTR_FAX_CLASS20_SUPPORT 0x0303
|
||||
#define SDP_ATTR_SUPPORTED_FORMATS_LIST 0x0303
|
||||
#define SDP_ATTR_FAX_CLASS2_SUPPORT 0x0304
|
||||
#define SDP_ATTR_AUDIO_FEEDBACK_SUPPORT 0x0305
|
||||
#define SDP_ATTR_NETWORK_ADDRESS 0x0306
|
||||
#define SDP_ATTR_WAP_GATEWAY 0x0307
|
||||
#define SDP_ATTR_HOMEPAGE_URL 0x0308
|
||||
#define SDP_ATTR_WAP_STACK_TYPE 0x0309
|
||||
#define SDP_ATTR_SECURITY_DESC 0x030a
|
||||
#define SDP_ATTR_NET_ACCESS_TYPE 0x030b
|
||||
#define SDP_ATTR_MAX_NET_ACCESSRATE 0x030c
|
||||
#define SDP_ATTR_IP4_SUBNET 0x030d
|
||||
#define SDP_ATTR_IP6_SUBNET 0x030e
|
||||
#define SDP_ATTR_SUPPORTED_CAPABILITIES 0x0310
|
||||
#define SDP_ATTR_SUPPORTED_FEATURES 0x0311
|
||||
#define SDP_ATTR_SUPPORTED_FUNCTIONS 0x0312
|
||||
#define SDP_ATTR_TOTAL_IMAGING_DATA_CAPACITY 0x0313
|
||||
#define SDP_ATTR_SUPPORTED_REPOSITORIES 0x0314
|
||||
#define SDP_ATTR_MAS_INSTANCE_ID 0x0315
|
||||
#define SDP_ATTR_SUPPORTED_MESSAGE_TYPES 0x0316
|
||||
|
||||
#define SDP_ATTR_SPECIFICATION_ID 0x0200
|
||||
#define SDP_ATTR_VENDOR_ID 0x0201
|
||||
#define SDP_ATTR_PRODUCT_ID 0x0202
|
||||
#define SDP_ATTR_VERSION 0x0203
|
||||
#define SDP_ATTR_PRIMARY_RECORD 0x0204
|
||||
#define SDP_ATTR_VENDOR_ID_SOURCE 0x0205
|
||||
|
||||
#define SDP_ATTR_HID_DEVICE_RELEASE_NUMBER 0x0200
|
||||
#define SDP_ATTR_HID_PARSER_VERSION 0x0201
|
||||
#define SDP_ATTR_HID_DEVICE_SUBCLASS 0x0202
|
||||
#define SDP_ATTR_HID_COUNTRY_CODE 0x0203
|
||||
#define SDP_ATTR_HID_VIRTUAL_CABLE 0x0204
|
||||
#define SDP_ATTR_HID_RECONNECT_INITIATE 0x0205
|
||||
#define SDP_ATTR_HID_DESCRIPTOR_LIST 0x0206
|
||||
#define SDP_ATTR_HID_LANG_ID_BASE_LIST 0x0207
|
||||
#define SDP_ATTR_HID_SDP_DISABLE 0x0208
|
||||
#define SDP_ATTR_HID_BATTERY_POWER 0x0209
|
||||
#define SDP_ATTR_HID_REMOTE_WAKEUP 0x020a
|
||||
#define SDP_ATTR_HID_PROFILE_VERSION 0x020b
|
||||
#define SDP_ATTR_HID_SUPERVISION_TIMEOUT 0x020c
|
||||
#define SDP_ATTR_HID_NORMALLY_CONNECTABLE 0x020d
|
||||
#define SDP_ATTR_HID_BOOT_DEVICE 0x020e
|
||||
|
||||
/*
|
||||
* These identifiers are based on the SDP spec stating that
|
||||
* "base attribute id of the primary (universal) language must be 0x0100"
|
||||
*
|
||||
* Other languages should have their own offset; e.g.:
|
||||
* #define XXXLangBase yyyy
|
||||
* #define AttrServiceName_XXX 0x0000+XXXLangBase
|
||||
*/
|
||||
#define SDP_PRIMARY_LANG_BASE 0x0100
|
||||
|
||||
#define SDP_ATTR_SVCNAME_PRIMARY 0x0000 + SDP_PRIMARY_LANG_BASE
|
||||
#define SDP_ATTR_SVCDESC_PRIMARY 0x0001 + SDP_PRIMARY_LANG_BASE
|
||||
#define SDP_ATTR_PROVNAME_PRIMARY 0x0002 + SDP_PRIMARY_LANG_BASE
|
||||
|
||||
/*
|
||||
* The Data representation in SDP PDUs (pps 339, 340 of BT SDP Spec)
|
||||
* These are the exact data type+size descriptor values
|
||||
* that go into the PDU buffer.
|
||||
*
|
||||
* The datatype (leading 5bits) + size descriptor (last 3 bits)
|
||||
* is 8 bits. The size descriptor is critical to extract the
|
||||
* right number of bytes for the data value from the PDU.
|
||||
*
|
||||
* For most basic types, the datatype+size descriptor is
|
||||
* straightforward. However for constructed types and strings,
|
||||
* the size of the data is in the next "n" bytes following the
|
||||
* 8 bits (datatype+size) descriptor. Exactly what the "n" is
|
||||
* specified in the 3 bits of the data size descriptor.
|
||||
*
|
||||
* TextString and URLString can be of size 2^{8, 16, 32} bytes
|
||||
* DataSequence and DataSequenceAlternates can be of size 2^{8, 16, 32}
|
||||
* The size are computed post-facto in the API and are not known apriori
|
||||
*/
|
||||
#define SDP_DATA_NIL 0x00
|
||||
#define SDP_UINT8 0x08
|
||||
#define SDP_UINT16 0x09
|
||||
#define SDP_UINT32 0x0A
|
||||
#define SDP_UINT64 0x0B
|
||||
#define SDP_UINT128 0x0C
|
||||
#define SDP_INT8 0x10
|
||||
#define SDP_INT16 0x11
|
||||
#define SDP_INT32 0x12
|
||||
#define SDP_INT64 0x13
|
||||
#define SDP_INT128 0x14
|
||||
#define SDP_UUID_UNSPEC 0x18
|
||||
#define SDP_UUID16 0x19
|
||||
#define SDP_UUID32 0x1A
|
||||
#define SDP_UUID128 0x1C
|
||||
#define SDP_TEXT_STR_UNSPEC 0x20
|
||||
#define SDP_TEXT_STR8 0x25
|
||||
#define SDP_TEXT_STR16 0x26
|
||||
#define SDP_TEXT_STR32 0x27
|
||||
#define SDP_BOOL 0x28
|
||||
#define SDP_SEQ_UNSPEC 0x30
|
||||
#define SDP_SEQ8 0x35
|
||||
#define SDP_SEQ16 0x36
|
||||
#define SDP_SEQ32 0x37
|
||||
#define SDP_ALT_UNSPEC 0x38
|
||||
#define SDP_ALT8 0x3D
|
||||
#define SDP_ALT16 0x3E
|
||||
#define SDP_ALT32 0x3F
|
||||
#define SDP_URL_STR_UNSPEC 0x40
|
||||
#define SDP_URL_STR8 0x45
|
||||
#define SDP_URL_STR16 0x46
|
||||
#define SDP_URL_STR32 0x47
|
||||
|
||||
/*
|
||||
* The PDU identifiers of SDP packets between client and server
|
||||
*/
|
||||
#define SDP_ERROR_RSP 0x01
|
||||
#define SDP_SVC_SEARCH_REQ 0x02
|
||||
#define SDP_SVC_SEARCH_RSP 0x03
|
||||
#define SDP_SVC_ATTR_REQ 0x04
|
||||
#define SDP_SVC_ATTR_RSP 0x05
|
||||
#define SDP_SVC_SEARCH_ATTR_REQ 0x06
|
||||
#define SDP_SVC_SEARCH_ATTR_RSP 0x07
|
||||
|
||||
/*
|
||||
* Some additions to support service registration.
|
||||
* These are outside the scope of the Bluetooth specification
|
||||
*/
|
||||
#define SDP_SVC_REGISTER_REQ 0x75
|
||||
#define SDP_SVC_REGISTER_RSP 0x76
|
||||
#define SDP_SVC_UPDATE_REQ 0x77
|
||||
#define SDP_SVC_UPDATE_RSP 0x78
|
||||
#define SDP_SVC_REMOVE_REQ 0x79
|
||||
#define SDP_SVC_REMOVE_RSP 0x80
|
||||
|
||||
/*
|
||||
* SDP Error codes
|
||||
*/
|
||||
#define SDP_INVALID_VERSION 0x0001
|
||||
#define SDP_INVALID_RECORD_HANDLE 0x0002
|
||||
#define SDP_INVALID_SYNTAX 0x0003
|
||||
#define SDP_INVALID_PDU_SIZE 0x0004
|
||||
#define SDP_INVALID_CSTATE 0x0005
|
||||
|
||||
/*
|
||||
* SDP PDU
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t pdu_id;
|
||||
uint16_t tid;
|
||||
uint16_t plen;
|
||||
} __attribute__ ((packed)) sdp_pdu_hdr_t;
|
||||
|
||||
/*
|
||||
* Common definitions for attributes in the SDP.
|
||||
* Should the type of any of these change, you need only make a change here.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
union {
|
||||
uint16_t uuid16;
|
||||
uint32_t uuid32;
|
||||
uint128_t uuid128;
|
||||
} value;
|
||||
} uuid_t;
|
||||
|
||||
#define SDP_IS_UUID(x) ((x) == SDP_UUID16 || (x) == SDP_UUID32 || \
|
||||
(x) == SDP_UUID128)
|
||||
#define SDP_IS_ALT(x) ((x) == SDP_ALT8 || (x) == SDP_ALT16 || (x) == SDP_ALT32)
|
||||
#define SDP_IS_SEQ(x) ((x) == SDP_SEQ8 || (x) == SDP_SEQ16 || (x) == SDP_SEQ32)
|
||||
#define SDP_IS_TEXT_STR(x) ((x) == SDP_TEXT_STR8 || (x) == SDP_TEXT_STR16 || \
|
||||
(x) == SDP_TEXT_STR32)
|
||||
|
||||
typedef struct _sdp_list sdp_list_t;
|
||||
struct _sdp_list {
|
||||
sdp_list_t *next;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/*
|
||||
* User-visible strings can be in many languages
|
||||
* in addition to the universal language.
|
||||
*
|
||||
* Language meta-data includes language code in ISO639
|
||||
* followed by the encoding format. The third field in this
|
||||
* structure is the attribute offset for the language.
|
||||
* User-visible strings in the specified language can be
|
||||
* obtained at this offset.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t code_ISO639;
|
||||
uint16_t encoding;
|
||||
uint16_t base_offset;
|
||||
} sdp_lang_attr_t;
|
||||
|
||||
/*
|
||||
* Profile descriptor is the Bluetooth profile metadata. If a
|
||||
* service conforms to a well-known profile, then its profile
|
||||
* identifier (UUID) is an attribute of the service. In addition,
|
||||
* if the profile has a version number it is specified here.
|
||||
*/
|
||||
typedef struct {
|
||||
uuid_t uuid;
|
||||
uint16_t version;
|
||||
} sdp_profile_desc_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
} sdp_version_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *data;
|
||||
uint32_t data_size;
|
||||
uint32_t buf_size;
|
||||
} sdp_buf_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t handle;
|
||||
|
||||
/* Search pattern: a sequence of all UUIDs seen in this record */
|
||||
sdp_list_t *pattern;
|
||||
sdp_list_t *attrlist;
|
||||
|
||||
/* Main service class for Extended Inquiry Response */
|
||||
uuid_t svclass;
|
||||
} sdp_record_t;
|
||||
|
||||
typedef struct sdp_data_struct sdp_data_t;
|
||||
struct sdp_data_struct {
|
||||
uint8_t dtd;
|
||||
uint16_t attrId;
|
||||
union {
|
||||
int8_t int8;
|
||||
int16_t int16;
|
||||
int32_t int32;
|
||||
int64_t int64;
|
||||
uint128_t int128;
|
||||
uint8_t uint8;
|
||||
uint16_t uint16;
|
||||
uint32_t uint32;
|
||||
uint64_t uint64;
|
||||
uint128_t uint128;
|
||||
uuid_t uuid;
|
||||
char *str;
|
||||
sdp_data_t *dataseq;
|
||||
} val;
|
||||
sdp_data_t *next;
|
||||
int unitSize;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SDP_H */
|
||||
633
external/cache/sources/hcitools/lib/bluetooth/sdp_lib.h
vendored
Normal file
633
external/cache/sources/hcitools/lib/bluetooth/sdp_lib.h
vendored
Normal file
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2001-2002 Nokia Corporation
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
* Copyright (C) 2002-2003 Stephen Crane <steve.crane@rococosoft.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SDP_LIB_H
|
||||
#define __SDP_LIB_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SDP lists
|
||||
*/
|
||||
typedef void(*sdp_list_func_t)(void *, void *);
|
||||
typedef void(*sdp_free_func_t)(void *);
|
||||
typedef int (*sdp_comp_func_t)(const void *, const void *);
|
||||
|
||||
sdp_list_t *sdp_list_append(sdp_list_t *list, void *d);
|
||||
sdp_list_t *sdp_list_remove(sdp_list_t *list, void *d);
|
||||
sdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *data, sdp_comp_func_t f);
|
||||
void sdp_list_free(sdp_list_t *list, sdp_free_func_t f);
|
||||
|
||||
static inline int sdp_list_len(const sdp_list_t *list)
|
||||
{
|
||||
int n = 0;
|
||||
for (; list; list = list->next)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline sdp_list_t *sdp_list_find(sdp_list_t *list, void *u, sdp_comp_func_t f)
|
||||
{
|
||||
for (; list; list = list->next)
|
||||
if (f(list->data, u) == 0)
|
||||
return list;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void sdp_list_foreach(sdp_list_t *list, sdp_list_func_t f, void *u)
|
||||
{
|
||||
for (; list; list = list->next)
|
||||
f(list->data, u);
|
||||
}
|
||||
|
||||
/*
|
||||
* Values of the flags parameter to sdp_record_register
|
||||
*/
|
||||
#define SDP_RECORD_PERSIST 0x01
|
||||
#define SDP_DEVICE_RECORD 0x02
|
||||
|
||||
/*
|
||||
* Values of the flags parameter to sdp_connect
|
||||
*/
|
||||
#define SDP_RETRY_IF_BUSY 0x01
|
||||
#define SDP_WAIT_ON_CLOSE 0x02
|
||||
#define SDP_NON_BLOCKING 0x04
|
||||
|
||||
/*
|
||||
* a session with an SDP server
|
||||
*/
|
||||
typedef struct {
|
||||
int sock;
|
||||
int state;
|
||||
int local;
|
||||
int flags;
|
||||
uint16_t tid; /* Current transaction ID */
|
||||
void *priv;
|
||||
} sdp_session_t;
|
||||
|
||||
typedef enum {
|
||||
/*
|
||||
* Attributes are specified as individual elements
|
||||
*/
|
||||
SDP_ATTR_REQ_INDIVIDUAL = 1,
|
||||
/*
|
||||
* Attributes are specified as a range
|
||||
*/
|
||||
SDP_ATTR_REQ_RANGE
|
||||
} sdp_attrreq_type_t;
|
||||
|
||||
/*
|
||||
* When the pdu_id(type) is a sdp error response, check the status value
|
||||
* to figure out the error reason. For status values 0x0001-0x0006 check
|
||||
* Bluetooth SPEC. If the status is 0xffff, call sdp_get_error function
|
||||
* to get the real reason:
|
||||
* - wrong transaction ID(EPROTO)
|
||||
* - wrong PDU id or(EPROTO)
|
||||
* - I/O error
|
||||
*/
|
||||
typedef void sdp_callback_t(uint8_t type, uint16_t status, uint8_t *rsp, size_t size, void *udata);
|
||||
|
||||
/*
|
||||
* create an L2CAP connection to a Bluetooth device
|
||||
*
|
||||
* INPUT:
|
||||
*
|
||||
* bdaddr_t *src:
|
||||
* Address of the local device to use to make the connection
|
||||
* (or BDADDR_ANY)
|
||||
*
|
||||
* bdaddr_t *dst:
|
||||
* Address of the SDP server device
|
||||
*/
|
||||
sdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t flags);
|
||||
int sdp_close(sdp_session_t *session);
|
||||
int sdp_get_socket(const sdp_session_t *session);
|
||||
|
||||
/*
|
||||
* SDP transaction: functions for asynchronous search.
|
||||
*/
|
||||
sdp_session_t *sdp_create(int sk, uint32_t flags);
|
||||
int sdp_get_error(sdp_session_t *session);
|
||||
int sdp_process(sdp_session_t *session);
|
||||
int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata);
|
||||
|
||||
int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num);
|
||||
int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list);
|
||||
int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list);
|
||||
|
||||
uint16_t sdp_gen_tid(sdp_session_t *session);
|
||||
|
||||
/*
|
||||
* find all devices in the piconet
|
||||
*/
|
||||
int sdp_general_inquiry(inquiry_info *ii, int dev_num, int duration, uint8_t *found);
|
||||
|
||||
/* flexible extraction of basic attributes - Jean II */
|
||||
int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attr, int *value);
|
||||
int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attr, char *value, int valuelen);
|
||||
|
||||
/*
|
||||
* Basic sdp data functions
|
||||
*/
|
||||
sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value);
|
||||
sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, uint32_t length);
|
||||
void sdp_data_free(sdp_data_t *data);
|
||||
sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attr_id);
|
||||
|
||||
sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len);
|
||||
sdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length, int len);
|
||||
sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *data);
|
||||
|
||||
int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *data);
|
||||
void sdp_attr_remove(sdp_record_t *rec, uint16_t attr);
|
||||
void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *data);
|
||||
int sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t attr, sdp_list_t *seq);
|
||||
int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **seqp);
|
||||
|
||||
/*
|
||||
* NOTE that none of the functions below will update the SDP server,
|
||||
* unless the {register, update}sdp_record_t() function is invoked.
|
||||
* All functions which return an integer value, return 0 on success
|
||||
* or -1 on failure.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create an attribute and add it to the service record's attribute list.
|
||||
* This consists of the data type descriptor of the attribute,
|
||||
* the value of the attribute and the attribute identifier.
|
||||
*/
|
||||
int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd, const void *p);
|
||||
|
||||
/*
|
||||
* Set the information attributes of the service record.
|
||||
* The set of attributes comprises service name, description
|
||||
* and provider name
|
||||
*/
|
||||
void sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov, const char *desc);
|
||||
|
||||
/*
|
||||
* Set the ServiceClassID attribute to the sequence specified by seq.
|
||||
* Note that the identifiers need to be in sorted order from the most
|
||||
* specific to the most generic service class that this service
|
||||
* conforms to.
|
||||
*/
|
||||
static inline int sdp_set_service_classes(sdp_record_t *rec, sdp_list_t *seq)
|
||||
{
|
||||
return sdp_set_uuidseq_attr(rec, SDP_ATTR_SVCLASS_ID_LIST, seq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the service classes to which the service conforms.
|
||||
*
|
||||
* When set, the list contains elements of ServiceClassIdentifer(uint16_t)
|
||||
* ordered from most specific to most generic
|
||||
*/
|
||||
static inline int sdp_get_service_classes(const sdp_record_t *rec, sdp_list_t **seqp)
|
||||
{
|
||||
return sdp_get_uuidseq_attr(rec, SDP_ATTR_SVCLASS_ID_LIST, seqp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the BrowseGroupList attribute to the list specified by seq.
|
||||
*
|
||||
* A service can belong to one or more service groups
|
||||
* and the list comprises such group identifiers (UUIDs)
|
||||
*/
|
||||
static inline int sdp_set_browse_groups(sdp_record_t *rec, sdp_list_t *seq)
|
||||
{
|
||||
return sdp_set_uuidseq_attr(rec, SDP_ATTR_BROWSE_GRP_LIST, seq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the access protocols of the record to those specified in proto
|
||||
*/
|
||||
int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *proto);
|
||||
|
||||
/*
|
||||
* Set the additional access protocols of the record to those specified in proto
|
||||
*/
|
||||
int sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *proto);
|
||||
|
||||
/*
|
||||
* Get protocol port (i.e. PSM for L2CAP, Channel for RFCOMM)
|
||||
*/
|
||||
int sdp_get_proto_port(const sdp_list_t *list, int proto);
|
||||
|
||||
/*
|
||||
* Get protocol descriptor.
|
||||
*/
|
||||
sdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto);
|
||||
|
||||
/*
|
||||
* Set the LanguageBase attributes to the values specified in list
|
||||
* (a linked list of sdp_lang_attr_t objects, one for each language in
|
||||
* which user-visible attributes are present).
|
||||
*/
|
||||
int sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *list);
|
||||
|
||||
/*
|
||||
* Set the ServiceInfoTimeToLive attribute of the service.
|
||||
* This is the number of seconds that this record is guaranteed
|
||||
* not to change after being obtained by a client.
|
||||
*/
|
||||
static inline int sdp_set_service_ttl(sdp_record_t *rec, uint32_t ttl)
|
||||
{
|
||||
return sdp_attr_add_new(rec, SDP_ATTR_SVCINFO_TTL, SDP_UINT32, &ttl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the ServiceRecordState attribute of a service. This is
|
||||
* guaranteed to change if there is any kind of modification to
|
||||
* the record.
|
||||
*/
|
||||
static inline int sdp_set_record_state(sdp_record_t *rec, uint32_t state)
|
||||
{
|
||||
return sdp_attr_add_new(rec, SDP_ATTR_RECORD_STATE, SDP_UINT32, &state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the ServiceID attribute of a service.
|
||||
*/
|
||||
void sdp_set_service_id(sdp_record_t *rec, uuid_t uuid);
|
||||
|
||||
/*
|
||||
* Set the GroupID attribute of a service
|
||||
*/
|
||||
void sdp_set_group_id(sdp_record_t *rec, uuid_t grouuuid);
|
||||
|
||||
/*
|
||||
* Set the ServiceAvailability attribute of a service.
|
||||
*
|
||||
* Note that this represents the relative availability
|
||||
* of the service: 0x00 means completely unavailable;
|
||||
* 0xFF means maximum availability.
|
||||
*/
|
||||
static inline int sdp_set_service_avail(sdp_record_t *rec, uint8_t avail)
|
||||
{
|
||||
return sdp_attr_add_new(rec, SDP_ATTR_SERVICE_AVAILABILITY, SDP_UINT8, &avail);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the profile descriptor list attribute of a record.
|
||||
*
|
||||
* Each element in the list is an object of type
|
||||
* sdp_profile_desc_t which is a definition of the
|
||||
* Bluetooth profile that this service conforms to.
|
||||
*/
|
||||
int sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *desc);
|
||||
|
||||
/*
|
||||
* Set URL attributes of a record.
|
||||
*
|
||||
* ClientExecutableURL: a URL to a client's platform specific (WinCE,
|
||||
* PalmOS) executable code that can be used to access this service.
|
||||
*
|
||||
* DocumentationURL: a URL pointing to service documentation
|
||||
*
|
||||
* IconURL: a URL to an icon that can be used to represent this service.
|
||||
*
|
||||
* Note: pass NULL for any URLs that you don't want to set or remove
|
||||
*/
|
||||
void sdp_set_url_attr(sdp_record_t *rec, const char *clientExecURL, const char *docURL, const char *iconURL);
|
||||
|
||||
/*
|
||||
* a service search request.
|
||||
*
|
||||
* INPUT :
|
||||
*
|
||||
* sdp_list_t *search
|
||||
* list containing elements of the search
|
||||
* pattern. Each entry in the list is a UUID
|
||||
* of the service to be searched
|
||||
*
|
||||
* uint16_t max_rec_num
|
||||
* An integer specifying the maximum number of
|
||||
* entries that the client can handle in the response.
|
||||
*
|
||||
* OUTPUT :
|
||||
*
|
||||
* int return value
|
||||
* 0
|
||||
* The request completed successfully. This does not
|
||||
* mean the requested services were found
|
||||
* -1
|
||||
* The request completed unsuccessfully
|
||||
*
|
||||
* sdp_list_t *rsp_list
|
||||
* This variable is set on a successful return if there are
|
||||
* non-zero service handles. It is a singly linked list of
|
||||
* service record handles (uint16_t)
|
||||
*/
|
||||
int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num, sdp_list_t **rsp_list);
|
||||
|
||||
/*
|
||||
* a service attribute request.
|
||||
*
|
||||
* INPUT :
|
||||
*
|
||||
* uint32_t handle
|
||||
* The handle of the service for which the attribute(s) are
|
||||
* requested
|
||||
*
|
||||
* sdp_attrreq_type_t reqtype
|
||||
* Attribute identifiers are 16 bit unsigned integers specified
|
||||
* in one of 2 ways described below :
|
||||
* SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
|
||||
* They are the actual attribute identifiers in ascending order
|
||||
*
|
||||
* SDP_ATTR_REQ_RANGE - 32bit identifier range
|
||||
* The high-order 16bits is the start of range
|
||||
* the low-order 16bits are the end of range
|
||||
* 0x0000 to 0xFFFF gets all attributes
|
||||
*
|
||||
* sdp_list_t *attrid_list
|
||||
* Singly linked list containing attribute identifiers desired.
|
||||
* Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
|
||||
* or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
|
||||
*
|
||||
* OUTPUT :
|
||||
* int return value
|
||||
* 0
|
||||
* The request completed successfully. This does not
|
||||
* mean the requested services were found
|
||||
* -1
|
||||
* The request completed unsuccessfully due to a timeout
|
||||
*/
|
||||
sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list);
|
||||
|
||||
/*
|
||||
* This is a service search request combined with the service
|
||||
* attribute request. First a service class match is done and
|
||||
* for matching service, requested attributes are extracted
|
||||
*
|
||||
* INPUT :
|
||||
*
|
||||
* sdp_list_t *search
|
||||
* Singly linked list containing elements of the search
|
||||
* pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
|
||||
* of the service to be searched
|
||||
*
|
||||
* AttributeSpecification attrSpec
|
||||
* Attribute identifiers are 16 bit unsigned integers specified
|
||||
* in one of 2 ways described below :
|
||||
* SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
|
||||
* They are the actual attribute identifiers in ascending order
|
||||
*
|
||||
* SDP_ATTR_REQ_RANGE - 32bit identifier range
|
||||
* The high-order 16bits is the start of range
|
||||
* the low-order 16bits are the end of range
|
||||
* 0x0000 to 0xFFFF gets all attributes
|
||||
*
|
||||
* sdp_list_t *attrid_list
|
||||
* Singly linked list containing attribute identifiers desired.
|
||||
* Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
|
||||
* or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
|
||||
*
|
||||
* OUTPUT :
|
||||
* int return value
|
||||
* 0
|
||||
* The request completed successfully. This does not
|
||||
* mean the requested services were found
|
||||
* -1
|
||||
* The request completed unsuccessfully due to a timeout
|
||||
*
|
||||
* sdp_list_t *rsp_list
|
||||
* This variable is set on a successful return to point to
|
||||
* service(s) found. Each element of this list is of type
|
||||
* sdp_record_t *.
|
||||
*/
|
||||
int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list, sdp_list_t **rsp_list);
|
||||
|
||||
/*
|
||||
* Allocate/free a service record and its attributes
|
||||
*/
|
||||
sdp_record_t *sdp_record_alloc(void);
|
||||
void sdp_record_free(sdp_record_t *rec);
|
||||
|
||||
/*
|
||||
* Register a service record.
|
||||
*
|
||||
* Note: It is the responsbility of the Service Provider to create the
|
||||
* record first and set its attributes using setXXX() methods.
|
||||
*
|
||||
* The service provider must then call sdp_record_register() to make
|
||||
* the service record visible to SDP clients. This function returns 0
|
||||
* on success or -1 on failure (and sets errno).
|
||||
*/
|
||||
int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, uint8_t *data, uint32_t size, uint8_t flags, uint32_t *handle);
|
||||
int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags);
|
||||
int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags);
|
||||
|
||||
/*
|
||||
* Unregister a service record.
|
||||
*/
|
||||
int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle);
|
||||
int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec);
|
||||
int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec);
|
||||
|
||||
/*
|
||||
* Update an existing service record. (Calling this function
|
||||
* before a previous call to sdp_record_register() will result
|
||||
* in an error.)
|
||||
*/
|
||||
int sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size);
|
||||
int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec);
|
||||
int sdp_record_update(sdp_session_t *sess, const sdp_record_t *rec);
|
||||
|
||||
void sdp_record_print(const sdp_record_t *rec);
|
||||
|
||||
/*
|
||||
* UUID functions
|
||||
*/
|
||||
uuid_t *sdp_uuid16_create(uuid_t *uuid, uint16_t data);
|
||||
uuid_t *sdp_uuid32_create(uuid_t *uuid, uint32_t data);
|
||||
uuid_t *sdp_uuid128_create(uuid_t *uuid, const void *data);
|
||||
int sdp_uuid16_cmp(const void *p1, const void *p2);
|
||||
int sdp_uuid128_cmp(const void *p1, const void *p2);
|
||||
int sdp_uuid_cmp(const void *p1, const void *p2);
|
||||
uuid_t *sdp_uuid_to_uuid128(const uuid_t *uuid);
|
||||
void sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16);
|
||||
void sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32);
|
||||
int sdp_uuid128_to_uuid(uuid_t *uuid);
|
||||
int sdp_uuid_to_proto(uuid_t *uuid);
|
||||
int sdp_uuid_extract(const uint8_t *buffer, int bufsize, uuid_t *uuid, int *scanned);
|
||||
void sdp_uuid_print(const uuid_t *uuid);
|
||||
|
||||
#define MAX_LEN_UUID_STR 37
|
||||
#define MAX_LEN_PROTOCOL_UUID_STR 8
|
||||
#define MAX_LEN_SERVICECLASS_UUID_STR 28
|
||||
#define MAX_LEN_PROFILEDESCRIPTOR_UUID_STR 28
|
||||
|
||||
int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n);
|
||||
int sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n);
|
||||
int sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n);
|
||||
int sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n);
|
||||
|
||||
/*
|
||||
* In all the sdp_get_XXX(handle, XXX *xxx) functions below,
|
||||
* the XXX * is set to point to the value, should it exist
|
||||
* and 0 is returned. If the value does not exist, -1 is
|
||||
* returned and errno set to ENODATA.
|
||||
*
|
||||
* In all the methods below, the memory management rules are
|
||||
* simple. Don't free anything! The pointer returned, in the
|
||||
* case of constructed types, is a pointer to the contents
|
||||
* of the sdp_record_t.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get the access protocols from the service record
|
||||
*/
|
||||
int sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **protos);
|
||||
|
||||
/*
|
||||
* Get the additional access protocols from the service record
|
||||
*/
|
||||
int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **protos);
|
||||
|
||||
/*
|
||||
* Extract the list of browse groups to which the service belongs.
|
||||
* When set, seqp contains elements of GroupID (uint16_t)
|
||||
*/
|
||||
static inline int sdp_get_browse_groups(const sdp_record_t *rec, sdp_list_t **seqp)
|
||||
{
|
||||
return sdp_get_uuidseq_attr(rec, SDP_ATTR_BROWSE_GRP_LIST, seqp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract language attribute meta-data of the service record.
|
||||
* For each language in the service record, LangSeq has a struct of type
|
||||
* sdp_lang_attr_t.
|
||||
*/
|
||||
int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq);
|
||||
|
||||
/*
|
||||
* Extract the Bluetooth profile descriptor sequence from a record.
|
||||
* Each element in the list is of type sdp_profile_desc_t
|
||||
* which contains the UUID of the profile and its version number
|
||||
* (encoded as major and minor in the high-order 8bits
|
||||
* and low-order 8bits respectively of the uint16_t)
|
||||
*/
|
||||
int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDesc);
|
||||
|
||||
/*
|
||||
* Extract SDP server version numbers
|
||||
*
|
||||
* Note: that this is an attribute of the SDP server only and
|
||||
* contains a list of uint16_t each of which represent the
|
||||
* major and minor SDP version numbers supported by this server
|
||||
*/
|
||||
int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **pVnumList);
|
||||
|
||||
int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid);
|
||||
int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid);
|
||||
int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState);
|
||||
int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail);
|
||||
int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo);
|
||||
int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState);
|
||||
|
||||
static inline int sdp_get_service_name(const sdp_record_t *rec, char *str, int len)
|
||||
{
|
||||
return sdp_get_string_attr(rec, SDP_ATTR_SVCNAME_PRIMARY, str, len);
|
||||
}
|
||||
|
||||
static inline int sdp_get_service_desc(const sdp_record_t *rec, char *str, int len)
|
||||
{
|
||||
return sdp_get_string_attr(rec, SDP_ATTR_SVCDESC_PRIMARY, str, len);
|
||||
}
|
||||
|
||||
static inline int sdp_get_provider_name(const sdp_record_t *rec, char *str, int len)
|
||||
{
|
||||
return sdp_get_string_attr(rec, SDP_ATTR_PROVNAME_PRIMARY, str, len);
|
||||
}
|
||||
|
||||
static inline int sdp_get_doc_url(const sdp_record_t *rec, char *str, int len)
|
||||
{
|
||||
return sdp_get_string_attr(rec, SDP_ATTR_DOC_URL, str, len);
|
||||
}
|
||||
|
||||
static inline int sdp_get_clnt_exec_url(const sdp_record_t *rec, char *str, int len)
|
||||
{
|
||||
return sdp_get_string_attr(rec, SDP_ATTR_CLNT_EXEC_URL, str, len);
|
||||
}
|
||||
|
||||
static inline int sdp_get_icon_url(const sdp_record_t *rec, char *str, int len)
|
||||
{
|
||||
return sdp_get_string_attr(rec, SDP_ATTR_ICON_URL, str, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the supported features
|
||||
* sf should be a list of list with each feature data
|
||||
* Returns 0 on success -1 on fail
|
||||
*/
|
||||
int sdp_set_supp_feat(sdp_record_t *rec, const sdp_list_t *sf);
|
||||
|
||||
/*
|
||||
* Get the supported features
|
||||
* seqp is set to a list of list with each feature data
|
||||
* Returns 0 on success, if an error occurred -1 is returned and errno is set
|
||||
*/
|
||||
int sdp_get_supp_feat(const sdp_record_t *rec, sdp_list_t **seqp);
|
||||
|
||||
sdp_record_t *sdp_extract_pdu(const uint8_t *pdata, int bufsize, int *scanned);
|
||||
sdp_record_t *sdp_copy_record(sdp_record_t *rec);
|
||||
|
||||
void sdp_data_print(sdp_data_t *data);
|
||||
void sdp_print_service_attr(sdp_list_t *alist);
|
||||
|
||||
int sdp_attrid_comp_func(const void *key1, const void *key2);
|
||||
|
||||
void sdp_set_seq_len(uint8_t *ptr, uint32_t length);
|
||||
void sdp_set_attrid(sdp_buf_t *pdu, uint16_t id);
|
||||
void sdp_append_to_pdu(sdp_buf_t *dst, sdp_data_t *d);
|
||||
void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len);
|
||||
|
||||
int sdp_gen_pdu(sdp_buf_t *pdu, sdp_data_t *data);
|
||||
int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *pdu);
|
||||
|
||||
int sdp_extract_seqtype(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size);
|
||||
|
||||
sdp_data_t *sdp_extract_attr(const uint8_t *pdata, int bufsize, int *extractedLength, sdp_record_t *rec);
|
||||
|
||||
void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid);
|
||||
void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq);
|
||||
|
||||
int sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *req, uint8_t *rsp, uint32_t reqsize, uint32_t *rspsize);
|
||||
|
||||
void sdp_add_lang_attr(sdp_record_t *rec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SDP_LIB_H */
|
||||
2928
external/cache/sources/hcitools/lib/hci.c
vendored
Normal file
2928
external/cache/sources/hcitools/lib/hci.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
594
external/cache/sources/hcitools/lib/mgmt.h
vendored
Normal file
594
external/cache/sources/hcitools/lib/mgmt.h
vendored
Normal file
@@ -0,0 +1,594 @@
|
||||
/*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
* Copyright (C) 2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#define MGMT_INDEX_NONE 0xFFFF
|
||||
|
||||
#define MGMT_STATUS_SUCCESS 0x00
|
||||
#define MGMT_STATUS_UNKNOWN_COMMAND 0x01
|
||||
#define MGMT_STATUS_NOT_CONNECTED 0x02
|
||||
#define MGMT_STATUS_FAILED 0x03
|
||||
#define MGMT_STATUS_CONNECT_FAILED 0x04
|
||||
#define MGMT_STATUS_AUTH_FAILED 0x05
|
||||
#define MGMT_STATUS_NOT_PAIRED 0x06
|
||||
#define MGMT_STATUS_NO_RESOURCES 0x07
|
||||
#define MGMT_STATUS_TIMEOUT 0x08
|
||||
#define MGMT_STATUS_ALREADY_CONNECTED 0x09
|
||||
#define MGMT_STATUS_BUSY 0x0a
|
||||
#define MGMT_STATUS_REJECTED 0x0b
|
||||
#define MGMT_STATUS_NOT_SUPPORTED 0x0c
|
||||
#define MGMT_STATUS_INVALID_PARAMS 0x0d
|
||||
#define MGMT_STATUS_DISCONNECTED 0x0e
|
||||
#define MGMT_STATUS_NOT_POWERED 0x0f
|
||||
#define MGMT_STATUS_CANCELLED 0x10
|
||||
#define MGMT_STATUS_INVALID_INDEX 0x11
|
||||
#define MGMT_STATUS_RFKILLED 0x12
|
||||
|
||||
struct mgmt_hdr {
|
||||
uint16_t opcode;
|
||||
uint16_t index;
|
||||
uint16_t len;
|
||||
} __packed;
|
||||
#define MGMT_HDR_SIZE 6
|
||||
|
||||
struct mgmt_addr_info {
|
||||
bdaddr_t bdaddr;
|
||||
uint8_t type;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_READ_VERSION 0x0001
|
||||
struct mgmt_rp_read_version {
|
||||
uint8_t version;
|
||||
uint16_t revision;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_READ_COMMANDS 0x0002
|
||||
struct mgmt_rp_read_commands {
|
||||
uint16_t num_commands;
|
||||
uint16_t num_events;
|
||||
uint16_t opcodes[0];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_READ_INDEX_LIST 0x0003
|
||||
struct mgmt_rp_read_index_list {
|
||||
uint16_t num_controllers;
|
||||
uint16_t index[0];
|
||||
} __packed;
|
||||
|
||||
/* Reserve one extra byte for names in management messages so that they
|
||||
* are always guaranteed to be nul-terminated */
|
||||
#define MGMT_MAX_NAME_LENGTH (248 + 1)
|
||||
#define MGMT_MAX_SHORT_NAME_LENGTH (10 + 1)
|
||||
|
||||
#define MGMT_SETTING_POWERED 0x00000001
|
||||
#define MGMT_SETTING_CONNECTABLE 0x00000002
|
||||
#define MGMT_SETTING_FAST_CONNECTABLE 0x00000004
|
||||
#define MGMT_SETTING_DISCOVERABLE 0x00000008
|
||||
#define MGMT_SETTING_PAIRABLE 0x00000010
|
||||
#define MGMT_SETTING_LINK_SECURITY 0x00000020
|
||||
#define MGMT_SETTING_SSP 0x00000040
|
||||
#define MGMT_SETTING_BREDR 0x00000080
|
||||
#define MGMT_SETTING_HS 0x00000100
|
||||
#define MGMT_SETTING_LE 0x00000200
|
||||
#define MGMT_SETTING_ADVERTISING 0x00000400
|
||||
|
||||
#define MGMT_OP_READ_INFO 0x0004
|
||||
struct mgmt_rp_read_info {
|
||||
bdaddr_t bdaddr;
|
||||
uint8_t version;
|
||||
uint16_t manufacturer;
|
||||
uint32_t supported_settings;
|
||||
uint32_t current_settings;
|
||||
uint8_t dev_class[3];
|
||||
uint8_t name[MGMT_MAX_NAME_LENGTH];
|
||||
uint8_t short_name[MGMT_MAX_SHORT_NAME_LENGTH];
|
||||
} __packed;
|
||||
|
||||
struct mgmt_mode {
|
||||
uint8_t val;
|
||||
} __packed;
|
||||
|
||||
struct mgmt_cod {
|
||||
uint8_t val[3];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_SET_POWERED 0x0005
|
||||
|
||||
#define MGMT_OP_SET_DISCOVERABLE 0x0006
|
||||
struct mgmt_cp_set_discoverable {
|
||||
uint8_t val;
|
||||
uint16_t timeout;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_SET_CONNECTABLE 0x0007
|
||||
|
||||
#define MGMT_OP_SET_FAST_CONNECTABLE 0x0008
|
||||
|
||||
#define MGMT_OP_SET_PAIRABLE 0x0009
|
||||
|
||||
#define MGMT_OP_SET_LINK_SECURITY 0x000A
|
||||
|
||||
#define MGMT_OP_SET_SSP 0x000B
|
||||
|
||||
#define MGMT_OP_SET_HS 0x000C
|
||||
|
||||
#define MGMT_OP_SET_LE 0x000D
|
||||
|
||||
#define MGMT_OP_SET_DEV_CLASS 0x000E
|
||||
struct mgmt_cp_set_dev_class {
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_SET_LOCAL_NAME 0x000F
|
||||
struct mgmt_cp_set_local_name {
|
||||
uint8_t name[MGMT_MAX_NAME_LENGTH];
|
||||
uint8_t short_name[MGMT_MAX_SHORT_NAME_LENGTH];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_ADD_UUID 0x0010
|
||||
struct mgmt_cp_add_uuid {
|
||||
uint8_t uuid[16];
|
||||
uint8_t svc_hint;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_REMOVE_UUID 0x0011
|
||||
struct mgmt_cp_remove_uuid {
|
||||
uint8_t uuid[16];
|
||||
} __packed;
|
||||
|
||||
struct mgmt_link_key_info {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t type;
|
||||
uint8_t val[16];
|
||||
uint8_t pin_len;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_LOAD_LINK_KEYS 0x0012
|
||||
struct mgmt_cp_load_link_keys {
|
||||
uint8_t debug_keys;
|
||||
uint16_t key_count;
|
||||
struct mgmt_link_key_info keys[0];
|
||||
} __packed;
|
||||
|
||||
struct mgmt_ltk_info {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t authenticated;
|
||||
uint8_t master;
|
||||
uint8_t enc_size;
|
||||
uint16_t ediv;
|
||||
uint8_t rand[8];
|
||||
uint8_t val[16];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_LOAD_LONG_TERM_KEYS 0x0013
|
||||
struct mgmt_cp_load_long_term_keys {
|
||||
uint16_t key_count;
|
||||
struct mgmt_ltk_info keys[0];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_DISCONNECT 0x0014
|
||||
struct mgmt_cp_disconnect {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
struct mgmt_rp_disconnect {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_GET_CONNECTIONS 0x0015
|
||||
struct mgmt_rp_get_connections {
|
||||
uint16_t conn_count;
|
||||
struct mgmt_addr_info addr[0];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_PIN_CODE_REPLY 0x0016
|
||||
struct mgmt_cp_pin_code_reply {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t pin_len;
|
||||
uint8_t pin_code[16];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_PIN_CODE_NEG_REPLY 0x0017
|
||||
struct mgmt_cp_pin_code_neg_reply {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_SET_IO_CAPABILITY 0x0018
|
||||
struct mgmt_cp_set_io_capability {
|
||||
uint8_t io_capability;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_PAIR_DEVICE 0x0019
|
||||
struct mgmt_cp_pair_device {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t io_cap;
|
||||
} __packed;
|
||||
struct mgmt_rp_pair_device {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_CANCEL_PAIR_DEVICE 0x001A
|
||||
|
||||
#define MGMT_OP_UNPAIR_DEVICE 0x001B
|
||||
struct mgmt_cp_unpair_device {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t disconnect;
|
||||
} __packed;
|
||||
struct mgmt_rp_unpair_device {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_USER_CONFIRM_REPLY 0x001C
|
||||
struct mgmt_cp_user_confirm_reply {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
struct mgmt_rp_user_confirm_reply {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x001D
|
||||
|
||||
#define MGMT_OP_USER_PASSKEY_REPLY 0x001E
|
||||
struct mgmt_cp_user_passkey_reply {
|
||||
struct mgmt_addr_info addr;
|
||||
uint32_t passkey;
|
||||
} __packed;
|
||||
struct mgmt_rp_user_passkey_reply {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_USER_PASSKEY_NEG_REPLY 0x001F
|
||||
struct mgmt_cp_user_passkey_neg_reply {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0020
|
||||
struct mgmt_rp_read_local_oob_data {
|
||||
uint8_t hash[16];
|
||||
uint8_t randomizer[16];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0021
|
||||
struct mgmt_cp_add_remote_oob_data {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t hash[16];
|
||||
uint8_t randomizer[16];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x0022
|
||||
struct mgmt_cp_remove_remote_oob_data {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_START_DISCOVERY 0x0023
|
||||
struct mgmt_cp_start_discovery {
|
||||
uint8_t type;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_STOP_DISCOVERY 0x0024
|
||||
struct mgmt_cp_stop_discovery {
|
||||
uint8_t type;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_CONFIRM_NAME 0x0025
|
||||
struct mgmt_cp_confirm_name {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t name_known;
|
||||
} __packed;
|
||||
struct mgmt_rp_confirm_name {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_BLOCK_DEVICE 0x0026
|
||||
struct mgmt_cp_block_device {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_UNBLOCK_DEVICE 0x0027
|
||||
struct mgmt_cp_unblock_device {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_SET_DEVICE_ID 0x0028
|
||||
struct mgmt_cp_set_device_id {
|
||||
uint16_t source;
|
||||
uint16_t vendor;
|
||||
uint16_t product;
|
||||
uint16_t version;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_SET_ADVERTISING 0x0029
|
||||
|
||||
#define MGMT_OP_SET_BREDR 0x002A
|
||||
|
||||
#define MGMT_OP_SET_STATIC_ADDRESS 0x002B
|
||||
struct mgmt_cp_set_static_address {
|
||||
bdaddr_t bdaddr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_SET_SCAN_PARAMS 0x002C
|
||||
struct mgmt_cp_set_scan_params {
|
||||
uint16_t interval;
|
||||
uint16_t window;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_CMD_COMPLETE 0x0001
|
||||
struct mgmt_ev_cmd_complete {
|
||||
uint16_t opcode;
|
||||
uint8_t status;
|
||||
uint8_t data[0];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_CMD_STATUS 0x0002
|
||||
struct mgmt_ev_cmd_status {
|
||||
uint16_t opcode;
|
||||
uint8_t status;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_CONTROLLER_ERROR 0x0003
|
||||
struct mgmt_ev_controller_error {
|
||||
uint8_t error_code;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_INDEX_ADDED 0x0004
|
||||
|
||||
#define MGMT_EV_INDEX_REMOVED 0x0005
|
||||
|
||||
#define MGMT_EV_NEW_SETTINGS 0x0006
|
||||
|
||||
#define MGMT_EV_CLASS_OF_DEV_CHANGED 0x0007
|
||||
struct mgmt_ev_class_of_dev_changed {
|
||||
uint8_t class_of_dev[3];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_LOCAL_NAME_CHANGED 0x0008
|
||||
struct mgmt_ev_local_name_changed {
|
||||
uint8_t name[MGMT_MAX_NAME_LENGTH];
|
||||
uint8_t short_name[MGMT_MAX_SHORT_NAME_LENGTH];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_NEW_LINK_KEY 0x0009
|
||||
struct mgmt_ev_new_link_key {
|
||||
uint8_t store_hint;
|
||||
struct mgmt_link_key_info key;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_NEW_LONG_TERM_KEY 0x000A
|
||||
struct mgmt_ev_new_long_term_key {
|
||||
uint8_t store_hint;
|
||||
struct mgmt_ltk_info key;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_DEVICE_CONNECTED 0x000B
|
||||
struct mgmt_ev_device_connected {
|
||||
struct mgmt_addr_info addr;
|
||||
uint32_t flags;
|
||||
uint16_t eir_len;
|
||||
uint8_t eir[0];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_DEV_DISCONN_UNKNOWN 0x00
|
||||
#define MGMT_DEV_DISCONN_TIMEOUT 0x01
|
||||
#define MGMT_DEV_DISCONN_LOCAL_HOST 0x02
|
||||
#define MGMT_DEV_DISCONN_REMOTE 0x03
|
||||
|
||||
#define MGMT_EV_DEVICE_DISCONNECTED 0x000C
|
||||
struct mgmt_ev_device_disconnected {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t reason;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_CONNECT_FAILED 0x000D
|
||||
struct mgmt_ev_connect_failed {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t status;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_PIN_CODE_REQUEST 0x000E
|
||||
struct mgmt_ev_pin_code_request {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t secure;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
|
||||
struct mgmt_ev_user_confirm_request {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t confirm_hint;
|
||||
uint32_t value;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_USER_PASSKEY_REQUEST 0x0010
|
||||
struct mgmt_ev_user_passkey_request {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_AUTH_FAILED 0x0011
|
||||
struct mgmt_ev_auth_failed {
|
||||
struct mgmt_addr_info addr;
|
||||
uint8_t status;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_DEV_FOUND_CONFIRM_NAME 0x01
|
||||
#define MGMT_DEV_FOUND_LEGACY_PAIRING 0x02
|
||||
|
||||
#define MGMT_EV_DEVICE_FOUND 0x0012
|
||||
struct mgmt_ev_device_found {
|
||||
struct mgmt_addr_info addr;
|
||||
int8_t rssi;
|
||||
uint32_t flags;
|
||||
uint16_t eir_len;
|
||||
uint8_t eir[0];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_DISCOVERING 0x0013
|
||||
struct mgmt_ev_discovering {
|
||||
uint8_t type;
|
||||
uint8_t discovering;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_DEVICE_BLOCKED 0x0014
|
||||
struct mgmt_ev_device_blocked {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_DEVICE_UNBLOCKED 0x0015
|
||||
struct mgmt_ev_device_unblocked {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_DEVICE_UNPAIRED 0x0016
|
||||
struct mgmt_ev_device_unpaired {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_PASSKEY_NOTIFY 0x0017
|
||||
struct mgmt_ev_passkey_notify {
|
||||
struct mgmt_addr_info addr;
|
||||
uint32_t passkey;
|
||||
uint8_t entered;
|
||||
} __packed;
|
||||
|
||||
static const char *mgmt_op[] = {
|
||||
"<0x0000>",
|
||||
"Read Version",
|
||||
"Read Commands",
|
||||
"Read Index List",
|
||||
"Read Controller Info",
|
||||
"Set Powered",
|
||||
"Set Discoverable",
|
||||
"Set Connectable",
|
||||
"Set Fast Connectable", /* 0x0008 */
|
||||
"Set Pairable",
|
||||
"Set Link Security",
|
||||
"Set Secure Simple Pairing",
|
||||
"Set High Speed",
|
||||
"Set Low Energy",
|
||||
"Set Dev Class",
|
||||
"Set Local Name",
|
||||
"Add UUID", /* 0x0010 */
|
||||
"Remove UUID",
|
||||
"Load Link Keys",
|
||||
"Load Long Term Keys",
|
||||
"Disconnect",
|
||||
"Get Connections",
|
||||
"PIN Code Reply",
|
||||
"PIN Code Neg Reply",
|
||||
"Set IO Capability", /* 0x0018 */
|
||||
"Pair Device",
|
||||
"Cancel Pair Device",
|
||||
"Unpair Device",
|
||||
"User Confirm Reply",
|
||||
"User Confirm Neg Reply",
|
||||
"User Passkey Reply",
|
||||
"User Passkey Neg Reply",
|
||||
"Read Local OOB Data", /* 0x0020 */
|
||||
"Add Remote OOB Data",
|
||||
"Remove Remove OOB Data",
|
||||
"Start Discovery",
|
||||
"Stop Discovery",
|
||||
"Confirm Name",
|
||||
"Block Device",
|
||||
"Unblock Device",
|
||||
"Set Device ID",
|
||||
"Set Advertising",
|
||||
"Set BR/EDR",
|
||||
"Set Static Address",
|
||||
"Set Scan Parameters",
|
||||
};
|
||||
|
||||
static const char *mgmt_ev[] = {
|
||||
"<0x0000>",
|
||||
"Command Complete",
|
||||
"Command Status",
|
||||
"Controller Error",
|
||||
"Index Added",
|
||||
"Index Removed",
|
||||
"New Settings",
|
||||
"Class of Device Changed",
|
||||
"Local Name Changed", /* 0x0008 */
|
||||
"New Link Key",
|
||||
"New Long Term Key",
|
||||
"Device Connected",
|
||||
"Device Disconnected",
|
||||
"Connect Failed",
|
||||
"PIN Code Request",
|
||||
"User Confirm Request",
|
||||
"User Passkey Request", /* 0x0010 */
|
||||
"Authentication Failed",
|
||||
"Device Found",
|
||||
"Discovering",
|
||||
"Device Blocked",
|
||||
"Device Unblocked",
|
||||
"Device Unpaired",
|
||||
"Passkey Notify",
|
||||
};
|
||||
|
||||
static const char *mgmt_status[] = {
|
||||
"Success",
|
||||
"Unknown Command",
|
||||
"Not Connected",
|
||||
"Failed",
|
||||
"Connect Failed",
|
||||
"Authentication Failed",
|
||||
"Not Paired",
|
||||
"No Resources",
|
||||
"Timeout",
|
||||
"Already Connected",
|
||||
"Busy",
|
||||
"Rejected",
|
||||
"Not Supported",
|
||||
"Invalid Parameters",
|
||||
"Disconnected",
|
||||
"Not Powered",
|
||||
"Cancelled",
|
||||
"Invalid Index",
|
||||
"Blocked through rfkill",
|
||||
};
|
||||
|
||||
#ifndef NELEM
|
||||
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
static inline const char *mgmt_opstr(uint16_t op)
|
||||
{
|
||||
if (op >= NELEM(mgmt_op))
|
||||
return "<unknown opcode>";
|
||||
return mgmt_op[op];
|
||||
}
|
||||
|
||||
static inline const char *mgmt_evstr(uint16_t ev)
|
||||
{
|
||||
if (ev >= NELEM(mgmt_ev))
|
||||
return "<unknown event>";
|
||||
return mgmt_ev[ev];
|
||||
}
|
||||
|
||||
static inline const char *mgmt_errstr(uint8_t status)
|
||||
{
|
||||
if (status >= NELEM(mgmt_status))
|
||||
return "<unknown status>";
|
||||
return mgmt_status[status];
|
||||
}
|
||||
4919
external/cache/sources/hcitools/lib/sdp.c
vendored
Normal file
4919
external/cache/sources/hcitools/lib/sdp.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
278
external/cache/sources/hcitools/lib/uuid.c
vendored
Normal file
278
external/cache/sources/hcitools/lib/uuid.c
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011 Nokia Corporation
|
||||
* Copyright (C) 2011 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "uuid.h"
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
static uint128_t bluetooth_base_uuid = {
|
||||
.data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
|
||||
};
|
||||
|
||||
#define BASE_UUID16_OFFSET 2
|
||||
#define BASE_UUID32_OFFSET 0
|
||||
|
||||
#else
|
||||
static uint128_t bluetooth_base_uuid = {
|
||||
.data = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
|
||||
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
};
|
||||
|
||||
#define BASE_UUID16_OFFSET 12
|
||||
#define BASE_UUID32_OFFSET BASE_UUID16_OFFSET
|
||||
|
||||
#endif
|
||||
|
||||
static void bt_uuid16_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst)
|
||||
{
|
||||
dst->value.u128 = bluetooth_base_uuid;
|
||||
dst->type = BT_UUID128;
|
||||
|
||||
memcpy(&dst->value.u128.data[BASE_UUID16_OFFSET],
|
||||
&src->value.u16, sizeof(src->value.u16));
|
||||
}
|
||||
|
||||
static void bt_uuid32_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst)
|
||||
{
|
||||
dst->value.u128 = bluetooth_base_uuid;
|
||||
dst->type = BT_UUID128;
|
||||
|
||||
memcpy(&dst->value.u128.data[BASE_UUID32_OFFSET],
|
||||
&src->value.u32, sizeof(src->value.u32));
|
||||
}
|
||||
|
||||
void bt_uuid_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst)
|
||||
{
|
||||
switch (src->type) {
|
||||
case BT_UUID128:
|
||||
*dst = *src;
|
||||
break;
|
||||
case BT_UUID32:
|
||||
bt_uuid32_to_uuid128(src, dst);
|
||||
break;
|
||||
case BT_UUID16:
|
||||
bt_uuid16_to_uuid128(src, dst);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int bt_uuid128_cmp(const bt_uuid_t *u1, const bt_uuid_t *u2)
|
||||
{
|
||||
return memcmp(&u1->value.u128, &u2->value.u128, sizeof(uint128_t));
|
||||
}
|
||||
|
||||
int bt_uuid16_create(bt_uuid_t *btuuid, uint16_t value)
|
||||
{
|
||||
memset(btuuid, 0, sizeof(bt_uuid_t));
|
||||
btuuid->type = BT_UUID16;
|
||||
btuuid->value.u16 = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value)
|
||||
{
|
||||
memset(btuuid, 0, sizeof(bt_uuid_t));
|
||||
btuuid->type = BT_UUID32;
|
||||
btuuid->value.u32 = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value)
|
||||
{
|
||||
memset(btuuid, 0, sizeof(bt_uuid_t));
|
||||
btuuid->type = BT_UUID128;
|
||||
btuuid->value.u128 = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2)
|
||||
{
|
||||
bt_uuid_t u1, u2;
|
||||
|
||||
bt_uuid_to_uuid128(uuid1, &u1);
|
||||
bt_uuid_to_uuid128(uuid2, &u2);
|
||||
|
||||
return bt_uuid128_cmp(&u1, &u2);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert the UUID to string, copying a maximum of n characters.
|
||||
*/
|
||||
int bt_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n)
|
||||
{
|
||||
if (!uuid) {
|
||||
snprintf(str, n, "NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (uuid->type) {
|
||||
case BT_UUID16:
|
||||
snprintf(str, n, "%.4x", uuid->value.u16);
|
||||
break;
|
||||
case BT_UUID32:
|
||||
snprintf(str, n, "%.8x", uuid->value.u32);
|
||||
break;
|
||||
case BT_UUID128: {
|
||||
unsigned int data0;
|
||||
unsigned short data1;
|
||||
unsigned short data2;
|
||||
unsigned short data3;
|
||||
unsigned int data4;
|
||||
unsigned short data5;
|
||||
|
||||
uint128_t nvalue;
|
||||
const uint8_t *data = (uint8_t *) &nvalue;
|
||||
|
||||
hton128(&uuid->value.u128, &nvalue);
|
||||
|
||||
memcpy(&data0, &data[0], 4);
|
||||
memcpy(&data1, &data[4], 2);
|
||||
memcpy(&data2, &data[6], 2);
|
||||
memcpy(&data3, &data[8], 2);
|
||||
memcpy(&data4, &data[10], 4);
|
||||
memcpy(&data5, &data[14], 2);
|
||||
|
||||
snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
|
||||
ntohl(data0), ntohs(data1),
|
||||
ntohs(data2), ntohs(data3),
|
||||
ntohl(data4), ntohs(data5));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
|
||||
return -EINVAL; /* Enum type of UUID not set */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_uuid128(const char *string)
|
||||
{
|
||||
return (strlen(string) == 36 &&
|
||||
string[8] == '-' &&
|
||||
string[13] == '-' &&
|
||||
string[18] == '-' &&
|
||||
string[23] == '-');
|
||||
}
|
||||
|
||||
static inline int is_uuid32(const char *string)
|
||||
{
|
||||
return (strlen(string) == 8 || strlen(string) == 10);
|
||||
}
|
||||
|
||||
static inline int is_uuid16(const char *string)
|
||||
{
|
||||
return (strlen(string) == 4 || strlen(string) == 6);
|
||||
}
|
||||
|
||||
static int bt_string_to_uuid16(bt_uuid_t *uuid, const char *string)
|
||||
{
|
||||
uint16_t u16;
|
||||
char *endptr = NULL;
|
||||
|
||||
u16 = strtol(string, &endptr, 16);
|
||||
if (endptr && *endptr == '\0') {
|
||||
bt_uuid16_create(uuid, u16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int bt_string_to_uuid32(bt_uuid_t *uuid, const char *string)
|
||||
{
|
||||
uint32_t u32;
|
||||
char *endptr = NULL;
|
||||
|
||||
u32 = strtol(string, &endptr, 16);
|
||||
if (endptr && *endptr == '\0') {
|
||||
bt_uuid32_create(uuid, u32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int bt_string_to_uuid128(bt_uuid_t *uuid, const char *string)
|
||||
{
|
||||
uint32_t data0, data4;
|
||||
uint16_t data1, data2, data3, data5;
|
||||
uint128_t n128, u128;
|
||||
uint8_t *val = (uint8_t *) &n128;
|
||||
|
||||
if (sscanf(string, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
|
||||
&data0, &data1, &data2,
|
||||
&data3, &data4, &data5) != 6)
|
||||
return -EINVAL;
|
||||
|
||||
data0 = htonl(data0);
|
||||
data1 = htons(data1);
|
||||
data2 = htons(data2);
|
||||
data3 = htons(data3);
|
||||
data4 = htonl(data4);
|
||||
data5 = htons(data5);
|
||||
|
||||
memcpy(&val[0], &data0, 4);
|
||||
memcpy(&val[4], &data1, 2);
|
||||
memcpy(&val[6], &data2, 2);
|
||||
memcpy(&val[8], &data3, 2);
|
||||
memcpy(&val[10], &data4, 4);
|
||||
memcpy(&val[14], &data5, 2);
|
||||
|
||||
ntoh128(&n128, &u128);
|
||||
|
||||
bt_uuid128_create(uuid, u128);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_string_to_uuid(bt_uuid_t *uuid, const char *string)
|
||||
{
|
||||
if (is_uuid128(string))
|
||||
return bt_string_to_uuid128(uuid, string);
|
||||
else if (is_uuid32(string))
|
||||
return bt_string_to_uuid32(uuid, string);
|
||||
else if (is_uuid16(string))
|
||||
return bt_string_to_uuid16(uuid, string);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int bt_uuid_strcmp(const void *a, const void *b)
|
||||
{
|
||||
return strcasecmp(a, b);
|
||||
}
|
||||
140
external/cache/sources/hcitools/lib/uuid.h
vendored
Normal file
140
external/cache/sources/hcitools/lib/uuid.h
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011 Nokia Corporation
|
||||
* Copyright (C) 2011 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __BLUETOOTH_UUID_H
|
||||
#define __BLUETOOTH_UUID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
#define GENERIC_AUDIO_UUID "00001203-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define HSP_HS_UUID "00001108-0000-1000-8000-00805f9b34fb"
|
||||
#define HSP_AG_UUID "00001112-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define HFP_HS_UUID "0000111e-0000-1000-8000-00805f9b34fb"
|
||||
#define HFP_AG_UUID "0000111f-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define ADVANCED_AUDIO_UUID "0000110d-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define A2DP_SOURCE_UUID "0000110a-0000-1000-8000-00805f9b34fb"
|
||||
#define A2DP_SINK_UUID "0000110b-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define AVRCP_REMOTE_UUID "0000110e-0000-1000-8000-00805f9b34fb"
|
||||
#define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define PANU_UUID "00001115-0000-1000-8000-00805f9b34fb"
|
||||
#define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb"
|
||||
#define GN_UUID "00001117-0000-1000-8000-00805f9b34fb"
|
||||
#define BNEP_SVC_UUID "0000000f-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define PNPID_UUID "00002a50-0000-1000-8000-00805f9b34fb"
|
||||
#define DEVICE_INFORMATION_UUID "0000180a-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define GATT_UUID "00001801-0000-1000-8000-00805f9b34fb"
|
||||
#define IMMEDIATE_ALERT_UUID "00001802-0000-1000-8000-00805f9b34fb"
|
||||
#define LINK_LOSS_UUID "00001803-0000-1000-8000-00805f9b34fb"
|
||||
#define TX_POWER_UUID "00001804-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define SAP_UUID "0000112D-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define HEART_RATE_UUID "0000180d-0000-1000-8000-00805f9b34fb"
|
||||
#define HEART_RATE_MEASUREMENT_UUID "00002a37-0000-1000-8000-00805f9b34fb"
|
||||
#define BODY_SENSOR_LOCATION_UUID "00002a38-0000-1000-8000-00805f9b34fb"
|
||||
#define HEART_RATE_CONTROL_POINT_UUID "00002a39-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define HEALTH_THERMOMETER_UUID "00001809-0000-1000-8000-00805f9b34fb"
|
||||
#define TEMPERATURE_MEASUREMENT_UUID "00002a1c-0000-1000-8000-00805f9b34fb"
|
||||
#define TEMPERATURE_TYPE_UUID "00002a1d-0000-1000-8000-00805f9b34fb"
|
||||
#define INTERMEDIATE_TEMPERATURE_UUID "00002a1e-0000-1000-8000-00805f9b34fb"
|
||||
#define MEASUREMENT_INTERVAL_UUID "00002a21-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define CYCLING_SC_UUID "00001816-0000-1000-8000-00805f9b34fb"
|
||||
#define CSC_MEASUREMENT_UUID "00002a5b-0000-1000-8000-00805f9b34fb"
|
||||
#define CSC_FEATURE_UUID "00002a5c-0000-1000-8000-00805f9b34fb"
|
||||
#define SENSOR_LOCATION_UUID "00002a5d-0000-1000-8000-00805f9b34fb"
|
||||
#define SC_CONTROL_POINT_UUID "00002a55-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define RFCOMM_UUID_STR "00000003-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define HDP_UUID "00001400-0000-1000-8000-00805f9b34fb"
|
||||
#define HDP_SOURCE_UUID "00001401-0000-1000-8000-00805f9b34fb"
|
||||
#define HDP_SINK_UUID "00001402-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define DUN_GW_UUID "00001103-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define GAP_UUID "00001800-0000-1000-8000-00805f9b34fb"
|
||||
#define PNP_UUID "00001200-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define SPP_UUID "00001101-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
#define OBEX_SYNC_UUID "00001104-0000-1000-8000-00805f9b34fb"
|
||||
#define OBEX_OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
|
||||
#define OBEX_FTP_UUID "00001106-0000-1000-8000-00805f9b34fb"
|
||||
#define OBEX_PCE_UUID "0000112e-0000-1000-8000-00805f9b34fb"
|
||||
#define OBEX_PSE_UUID "0000112f-0000-1000-8000-00805f9b34fb"
|
||||
#define OBEX_PBAP_UUID "00001130-0000-1000-8000-00805f9b34fb"
|
||||
#define OBEX_MAS_UUID "00001132-0000-1000-8000-00805f9b34fb"
|
||||
#define OBEX_MNS_UUID "00001133-0000-1000-8000-00805f9b34fb"
|
||||
#define OBEX_MAP_UUID "00001134-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
BT_UUID_UNSPEC = 0,
|
||||
BT_UUID16 = 16,
|
||||
BT_UUID32 = 32,
|
||||
BT_UUID128 = 128,
|
||||
} type;
|
||||
union {
|
||||
uint16_t u16;
|
||||
uint32_t u32;
|
||||
uint128_t u128;
|
||||
} value;
|
||||
} bt_uuid_t;
|
||||
|
||||
int bt_uuid_strcmp(const void *a, const void *b);
|
||||
|
||||
int bt_uuid16_create(bt_uuid_t *btuuid, uint16_t value);
|
||||
int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value);
|
||||
int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value);
|
||||
|
||||
int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2);
|
||||
void bt_uuid_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst);
|
||||
|
||||
#define MAX_LEN_UUID_STR 37
|
||||
|
||||
int bt_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n);
|
||||
int bt_string_to_uuid(bt_uuid_t *uuid, const char *string);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BLUETOOTH_UUID_H */
|
||||
2149
external/cache/sources/hcitools/monitor/bt.h
vendored
Normal file
2149
external/cache/sources/hcitools/monitor/bt.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
423
external/cache/sources/hcitools/monitor/btsnoop.c
vendored
Normal file
423
external/cache/sources/hcitools/monitor/btsnoop.c
vendored
Normal file
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
|
||||
#include "btsnoop.h"
|
||||
|
||||
struct btsnoop_hdr {
|
||||
uint8_t id[8]; /* Identification Pattern */
|
||||
uint32_t version; /* Version Number = 1 */
|
||||
uint32_t type; /* Datalink Type */
|
||||
} __attribute__ ((packed));
|
||||
#define BTSNOOP_HDR_SIZE (sizeof(struct btsnoop_hdr))
|
||||
|
||||
struct btsnoop_pkt {
|
||||
uint32_t size; /* Original Length */
|
||||
uint32_t len; /* Included Length */
|
||||
uint32_t flags; /* Packet Flags */
|
||||
uint32_t drops; /* Cumulative Drops */
|
||||
uint64_t ts; /* Timestamp microseconds */
|
||||
uint8_t data[0]; /* Packet Data */
|
||||
} __attribute__ ((packed));
|
||||
#define BTSNOOP_PKT_SIZE (sizeof(struct btsnoop_pkt))
|
||||
|
||||
static const uint8_t btsnoop_id[] = { 0x62, 0x74, 0x73, 0x6e,
|
||||
0x6f, 0x6f, 0x70, 0x00 };
|
||||
|
||||
static const uint32_t btsnoop_version = 1;
|
||||
static uint32_t btsnoop_type = 0;
|
||||
|
||||
static int btsnoop_fd = -1;
|
||||
static uint16_t btsnoop_index = 0xffff;
|
||||
|
||||
void btsnoop_create(const char *path, uint32_t type)
|
||||
{
|
||||
struct btsnoop_hdr hdr;
|
||||
ssize_t written;
|
||||
|
||||
if (btsnoop_fd >= 0)
|
||||
return;
|
||||
|
||||
btsnoop_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (btsnoop_fd < 0)
|
||||
return;
|
||||
|
||||
btsnoop_type = type;
|
||||
|
||||
memcpy(hdr.id, btsnoop_id, sizeof(btsnoop_id));
|
||||
hdr.version = htonl(btsnoop_version);
|
||||
hdr.type = htonl(btsnoop_type);
|
||||
|
||||
written = write(btsnoop_fd, &hdr, BTSNOOP_HDR_SIZE);
|
||||
if (written < 0) {
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void btsnoop_write(struct timeval *tv, uint32_t flags,
|
||||
const void *data, uint16_t size)
|
||||
{
|
||||
struct btsnoop_pkt pkt;
|
||||
uint64_t ts;
|
||||
ssize_t written;
|
||||
|
||||
ts = (tv->tv_sec - 946684800ll) * 1000000ll + tv->tv_usec;
|
||||
|
||||
pkt.size = htonl(size);
|
||||
pkt.len = htonl(size);
|
||||
pkt.flags = htonl(flags);
|
||||
pkt.drops = htonl(0);
|
||||
pkt.ts = hton64(ts + 0x00E03AB44A676000ll);
|
||||
|
||||
written = write(btsnoop_fd, &pkt, BTSNOOP_PKT_SIZE);
|
||||
if (written < 0)
|
||||
return;
|
||||
|
||||
if (data && size > 0) {
|
||||
written = write(btsnoop_fd, data, size);
|
||||
if (written < 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_flags_from_opcode(uint16_t opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case BTSNOOP_OPCODE_NEW_INDEX:
|
||||
case BTSNOOP_OPCODE_DEL_INDEX:
|
||||
break;
|
||||
case BTSNOOP_OPCODE_COMMAND_PKT:
|
||||
return 0x02;
|
||||
case BTSNOOP_OPCODE_EVENT_PKT:
|
||||
return 0x03;
|
||||
case BTSNOOP_OPCODE_ACL_TX_PKT:
|
||||
return 0x00;
|
||||
case BTSNOOP_OPCODE_ACL_RX_PKT:
|
||||
return 0x01;
|
||||
case BTSNOOP_OPCODE_SCO_TX_PKT:
|
||||
case BTSNOOP_OPCODE_SCO_RX_PKT:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void btsnoop_write_hci(struct timeval *tv, uint16_t index, uint16_t opcode,
|
||||
const void *data, uint16_t size)
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
if (!tv)
|
||||
return;
|
||||
|
||||
if (btsnoop_fd < 0)
|
||||
return;
|
||||
|
||||
switch (btsnoop_type) {
|
||||
case BTSNOOP_TYPE_HCI:
|
||||
if (btsnoop_index == 0xffff)
|
||||
btsnoop_index = index;
|
||||
|
||||
if (index != btsnoop_index)
|
||||
return;
|
||||
|
||||
flags = get_flags_from_opcode(opcode);
|
||||
if (flags == 0xff)
|
||||
return;
|
||||
break;
|
||||
|
||||
case BTSNOOP_TYPE_EXTENDED_HCI:
|
||||
flags = (index << 16) | opcode;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
btsnoop_write(tv, flags, data, size);
|
||||
}
|
||||
|
||||
void btsnoop_write_phy(struct timeval *tv, uint16_t frequency,
|
||||
const void *data, uint16_t size)
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
if (!tv)
|
||||
return;
|
||||
|
||||
if (btsnoop_fd < 0)
|
||||
return;
|
||||
|
||||
switch (btsnoop_type) {
|
||||
case BTSNOOP_TYPE_EXTENDED_PHY:
|
||||
flags = (1 << 16) | frequency;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
btsnoop_write(tv, flags, data, size);
|
||||
}
|
||||
|
||||
int btsnoop_open(const char *path, uint32_t *type)
|
||||
{
|
||||
struct btsnoop_hdr hdr;
|
||||
ssize_t len;
|
||||
|
||||
if (btsnoop_fd >= 0) {
|
||||
fprintf(stderr, "Too many open files\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
btsnoop_fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (btsnoop_fd < 0) {
|
||||
perror("Failed to open file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = read(btsnoop_fd, &hdr, BTSNOOP_HDR_SIZE);
|
||||
if (len < 0 || len != BTSNOOP_HDR_SIZE) {
|
||||
perror("Failed to read header");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(hdr.id, btsnoop_id, sizeof(btsnoop_id))) {
|
||||
fprintf(stderr, "Invalid btsnoop header\n");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ntohl(hdr.version) != btsnoop_version) {
|
||||
fprintf(stderr, "Invalid btsnoop version\n");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
btsnoop_type = ntohl(hdr.type);
|
||||
|
||||
if (type)
|
||||
*type = btsnoop_type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t get_opcode_from_flags(uint8_t type, uint32_t flags)
|
||||
{
|
||||
switch (type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
return BTSNOOP_OPCODE_COMMAND_PKT;
|
||||
case HCI_ACLDATA_PKT:
|
||||
if (flags & 0x01)
|
||||
return BTSNOOP_OPCODE_ACL_RX_PKT;
|
||||
else
|
||||
return BTSNOOP_OPCODE_ACL_TX_PKT;
|
||||
case HCI_SCODATA_PKT:
|
||||
if (flags & 0x01)
|
||||
return BTSNOOP_OPCODE_SCO_RX_PKT;
|
||||
else
|
||||
return BTSNOOP_OPCODE_SCO_TX_PKT;
|
||||
case HCI_EVENT_PKT:
|
||||
return BTSNOOP_OPCODE_EVENT_PKT;
|
||||
case 0xff:
|
||||
if (flags & 0x02) {
|
||||
if (flags & 0x01)
|
||||
return BTSNOOP_OPCODE_EVENT_PKT;
|
||||
else
|
||||
return BTSNOOP_OPCODE_COMMAND_PKT;
|
||||
} else {
|
||||
if (flags & 0x01)
|
||||
return BTSNOOP_OPCODE_ACL_RX_PKT;
|
||||
else
|
||||
return BTSNOOP_OPCODE_ACL_TX_PKT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
int btsnoop_read_hci(struct timeval *tv, uint16_t *index, uint16_t *opcode,
|
||||
void *data, uint16_t *size)
|
||||
{
|
||||
struct btsnoop_pkt pkt;
|
||||
uint32_t toread, flags;
|
||||
uint64_t ts;
|
||||
uint8_t pkt_type;
|
||||
ssize_t len;
|
||||
|
||||
if (btsnoop_fd < 0)
|
||||
return -1;
|
||||
|
||||
len = read(btsnoop_fd, &pkt, BTSNOOP_PKT_SIZE);
|
||||
if (len == 0)
|
||||
return -1;
|
||||
|
||||
if (len < 0 || len != BTSNOOP_PKT_SIZE) {
|
||||
perror("Failed to read packet");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
toread = ntohl(pkt.size);
|
||||
flags = ntohl(pkt.flags);
|
||||
|
||||
ts = ntoh64(pkt.ts) - 0x00E03AB44A676000ll;
|
||||
tv->tv_sec = (ts / 1000000ll) + 946684800ll;
|
||||
tv->tv_usec = ts % 1000000ll;
|
||||
|
||||
switch (btsnoop_type) {
|
||||
case BTSNOOP_TYPE_HCI:
|
||||
*index = 0;
|
||||
*opcode = get_opcode_from_flags(0xff, flags);
|
||||
break;
|
||||
|
||||
case BTSNOOP_TYPE_UART:
|
||||
len = read(btsnoop_fd, &pkt_type, 1);
|
||||
if (len < 0) {
|
||||
perror("Failed to read packet type");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
toread--;
|
||||
|
||||
*index = 0;
|
||||
*opcode = get_opcode_from_flags(pkt_type, flags);
|
||||
break;
|
||||
|
||||
case BTSNOOP_TYPE_EXTENDED_HCI:
|
||||
*index = flags >> 16;
|
||||
*opcode = flags & 0xffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unknown packet type\n");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = read(btsnoop_fd, data, toread);
|
||||
if (len < 0) {
|
||||
perror("Failed to read data");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*size = toread;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int btsnoop_read_phy(struct timeval *tv, uint16_t *frequency,
|
||||
void *data, uint16_t *size)
|
||||
{
|
||||
struct btsnoop_pkt pkt;
|
||||
uint32_t toread, flags;
|
||||
uint64_t ts;
|
||||
ssize_t len;
|
||||
|
||||
if (btsnoop_fd < 0)
|
||||
return -1;
|
||||
|
||||
len = read(btsnoop_fd, &pkt, BTSNOOP_PKT_SIZE);
|
||||
if (len == 0)
|
||||
return -1;
|
||||
|
||||
if (len < 0 || len != BTSNOOP_PKT_SIZE) {
|
||||
perror("Failed to read packet");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
toread = ntohl(pkt.size);
|
||||
flags = ntohl(pkt.flags);
|
||||
|
||||
ts = ntoh64(pkt.ts) - 0x00E03AB44A676000ll;
|
||||
tv->tv_sec = (ts / 1000000ll) + 946684800ll;
|
||||
tv->tv_usec = ts % 1000000ll;
|
||||
|
||||
switch (btsnoop_type) {
|
||||
case BTSNOOP_TYPE_EXTENDED_PHY:
|
||||
if ((flags >> 16) != 1)
|
||||
break;
|
||||
*frequency = flags & 0xffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unknown packet type\n");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = read(btsnoop_fd, data, toread);
|
||||
if (len < 0) {
|
||||
perror("Failed to read data");
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*size = toread;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btsnoop_close(void)
|
||||
{
|
||||
if (btsnoop_fd < 0)
|
||||
return;
|
||||
|
||||
close(btsnoop_fd);
|
||||
btsnoop_fd = -1;
|
||||
|
||||
btsnoop_index = 0xffff;
|
||||
}
|
||||
57
external/cache/sources/hcitools/monitor/btsnoop.h
vendored
Normal file
57
external/cache/sources/hcitools/monitor/btsnoop.h
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define BTSNOOP_TYPE_HCI 1001
|
||||
#define BTSNOOP_TYPE_UART 1002
|
||||
#define BTSNOOP_TYPE_BCSP 1003
|
||||
#define BTSNOOP_TYPE_3WIRE 1004
|
||||
|
||||
#define BTSNOOP_TYPE_EXTENDED_HCI 2001
|
||||
#define BTSNOOP_TYPE_EXTENDED_PHY 2002
|
||||
|
||||
#define BTSNOOP_OPCODE_NEW_INDEX 0
|
||||
#define BTSNOOP_OPCODE_DEL_INDEX 1
|
||||
#define BTSNOOP_OPCODE_COMMAND_PKT 2
|
||||
#define BTSNOOP_OPCODE_EVENT_PKT 3
|
||||
#define BTSNOOP_OPCODE_ACL_TX_PKT 4
|
||||
#define BTSNOOP_OPCODE_ACL_RX_PKT 5
|
||||
#define BTSNOOP_OPCODE_SCO_TX_PKT 6
|
||||
#define BTSNOOP_OPCODE_SCO_RX_PKT 7
|
||||
|
||||
void btsnoop_create(const char *path, uint32_t type);
|
||||
void btsnoop_write(struct timeval *tv, uint32_t flags,
|
||||
const void *data, uint16_t size);
|
||||
void btsnoop_write_hci(struct timeval *tv, uint16_t index, uint16_t opcode,
|
||||
const void *data, uint16_t size);
|
||||
void btsnoop_write_phy(struct timeval *tv, uint16_t frequency,
|
||||
const void *data, uint16_t size);
|
||||
int btsnoop_open(const char *path, uint32_t *type);
|
||||
int btsnoop_read_hci(struct timeval *tv, uint16_t *index, uint16_t *opcode,
|
||||
void *data, uint16_t *size);
|
||||
int btsnoop_read_phy(struct timeval *tv, uint16_t *frequency,
|
||||
void *data, uint16_t *size);
|
||||
void btsnoop_close(void);
|
||||
891
external/cache/sources/hcitools/monitor/control.c
vendored
Normal file
891
external/cache/sources/hcitools/monitor/control.c
vendored
Normal file
@@ -0,0 +1,891 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <lib/bluetooth/bluetooth.h>
|
||||
#include <lib/bluetooth/hci.h>
|
||||
#include <lib/mgmt.h>
|
||||
|
||||
#include "mainloop.h"
|
||||
#include "display.h"
|
||||
#include "packet.h"
|
||||
#include "btsnoop.h"
|
||||
#include "hcidump.h"
|
||||
#include "control.h"
|
||||
|
||||
static bool hcidump_fallback = false;
|
||||
|
||||
#define MAX_PACKET_SIZE (1486 + 4)
|
||||
|
||||
struct control_data {
|
||||
uint16_t channel;
|
||||
int fd;
|
||||
unsigned char buf[MAX_PACKET_SIZE];
|
||||
uint16_t offset;
|
||||
};
|
||||
|
||||
static void free_data(void *user_data)
|
||||
{
|
||||
struct control_data *data = user_data;
|
||||
|
||||
close(data->fd);
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void mgmt_index_added(uint16_t len, const void *buf)
|
||||
{
|
||||
printf("@ Index Added\n");
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_index_removed(uint16_t len, const void *buf)
|
||||
{
|
||||
printf("@ Index Removed\n");
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_controller_error(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_controller_error *ev = buf;
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Controller Error control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("@ Controller Error: 0x%2.2x\n", ev->error_code);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
#ifndef NELEM
|
||||
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
static const char *settings_str[] = {
|
||||
"powered", "connectable", "fast-connectable", "discoverable",
|
||||
"pairable", "link-security", "ssp", "br/edr", "hs", "le",
|
||||
"advertising",
|
||||
};
|
||||
|
||||
static void mgmt_new_settings(uint16_t len, const void *buf)
|
||||
{
|
||||
uint32_t settings;
|
||||
unsigned int i;
|
||||
|
||||
if (len < 4) {
|
||||
printf("* Malformed New Settings control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
settings = bt_get_le32(buf);
|
||||
|
||||
printf("@ New Settings: 0x%4.4x\n", settings);
|
||||
|
||||
printf("%-12c", ' ');
|
||||
for (i = 0; i < NELEM(settings_str); i++) {
|
||||
if (settings & (1 << i))
|
||||
printf("%s ", settings_str[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
buf += 4;
|
||||
len -= 4;
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_class_of_dev_changed(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_class_of_dev_changed *ev = buf;
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Class of Device Changed control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("@ Class of Device Changed: 0x%2.2x%2.2x%2.2x\n",
|
||||
ev->class_of_dev[2],
|
||||
ev->class_of_dev[1],
|
||||
ev->class_of_dev[0]);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_local_name_changed(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_local_name_changed *ev = buf;
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Local Name Changed control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("@ Local Name Changed: %s (%s)\n", ev->name, ev->short_name);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_new_link_key(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_new_link_key *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed New Link Key control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->key.addr.bdaddr, str);
|
||||
|
||||
printf("@ New Link Key: %s (%d)\n", str, ev->key.addr.type);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_new_long_term_key(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_new_long_term_key *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed New Long Term Key control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->key.addr.bdaddr, str);
|
||||
|
||||
printf("@ New Long Term Key: %s (%d)\n", str, ev->key.addr.type);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_device_connected(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_device_connected *ev = buf;
|
||||
uint32_t flags;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Device Connected control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
flags = btohl(ev->flags);
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ Device Connected: %s (%d) flags 0x%4.4x\n",
|
||||
str, ev->addr.type, flags);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_device_disconnected(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_device_disconnected *ev = buf;
|
||||
char str[18];
|
||||
uint8_t reason;
|
||||
uint16_t consumed_len;
|
||||
|
||||
if (len < sizeof(struct mgmt_addr_info)) {
|
||||
printf("* Malformed Device Disconnected control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
reason = MGMT_DEV_DISCONN_UNKNOWN;
|
||||
consumed_len = len;
|
||||
} else {
|
||||
reason = ev->reason;
|
||||
consumed_len = sizeof(*ev);
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ Device Disconnected: %s (%d) reason %u\n", str, ev->addr.type,
|
||||
reason);
|
||||
|
||||
buf += consumed_len;
|
||||
len -= consumed_len;
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_connect_failed(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_connect_failed *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Connect Failed control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ Connect Failed: %s (%d) status 0x%2.2x\n",
|
||||
str, ev->addr.type, ev->status);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_pin_code_request(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_pin_code_request *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed PIN Code Request control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ PIN Code Request: %s (%d) secure 0x%2.2x\n",
|
||||
str, ev->addr.type, ev->secure);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_user_confirm_request(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_user_confirm_request *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed User Confirmation Request control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ User Confirmation Request: %s (%d) hint %d value %d\n",
|
||||
str, ev->addr.type, ev->confirm_hint, ev->value);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_user_passkey_request(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_user_passkey_request *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed User Passkey Request control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ PIN User Passkey Request: %s (%d)\n", str, ev->addr.type);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_auth_failed(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_auth_failed *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Authentication Failed control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ Authentication Failed: %s (%d) status 0x%2.2x\n",
|
||||
str, ev->addr.type, ev->status);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_device_found(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_device_found *ev = buf;
|
||||
uint32_t flags;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Device Found control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
flags = btohl(ev->flags);
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ Device Found: %s (%d) rssi %d flags 0x%4.4x\n",
|
||||
str, ev->addr.type, ev->rssi, flags);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_discovering(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_discovering *ev = buf;
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Discovering control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("@ Discovering: 0x%2.2x (%d)\n", ev->discovering, ev->type);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_device_blocked(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_device_blocked *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Device Blocked control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ Device Blocked: %s (%d)\n", str, ev->addr.type);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_device_unblocked(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_device_unblocked *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Device Unblocked control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ Device Unblocked: %s (%d)\n", str, ev->addr.type);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_device_unpaired(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_device_unpaired *ev = buf;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Device Unpaired control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
printf("@ Device Unpaired: %s (%d)\n", str, ev->addr.type);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
static void mgmt_passkey_notify(uint16_t len, const void *buf)
|
||||
{
|
||||
const struct mgmt_ev_passkey_notify *ev = buf;
|
||||
uint32_t passkey;
|
||||
char str[18];
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
printf("* Malformed Passkey Notify control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ba2str(&ev->addr.bdaddr, str);
|
||||
|
||||
passkey = btohl(ev->passkey);
|
||||
|
||||
printf("@ Passkey Notify: %s (%d) passkey %06u entered %u\n",
|
||||
str, ev->addr.type, passkey, ev->entered);
|
||||
|
||||
buf += sizeof(*ev);
|
||||
len -= sizeof(*ev);
|
||||
|
||||
packet_hexdump(buf, len);
|
||||
}
|
||||
|
||||
void control_message(uint16_t opcode, const void *data, uint16_t size)
|
||||
{
|
||||
switch (opcode) {
|
||||
case MGMT_EV_INDEX_ADDED:
|
||||
mgmt_index_added(size, data);
|
||||
break;
|
||||
case MGMT_EV_INDEX_REMOVED:
|
||||
mgmt_index_removed(size, data);
|
||||
break;
|
||||
case MGMT_EV_CONTROLLER_ERROR:
|
||||
mgmt_controller_error(size, data);
|
||||
break;
|
||||
case MGMT_EV_NEW_SETTINGS:
|
||||
mgmt_new_settings(size, data);
|
||||
break;
|
||||
case MGMT_EV_CLASS_OF_DEV_CHANGED:
|
||||
mgmt_class_of_dev_changed(size, data);
|
||||
break;
|
||||
case MGMT_EV_LOCAL_NAME_CHANGED:
|
||||
mgmt_local_name_changed(size, data);
|
||||
break;
|
||||
case MGMT_EV_NEW_LINK_KEY:
|
||||
mgmt_new_link_key(size, data);
|
||||
break;
|
||||
case MGMT_EV_NEW_LONG_TERM_KEY:
|
||||
mgmt_new_long_term_key(size, data);
|
||||
break;
|
||||
case MGMT_EV_DEVICE_CONNECTED:
|
||||
mgmt_device_connected(size, data);
|
||||
break;
|
||||
case MGMT_EV_DEVICE_DISCONNECTED:
|
||||
mgmt_device_disconnected(size, data);
|
||||
break;
|
||||
case MGMT_EV_CONNECT_FAILED:
|
||||
mgmt_connect_failed(size, data);
|
||||
break;
|
||||
case MGMT_EV_PIN_CODE_REQUEST:
|
||||
mgmt_pin_code_request(size, data);
|
||||
break;
|
||||
case MGMT_EV_USER_CONFIRM_REQUEST:
|
||||
mgmt_user_confirm_request(size, data);
|
||||
break;
|
||||
case MGMT_EV_USER_PASSKEY_REQUEST:
|
||||
mgmt_user_passkey_request(size, data);
|
||||
break;
|
||||
case MGMT_EV_AUTH_FAILED:
|
||||
mgmt_auth_failed(size, data);
|
||||
break;
|
||||
case MGMT_EV_DEVICE_FOUND:
|
||||
mgmt_device_found(size, data);
|
||||
break;
|
||||
case MGMT_EV_DISCOVERING:
|
||||
mgmt_discovering(size, data);
|
||||
break;
|
||||
case MGMT_EV_DEVICE_BLOCKED:
|
||||
mgmt_device_blocked(size, data);
|
||||
break;
|
||||
case MGMT_EV_DEVICE_UNBLOCKED:
|
||||
mgmt_device_unblocked(size, data);
|
||||
break;
|
||||
case MGMT_EV_DEVICE_UNPAIRED:
|
||||
mgmt_device_unpaired(size, data);
|
||||
break;
|
||||
case MGMT_EV_PASSKEY_NOTIFY:
|
||||
mgmt_passkey_notify(size, data);
|
||||
break;
|
||||
default:
|
||||
printf("* Unknown control (code %d len %d)\n", opcode, size);
|
||||
packet_hexdump(data, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void data_callback(int fd, uint32_t events, void *user_data)
|
||||
{
|
||||
struct control_data *data = user_data;
|
||||
unsigned char control[32];
|
||||
struct mgmt_hdr hdr;
|
||||
struct msghdr msg;
|
||||
struct iovec iov[2];
|
||||
|
||||
if (events & (EPOLLERR | EPOLLHUP)) {
|
||||
mainloop_remove_fd(data->fd);
|
||||
return;
|
||||
}
|
||||
|
||||
iov[0].iov_base = &hdr;
|
||||
iov[0].iov_len = MGMT_HDR_SIZE;
|
||||
iov[1].iov_base = data->buf;
|
||||
iov[1].iov_len = sizeof(data->buf);
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = 2;
|
||||
msg.msg_control = control;
|
||||
msg.msg_controllen = sizeof(control);
|
||||
|
||||
while (1) {
|
||||
struct cmsghdr *cmsg;
|
||||
struct timeval *tv = NULL;
|
||||
struct timeval ctv;
|
||||
uint16_t opcode, index, pktlen;
|
||||
ssize_t len;
|
||||
|
||||
len = recvmsg(data->fd, &msg, MSG_DONTWAIT);
|
||||
if (len < 0)
|
||||
break;
|
||||
|
||||
if (len < MGMT_HDR_SIZE)
|
||||
break;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
continue;
|
||||
|
||||
if (cmsg->cmsg_type == SCM_TIMESTAMP) {
|
||||
memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv));
|
||||
tv = &ctv;
|
||||
}
|
||||
}
|
||||
|
||||
opcode = btohs(hdr.opcode);
|
||||
index = btohs(hdr.index);
|
||||
pktlen = btohs(hdr.len);
|
||||
|
||||
switch (data->channel) {
|
||||
case HCI_CHANNEL_CONTROL:
|
||||
packet_control(tv, index, opcode, data->buf, pktlen);
|
||||
break;
|
||||
case HCI_CHANNEL_MONITOR:
|
||||
packet_monitor(tv, index, opcode, data->buf, pktlen);
|
||||
btsnoop_write_hci(tv, index, opcode, data->buf, pktlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int open_socket(uint16_t channel)
|
||||
{
|
||||
struct sockaddr_hci addr;
|
||||
int fd, opt = 1;
|
||||
|
||||
fd = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);
|
||||
if (fd < 0) {
|
||||
perror("Failed to open channel");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.hci_family = AF_BLUETOOTH;
|
||||
addr.hci_dev = HCI_DEV_NONE;
|
||||
addr.hci_channel = channel;
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
if (errno == EINVAL) {
|
||||
/* Fallback to hcidump support */
|
||||
hcidump_fallback = true;
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
perror("Failed to bind channel");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)) < 0) {
|
||||
perror("Failed to enable timestamps");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int open_channel(uint16_t channel)
|
||||
{
|
||||
struct control_data *data;
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->channel = channel;
|
||||
|
||||
data->fd = open_socket(channel);
|
||||
if (data->fd < 0) {
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mainloop_add_fd(data->fd, EPOLLIN, data_callback, data, free_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void client_callback(int fd, uint32_t events, void *user_data)
|
||||
{
|
||||
struct control_data *data = user_data;
|
||||
ssize_t len;
|
||||
|
||||
if (events & (EPOLLERR | EPOLLHUP)) {
|
||||
mainloop_remove_fd(data->fd);
|
||||
return;
|
||||
}
|
||||
|
||||
len = recv(data->fd, data->buf + data->offset,
|
||||
sizeof(data->buf) - data->offset, MSG_DONTWAIT);
|
||||
if (len < 0)
|
||||
return;
|
||||
|
||||
data->offset += len;
|
||||
|
||||
if (data->offset > MGMT_HDR_SIZE) {
|
||||
struct mgmt_hdr *hdr = (struct mgmt_hdr *) data->buf;
|
||||
uint16_t pktlen = btohs(hdr->len);
|
||||
|
||||
if (data->offset > pktlen + MGMT_HDR_SIZE) {
|
||||
uint16_t opcode = btohs(hdr->opcode);
|
||||
uint16_t index = btohs(hdr->index);
|
||||
|
||||
packet_monitor(NULL, index, opcode,
|
||||
data->buf + MGMT_HDR_SIZE, pktlen);
|
||||
|
||||
data->offset -= pktlen + MGMT_HDR_SIZE;
|
||||
|
||||
if (data->offset > 0)
|
||||
memmove(data->buf, data->buf +
|
||||
MGMT_HDR_SIZE + pktlen, data->offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void server_accept_callback(int fd, uint32_t events, void *user_data)
|
||||
{
|
||||
struct control_data *data;
|
||||
struct sockaddr_un addr;
|
||||
socklen_t len;
|
||||
int nfd;
|
||||
|
||||
if (events & (EPOLLERR | EPOLLHUP)) {
|
||||
mainloop_remove_fd(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
len = sizeof(addr);
|
||||
|
||||
nfd = accept(fd, (struct sockaddr *) &addr, &len);
|
||||
if (nfd < 0) {
|
||||
perror("Failed to accept client socket");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("--- New monitor connection ---\n");
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (!data) {
|
||||
close(nfd);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->channel = HCI_CHANNEL_MONITOR;
|
||||
data->fd = nfd;
|
||||
|
||||
mainloop_add_fd(data->fd, EPOLLIN, client_callback, data, free_data);
|
||||
}
|
||||
|
||||
static int server_fd = -1;
|
||||
|
||||
void control_server(const char *path)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
int fd;
|
||||
|
||||
if (server_fd >= 0)
|
||||
return;
|
||||
|
||||
unlink(path);
|
||||
|
||||
fd = socket(PF_UNIX, SOCK_STREAM | O_CLOEXEC, 0);
|
||||
if (fd < 0) {
|
||||
perror("Failed to open server socket");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, path);
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
perror("Failed to bind server socket");
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (listen(fd, 5) < 0) {
|
||||
perror("Failed to listen server socket");
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainloop_add_fd(fd, EPOLLIN, server_accept_callback,
|
||||
NULL, NULL) < 0) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
server_fd = fd;
|
||||
}
|
||||
|
||||
void control_writer(const char *path)
|
||||
{
|
||||
btsnoop_create(path, BTSNOOP_TYPE_EXTENDED_HCI);
|
||||
}
|
||||
|
||||
void control_reader(const char *path)
|
||||
{
|
||||
unsigned char buf[MAX_PACKET_SIZE];
|
||||
uint16_t pktlen;
|
||||
uint32_t type;
|
||||
struct timeval tv;
|
||||
|
||||
if (btsnoop_open(path, &type) < 0)
|
||||
return;
|
||||
|
||||
switch (type) {
|
||||
case BTSNOOP_TYPE_HCI:
|
||||
case BTSNOOP_TYPE_UART:
|
||||
case BTSNOOP_TYPE_EXTENDED_PHY:
|
||||
packet_del_filter(PACKET_FILTER_SHOW_INDEX);
|
||||
break;
|
||||
|
||||
case BTSNOOP_TYPE_EXTENDED_HCI:
|
||||
packet_add_filter(PACKET_FILTER_SHOW_INDEX);
|
||||
break;
|
||||
}
|
||||
|
||||
open_pager();
|
||||
|
||||
switch (type) {
|
||||
case BTSNOOP_TYPE_HCI:
|
||||
case BTSNOOP_TYPE_UART:
|
||||
case BTSNOOP_TYPE_EXTENDED_HCI:
|
||||
while (1) {
|
||||
uint16_t index, opcode;
|
||||
|
||||
if (btsnoop_read_hci(&tv, &index, &opcode,
|
||||
buf, &pktlen) < 0)
|
||||
break;
|
||||
|
||||
packet_monitor(&tv, index, opcode, buf, pktlen);
|
||||
}
|
||||
break;
|
||||
|
||||
case BTSNOOP_TYPE_EXTENDED_PHY:
|
||||
while (1) {
|
||||
uint16_t frequency;
|
||||
|
||||
if (btsnoop_read_phy(&tv, &frequency,
|
||||
buf, &pktlen) < 0)
|
||||
break;
|
||||
|
||||
packet_simulator(&tv, frequency, buf, pktlen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
close_pager();
|
||||
|
||||
btsnoop_close();
|
||||
}
|
||||
|
||||
int control_tracing(void)
|
||||
{
|
||||
packet_add_filter(PACKET_FILTER_SHOW_INDEX);
|
||||
|
||||
if (server_fd >= 0)
|
||||
return 0;
|
||||
|
||||
if (open_channel(HCI_CHANNEL_MONITOR) < 0) {
|
||||
if (!hcidump_fallback)
|
||||
return -1;
|
||||
if (hcidump_tracing() < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
open_channel(HCI_CHANNEL_CONTROL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
32
external/cache/sources/hcitools/monitor/control.h
vendored
Normal file
32
external/cache/sources/hcitools/monitor/control.h
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void control_writer(const char *path);
|
||||
void control_reader(const char *path);
|
||||
void control_server(const char *path);
|
||||
int control_tracing(void);
|
||||
|
||||
void control_message(uint16_t opcode, const void *data, uint16_t size);
|
||||
84
external/cache/sources/hcitools/monitor/crc.c
vendored
Normal file
84
external/cache/sources/hcitools/monitor/crc.c
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "crc.h"
|
||||
|
||||
uint32_t crc24_bit_reverse(uint32_t value)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < 24; i++)
|
||||
result |= ((value >> i) & 1) << (23 - i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t crc24_calculate(uint32_t preset, const uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint32_t state = preset;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
uint8_t n, cur = data[i];
|
||||
|
||||
for (n = 0; n < 8; n++) {
|
||||
int next_bit = (state ^ cur) & 1;
|
||||
|
||||
cur >>= 1;
|
||||
state >>= 1;
|
||||
if (next_bit) {
|
||||
state |= 1 << 23;
|
||||
state ^= 0x5a6000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
uint32_t crc24_reverse(uint32_t crc, const uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint32_t state = crc;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
uint8_t n, cur = data[len - i - 1];
|
||||
|
||||
for (n = 0; n < 8; n++) {
|
||||
int top_bit = state >> 23;
|
||||
|
||||
state = (state << 1) & 0xffffff;
|
||||
state |= top_bit ^ ((cur >> (7 - n)) & 1);
|
||||
if (top_bit)
|
||||
state ^= 0xb4c000;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
30
external/cache/sources/hcitools/monitor/crc.h
vendored
Normal file
30
external/cache/sources/hcitools/monitor/crc.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t crc24_bit_reverse(uint32_t value);
|
||||
|
||||
uint32_t crc24_calculate(uint32_t preset, const uint8_t *data, uint8_t len);
|
||||
uint32_t crc24_reverse(uint32_t crc, const uint8_t *data, uint8_t len);
|
||||
171
external/cache/sources/hcitools/monitor/display.c
vendored
Normal file
171
external/cache/sources/hcitools/monitor/display.c
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "display.h"
|
||||
|
||||
static pid_t pager_pid = 0;
|
||||
|
||||
bool use_color(void)
|
||||
{
|
||||
static int cached_use_color = -1;
|
||||
|
||||
if (__builtin_expect(!!(cached_use_color < 0), 0))
|
||||
cached_use_color = isatty(STDOUT_FILENO) > 0 || pager_pid > 0;
|
||||
|
||||
return cached_use_color;
|
||||
}
|
||||
|
||||
int num_columns(void)
|
||||
{
|
||||
static int cached_num_columns = -1;
|
||||
|
||||
if (__builtin_expect(!!(cached_num_columns < 0), 0)) {
|
||||
struct winsize ws;
|
||||
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
|
||||
return -1;
|
||||
|
||||
if (ws.ws_col > 0)
|
||||
cached_num_columns = ws.ws_col;
|
||||
}
|
||||
|
||||
return cached_num_columns;
|
||||
}
|
||||
|
||||
static void close_pipe(int p[])
|
||||
{
|
||||
if (p[0] >= 0)
|
||||
close(p[0]);
|
||||
if (p[1] >= 0)
|
||||
close(p[1]);
|
||||
}
|
||||
|
||||
static void wait_for_terminate(pid_t pid)
|
||||
{
|
||||
siginfo_t dummy;
|
||||
|
||||
for (;;) {
|
||||
memset(&dummy, 0, sizeof(dummy));
|
||||
|
||||
if (waitid(P_PID, pid, &dummy, WEXITED) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void open_pager(void)
|
||||
{
|
||||
const char *pager;
|
||||
pid_t parent_pid;
|
||||
int fd[2];
|
||||
|
||||
if (pager_pid > 0)
|
||||
return;
|
||||
|
||||
pager = getenv("PAGER");
|
||||
if (pager) {
|
||||
if (!*pager || strcmp(pager, "cat") == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(isatty(STDOUT_FILENO) > 0))
|
||||
return;
|
||||
|
||||
num_columns();
|
||||
|
||||
if (pipe(fd) < 0) {
|
||||
perror("Failed to create pager pipe");
|
||||
return;
|
||||
}
|
||||
|
||||
parent_pid = getpid();
|
||||
|
||||
pager_pid = fork();
|
||||
if (pager_pid < 0) {
|
||||
perror("Failed to fork pager");
|
||||
close_pipe(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pager_pid == 0) {
|
||||
dup2(fd[0], STDIN_FILENO);
|
||||
close_pipe(fd);
|
||||
|
||||
setenv("LESS", "FRSX", 0);
|
||||
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (getppid() != parent_pid)
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
if (pager) {
|
||||
execlp(pager, pager, NULL);
|
||||
execl("/bin/sh", "sh", "-c", pager, NULL);
|
||||
}
|
||||
|
||||
execlp("pager", "pager", NULL);
|
||||
execlp("less", "less", NULL);
|
||||
execlp("more", "more", NULL);
|
||||
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (dup2(fd[1], STDOUT_FILENO) < 0) {
|
||||
perror("Failed to duplicate pager pipe");
|
||||
return;
|
||||
}
|
||||
|
||||
close_pipe(fd);
|
||||
}
|
||||
|
||||
void close_pager(void)
|
||||
{
|
||||
if (pager_pid <= 0)
|
||||
return;
|
||||
|
||||
fclose(stdout);
|
||||
kill(pager_pid, SIGCONT);
|
||||
wait_for_terminate(pager_pid);
|
||||
pager_pid = 0;
|
||||
}
|
||||
60
external/cache/sources/hcitools/monitor/display.h
vendored
Normal file
60
external/cache/sources/hcitools/monitor/display.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool use_color(void);
|
||||
|
||||
#define COLOR_OFF "\x1B[0m"
|
||||
#define COLOR_BLACK "\x1B[0;30m"
|
||||
#define COLOR_RED "\x1B[0;31m"
|
||||
#define COLOR_GREEN "\x1B[0;32m"
|
||||
#define COLOR_YELLOW "\x1B[0;33m"
|
||||
#define COLOR_BLUE "\x1B[0;34m"
|
||||
#define COLOR_MAGENTA "\x1B[0;35m"
|
||||
#define COLOR_CYAN "\x1B[0;36m"
|
||||
#define COLOR_WHITE "\x1B[0;37m"
|
||||
#define COLOR_WHITE_BG "\x1B[0;47m"
|
||||
#define COLOR_HIGHLIGHT "\x1B[1;39m"
|
||||
|
||||
#define COLOR_ERROR "\x1B[1;31m"
|
||||
|
||||
#define print_indent(indent, color1, prefix, title, color2, fmt, args...) \
|
||||
do { \
|
||||
printf("%*c%s%s%s%s" fmt "%s\n", (indent), ' ', \
|
||||
use_color() ? (color1) : "", prefix, title, \
|
||||
use_color() ? (color2) : "", ## args, \
|
||||
use_color() ? COLOR_OFF : ""); \
|
||||
} while (0)
|
||||
|
||||
#define print_text(color, fmt, args...) \
|
||||
print_indent(8, COLOR_OFF, "", "", color, fmt, ## args)
|
||||
|
||||
#define print_field(fmt, args...) \
|
||||
print_indent(8, COLOR_OFF, "", "", COLOR_OFF, fmt, ## args)
|
||||
|
||||
int num_columns(void);
|
||||
|
||||
void open_pager(void);
|
||||
void close_pager(void);
|
||||
411
external/cache/sources/hcitools/monitor/hcidump.c
vendored
Normal file
411
external/cache/sources/hcitools/monitor/hcidump.c
vendored
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
|
||||
#include "mainloop.h"
|
||||
#include "packet.h"
|
||||
#include "hcidump.h"
|
||||
|
||||
struct hcidump_data {
|
||||
uint16_t index;
|
||||
int fd;
|
||||
};
|
||||
|
||||
static void free_data(void *user_data)
|
||||
{
|
||||
struct hcidump_data *data = user_data;
|
||||
|
||||
close(data->fd);
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
static int open_hci_dev(uint16_t index)
|
||||
{
|
||||
struct sockaddr_hci addr;
|
||||
struct hci_filter flt;
|
||||
int fd, opt = 1;
|
||||
|
||||
fd = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);
|
||||
if (fd < 0) {
|
||||
perror("Failed to open channel");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Setup filter */
|
||||
hci_filter_clear(&flt);
|
||||
hci_filter_all_ptypes(&flt);
|
||||
hci_filter_all_events(&flt);
|
||||
|
||||
if (setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
|
||||
perror("Failed to set HCI filter");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
|
||||
perror("Failed to enable HCI data direction info");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
|
||||
perror("Failed to enable HCI time stamps");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.hci_family = AF_BLUETOOTH;
|
||||
addr.hci_dev = index;
|
||||
addr.hci_channel = HCI_CHANNEL_RAW;
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
perror("Failed to bind channel");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void device_callback(int fd, uint32_t events, void *user_data)
|
||||
{
|
||||
struct hcidump_data *data = user_data;
|
||||
unsigned char buf[HCI_MAX_FRAME_SIZE * 2];
|
||||
unsigned char control[64];
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
|
||||
if (events & (EPOLLERR | EPOLLHUP)) {
|
||||
mainloop_remove_fd(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = sizeof(buf);
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = control;
|
||||
msg.msg_controllen = sizeof(control);
|
||||
|
||||
while (1) {
|
||||
struct cmsghdr *cmsg;
|
||||
struct timeval *tv = NULL;
|
||||
struct timeval ctv;
|
||||
int dir = -1;
|
||||
ssize_t len;
|
||||
|
||||
len = recvmsg(fd, &msg, MSG_DONTWAIT);
|
||||
if (len < 0)
|
||||
break;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level != SOL_HCI)
|
||||
continue;
|
||||
|
||||
switch (cmsg->cmsg_type) {
|
||||
case HCI_DATA_DIR:
|
||||
memcpy(&dir, CMSG_DATA(cmsg), sizeof(dir));
|
||||
break;
|
||||
case HCI_CMSG_TSTAMP:
|
||||
memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv));
|
||||
tv = &ctv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dir < 0 || len < 1)
|
||||
continue;
|
||||
|
||||
switch (buf[0]) {
|
||||
case HCI_COMMAND_PKT:
|
||||
packet_hci_command(tv, data->index, buf + 1, len - 1);
|
||||
break;
|
||||
case HCI_EVENT_PKT:
|
||||
packet_hci_event(tv, data->index, buf + 1, len - 1);
|
||||
break;
|
||||
case HCI_ACLDATA_PKT:
|
||||
packet_hci_acldata(tv, data->index, !!dir,
|
||||
buf + 1, len - 1);
|
||||
break;
|
||||
case HCI_SCODATA_PKT:
|
||||
packet_hci_scodata(tv, data->index, !!dir,
|
||||
buf + 1, len - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void open_device(uint16_t index)
|
||||
{
|
||||
struct hcidump_data *data;
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->index = index;
|
||||
|
||||
data->fd = open_hci_dev(index);
|
||||
if (data->fd < 0) {
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
mainloop_add_fd(data->fd, EPOLLIN, device_callback, data, free_data);
|
||||
}
|
||||
|
||||
static void device_info(int fd, uint16_t index, uint8_t *type, uint8_t *bus,
|
||||
bdaddr_t *bdaddr, char *name)
|
||||
{
|
||||
struct hci_dev_info di;
|
||||
|
||||
memset(&di, 0, sizeof(di));
|
||||
di.dev_id = index;
|
||||
|
||||
if (ioctl(fd, HCIGETDEVINFO, (void *) &di) < 0) {
|
||||
perror("Failed to get device information");
|
||||
return;
|
||||
}
|
||||
|
||||
*type = di.type >> 4;
|
||||
*bus = di.type & 0x0f;
|
||||
|
||||
bacpy(bdaddr, &di.bdaddr);
|
||||
memcpy(name, di.name, 8);
|
||||
}
|
||||
|
||||
static void device_list(int fd, int max_dev)
|
||||
{
|
||||
struct hci_dev_list_req *dl;
|
||||
struct hci_dev_req *dr;
|
||||
int i;
|
||||
|
||||
dl = malloc(max_dev * sizeof(*dr) + sizeof(*dl));
|
||||
if (!dl) {
|
||||
perror("Failed to allocate device list memory");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(dl, 0, max_dev * sizeof(*dr) + sizeof(*dl));
|
||||
dl->dev_num = max_dev;
|
||||
|
||||
dr = dl->dev_req;
|
||||
|
||||
if (ioctl(fd, HCIGETDEVLIST, (void *) dl) < 0) {
|
||||
perror("Failed to get device list");
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < dl->dev_num; i++, dr++) {
|
||||
struct timeval tmp_tv, *tv = NULL;
|
||||
uint8_t type = 0xff, bus = 0xff;
|
||||
char str[18], name[8] = "";
|
||||
bdaddr_t bdaddr;
|
||||
|
||||
bacpy(&bdaddr, BDADDR_ANY);
|
||||
|
||||
if (!gettimeofday(&tmp_tv, NULL))
|
||||
tv = &tmp_tv;
|
||||
|
||||
device_info(fd, dr->dev_id, &type, &bus, &bdaddr, name);
|
||||
ba2str(&bdaddr, str);
|
||||
packet_new_index(tv, dr->dev_id, str, type, bus, name);
|
||||
open_device(dr->dev_id);
|
||||
}
|
||||
|
||||
done:
|
||||
free(dl);
|
||||
}
|
||||
|
||||
static int open_stack_internal(void)
|
||||
{
|
||||
struct sockaddr_hci addr;
|
||||
struct hci_filter flt;
|
||||
int fd, opt = 1;
|
||||
|
||||
fd = socket(AF_BLUETOOTH, SOCK_RAW | O_CLOEXEC, BTPROTO_HCI);
|
||||
if (fd < 0) {
|
||||
perror("Failed to open channel");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Setup filter */
|
||||
hci_filter_clear(&flt);
|
||||
hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
|
||||
hci_filter_set_event(EVT_STACK_INTERNAL, &flt);
|
||||
|
||||
if (setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
|
||||
perror("Failed to set HCI filter");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
|
||||
perror("Failed to enable HCI time stamps");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.hci_family = AF_BLUETOOTH;
|
||||
addr.hci_dev = HCI_DEV_NONE;
|
||||
addr.hci_channel = HCI_CHANNEL_RAW;
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
perror("Failed to bind channel");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
device_list(fd, HCI_MAX_DEV);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void stack_internal_callback(int fd, uint32_t events, void *user_data)
|
||||
{
|
||||
unsigned char buf[HCI_MAX_FRAME_SIZE];
|
||||
unsigned char control[32];
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
struct cmsghdr *cmsg;
|
||||
ssize_t len;
|
||||
hci_event_hdr *eh;
|
||||
evt_stack_internal *si;
|
||||
evt_si_device *sd;
|
||||
struct timeval *tv = NULL;
|
||||
struct timeval ctv;
|
||||
uint8_t type = 0xff, bus = 0xff;
|
||||
char str[18], name[8] = "";
|
||||
bdaddr_t bdaddr;
|
||||
|
||||
bacpy(&bdaddr, BDADDR_ANY);
|
||||
|
||||
if (events & (EPOLLERR | EPOLLHUP)) {
|
||||
mainloop_remove_fd(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = sizeof(buf);
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = control;
|
||||
msg.msg_controllen = sizeof(control);
|
||||
|
||||
len = recvmsg(fd, &msg, MSG_DONTWAIT);
|
||||
if (len < 0)
|
||||
return;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level != SOL_HCI)
|
||||
continue;
|
||||
|
||||
switch (cmsg->cmsg_type) {
|
||||
case HCI_CMSG_TSTAMP:
|
||||
memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv));
|
||||
tv = &ctv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len < 1 + HCI_EVENT_HDR_SIZE + EVT_STACK_INTERNAL_SIZE +
|
||||
EVT_SI_DEVICE_SIZE)
|
||||
return;
|
||||
|
||||
if (buf[0] != HCI_EVENT_PKT)
|
||||
return;
|
||||
|
||||
eh = (hci_event_hdr *) (buf + 1);
|
||||
if (eh->evt != EVT_STACK_INTERNAL)
|
||||
return;
|
||||
|
||||
si = (evt_stack_internal *) (buf + 1 + HCI_EVENT_HDR_SIZE);
|
||||
if (si->type != EVT_SI_DEVICE)
|
||||
return;
|
||||
|
||||
sd = (evt_si_device *) &si->data;
|
||||
|
||||
switch (sd->event) {
|
||||
case HCI_DEV_REG:
|
||||
device_info(fd, sd->dev_id, &type, &bus, &bdaddr, name);
|
||||
ba2str(&bdaddr, str);
|
||||
packet_new_index(tv, sd->dev_id, str, type, bus, name);
|
||||
open_device(sd->dev_id);
|
||||
break;
|
||||
case HCI_DEV_UNREG:
|
||||
ba2str(&bdaddr, str);
|
||||
packet_del_index(tv, sd->dev_id, str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int hcidump_tracing(void)
|
||||
{
|
||||
struct hcidump_data *data;
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->index = HCI_DEV_NONE;
|
||||
|
||||
data->fd = open_stack_internal();
|
||||
if (data->fd < 0) {
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mainloop_add_fd(data->fd, EPOLLIN, stack_internal_callback,
|
||||
data, free_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
25
external/cache/sources/hcitools/monitor/hcidump.h
vendored
Normal file
25
external/cache/sources/hcitools/monitor/hcidump.h
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
int hcidump_tracing(void);
|
||||
2690
external/cache/sources/hcitools/monitor/l2cap.c
vendored
Normal file
2690
external/cache/sources/hcitools/monitor/l2cap.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
61
external/cache/sources/hcitools/monitor/l2cap.h
vendored
Normal file
61
external/cache/sources/hcitools/monitor/l2cap.h
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct l2cap_frame {
|
||||
uint16_t index;
|
||||
bool in;
|
||||
uint16_t handle;
|
||||
uint16_t cid;
|
||||
const void *data;
|
||||
uint16_t size;
|
||||
};
|
||||
|
||||
static inline void l2cap_frame_init(struct l2cap_frame *frame,
|
||||
uint16_t index, bool in, uint16_t handle,
|
||||
uint16_t cid, const void *data, uint16_t size)
|
||||
{
|
||||
frame->index = index;
|
||||
frame->in = in;
|
||||
frame->handle = handle;
|
||||
frame->cid = cid;
|
||||
frame->data = data;
|
||||
frame->size = size;
|
||||
}
|
||||
|
||||
static inline void l2cap_frame_pull(struct l2cap_frame *frame,
|
||||
const struct l2cap_frame *source, uint16_t len)
|
||||
{
|
||||
frame->index = source->index;
|
||||
frame->in = source->in;
|
||||
frame->handle = source->handle;
|
||||
frame->cid = source->cid;
|
||||
frame->data = source->data + len;
|
||||
frame->size = source->size - len;
|
||||
}
|
||||
|
||||
void l2cap_packet(uint16_t index, bool in, uint16_t handle, uint8_t flags,
|
||||
const void *data, uint16_t size);
|
||||
549
external/cache/sources/hcitools/monitor/ll.c
vendored
Normal file
549
external/cache/sources/hcitools/monitor/ll.c
vendored
Normal file
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "packet.h"
|
||||
#include "crc.h"
|
||||
#include "bt.h"
|
||||
#include "ll.h"
|
||||
|
||||
#define COLOR_OPCODE COLOR_MAGENTA
|
||||
#define COLOR_OPCODE_UNKNOWN COLOR_WHITE_BG
|
||||
|
||||
#define MAX_CHANNEL 16
|
||||
|
||||
struct channel_data {
|
||||
uint32_t access_addr;
|
||||
uint32_t crc_init;
|
||||
};
|
||||
|
||||
static struct channel_data channel_list[MAX_CHANNEL];
|
||||
|
||||
static void set_crc_init(uint32_t access_addr, uint32_t crc_init)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CHANNEL; i++) {
|
||||
if (channel_list[i].access_addr == 0x00000000 ||
|
||||
channel_list[i].access_addr == access_addr) {
|
||||
channel_list[i].access_addr = access_addr;
|
||||
channel_list[i].crc_init = crc_init;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_crc_init(uint32_t access_addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CHANNEL; i++) {
|
||||
if (channel_list[i].access_addr == access_addr)
|
||||
return channel_list[i].crc_init;
|
||||
}
|
||||
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
static void advertising_packet(const void *data, uint8_t size)
|
||||
{
|
||||
const uint8_t *ptr = data;
|
||||
uint8_t pdu_type, length, win_size, hop, sca;
|
||||
bool tx_add, rx_add;
|
||||
uint32_t access_addr, crc_init;
|
||||
uint16_t win_offset, interval, latency, timeout;
|
||||
const char *str;
|
||||
|
||||
if (size < 2) {
|
||||
print_text(COLOR_ERROR, "packet too short");
|
||||
packet_hexdump(data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
pdu_type = ptr[0] & 0x0f;
|
||||
tx_add = !!(ptr[0] & 0x40);
|
||||
rx_add = !!(ptr[0] & 0x80);
|
||||
length = ptr[1] & 0x3f;
|
||||
|
||||
switch (pdu_type) {
|
||||
case 0x00:
|
||||
str = "ADV_IND";
|
||||
break;
|
||||
case 0x01:
|
||||
str = "ADV_DIRECT_IND";
|
||||
break;
|
||||
case 0x02:
|
||||
str = "ADV_NONCONN_IND";
|
||||
break;
|
||||
case 0x03:
|
||||
str = "SCAN_REQ";
|
||||
break;
|
||||
case 0x04:
|
||||
str = "SCAN_RSP";
|
||||
break;
|
||||
case 0x05:
|
||||
str = "CONNECT_REQ";
|
||||
break;
|
||||
case 0x06:
|
||||
str = "ADV_SCAN_IND";
|
||||
break;
|
||||
default:
|
||||
str = "Reserved";
|
||||
break;
|
||||
}
|
||||
|
||||
print_field("Type: %s (0x%2.2x)", str, pdu_type);
|
||||
print_field("TxAdd: %u", tx_add);
|
||||
print_field("RxAdd: %u", rx_add);
|
||||
print_field("Length: %u", length);
|
||||
|
||||
if (length != size - 2) {
|
||||
print_text(COLOR_ERROR, "packet size mismatch");
|
||||
packet_hexdump(data + 2, size - 2);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (pdu_type) {
|
||||
case 0x00: /* ADV_IND */
|
||||
case 0x02: /* AVD_NONCONN_IND */
|
||||
case 0x06: /* ADV_SCAN_IND */
|
||||
case 0x04: /* SCAN_RSP */
|
||||
if (length < 6) {
|
||||
print_text(COLOR_ERROR, "payload too short");
|
||||
packet_hexdump(data + 2, length);
|
||||
return;
|
||||
}
|
||||
|
||||
packet_print_addr("Advertiser address", data + 2, tx_add);
|
||||
packet_print_ad(data + 8, length - 6);
|
||||
break;
|
||||
|
||||
case 0x01: /* ADV_DIRECT_IND */
|
||||
if (length < 12) {
|
||||
print_text(COLOR_ERROR, "payload too short");
|
||||
packet_hexdump(data + 2, length);
|
||||
return;
|
||||
}
|
||||
|
||||
packet_print_addr("Advertiser address", data + 2, tx_add);
|
||||
packet_print_addr("Inititator address", data + 8, rx_add);
|
||||
break;
|
||||
|
||||
case 0x03: /* SCAN_REQ */
|
||||
if (length < 12) {
|
||||
print_text(COLOR_ERROR, "payload too short");
|
||||
packet_hexdump(data + 2, length);
|
||||
return;
|
||||
}
|
||||
|
||||
packet_print_addr("Scanner address", data + 2, tx_add);
|
||||
packet_print_addr("Advertiser address", data + 8, rx_add);
|
||||
break;
|
||||
|
||||
case 0x05: /* CONNECT_REQ */
|
||||
if (length < 34) {
|
||||
print_text(COLOR_ERROR, "payload too short");
|
||||
packet_hexdump(data + 2, length);
|
||||
return;
|
||||
}
|
||||
|
||||
packet_print_addr("Inititator address", data + 2, tx_add);
|
||||
packet_print_addr("Advertiser address", data + 8, rx_add);
|
||||
|
||||
access_addr = ptr[14] | ptr[15] << 8 |
|
||||
ptr[16] << 16 | ptr[17] << 24;
|
||||
crc_init = ptr[18] | ptr[19] << 8 | ptr[20] << 16;
|
||||
|
||||
print_field("Access address: 0x%8.8x", access_addr);
|
||||
print_field("CRC init: 0x%6.6x", crc_init);
|
||||
|
||||
set_crc_init(access_addr, crc24_bit_reverse(crc_init));
|
||||
|
||||
win_size = ptr[21];
|
||||
win_offset = ptr[22] | ptr[23] << 8;
|
||||
interval = ptr[24] | ptr[25] << 8;
|
||||
latency = ptr[26] | ptr[27] << 8;
|
||||
timeout = ptr[28] | ptr[29] << 8;
|
||||
|
||||
print_field("Transmit window size: %u", win_size);
|
||||
print_field("Transmit window offset: %u", win_offset);
|
||||
print_field("Connection interval: %u", interval);
|
||||
print_field("Connection slave latency: %u", latency);
|
||||
print_field("Connection supervision timeout: %u", timeout);
|
||||
|
||||
packet_print_channel_map_ll(ptr + 30);
|
||||
|
||||
hop = ptr[35] & 0x1f;
|
||||
sca = (ptr[35] & 0xe0) >> 5;
|
||||
|
||||
switch (sca) {
|
||||
case 0:
|
||||
str = "251 ppm to 500 ppm";
|
||||
break;
|
||||
case 1:
|
||||
str = "151 ppm to 250 ppm";
|
||||
break;
|
||||
case 2:
|
||||
str = "101 ppm to 150ppm";
|
||||
break;
|
||||
case 3:
|
||||
str = "76 ppm to 100 ppm";
|
||||
break;
|
||||
case 4:
|
||||
str = "51 ppm to 75 ppm";
|
||||
break;
|
||||
case 5:
|
||||
str = "31 ppm to 50 ppm";
|
||||
break;
|
||||
case 6:
|
||||
str = "21 ppm to 30 ppm";
|
||||
break;
|
||||
case 7:
|
||||
str = "0 ppm to 20 ppm";
|
||||
break;
|
||||
default:
|
||||
str = "Invalid";
|
||||
break;
|
||||
}
|
||||
|
||||
print_field("Hop increment: %u", hop);
|
||||
print_field("Sleep clock accuracy: %s (%u)", str, sca);
|
||||
break;
|
||||
|
||||
default:
|
||||
packet_hexdump(data + 2, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void data_packet(const void *data, uint8_t size)
|
||||
{
|
||||
const uint8_t *ptr = data;
|
||||
uint8_t llid, length;
|
||||
bool nesn, sn, md;
|
||||
const char *str;
|
||||
|
||||
if (size < 2) {
|
||||
print_text(COLOR_ERROR, "packet too short");
|
||||
packet_hexdump(data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
llid = ptr[0] & 0x03;
|
||||
nesn = !!(ptr[0] & 0x04);
|
||||
sn = !!(ptr[0] & 0x08);
|
||||
md = !!(ptr[0] & 0x10);
|
||||
length = ptr[1] & 0x1f;
|
||||
|
||||
switch (llid) {
|
||||
case 0x01:
|
||||
if (length > 0)
|
||||
str = "Continuation fragement of L2CAP message";
|
||||
else
|
||||
str = "Empty message";
|
||||
break;
|
||||
case 0x02:
|
||||
str = "Start of L2CAP message";
|
||||
break;
|
||||
case 0x03:
|
||||
str = "Control";
|
||||
break;
|
||||
default:
|
||||
str = "Reserved";
|
||||
break;
|
||||
}
|
||||
|
||||
print_field("LLID: %s (0x%2.2x)", str, llid);
|
||||
print_field("Next expected sequence number: %u", nesn);
|
||||
print_field("Sequence number: %u", sn);
|
||||
print_field("More data: %u", md);
|
||||
print_field("Length: %u", length);
|
||||
|
||||
switch (llid) {
|
||||
case 0x03:
|
||||
llcp_packet(data + 2, size - 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
packet_hexdump(data + 2, size - 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ll_packet(uint16_t frequency, const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_hdr *hdr = data;
|
||||
uint8_t channel = (frequency - 2402) / 2;
|
||||
uint32_t access_addr;
|
||||
char access_str[12];
|
||||
const char *channel_label, *channel_color;
|
||||
const uint8_t *pdu_data;
|
||||
uint8_t pdu_len;
|
||||
uint32_t pdu_crc, crc, crc_init;
|
||||
|
||||
if (size < sizeof(*hdr)) {
|
||||
print_text(COLOR_ERROR, "packet missing header");
|
||||
packet_hexdump(data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (size < sizeof(*hdr) + 3) {
|
||||
print_text(COLOR_ERROR, "packet missing checksum");
|
||||
packet_hexdump(data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdr->preamble != 0xaa && hdr->preamble != 0x55) {
|
||||
print_text(COLOR_ERROR, "invalid preamble");
|
||||
packet_hexdump(data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
access_addr = btohl(hdr->access_addr);
|
||||
|
||||
pdu_data = data + sizeof(*hdr);
|
||||
pdu_len = size - sizeof(*hdr) - 3;
|
||||
|
||||
pdu_crc = pdu_data[pdu_len + 0] | (pdu_data[pdu_len + 1] << 8) |
|
||||
(pdu_data[pdu_len + 2] << 16);
|
||||
|
||||
if (access_addr == 0x8e89bed6) {
|
||||
channel_label = "Advertising channel: ";
|
||||
channel_color = COLOR_MAGENTA;
|
||||
} else {
|
||||
channel_label = "Data channel: ";
|
||||
channel_color = COLOR_CYAN;
|
||||
}
|
||||
|
||||
sprintf(access_str, "0x%8.8x", access_addr);
|
||||
|
||||
print_indent(6, channel_color, channel_label, access_str, COLOR_OFF,
|
||||
" (channel %d) len %d crc 0x%6.6x", channel, pdu_len, pdu_crc);
|
||||
|
||||
if (access_addr == 0x8e89bed6)
|
||||
crc_init = 0xaaaaaa;
|
||||
else
|
||||
crc_init = get_crc_init(access_addr);
|
||||
|
||||
if (crc_init) {
|
||||
crc = crc24_calculate(crc_init, pdu_data, pdu_len);
|
||||
|
||||
if (crc != pdu_crc) {
|
||||
print_text(COLOR_ERROR, "invalid checksum");
|
||||
packet_hexdump(pdu_data, pdu_len);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
print_text(COLOR_ERROR, "unknown access address");
|
||||
|
||||
if (access_addr == 0x8e89bed6)
|
||||
advertising_packet(pdu_data, pdu_len);
|
||||
else
|
||||
data_packet(pdu_data, pdu_len);
|
||||
}
|
||||
|
||||
static void null_pdu(const void *data, uint8_t size)
|
||||
{
|
||||
}
|
||||
|
||||
static void conn_update_req(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_conn_update_req *pdu = data;
|
||||
|
||||
print_field("Transmit window size: %u", pdu->win_size);
|
||||
print_field("Transmit window offset: %u", btohs(pdu->win_offset));
|
||||
print_field("Connection interval: %u", btohs(pdu->interval));
|
||||
print_field("Connection slave latency: %u", btohs(pdu->latency));
|
||||
print_field("Connection supervision timeout: %u", btohs(pdu->timeout));;
|
||||
print_field("Connection instant: %u", btohs(pdu->instant));
|
||||
}
|
||||
|
||||
static void channel_map_req(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_channel_map_req *pdu = data;
|
||||
|
||||
packet_print_channel_map_ll(pdu->map);
|
||||
print_field("Connection instant: %u", btohs(pdu->instant));
|
||||
}
|
||||
|
||||
static void terminate_ind(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_terminate_ind *pdu = data;
|
||||
|
||||
print_field("Error code: 0x%2.2x", pdu->error);
|
||||
}
|
||||
|
||||
static void enc_req(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_enc_req *pdu = data;
|
||||
|
||||
print_field("Rand: 0x%16.16" PRIx64, btohll(pdu->rand));
|
||||
print_field("EDIV: 0x%4.4x", btohs(pdu->ediv));
|
||||
print_field("SKD (master): 0x%16.16" PRIx64, btohll(pdu->skd));
|
||||
print_field("IV (master): 0x%8.8x", btohl(pdu->iv));
|
||||
}
|
||||
|
||||
static void enc_rsp(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_enc_rsp *pdu = data;
|
||||
|
||||
print_field("SKD (slave): 0x%16.16" PRIx64, btohll(pdu->skd));
|
||||
print_field("IV (slave): 0x%8.8x", btohl(pdu->iv));
|
||||
}
|
||||
|
||||
static const char *opcode_to_string(uint8_t opcode);
|
||||
|
||||
static void unknown_rsp(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_unknown_rsp *pdu = data;
|
||||
|
||||
print_field("Unknown type: %s (0x%2.2x)",
|
||||
opcode_to_string(pdu->type), pdu->type);
|
||||
}
|
||||
|
||||
static void feature_req(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_feature_req *pdu = data;
|
||||
|
||||
packet_print_features_ll(pdu->features);
|
||||
}
|
||||
|
||||
static void feature_rsp(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_feature_rsp *pdu = data;
|
||||
|
||||
packet_print_features_ll(pdu->features);
|
||||
}
|
||||
|
||||
static void version_ind(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_version_ind *pdu = data;
|
||||
|
||||
packet_print_version("Version", pdu->version,
|
||||
"Subversion", btohs(pdu->subversion));
|
||||
packet_print_company("Company", btohs(pdu->company));
|
||||
}
|
||||
|
||||
static void reject_ind(const void *data, uint8_t size)
|
||||
{
|
||||
const struct bt_ll_reject_ind *pdu = data;
|
||||
|
||||
print_field("Error code: 0x%2.2x", pdu->error);
|
||||
}
|
||||
|
||||
struct llcp_data {
|
||||
uint8_t opcode;
|
||||
const char *str;
|
||||
void (*func) (const void *data, uint8_t size);
|
||||
uint8_t size;
|
||||
bool fixed;
|
||||
};
|
||||
|
||||
static const struct llcp_data llcp_table[] = {
|
||||
{ 0x00, "LL_CONNECTION_UPDATE_REQ", conn_update_req, 11, true },
|
||||
{ 0x01, "LL_CHANNEL_MAP_REQ", channel_map_req, 7, true },
|
||||
{ 0x02, "LL_TERMINATE_IND", terminate_ind, 1, true },
|
||||
{ 0x03, "LL_ENC_REQ", enc_req, 22, true },
|
||||
{ 0x04, "LL_ENC_RSP", enc_rsp, 12, true },
|
||||
{ 0x05, "LL_START_ENC_REQ", null_pdu, 0, true },
|
||||
{ 0x06, "LL_START_ENC_RSP", null_pdu, 0, true },
|
||||
{ 0x07, "LL_UNKNOWN_RSP", unknown_rsp, 1, true },
|
||||
{ 0x08, "LL_FEATURE_REQ", feature_req, 8, true },
|
||||
{ 0x09, "LL_FEATURE_RSP", feature_rsp, 8, true },
|
||||
{ 0x0a, "LL_PAUSE_ENC_REQ", null_pdu, 0, true },
|
||||
{ 0x0b, "LL_PAUSE_ENC_RSP", null_pdu, 0, true },
|
||||
{ 0x0c, "LL_VERSION_IND", version_ind, 5, true },
|
||||
{ 0x0d, "LL_REJECT_IND", reject_ind, 1, true },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const char *opcode_to_string(uint8_t opcode)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; llcp_table[i].str; i++) {
|
||||
if (llcp_table[i].opcode == opcode)
|
||||
return llcp_table[i].str;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
void llcp_packet(const void *data, uint8_t size)
|
||||
{
|
||||
uint8_t opcode = ((const uint8_t *) data)[0];
|
||||
const struct llcp_data *llcp_data = NULL;
|
||||
const char *opcode_color, *opcode_str;
|
||||
int i;
|
||||
|
||||
for (i = 0; llcp_table[i].str; i++) {
|
||||
if (llcp_table[i].opcode == opcode) {
|
||||
llcp_data = &llcp_table[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (llcp_data) {
|
||||
if (llcp_data->func)
|
||||
opcode_color = COLOR_OPCODE;
|
||||
else
|
||||
opcode_color = COLOR_OPCODE_UNKNOWN;
|
||||
opcode_str = llcp_data->str;
|
||||
} else {
|
||||
opcode_color = COLOR_OPCODE_UNKNOWN;
|
||||
opcode_str = "Unknown";
|
||||
}
|
||||
|
||||
print_indent(6, opcode_color, "", opcode_str, COLOR_OFF,
|
||||
" (0x%2.2x)", opcode);
|
||||
|
||||
if (!llcp_data || !llcp_data->func) {
|
||||
packet_hexdump(data + 1, size - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (llcp_data->fixed) {
|
||||
if (size - 1 != llcp_data->size) {
|
||||
print_text(COLOR_ERROR, "invalid packet size");
|
||||
packet_hexdump(data + 1, size - 1);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (size - 1 < llcp_data->size) {
|
||||
print_text(COLOR_ERROR, "too short packet");
|
||||
packet_hexdump(data + 1, size - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
llcp_data->func(data + 1, size - 1);
|
||||
}
|
||||
28
external/cache/sources/hcitools/monitor/ll.h
vendored
Normal file
28
external/cache/sources/hcitools/monitor/ll.h
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void ll_packet(uint16_t frequency, const void *data, uint8_t size);
|
||||
void llcp_packet(const void *data, uint8_t size);
|
||||
215
external/cache/sources/hcitools/monitor/lmp.c
vendored
Normal file
215
external/cache/sources/hcitools/monitor/lmp.c
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "packet.h"
|
||||
#include "lmp.h"
|
||||
|
||||
#define COLOR_OPCODE COLOR_MAGENTA
|
||||
#define COLOR_OPCODE_UNKNOWN COLOR_WHITE_BG
|
||||
|
||||
#define ESC4(x) ((127 << 8) | (x))
|
||||
|
||||
struct lmp_data {
|
||||
uint16_t opcode;
|
||||
const char *str;
|
||||
void (*func) (const void *data, uint8_t size);
|
||||
uint8_t size;
|
||||
bool fixed;
|
||||
};
|
||||
|
||||
static const struct lmp_data lmp_table[] = {
|
||||
{ 1, "LMP_name_req" },
|
||||
{ 2, "LMP_name_res" },
|
||||
{ 3, "LMP_accepted" },
|
||||
{ 4, "LMP_not_accepted" },
|
||||
{ 5, "LMP_clkoffset_req" },
|
||||
{ 6, "LMP_clkoffset_res" },
|
||||
{ 7, "LMP_detach" },
|
||||
{ 8, "LMP_in_rand" },
|
||||
{ 9, "LMP_comb_key" },
|
||||
{ 10, "LMP_unit_key" },
|
||||
{ 11, "LMP_au_rand" },
|
||||
{ 12, "LMP_sres" },
|
||||
{ 13, "LMP_temp_rand" },
|
||||
{ 14, "LMP_temp_key" },
|
||||
{ 15, "LMP_encryption_mode_req" },
|
||||
{ 16, "LMP_encryption_key_size_req" },
|
||||
{ 17, "LMP_start_encryption_req" },
|
||||
{ 18, "LMP_stop_encryption_req" },
|
||||
{ 19, "LMP_switch_req" },
|
||||
{ 20, "LMP_hold" },
|
||||
{ 21, "LMP_hold_req" },
|
||||
{ 22, "LMP_sniff" },
|
||||
{ 23, "LMP_sniff_req" },
|
||||
{ 24, "LMP_unsniff_req" },
|
||||
{ 25, "LMP_park_req" },
|
||||
{ 26, "LMP_park" },
|
||||
{ 27, "LMP_set_broadcast_scan_window" },
|
||||
{ 28, "LMP_modify_beacon" },
|
||||
{ 29, "LMP_unpark_BD_ADDR_req" },
|
||||
{ 30, "LMP_unpark_PM_ADDR_req" },
|
||||
{ 31, "LMP_incr_power_req" },
|
||||
{ 32, "LMP_decr_power_req" },
|
||||
{ 33, "LMP_max_power" },
|
||||
{ 34, "LMP_min_power" },
|
||||
{ 35, "LMP_auto_rate" },
|
||||
{ 36, "LMP_preferred_rate" },
|
||||
{ 37, "LMP_version_req" },
|
||||
{ 38, "LMP_version_res" },
|
||||
{ 39, "LMP_features_req" },
|
||||
{ 40, "LMP_features_res" },
|
||||
{ 41, "LMP_quality_of_service" },
|
||||
{ 42, "LMP_quality_of_service_req" },
|
||||
{ 43, "LMP_SCO_link_req" },
|
||||
{ 44, "LMP_remove_SCO_link_req" },
|
||||
{ 45, "LMP_max_slot" },
|
||||
{ 46, "LMP_max_slot_req" },
|
||||
{ 47, "LMP_timing_accuracy_req" },
|
||||
{ 48, "LMP_timing_accuracy_res" },
|
||||
{ 49, "LMP_setup_complete" },
|
||||
{ 50, "LMP_use_semi_permanent_key" },
|
||||
{ 51, "LMP_host_connection_req" },
|
||||
{ 52, "LMP_slot_offset" },
|
||||
{ 53, "LMP_page_mode_req" },
|
||||
{ 54, "LMP_Page_scan_mode_req" },
|
||||
{ 55, "LMP_supervision_timeout" },
|
||||
{ 56, "LMP_test_activate" },
|
||||
{ 57, "LMP_test_control" },
|
||||
{ 58, "LMP_encryption_key_size_mask_req" },
|
||||
{ 59, "LMP_encryption_key_size_mask_res" },
|
||||
{ 60, "LMP_set_AFH" },
|
||||
{ 61, "LMP_encapsulated_header" },
|
||||
{ 62, "LMP_encapsulated_payload" },
|
||||
{ 63, "LMP_simple_pairing_confirm" },
|
||||
{ 64, "LMP_simple_pairing_number" },
|
||||
{ 65, "LMP_DHkey_check" },
|
||||
{ 66, "LMP_pause_encryption_aes_req" },
|
||||
{ ESC4(1), "LMP_accepted_ext" },
|
||||
{ ESC4(2), "LMP_not_accepted_ext" },
|
||||
{ ESC4(3), "LMP_features_req_ext" },
|
||||
{ ESC4(4), "LMP_features_res_ext" },
|
||||
{ ESC4(5), "LMP_clk_adj" },
|
||||
{ ESC4(6), "LMP_clk_adj_ack" },
|
||||
{ ESC4(7), "LMP_clk_adj_req" },
|
||||
{ ESC4(11), "LMP_packet_type_table" },
|
||||
{ ESC4(12), "LMP_eSCO_link_req" },
|
||||
{ ESC4(13), "LMP_remove_eSCO_link_req" },
|
||||
{ ESC4(16), "LMP_channel_classification_req" },
|
||||
{ ESC4(17), "LMP_channel_classification" },
|
||||
{ ESC4(21), "LMP_sniff_subrating_req" },
|
||||
{ ESC4(22), "LMP_sniff_subrating_res" },
|
||||
{ ESC4(23), "LMP_pause_encryption_req" },
|
||||
{ ESC4(24), "LMP_resume_encryption_req" },
|
||||
{ ESC4(25), "LMP_IO_capability_req" },
|
||||
{ ESC4(26), "LMP_IO_capability_res" },
|
||||
{ ESC4(27), "LMP_numeric_comparision_failed" },
|
||||
{ ESC4(28), "LMP_passkey_failed" },
|
||||
{ ESC4(29), "LMP_oob_failed" },
|
||||
{ ESC4(30), "LMP_keypress_notification" },
|
||||
{ ESC4(31), "LMP_power_control_req" },
|
||||
{ ESC4(32), "LMP_power_control_res" },
|
||||
{ ESC4(33), "LMP_ping_req" },
|
||||
{ ESC4(34), "LMP_ping_res" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
void lmp_packet(const void *data, uint8_t size)
|
||||
{
|
||||
const struct lmp_data *lmp_data = NULL;
|
||||
const char *opcode_color, *opcode_str;
|
||||
uint16_t opcode;
|
||||
uint8_t tid, off;
|
||||
int i;
|
||||
|
||||
tid = ((const uint8_t *) data)[0] & 0x01;
|
||||
opcode = (((const uint8_t *) data)[0] & 0xfe) >> 1;
|
||||
|
||||
switch (opcode) {
|
||||
case 127:
|
||||
opcode = ESC4(((const uint8_t *) data)[1]);
|
||||
off = 2;
|
||||
break;
|
||||
case 126:
|
||||
case 125:
|
||||
case 124:
|
||||
return;
|
||||
default:
|
||||
off = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; lmp_table[i].str; i++) {
|
||||
if (lmp_table[i].opcode == opcode) {
|
||||
lmp_data = &lmp_table[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lmp_data) {
|
||||
if (lmp_data->func)
|
||||
opcode_color = COLOR_OPCODE;
|
||||
else
|
||||
opcode_color = COLOR_OPCODE_UNKNOWN;
|
||||
opcode_str = lmp_data->str;
|
||||
} else {
|
||||
opcode_color = COLOR_OPCODE_UNKNOWN;
|
||||
opcode_str = "Unknown";
|
||||
}
|
||||
|
||||
if (opcode & 0xff00)
|
||||
print_indent(6, opcode_color, "", opcode_str, COLOR_OFF,
|
||||
" (%d/%d) TID %d", opcode >> 8, opcode & 0xff, tid);
|
||||
else
|
||||
print_indent(6, opcode_color, "", opcode_str, COLOR_OFF,
|
||||
" (%d) TID %d", opcode, tid);
|
||||
|
||||
if (!lmp_data || !lmp_data->func) {
|
||||
packet_hexdump(data + off, size - off);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lmp_data->fixed) {
|
||||
if (size - 1 != lmp_data->size) {
|
||||
print_text(COLOR_ERROR, "invalid packet size");
|
||||
packet_hexdump(data + off, size - off);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (size - 1 < lmp_data->size) {
|
||||
print_text(COLOR_ERROR, "too short packet");
|
||||
packet_hexdump(data + off, size - off);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lmp_data->func(data + off, size - off);
|
||||
}
|
||||
27
external/cache/sources/hcitools/monitor/lmp.h
vendored
Normal file
27
external/cache/sources/hcitools/monitor/lmp.h
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void lmp_packet(const void *data, uint8_t size);
|
||||
167
external/cache/sources/hcitools/monitor/main.c
vendored
Normal file
167
external/cache/sources/hcitools/monitor/main.c
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "mainloop.h"
|
||||
#include "packet.h"
|
||||
#include "control.h"
|
||||
|
||||
static void signal_callback(int signum, void *user_data)
|
||||
{
|
||||
switch (signum) {
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
mainloop_quit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
printf("btmon - Bluetooth monitor\n"
|
||||
"Usage:\n");
|
||||
printf("\tbtmon [options]\n");
|
||||
printf("options:\n"
|
||||
"\t-r, --read <file> Read traces in btsnoop format\n"
|
||||
"\t-w, --write <file> Save traces in btsnoop format\n"
|
||||
"\t-s, --server <socket> Start monitor server socket\n"
|
||||
"\t-i, --index <num> Show only specified controller\n"
|
||||
"\t-t, --time Show time instead of time offset\n"
|
||||
"\t-T, --date Show time and date information\n"
|
||||
"\t-S, --sco Dump SCO traffic\n"
|
||||
"\t-h, --help Show help options\n");
|
||||
}
|
||||
|
||||
static const struct option main_options[] = {
|
||||
{ "read", required_argument, NULL, 'r' },
|
||||
{ "write", required_argument, NULL, 'w' },
|
||||
{ "server", required_argument, NULL, 's' },
|
||||
{ "index", required_argument, NULL, 'i' },
|
||||
{ "time", no_argument, NULL, 't' },
|
||||
{ "date", no_argument, NULL, 'T' },
|
||||
{ "sco", no_argument, NULL, 'S' },
|
||||
{ "version", no_argument, NULL, 'v' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ }
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned long filter_mask = 0;
|
||||
const char *str, *reader_path = NULL, *writer_path = NULL;
|
||||
sigset_t mask;
|
||||
|
||||
mainloop_init();
|
||||
|
||||
filter_mask |= PACKET_FILTER_SHOW_TIME_OFFSET;
|
||||
|
||||
for (;;) {
|
||||
int opt;
|
||||
|
||||
opt = getopt_long(argc, argv, "r:w:s:i:tTSvh",
|
||||
main_options, NULL);
|
||||
if (opt < 0)
|
||||
break;
|
||||
|
||||
switch (opt) {
|
||||
case 'r':
|
||||
reader_path = optarg;
|
||||
break;
|
||||
case 'w':
|
||||
writer_path = optarg;
|
||||
break;
|
||||
case 's':
|
||||
control_server(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
|
||||
str = optarg + 3;
|
||||
else
|
||||
str = optarg;
|
||||
if (!isdigit(*str)) {
|
||||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
packet_select_index(atoi(str));
|
||||
break;
|
||||
case 't':
|
||||
filter_mask &= ~PACKET_FILTER_SHOW_TIME_OFFSET;
|
||||
filter_mask |= PACKET_FILTER_SHOW_TIME;
|
||||
break;
|
||||
case 'T':
|
||||
filter_mask &= ~PACKET_FILTER_SHOW_TIME_OFFSET;
|
||||
filter_mask |= PACKET_FILTER_SHOW_TIME;
|
||||
filter_mask |= PACKET_FILTER_SHOW_DATE;
|
||||
break;
|
||||
case 'S':
|
||||
filter_mask |= PACKET_FILTER_SHOW_SCO_DATA;
|
||||
break;
|
||||
case 'v':
|
||||
printf("%s\n", VERSION);
|
||||
return EXIT_SUCCESS;
|
||||
case 'h':
|
||||
usage();
|
||||
return EXIT_SUCCESS;
|
||||
default:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind > 0) {
|
||||
fprintf(stderr, "Invalid command line parameters\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
|
||||
mainloop_set_signal(&mask, signal_callback, NULL, NULL);
|
||||
|
||||
printf("Bluetooth monitor ver %s\n", VERSION);
|
||||
|
||||
packet_set_filter(filter_mask);
|
||||
|
||||
if (reader_path) {
|
||||
control_reader(reader_path);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (writer_path)
|
||||
control_writer(writer_path);
|
||||
|
||||
if (control_tracing() < 0)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
return mainloop_run();
|
||||
}
|
||||
389
external/cache/sources/hcitools/monitor/mainloop.c
vendored
Normal file
389
external/cache/sources/hcitools/monitor/mainloop.c
vendored
Normal file
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#include "mainloop.h"
|
||||
|
||||
#define MAX_EPOLL_EVENTS 10
|
||||
|
||||
static int epoll_fd;
|
||||
static int epoll_terminate;
|
||||
|
||||
struct mainloop_data {
|
||||
int fd;
|
||||
uint32_t events;
|
||||
mainloop_event_func callback;
|
||||
mainloop_destroy_func destroy;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
#define MAX_MAINLOOP_ENTRIES 128
|
||||
|
||||
static struct mainloop_data *mainloop_list[MAX_MAINLOOP_ENTRIES];
|
||||
|
||||
struct timeout_data {
|
||||
int fd;
|
||||
mainloop_timeout_func callback;
|
||||
mainloop_destroy_func destroy;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
struct signal_data {
|
||||
int fd;
|
||||
sigset_t mask;
|
||||
mainloop_signal_func callback;
|
||||
mainloop_destroy_func destroy;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
static struct signal_data *signal_data;
|
||||
|
||||
void mainloop_init(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
||||
|
||||
for (i = 0; i < MAX_MAINLOOP_ENTRIES; i++)
|
||||
mainloop_list[i] = NULL;
|
||||
|
||||
epoll_terminate = 0;
|
||||
}
|
||||
|
||||
void mainloop_quit(void)
|
||||
{
|
||||
epoll_terminate = 1;
|
||||
}
|
||||
|
||||
static void signal_callback(int fd, uint32_t events, void *user_data)
|
||||
{
|
||||
struct signal_data *data = user_data;
|
||||
struct signalfd_siginfo si;
|
||||
ssize_t result;
|
||||
|
||||
if (events & (EPOLLERR | EPOLLHUP)) {
|
||||
mainloop_quit();
|
||||
return;
|
||||
}
|
||||
|
||||
result = read(fd, &si, sizeof(si));
|
||||
if (result != sizeof(si))
|
||||
return;
|
||||
|
||||
if (data->callback)
|
||||
data->callback(si.ssi_signo, data->user_data);
|
||||
}
|
||||
|
||||
int mainloop_run(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (signal_data) {
|
||||
if (sigprocmask(SIG_BLOCK, &signal_data->mask, NULL) < 0)
|
||||
return 1;
|
||||
|
||||
signal_data->fd = signalfd(-1, &signal_data->mask,
|
||||
SFD_NONBLOCK | SFD_CLOEXEC);
|
||||
if (signal_data->fd < 0)
|
||||
return 1;
|
||||
|
||||
if (mainloop_add_fd(signal_data->fd, EPOLLIN,
|
||||
signal_callback, signal_data, NULL) < 0) {
|
||||
close(signal_data->fd);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
while (!epoll_terminate) {
|
||||
struct epoll_event events[MAX_EPOLL_EVENTS];
|
||||
int n, nfds;
|
||||
|
||||
nfds = epoll_wait(epoll_fd, events, MAX_EPOLL_EVENTS, -1);
|
||||
if (nfds < 0)
|
||||
continue;
|
||||
|
||||
for (n = 0; n < nfds; n++) {
|
||||
struct mainloop_data *data = events[n].data.ptr;
|
||||
|
||||
data->callback(data->fd, events[n].events,
|
||||
data->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
if (signal_data) {
|
||||
mainloop_remove_fd(signal_data->fd);
|
||||
close(signal_data->fd);
|
||||
|
||||
if (signal_data->destroy)
|
||||
signal_data->destroy(signal_data->user_data);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_MAINLOOP_ENTRIES; i++) {
|
||||
struct mainloop_data *data = mainloop_list[i];
|
||||
|
||||
mainloop_list[i] = NULL;
|
||||
|
||||
if (data) {
|
||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, data->fd, NULL);
|
||||
|
||||
if (data->destroy)
|
||||
data->destroy(data->user_data);
|
||||
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
close(epoll_fd);
|
||||
epoll_fd = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mainloop_add_fd(int fd, uint32_t events, mainloop_event_func callback,
|
||||
void *user_data, mainloop_destroy_func destroy)
|
||||
{
|
||||
struct mainloop_data *data;
|
||||
struct epoll_event ev;
|
||||
int err;
|
||||
|
||||
if (fd < 0 || fd > MAX_MAINLOOP_ENTRIES - 1 || !callback)
|
||||
return -EINVAL;
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->fd = fd;
|
||||
data->events = events;
|
||||
data->callback = callback;
|
||||
data->destroy = destroy;
|
||||
data->user_data = user_data;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.events = events;
|
||||
ev.data.ptr = data;
|
||||
|
||||
err = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, data->fd, &ev);
|
||||
if (err < 0) {
|
||||
free(data);
|
||||
return err;
|
||||
}
|
||||
|
||||
mainloop_list[fd] = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mainloop_modify_fd(int fd, uint32_t events)
|
||||
{
|
||||
struct mainloop_data *data;
|
||||
struct epoll_event ev;
|
||||
int err;
|
||||
|
||||
if (fd < 0 || fd > MAX_MAINLOOP_ENTRIES - 1)
|
||||
return -EINVAL;
|
||||
|
||||
data = mainloop_list[fd];
|
||||
if (!data)
|
||||
return -ENXIO;
|
||||
|
||||
if (data->events == events)
|
||||
return 0;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.events = events;
|
||||
ev.data.ptr = data;
|
||||
|
||||
err = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, data->fd, &ev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
data->events = events;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mainloop_remove_fd(int fd)
|
||||
{
|
||||
struct mainloop_data *data;
|
||||
int err;
|
||||
|
||||
if (fd < 0 || fd > MAX_MAINLOOP_ENTRIES - 1)
|
||||
return -EINVAL;
|
||||
|
||||
data = mainloop_list[fd];
|
||||
if (!data)
|
||||
return -ENXIO;
|
||||
|
||||
mainloop_list[fd] = NULL;
|
||||
|
||||
err = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, data->fd, NULL);
|
||||
|
||||
if (data->destroy)
|
||||
data->destroy(data->user_data);
|
||||
|
||||
free(data);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void timeout_destroy(void *user_data)
|
||||
{
|
||||
struct timeout_data *data = user_data;
|
||||
|
||||
close(data->fd);
|
||||
data->fd = -1;
|
||||
|
||||
if (data->destroy)
|
||||
data->destroy(data->user_data);
|
||||
}
|
||||
|
||||
static void timeout_callback(int fd, uint32_t events, void *user_data)
|
||||
{
|
||||
struct timeout_data *data = user_data;
|
||||
uint64_t expired;
|
||||
ssize_t result;
|
||||
|
||||
if (events & (EPOLLERR | EPOLLHUP))
|
||||
return;
|
||||
|
||||
result = read(data->fd, &expired, sizeof(expired));
|
||||
if (result != sizeof(expired))
|
||||
return;
|
||||
|
||||
if (data->callback)
|
||||
data->callback(data->fd, data->user_data);
|
||||
}
|
||||
|
||||
static inline int timeout_set(int fd, unsigned int seconds)
|
||||
{
|
||||
struct itimerspec itimer;
|
||||
|
||||
memset(&itimer, 0, sizeof(itimer));
|
||||
itimer.it_interval.tv_sec = 0;
|
||||
itimer.it_interval.tv_nsec = 0;
|
||||
itimer.it_value.tv_sec = seconds;
|
||||
itimer.it_value.tv_nsec = 0;
|
||||
|
||||
return timerfd_settime(fd, 0, &itimer, NULL);
|
||||
}
|
||||
|
||||
int mainloop_add_timeout(unsigned int seconds, mainloop_timeout_func callback,
|
||||
void *user_data, mainloop_destroy_func destroy)
|
||||
{
|
||||
struct timeout_data *data;
|
||||
|
||||
if (!callback)
|
||||
return -EINVAL;
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->callback = callback;
|
||||
data->destroy = destroy;
|
||||
data->user_data = user_data;
|
||||
|
||||
data->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
|
||||
if (data->fd < 0) {
|
||||
free(data);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (seconds > 0) {
|
||||
if (timeout_set(data->fd, seconds) < 0) {
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
if (mainloop_add_fd(data->fd, EPOLLIN | EPOLLONESHOT,
|
||||
timeout_callback, data, timeout_destroy) < 0) {
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return data->fd;
|
||||
}
|
||||
|
||||
int mainloop_modify_timeout(int id, unsigned int seconds)
|
||||
{
|
||||
if (seconds > 0) {
|
||||
if (timeout_set(id, seconds) < 0)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (mainloop_modify_fd(id, EPOLLIN | EPOLLONESHOT) < 0)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mainloop_remove_timeout(int id)
|
||||
{
|
||||
return mainloop_remove_fd(id);
|
||||
}
|
||||
|
||||
int mainloop_set_signal(sigset_t *mask, mainloop_signal_func callback,
|
||||
void *user_data, mainloop_destroy_func destroy)
|
||||
{
|
||||
struct signal_data *data;
|
||||
|
||||
if (!mask || !callback)
|
||||
return -EINVAL;
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->callback = callback;
|
||||
data->destroy = destroy;
|
||||
data->user_data = user_data;
|
||||
|
||||
data->fd = -1;
|
||||
memcpy(&data->mask, mask, sizeof(sigset_t));
|
||||
|
||||
free(signal_data);
|
||||
signal_data = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
49
external/cache/sources/hcitools/monitor/mainloop.h
vendored
Normal file
49
external/cache/sources/hcitools/monitor/mainloop.h
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
typedef void (*mainloop_destroy_func) (void *user_data);
|
||||
|
||||
typedef void (*mainloop_event_func) (int fd, uint32_t events, void *user_data);
|
||||
typedef void (*mainloop_timeout_func) (int id, void *user_data);
|
||||
typedef void (*mainloop_signal_func) (int signum, void *user_data);
|
||||
|
||||
void mainloop_init(void);
|
||||
void mainloop_quit(void);
|
||||
int mainloop_run(void);
|
||||
|
||||
int mainloop_add_fd(int fd, uint32_t events, mainloop_event_func callback,
|
||||
void *user_data, mainloop_destroy_func destroy);
|
||||
int mainloop_modify_fd(int fd, uint32_t events);
|
||||
int mainloop_remove_fd(int fd);
|
||||
|
||||
int mainloop_add_timeout(unsigned int seconds, mainloop_timeout_func callback,
|
||||
void *user_data, mainloop_destroy_func destroy);
|
||||
int mainloop_modify_timeout(int fd, unsigned int seconds);
|
||||
int mainloop_remove_timeout(int id);
|
||||
|
||||
int mainloop_set_signal(sigset_t *mask, mainloop_signal_func callback,
|
||||
void *user_data, mainloop_destroy_func destroy);
|
||||
6474
external/cache/sources/hcitools/monitor/packet.c
vendored
Normal file
6474
external/cache/sources/hcitools/monitor/packet.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
69
external/cache/sources/hcitools/monitor/packet.h
vendored
Normal file
69
external/cache/sources/hcitools/monitor/packet.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define PACKET_FILTER_SHOW_INDEX (1 << 0)
|
||||
#define PACKET_FILTER_SHOW_DATE (1 << 1)
|
||||
#define PACKET_FILTER_SHOW_TIME (1 << 2)
|
||||
#define PACKET_FILTER_SHOW_TIME_OFFSET (1 << 3)
|
||||
#define PACKET_FILTER_SHOW_ACL_DATA (1 << 4)
|
||||
#define PACKET_FILTER_SHOW_SCO_DATA (1 << 5)
|
||||
|
||||
void packet_set_filter(unsigned long filter);
|
||||
void packet_add_filter(unsigned long filter);
|
||||
void packet_del_filter(unsigned long filter);
|
||||
|
||||
void packet_select_index(uint16_t index);
|
||||
|
||||
void packet_hexdump(const unsigned char *buf, uint16_t len);
|
||||
void packet_print_version(const char *label, uint8_t version,
|
||||
const char *sublabel, uint16_t subversion);
|
||||
void packet_print_company(const char *label, uint16_t company);
|
||||
void packet_print_addr(const char *label, const void *data, bool random);
|
||||
void packet_print_ad(const void *data, uint8_t size);
|
||||
void packet_print_features_ll(const uint8_t *features);
|
||||
void packet_print_channel_map_ll(const uint8_t *map);
|
||||
|
||||
void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode,
|
||||
const void *data, uint16_t size);
|
||||
void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode,
|
||||
const void *data, uint16_t size);
|
||||
void packet_simulator(struct timeval *tv, uint16_t frequency,
|
||||
const void *data, uint16_t size);
|
||||
|
||||
void packet_new_index(struct timeval *tv, uint16_t index, const char *label,
|
||||
uint8_t type, uint8_t bus, const char *name);
|
||||
void packet_del_index(struct timeval *tv, uint16_t index, const char *label);
|
||||
|
||||
void packet_hci_command(struct timeval *tv, uint16_t index,
|
||||
const void *data, uint16_t size);
|
||||
void packet_hci_event(struct timeval *tv, uint16_t index,
|
||||
const void *data, uint16_t size);
|
||||
void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in,
|
||||
const void *data, uint16_t size);
|
||||
void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in,
|
||||
const void *data, uint16_t size);
|
||||
748
external/cache/sources/hcitools/monitor/sdp.c
vendored
Normal file
748
external/cache/sources/hcitools/monitor/sdp.c
vendored
Normal file
@@ -0,0 +1,748 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
#include "bt.h"
|
||||
#include "packet.h"
|
||||
#include "display.h"
|
||||
#include "l2cap.h"
|
||||
#include "uuid.h"
|
||||
#include "sdp.h"
|
||||
|
||||
#define MAX_TID 16
|
||||
|
||||
struct tid_data {
|
||||
bool inuse;
|
||||
uint16_t tid;
|
||||
uint16_t channel;
|
||||
uint8_t cont[17];
|
||||
};
|
||||
|
||||
static struct tid_data tid_list[MAX_TID];
|
||||
|
||||
static struct tid_data *get_tid(uint16_t tid, uint16_t channel)
|
||||
{
|
||||
int i, n = -1;
|
||||
|
||||
for (i = 0; i < MAX_TID; i++) {
|
||||
if (!tid_list[i].inuse) {
|
||||
if (n < 0)
|
||||
n = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tid_list[i].tid == tid && tid_list[i].channel == channel)
|
||||
return &tid_list[i];
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
|
||||
tid_list[n].inuse = true;
|
||||
tid_list[n].tid = tid;
|
||||
tid_list[n].channel = channel;
|
||||
|
||||
return &tid_list[n];
|
||||
}
|
||||
|
||||
static void clear_tid(struct tid_data *tid)
|
||||
{
|
||||
if (tid)
|
||||
tid->inuse = false;
|
||||
}
|
||||
|
||||
static void print_uint(uint8_t indent, const uint8_t *data, uint32_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
print_field("%*c0x%2.2x", indent, ' ', data[0]);
|
||||
break;
|
||||
case 2:
|
||||
print_field("%*c0x%4.4x", indent, ' ', bt_get_be16(data));
|
||||
break;
|
||||
case 4:
|
||||
print_field("%*c0x%8.8x", indent, ' ', bt_get_be32(data));
|
||||
break;
|
||||
case 8:
|
||||
print_field("%*c0x%16.16" PRIx64, indent, ' ',
|
||||
bt_get_be64(data));
|
||||
break;
|
||||
default:
|
||||
packet_hexdump(data, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_sint(uint8_t indent, const uint8_t *data, uint32_t size)
|
||||
{
|
||||
packet_hexdump(data, size);
|
||||
}
|
||||
|
||||
static void print_uuid(uint8_t indent, const uint8_t *data, uint32_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 2:
|
||||
print_field("%*c%s (0x%4.4x)", indent, ' ',
|
||||
uuid16_to_str(bt_get_be16(data)), bt_get_be16(data));
|
||||
break;
|
||||
case 4:
|
||||
print_field("%*c%s (0x%8.8x)", indent, ' ',
|
||||
uuid32_to_str(bt_get_be32(data)), bt_get_be32(data));
|
||||
break;
|
||||
case 16:
|
||||
/* BASE_UUID = 00000000-0000-1000-8000-00805F9B34FB */
|
||||
print_field("%*c%8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.4x",
|
||||
indent, ' ',
|
||||
bt_get_be32(data), bt_get_be16(data + 4),
|
||||
bt_get_be16(data + 6), bt_get_be16(data + 8),
|
||||
bt_get_be16(data + 10), bt_get_be32(data + 12));
|
||||
if (bt_get_be16(data + 4) == 0x0000 &&
|
||||
bt_get_be16(data + 6) == 0x1000 &&
|
||||
bt_get_be16(data + 8) == 0x8000 &&
|
||||
bt_get_be16(data + 10) == 0x0080 &&
|
||||
bt_get_be32(data + 12) == 0x5F9B34FB)
|
||||
print_field("%*c%s", indent, ' ',
|
||||
uuid32_to_str(bt_get_be32(data)));
|
||||
break;
|
||||
default:
|
||||
packet_hexdump(data, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_string(uint8_t indent, const uint8_t *data, uint32_t size)
|
||||
{
|
||||
char *str = alloca(size + 1);
|
||||
|
||||
str[size] = '\0';
|
||||
strncpy(str, (const char *) data, size);
|
||||
|
||||
print_field("%*c%s [len %d]", indent, ' ', str, size);
|
||||
}
|
||||
|
||||
static void print_boolean(uint8_t indent, const uint8_t *data, uint32_t size)
|
||||
{
|
||||
print_field("%*c%s", indent, ' ', data[0] ? "true" : "false");
|
||||
}
|
||||
|
||||
#define SIZES(args...) ((uint8_t[]) { args, 0xff } )
|
||||
|
||||
static struct {
|
||||
uint8_t value;
|
||||
uint8_t *sizes;
|
||||
bool recurse;
|
||||
const char *str;
|
||||
void (*print) (uint8_t indent, const uint8_t *data, uint32_t size);
|
||||
} type_table[] = {
|
||||
{ 0, SIZES(0), false, "Nil" },
|
||||
{ 1, SIZES(0, 1, 2, 3, 4), false, "Unsigned Integer", print_uint },
|
||||
{ 2, SIZES(0, 1, 2, 3, 4), false, "Signed Integer", print_sint },
|
||||
{ 3, SIZES(1, 2, 4), false, "UUID", print_uuid },
|
||||
{ 4, SIZES(5, 6, 7), false, "String", print_string },
|
||||
{ 5, SIZES(0), false, "Boolean", print_boolean },
|
||||
{ 6, SIZES(5, 6, 7), true, "Sequence" },
|
||||
{ 7, SIZES(5, 6, 7), true, "Alternative" },
|
||||
{ 8, SIZES(5, 6, 7), false, "URL", print_string },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct {
|
||||
uint8_t index;
|
||||
uint8_t bits;
|
||||
uint8_t size;
|
||||
const char *str;
|
||||
} size_table[] = {
|
||||
{ 0, 0, 1, "1 byte" },
|
||||
{ 1, 0, 2, "2 bytes" },
|
||||
{ 2, 0, 4, "4 bytes" },
|
||||
{ 3, 0, 8, "8 bytes" },
|
||||
{ 4, 0, 16, "16 bytes" },
|
||||
{ 5, 8, 0, "8 bits" },
|
||||
{ 6, 16, 0, "16 bits" },
|
||||
{ 7, 32, 0, "32 bits" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static bool valid_size(uint8_t size, uint8_t *sizes)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; sizes[i] != 0xff; i++) {
|
||||
if (sizes[i] == size)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint8_t get_bits(const uint8_t *data, uint32_t size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; size_table[i].str; i++) {
|
||||
if (size_table[i].index == (data[0] & 0x07))
|
||||
return size_table[i].bits;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t get_size(const uint8_t *data, uint32_t size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; size_table[i].str; i++) {
|
||||
if (size_table[i].index == (data[0] & 0x07)) {
|
||||
switch (size_table[i].bits) {
|
||||
case 0:
|
||||
if ((data[0] & 0xf8) == 0)
|
||||
return 0;
|
||||
else
|
||||
return size_table[i].size;
|
||||
case 8:
|
||||
return data[1];
|
||||
case 16:
|
||||
return bt_get_be16(data + 1);
|
||||
case 32:
|
||||
return bt_get_be32(data + 1);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void decode_data_elements(uint32_t position, uint8_t indent,
|
||||
const uint8_t *data, uint32_t size,
|
||||
void (*print_func) (uint32_t, uint8_t, uint8_t,
|
||||
const uint8_t *, uint32_t))
|
||||
|
||||
{
|
||||
uint32_t datalen, elemlen, extrabits;
|
||||
int i;
|
||||
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
extrabits = get_bits(data, size);
|
||||
|
||||
if (size < 1 + (extrabits / 8)) {
|
||||
print_text(COLOR_ERROR, "data element descriptor too short");
|
||||
packet_hexdump(data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
datalen = get_size(data, size);
|
||||
|
||||
if (size < 1 + (extrabits / 8) + datalen) {
|
||||
print_text(COLOR_ERROR, "data element size too short");
|
||||
packet_hexdump(data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
elemlen = 1 + (extrabits / 8) + datalen;
|
||||
|
||||
for (i = 0; type_table[i].str; i++) {
|
||||
uint8_t type = (data[0] & 0xf8) >> 3;
|
||||
|
||||
if (type_table[i].value != type)
|
||||
continue;
|
||||
|
||||
if (print_func) {
|
||||
print_func(position, indent, type,
|
||||
data + 1 + (extrabits / 8), datalen);
|
||||
break;
|
||||
}
|
||||
|
||||
print_field("%*c%s (%d) with %u byte%s [%u extra bits] len %u",
|
||||
indent, ' ', type_table[i].str, type,
|
||||
datalen, datalen == 1 ? "" : "s",
|
||||
extrabits, elemlen);
|
||||
if (!valid_size(data[0] & 0x07, type_table[i].sizes)) {
|
||||
print_text(COLOR_ERROR, "invalid data element size");
|
||||
packet_hexdump(data + 1 + (extrabits / 8), datalen);
|
||||
break;
|
||||
}
|
||||
|
||||
if (type_table[i].recurse)
|
||||
decode_data_elements(0, indent + 2,
|
||||
data + 1 + (extrabits / 8), datalen,
|
||||
print_func);
|
||||
else if (type_table[i].print)
|
||||
type_table[i].print(indent + 2,
|
||||
data + 1 + (extrabits / 8), datalen);
|
||||
break;
|
||||
}
|
||||
|
||||
data += elemlen;
|
||||
size -= elemlen;
|
||||
|
||||
decode_data_elements(position + 1, indent, data, size, print_func);
|
||||
}
|
||||
|
||||
static uint32_t get_bytes(const uint8_t *data, uint32_t size)
|
||||
{
|
||||
switch (data[0] & 0x07) {
|
||||
case 5:
|
||||
return 2 + data[1];
|
||||
case 6:
|
||||
return 3 + bt_get_be16(data + 1);
|
||||
case 7:
|
||||
return 5 + bt_get_be32(data + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct {
|
||||
uint16_t id;
|
||||
const char *str;
|
||||
} attribute_table[] = {
|
||||
{ 0x0000, "Service Record Handle" },
|
||||
{ 0x0001, "Service Class ID List" },
|
||||
{ 0x0002, "Service Record State" },
|
||||
{ 0x0003, "Service ID" },
|
||||
{ 0x0004, "Protocol Descriptor List" },
|
||||
{ 0x0005, "Browse Group List" },
|
||||
{ 0x0006, "Language Base Attribute ID List" },
|
||||
{ 0x0007, "Service Info Time To Live" },
|
||||
{ 0x0008, "Service Availability" },
|
||||
{ 0x0009, "Bluetooth Profile Descriptor List" },
|
||||
{ 0x000a, "Documentation URL" },
|
||||
{ 0x000b, "Client Executable URL" },
|
||||
{ 0x000c, "Icon URL" },
|
||||
{ 0x000d, "Additional Protocol Descriptor List" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static void print_attr(uint32_t position, uint8_t indent, uint8_t type,
|
||||
const uint8_t *data, uint32_t size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((position % 2) == 0) {
|
||||
uint16_t id = bt_get_be16(data);
|
||||
const char *str = "Unknown";
|
||||
|
||||
for (i = 0; attribute_table[i].str; i++) {
|
||||
if (attribute_table[i].id == id)
|
||||
str = attribute_table[i].str;
|
||||
}
|
||||
|
||||
print_field("%*cAttribute: %s (0x%4.4x) [len %d]",
|
||||
indent, ' ', str, id, size);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; type_table[i].str; i++) {
|
||||
if (type_table[i].value != type)
|
||||
continue;
|
||||
|
||||
if (type_table[i].recurse)
|
||||
decode_data_elements(0, indent + 2, data, size, NULL);
|
||||
else if (type_table[i].print)
|
||||
type_table[i].print(indent + 2, data, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_attr_list(uint32_t position, uint8_t indent, uint8_t type,
|
||||
const uint8_t *data, uint32_t size)
|
||||
{
|
||||
print_field("%*cAttribute list: [len %d] {position %d}",
|
||||
indent, ' ', size, position);
|
||||
|
||||
decode_data_elements(0, indent + 2, data, size, print_attr);
|
||||
}
|
||||
|
||||
static void print_attr_lists(uint32_t position, uint8_t indent, uint8_t type,
|
||||
const uint8_t *data, uint32_t size)
|
||||
{
|
||||
decode_data_elements(0, indent, data, size, print_attr_list);
|
||||
}
|
||||
|
||||
static void print_continuation(const uint8_t *data, uint16_t size)
|
||||
{
|
||||
if (data[0] != size - 1) {
|
||||
print_text(COLOR_ERROR, "invalid continuation state");
|
||||
packet_hexdump(data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
print_field("Continuation state: %d", data[0]);
|
||||
packet_hexdump(data + 1, size - 1);
|
||||
}
|
||||
|
||||
static void store_continuation(struct tid_data *tid,
|
||||
const uint8_t *data, uint16_t size)
|
||||
{
|
||||
memcpy(tid->cont, data, size);
|
||||
print_continuation(data, size);
|
||||
}
|
||||
|
||||
#define MAX_CONT 8
|
||||
|
||||
struct cont_data {
|
||||
uint16_t channel;
|
||||
uint8_t cont[17];
|
||||
void *data;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
static struct cont_data cont_list[MAX_CONT];
|
||||
|
||||
static void handle_continuation(struct tid_data *tid, bool nested,
|
||||
uint16_t bytes, const uint8_t *data, uint16_t size)
|
||||
{
|
||||
uint8_t *newdata;
|
||||
int i, n = -1;
|
||||
|
||||
if (bytes + 1 > size) {
|
||||
print_text(COLOR_ERROR, "missing continuation state");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tid->cont[0] == 0x00 && data[bytes] == 0x00) {
|
||||
decode_data_elements(0, 2, data, bytes,
|
||||
nested ? print_attr_lists : print_attr_list);
|
||||
|
||||
print_continuation(data + bytes, size - bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CONT; i++) {
|
||||
if (cont_list[i].cont[0] == 0x00) {
|
||||
if (n < 0)
|
||||
n = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cont_list[i].channel != tid->channel)
|
||||
continue;
|
||||
|
||||
if (cont_list[i].cont[0] != tid->cont[0])
|
||||
continue;
|
||||
|
||||
if (!memcmp(cont_list[i].cont + 1,
|
||||
tid->cont + 1, tid->cont[0])) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print_continuation(data + bytes, size - bytes);
|
||||
|
||||
if (n < 0)
|
||||
return;
|
||||
|
||||
newdata = realloc(cont_list[n].data, cont_list[n].size + bytes);
|
||||
if (!newdata) {
|
||||
print_text(COLOR_ERROR, "failed buffer allocation");
|
||||
free(cont_list[n].data);
|
||||
cont_list[n].data = NULL;
|
||||
cont_list[n].size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
cont_list[n].channel = tid->channel;
|
||||
cont_list[n].data = newdata;
|
||||
|
||||
if (bytes > 0) {
|
||||
memcpy(cont_list[n].data + cont_list[n].size, data, bytes);
|
||||
cont_list[n].size += bytes;
|
||||
}
|
||||
|
||||
if (data[bytes] == 0x00) {
|
||||
print_field("Combined attribute bytes: %d", cont_list[n].size);
|
||||
|
||||
decode_data_elements(0, 2, cont_list[n].data, cont_list[n].size,
|
||||
nested ? print_attr_lists : print_attr_list);
|
||||
|
||||
free(cont_list[n].data);
|
||||
cont_list[n].data = NULL;
|
||||
cont_list[n].size = 0;
|
||||
} else
|
||||
memcpy(cont_list[i].cont, data + bytes, data[bytes] + 1);
|
||||
}
|
||||
|
||||
static uint16_t common_rsp(const struct l2cap_frame *frame,
|
||||
struct tid_data *tid)
|
||||
{
|
||||
uint16_t bytes;
|
||||
|
||||
if (frame->size < 2) {
|
||||
print_text(COLOR_ERROR, "invalid size");
|
||||
packet_hexdump(frame->data, frame->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytes = bt_get_be16(frame->data);
|
||||
print_field("Attribute bytes: %d", bytes);
|
||||
|
||||
if (bytes > frame->size - 2) {
|
||||
print_text(COLOR_ERROR, "invalid attribute size");
|
||||
packet_hexdump(frame->data + 2, frame->size - 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static void error_rsp(const struct l2cap_frame *frame, struct tid_data *tid)
|
||||
{
|
||||
uint16_t error;
|
||||
|
||||
clear_tid(tid);
|
||||
|
||||
if (frame->size < 2) {
|
||||
print_text(COLOR_ERROR, "invalid size");
|
||||
packet_hexdump(frame->data, frame->size);
|
||||
return;
|
||||
}
|
||||
|
||||
error = bt_get_be16(frame->data);
|
||||
|
||||
print_field("Error code: 0x%2.2x", error);
|
||||
}
|
||||
|
||||
static void service_req(const struct l2cap_frame *frame, struct tid_data *tid)
|
||||
{
|
||||
uint32_t search_bytes;
|
||||
|
||||
search_bytes = get_bytes(frame->data, frame->size);
|
||||
print_field("Search pattern: [len %d]", search_bytes);
|
||||
|
||||
if (search_bytes + 2 > frame->size) {
|
||||
print_text(COLOR_ERROR, "invalid search list length");
|
||||
packet_hexdump(frame->data, frame->size);
|
||||
return;
|
||||
}
|
||||
|
||||
decode_data_elements(0, 2, frame->data, search_bytes, NULL);
|
||||
|
||||
print_field("Max record count: %d",
|
||||
bt_get_be16(frame->data + search_bytes));
|
||||
|
||||
print_continuation(frame->data + search_bytes + 2,
|
||||
frame->size - search_bytes - 2);
|
||||
}
|
||||
|
||||
static void service_rsp(const struct l2cap_frame *frame, struct tid_data *tid)
|
||||
{
|
||||
uint16_t count;
|
||||
int i;
|
||||
|
||||
clear_tid(tid);
|
||||
|
||||
if (frame->size < 4) {
|
||||
print_text(COLOR_ERROR, "invalid size");
|
||||
packet_hexdump(frame->data, frame->size);
|
||||
return;
|
||||
}
|
||||
|
||||
count = bt_get_be16(frame->data + 2);
|
||||
|
||||
print_field("Total record count: %d", bt_get_be16(frame->data));
|
||||
print_field("Current record count: %d", count);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
print_field("Record handle: 0x%4.4x",
|
||||
bt_get_be32(frame->data + 4 + (i * 4)));
|
||||
|
||||
print_continuation(frame->data + 4 + (count * 4),
|
||||
frame->size - 4 - (count * 4));
|
||||
}
|
||||
|
||||
static void attr_req(const struct l2cap_frame *frame, struct tid_data *tid)
|
||||
{
|
||||
uint32_t attr_bytes;
|
||||
|
||||
if (frame->size < 6) {
|
||||
print_text(COLOR_ERROR, "invalid size");
|
||||
packet_hexdump(frame->data, frame->size);
|
||||
return;
|
||||
}
|
||||
|
||||
print_field("Record handle: 0x%4.4x", bt_get_be32(frame->data));
|
||||
print_field("Max attribute bytes: %d", bt_get_be16(frame->data + 4));
|
||||
|
||||
attr_bytes = get_bytes(frame->data + 6, frame->size - 6);
|
||||
print_field("Attribute list: [len %d]", attr_bytes);
|
||||
|
||||
if (attr_bytes + 6 > frame->size) {
|
||||
print_text(COLOR_ERROR, "invalid attribute list length");
|
||||
packet_hexdump(frame->data, frame->size);
|
||||
return;
|
||||
}
|
||||
|
||||
decode_data_elements(0, 2, frame->data + 6, attr_bytes, NULL);
|
||||
|
||||
store_continuation(tid, frame->data + 6 + attr_bytes,
|
||||
frame->size - 6 - attr_bytes);
|
||||
}
|
||||
|
||||
static void attr_rsp(const struct l2cap_frame *frame, struct tid_data *tid)
|
||||
{
|
||||
uint16_t bytes;
|
||||
|
||||
bytes = common_rsp(frame, tid);
|
||||
|
||||
handle_continuation(tid, false, bytes,
|
||||
frame->data + 2, frame->size - 2);
|
||||
|
||||
clear_tid(tid);
|
||||
}
|
||||
|
||||
static void search_attr_req(const struct l2cap_frame *frame,
|
||||
struct tid_data *tid)
|
||||
{
|
||||
uint32_t search_bytes, attr_bytes;
|
||||
|
||||
search_bytes = get_bytes(frame->data, frame->size);
|
||||
print_field("Search pattern: [len %d]", search_bytes);
|
||||
|
||||
if (search_bytes + 2 > frame->size) {
|
||||
print_text(COLOR_ERROR, "invalid search list length");
|
||||
packet_hexdump(frame->data, frame->size);
|
||||
return;
|
||||
}
|
||||
|
||||
decode_data_elements(0, 2, frame->data, search_bytes, NULL);
|
||||
|
||||
print_field("Max record count: %d",
|
||||
bt_get_be16(frame->data + search_bytes));
|
||||
|
||||
attr_bytes = get_bytes(frame->data + search_bytes + 2,
|
||||
frame->size - search_bytes - 2);
|
||||
print_field("Attribute list: [len %d]", attr_bytes);
|
||||
|
||||
decode_data_elements(0, 2, frame->data + search_bytes + 2,
|
||||
attr_bytes, NULL);
|
||||
|
||||
store_continuation(tid, frame->data + search_bytes + 2 + attr_bytes,
|
||||
frame->size - search_bytes - 2 - attr_bytes);
|
||||
}
|
||||
|
||||
static void search_attr_rsp(const struct l2cap_frame *frame,
|
||||
struct tid_data *tid)
|
||||
{
|
||||
uint16_t bytes;
|
||||
|
||||
bytes = common_rsp(frame, tid);
|
||||
|
||||
handle_continuation(tid, true, bytes, frame->data + 2, frame->size - 2);
|
||||
|
||||
clear_tid(tid);
|
||||
}
|
||||
|
||||
struct sdp_data {
|
||||
uint8_t pdu;
|
||||
const char *str;
|
||||
void (*func) (const struct l2cap_frame *frame, struct tid_data *tid);
|
||||
};
|
||||
|
||||
static const struct sdp_data sdp_table[] = {
|
||||
{ 0x01, "Error Response", error_rsp },
|
||||
{ 0x02, "Service Search Request", service_req },
|
||||
{ 0x03, "Service Search Response", service_rsp },
|
||||
{ 0x04, "Service Attribute Request", attr_req },
|
||||
{ 0x05, "Service Attribute Response", attr_rsp },
|
||||
{ 0x06, "Service Search Attribute Request", search_attr_req },
|
||||
{ 0x07, "Service Search Attribute Response", search_attr_rsp },
|
||||
{ }
|
||||
};
|
||||
|
||||
void sdp_packet(const struct l2cap_frame *frame, uint16_t channel)
|
||||
{
|
||||
uint8_t pdu;
|
||||
uint16_t tid, plen;
|
||||
struct l2cap_frame sdp_frame;
|
||||
struct tid_data *tid_info;
|
||||
const struct sdp_data *sdp_data = NULL;
|
||||
const char *pdu_color, *pdu_str;
|
||||
|
||||
int i;
|
||||
|
||||
if (frame->size < 5) {
|
||||
print_text(COLOR_ERROR, "frame too short");
|
||||
packet_hexdump(frame->data, frame->size);
|
||||
return;
|
||||
}
|
||||
|
||||
pdu = *((uint8_t *) frame->data);
|
||||
tid = bt_get_be16(frame->data + 1);
|
||||
plen = bt_get_be16(frame->data + 3);
|
||||
|
||||
if (frame->size != plen + 5) {
|
||||
print_text(COLOR_ERROR, "invalid frame size");
|
||||
packet_hexdump(frame->data, frame->size);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; sdp_table[i].str; i++) {
|
||||
if (sdp_table[i].pdu == pdu) {
|
||||
sdp_data = &sdp_table[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sdp_data) {
|
||||
if (sdp_data->func) {
|
||||
if (frame->in)
|
||||
pdu_color = COLOR_MAGENTA;
|
||||
else
|
||||
pdu_color = COLOR_BLUE;
|
||||
} else
|
||||
pdu_color = COLOR_WHITE_BG;
|
||||
pdu_str = sdp_data->str;
|
||||
} else {
|
||||
pdu_color = COLOR_WHITE_BG;
|
||||
pdu_str = "Unknown";
|
||||
}
|
||||
|
||||
print_indent(6, pdu_color, "SDP: ", pdu_str, COLOR_OFF,
|
||||
" (0x%2.2x) tid %d len %d", pdu, tid, plen);
|
||||
|
||||
if (!sdp_data || !sdp_data->func) {
|
||||
packet_hexdump(frame->data + 5, frame->size - 5);
|
||||
return;
|
||||
}
|
||||
|
||||
tid_info = get_tid(tid, channel);
|
||||
|
||||
l2cap_frame_pull(&sdp_frame, frame, 5);
|
||||
sdp_data->func(&sdp_frame, tid_info);
|
||||
}
|
||||
25
external/cache/sources/hcitools/monitor/sdp.h
vendored
Normal file
25
external/cache/sources/hcitools/monitor/sdp.h
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
void sdp_packet(const struct l2cap_frame *frame, uint16_t channel);
|
||||
284
external/cache/sources/hcitools/monitor/uuid.c
vendored
Normal file
284
external/cache/sources/hcitools/monitor/uuid.c
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "uuid.h"
|
||||
|
||||
static struct {
|
||||
uint16_t uuid;
|
||||
const char *str;
|
||||
} uuid16_table[] = {
|
||||
{ 0x0001, "SDP" },
|
||||
{ 0x0003, "RFCOMM" },
|
||||
{ 0x0005, "TCS-BIN" },
|
||||
{ 0x0007, "ATT" },
|
||||
{ 0x0008, "OBEX" },
|
||||
{ 0x000f, "BNEP" },
|
||||
{ 0x0010, "UPNP" },
|
||||
{ 0x0011, "HIDP" },
|
||||
{ 0x0012, "Hardcopy Control Channel" },
|
||||
{ 0x0014, "Hardcopy Data Channel" },
|
||||
{ 0x0016, "Hardcopy Notification" },
|
||||
{ 0x0017, "AVCTP" },
|
||||
{ 0x0019, "AVDTP" },
|
||||
{ 0x001b, "CMTP" },
|
||||
{ 0x001e, "MCAP Control Channel" },
|
||||
{ 0x001f, "MCAP Data Channel" },
|
||||
{ 0x0100, "L2CAP" },
|
||||
{ 0x1000, "Service Discovery Server Service Class" },
|
||||
{ 0x1001, "Browse Group Descriptor Service Class" },
|
||||
{ 0x1002, "Public Browse Root" },
|
||||
{ 0x1101, "Serial Port" },
|
||||
{ 0x1102, "LAN Access Using PPP" },
|
||||
{ 0x1103, "Dialup Networking" },
|
||||
{ 0x1104, "IrMC Sync" },
|
||||
{ 0x1105, "OBEX Object Push" },
|
||||
{ 0x1106, "OBEX File Transfer" },
|
||||
{ 0x1107, "IrMC Sync Command" },
|
||||
{ 0x1108, "Headset" },
|
||||
{ 0x1109, "Cordless Telephony" },
|
||||
{ 0x110a, "Audio Source" },
|
||||
{ 0x110b, "Audio Sink" },
|
||||
{ 0x110c, "A/V Remote Control Target" },
|
||||
{ 0x110d, "Advanced Audio Distribution" },
|
||||
{ 0x110e, "A/V Remote Control" },
|
||||
{ 0x110f, "A/V Remote Control Controller" },
|
||||
{ 0x1110, "Intercom" },
|
||||
{ 0x1111, "Fax" },
|
||||
{ 0x1112, "Headset AG" },
|
||||
{ 0x1113, "WAP" },
|
||||
{ 0x1114, "WAP Client" },
|
||||
{ 0x1115, "PANU" },
|
||||
{ 0x1116, "NAP" },
|
||||
{ 0x1117, "GN" },
|
||||
{ 0x1118, "Direct Printing" },
|
||||
{ 0x1119, "Reference Printing" },
|
||||
{ 0x111a, "Basic Imaging Profile" },
|
||||
{ 0x111b, "Imaging Responder" },
|
||||
{ 0x111c, "Imaging Automatic Archive" },
|
||||
{ 0x111d, "Imaging Referenced Objects" },
|
||||
{ 0x111e, "Handsfree" },
|
||||
{ 0x111f, "Handsfree Audio Gateway" },
|
||||
{ 0x1120, "Direct Printing Refrence Objects Service" },
|
||||
{ 0x1121, "Reflected UI" },
|
||||
{ 0x1122, "Basic Printing" },
|
||||
{ 0x1123, "Printing Status" },
|
||||
{ 0x1124, "Human Interface Device Service" },
|
||||
{ 0x1125, "Hardcopy Cable Replacement" },
|
||||
{ 0x1126, "HCR Print" },
|
||||
{ 0x1127, "HCR Scan" },
|
||||
{ 0x1128, "Common ISDN Access" },
|
||||
{ 0x112d, "SIM Access" },
|
||||
{ 0x112e, "Phonebook Access Client" },
|
||||
{ 0x112f, "Phonebook Access Server" },
|
||||
{ 0x1130, "Phonebook Access" },
|
||||
{ 0x1131, "Headset HS" },
|
||||
{ 0x1132, "Message Access Server" },
|
||||
{ 0x1133, "Message Notification Server" },
|
||||
{ 0x1134, "Message Access Profile" },
|
||||
{ 0x1135, "GNSS" },
|
||||
{ 0x1136, "GNSS Server" },
|
||||
{ 0x1200, "PnP Information" },
|
||||
{ 0x1201, "Generic Networking" },
|
||||
{ 0x1202, "Generic File Transfer" },
|
||||
{ 0x1203, "Generic Audio" },
|
||||
{ 0x1204, "Generic Telephony" },
|
||||
{ 0x1205, "UPNP Service" },
|
||||
{ 0x1206, "UPNP IP Service" },
|
||||
{ 0x1300, "UPNP IP PAN" },
|
||||
{ 0x1301, "UPNP IP LAP" },
|
||||
{ 0x1302, "UPNP IP L2CAP" },
|
||||
{ 0x1303, "Video Source" },
|
||||
{ 0x1304, "Video Sink" },
|
||||
{ 0x1305, "Video Distribution" },
|
||||
{ 0x1400, "HDP" },
|
||||
{ 0x1401, "HDP Source" },
|
||||
{ 0x1402, "HDP Sink" },
|
||||
{ 0x1800, "Generic Access Profile" },
|
||||
{ 0x1801, "Generic Attribute Profile" },
|
||||
{ 0x1802, "Immediate Alert" },
|
||||
{ 0x1803, "Link Loss" },
|
||||
{ 0x1804, "Tx Power" },
|
||||
{ 0x1805, "Current Time Service" },
|
||||
{ 0x1806, "Reference Time Update Service" },
|
||||
{ 0x1807, "Next DST Change Service" },
|
||||
{ 0x1808, "Glucose" },
|
||||
{ 0x1809, "Health Thermometer" },
|
||||
{ 0x180a, "Device Information" },
|
||||
/* 0x180b and 0x180c undefined */
|
||||
{ 0x180d, "Heart Rate" },
|
||||
{ 0x180e, "Phone Alert Status Service" },
|
||||
{ 0x180f, "Battery Service" },
|
||||
{ 0x1810, "Blood Pressure" },
|
||||
{ 0x1811, "Alert Notification Service" },
|
||||
{ 0x1812, "Human Interface Device" },
|
||||
{ 0x1813, "Scan Parameters" },
|
||||
{ 0x1814, "Running Speed and Cadence" },
|
||||
/* 0x1815 undefined */
|
||||
{ 0x1816, "Cycling Speed and Cadence" },
|
||||
{ 0x2800, "Primary Service" },
|
||||
{ 0x2801, "Secondary Service" },
|
||||
{ 0x2802, "Include" },
|
||||
{ 0x2803, "Characteristic" },
|
||||
{ 0x2900, "Characteristic Extended Properties" },
|
||||
{ 0x2901, "Characteristic User Description" },
|
||||
{ 0x2902, "Client Characteristic Configuration" },
|
||||
{ 0x2903, "Server Characteristic Configuration" },
|
||||
{ 0x2904, "Characteristic Format" },
|
||||
{ 0x2905, "Characteristic Aggregate Formate" },
|
||||
{ 0x2906, "Valid Range" },
|
||||
{ 0x2907, "External Report Reference" },
|
||||
{ 0x2908, "Report Reference" },
|
||||
{ 0x2a00, "Device Name" },
|
||||
{ 0x2a01, "Appearance" },
|
||||
{ 0x2a02, "Peripheral Privacy Flag" },
|
||||
{ 0x2a03, "Reconnection Address" },
|
||||
{ 0x2a04, "Peripheral Preferred Connection Parameters" },
|
||||
{ 0x2a05, "Service Changed" },
|
||||
{ 0x2a06, "Alert Level" },
|
||||
{ 0x2a07, "Tx Power Level" },
|
||||
{ 0x2a08, "Date Time" },
|
||||
{ 0x2a09, "Day of Week" },
|
||||
{ 0x2a0a, "Day Date Time" },
|
||||
/* 0x2a0b undefined */
|
||||
{ 0x2a0c, "Exact Time 256" },
|
||||
{ 0x2a0d, "DST Offset" },
|
||||
{ 0x2a0e, "Time Zone" },
|
||||
{ 0x2a0f, "Local Time Information" },
|
||||
/* 0x2a10 undefined */
|
||||
{ 0x2a11, "Time with DST" },
|
||||
{ 0x2a12, "Time Accuracy" },
|
||||
{ 0x2a13, "Time Source" },
|
||||
{ 0x2a14, "Reference Time Information" },
|
||||
/* 0x2a15 undefined */
|
||||
{ 0x2a16, "Time Update Control Point" },
|
||||
{ 0x2a17, "Time Update State" },
|
||||
{ 0x2a18, "Glucose Measurement" },
|
||||
{ 0x2a19, "Battery Level" },
|
||||
/* 0x2a1a and 0x2a1b undefined */
|
||||
{ 0x2a1c, "Temperature Measurement" },
|
||||
{ 0x2a1d, "Temperature Type" },
|
||||
{ 0x2a1e, "Intermediate Temperature" },
|
||||
/* 0x2a1f and 0x2a20 undefined */
|
||||
{ 0x2a21, "Measurement Interval" },
|
||||
{ 0x2a22, "Boot Keyboard Input Report" },
|
||||
{ 0x2a23, "System ID" },
|
||||
{ 0x2a24, "Model Number String" },
|
||||
{ 0x2a25, "Serial Number String" },
|
||||
{ 0x2a26, "Firmware Revision String" },
|
||||
{ 0x2a27, "Hardware Revision String" },
|
||||
{ 0x2a28, "Software Revision String" },
|
||||
{ 0x2a29, "Manufacturer Name String" },
|
||||
{ 0x2a2a, "IEEE 11073-20601 Regulatory Cert. Data List" },
|
||||
{ 0x2a2b, "Current Time" },
|
||||
/* 0x2a2c to 0x2a30 undefined */
|
||||
{ 0x2a31, "Scan Refresh" },
|
||||
{ 0x2a32, "Boot Keyboard Output Report" },
|
||||
{ 0x2a33, "Boot Mouse Input Report" },
|
||||
{ 0x2a34, "Glucose Measurement Context" },
|
||||
{ 0x2a35, "Blood Pressure Measurement" },
|
||||
{ 0x2a36, "Intermediate Cuff Pressure" },
|
||||
{ 0x2a37, "Heart Rate Measurement" },
|
||||
{ 0x2a38, "Body Sensor Location" },
|
||||
{ 0x2a39, "Heart Rate Control Point" },
|
||||
/* 0x2a3a to 0x2a3e undefined */
|
||||
{ 0x2a3f, "Alert Status" },
|
||||
{ 0x2a40, "Ringer Control Point" },
|
||||
{ 0x2a41, "Ringer Setting" },
|
||||
{ 0x2a42, "Alert Category ID Bit Mask" },
|
||||
{ 0x2a43, "Alert Category ID" },
|
||||
{ 0x2a44, "Alert Notification Control Point" },
|
||||
{ 0x2a45, "Unread Alert Status" },
|
||||
{ 0x2a46, "New Alert" },
|
||||
{ 0x2a47, "Supported New Alert Category" },
|
||||
{ 0x2a48, "Supported Unread Alert Category" },
|
||||
{ 0x2a49, "Blood Pressure Feature" },
|
||||
{ 0x2a4a, "HID Information" },
|
||||
{ 0x2a4b, "Report Map" },
|
||||
{ 0x2a4c, "HID Control Point" },
|
||||
{ 0x2a4d, "Report" },
|
||||
{ 0x2a4e, "Protocol Mode" },
|
||||
{ 0x2a4f, "Scan Interval Window" },
|
||||
{ 0x2a50, "PnP ID" },
|
||||
{ 0x2a51, "Glucose Feature" },
|
||||
{ 0x2a52, "Record Access Control Point" },
|
||||
{ 0x2a53, "RSC Measurement" },
|
||||
{ 0x2a54, "RSC Feature" },
|
||||
{ 0x2a55, "SC Control Point" },
|
||||
/* 0x2a56 to 0x2a5a undefined */
|
||||
{ 0x2a5b, "CSC Measurement" },
|
||||
{ 0x2a5c, "CSC Feature" },
|
||||
{ 0x2a5d, "Sensor Location" },
|
||||
{ }
|
||||
};
|
||||
|
||||
const char *uuid16_to_str(uint16_t uuid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; uuid16_table[i].str; i++) {
|
||||
if (uuid16_table[i].uuid == uuid)
|
||||
return uuid16_table[i].str;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
const char *uuid32_to_str(uint32_t uuid)
|
||||
{
|
||||
if ((uuid & 0xffff0000) == 0x0000)
|
||||
return uuid16_to_str(uuid & 0x0000ffff);
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
const char *uuid128_to_str(const unsigned char *uuid)
|
||||
{
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
const char *uuidstr_to_str(const char *uuid)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
if (!uuid)
|
||||
return NULL;
|
||||
|
||||
if (strlen(uuid) != 36)
|
||||
return NULL;
|
||||
|
||||
if (strncasecmp(uuid + 8, "-0000-1000-8000-00805f9b34fb", 28))
|
||||
return "Vendor specific";
|
||||
|
||||
if (sscanf(uuid, "%08x-0000-1000-8000-00805f9b34fb", &val) != 1)
|
||||
return NULL;
|
||||
|
||||
return uuid32_to_str(val);
|
||||
}
|
||||
31
external/cache/sources/hcitools/monitor/uuid.h
vendored
Normal file
31
external/cache/sources/hcitools/monitor/uuid.h
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
const char *uuid16_to_str(uint16_t uuid);
|
||||
const char *uuid32_to_str(uint32_t uuid);
|
||||
const char *uuid128_to_str(const unsigned char *uuid);
|
||||
|
||||
const char *uuidstr_to_str(const char *uuid);
|
||||
35
external/cache/sources/hcitools/monitor/vendor.c
vendored
Normal file
35
external/cache/sources/hcitools/monitor/vendor.c
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "packet.h"
|
||||
#include "vendor.h"
|
||||
|
||||
void vendor_event(uint16_t manufacturer, const void *data, uint8_t size)
|
||||
{
|
||||
packet_hexdump(data, size);
|
||||
}
|
||||
27
external/cache/sources/hcitools/monitor/vendor.h
vendored
Normal file
27
external/cache/sources/hcitools/monitor/vendor.h
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2011-2012 Intel Corporation
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void vendor_event(uint16_t manufacturer, const void *data, uint8_t size);
|
||||
56
external/cache/sources/hcitools/rule.mk
vendored
Normal file
56
external/cache/sources/hcitools/rule.mk
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
# define output directory
|
||||
|
||||
OUTPUT_BIN := $(shell (mkdir -p output); cd ./output; pwd)
|
||||
LIBDIR := $(shell cd $(pwd))/lib
|
||||
BINDIR := $(shell cd $(pwd))/$(OUTPUT_BIN)
|
||||
|
||||
# define compiler
|
||||
CC := gcc
|
||||
CXX := g++
|
||||
|
||||
CPPFLAGS := $(CPPFLAGS) -I$(shell (cd $(pwd)))/include
|
||||
|
||||
CFLAGS := -Wall -O3 -Os -pipe \
|
||||
-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 \
|
||||
-D_GNU_SOURCE -D_REENTRANT \
|
||||
$(CFLAGS)
|
||||
|
||||
# uses '=' let the variable parse when it's used
|
||||
# COMPILE: compiles the source file specified
|
||||
# COMPILEX: compiles the source file
|
||||
# COMPILE_MSG: print compiling message
|
||||
COMPILE = @$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
COMPILEX = @$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
COMPILECPP = @$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
COMPILECPPX = @$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
COMPILE_MSG = @echo " CC\t$<"
|
||||
|
||||
LDFLAGS := -L$(SYSROOT)/lib -L$(SYSROOT)/usr/lib -L$(LIBDIR) \
|
||||
$(LDFLAGS)
|
||||
|
||||
# uses '=' let the variable parse when it's used
|
||||
# LINK: link the objects specified
|
||||
# LINKX: compiles the objects
|
||||
# LINK_MSG: print linking message
|
||||
LINK = @$(CC) $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
LINKX = @$(CC) -o $(BINDIR)/$@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
LINKCPP = @$(CXX) $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
LINKCPPX = @$(CXX) -o $(BINDIR)/$@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
LINK_MSG = @echo " LN\t$^ -> $@"
|
||||
|
||||
AR = @arm-linux-gnueabi-ar
|
||||
|
||||
ARFLAGS := -rc
|
||||
|
||||
39
external/cache/sources/hcitools/textfile.h
vendored
Normal file
39
external/cache/sources/hcitools/textfile.h
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __TEXTFILE_H
|
||||
#define __TEXTFILE_H
|
||||
|
||||
int create_file(const char *filename, const mode_t mode);
|
||||
int create_name(char *buf, size_t size, const char *path,
|
||||
const char *address, const char *name);
|
||||
|
||||
int textfile_put(const char *pathname, const char *key, const char *value);
|
||||
int textfile_del(const char *pathname, const char *key);
|
||||
char *textfile_get(const char *pathname, const char *key);
|
||||
|
||||
typedef void (*textfile_cb) (char *key, char *value, void *data);
|
||||
|
||||
int textfile_foreach(const char *pathname, textfile_cb func, void *data);
|
||||
|
||||
#endif /* __TEXTFILE_H */
|
||||
339
external/cache/sources/orangepi-config/LICENSE
vendored
Normal file
339
external/cache/sources/orangepi-config/LICENSE
vendored
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{description}
|
||||
Copyright (C) {year} {fullname}
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
{signature of Ty Coon}, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
177
external/cache/sources/orangepi-config/debian-config
vendored
Normal file
177
external/cache/sources/orangepi-config/debian-config
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) Authors: http://www.armbian.com/authors, info@armbian.com
|
||||
#
|
||||
# This file is licensed under the terms of the GNU General Public
|
||||
# License version 2. This program is licensed "as is" without any
|
||||
# warranty of any kind, whether express or implied.
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check for root privileges
|
||||
#
|
||||
if [[ $EUID != 0 ]]; then
|
||||
echo "This tool requires root privileges. Try again with \"sudo \" please ..." >&2
|
||||
sleep 2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check for internet connection to install dependencies
|
||||
#
|
||||
wget -q --spider http://github.com
|
||||
if [[ $? -ne 0 ]]; then
|
||||
read -n 1 -s -p "Warning: Configuration cannot work properly without a working internet connection. \
|
||||
Press CTRL C to stop or any key to ignore and continue."
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# load functions, local first
|
||||
#
|
||||
if [[ -f ${BASH_SOURCE}-jobs ]]; then source ${BASH_SOURCE}-jobs;
|
||||
elif [[ -f /usr/lib/orangepi-config/jobs.sh ]]; then source /usr/lib/orangepi-config/jobs.sh;
|
||||
else exit 1;
|
||||
fi
|
||||
|
||||
if [[ -f ${BASH_SOURCE}-submenu ]]; then source ${BASH_SOURCE}-submenu;
|
||||
elif [[ -f /usr/lib/orangepi-config/submenu.sh ]]; then source /usr/lib/orangepi-config/submenu.sh;
|
||||
else exit 1;
|
||||
fi
|
||||
|
||||
if [[ -f ${BASH_SOURCE}-functions ]]; then source ${BASH_SOURCE}-functions;
|
||||
elif [[ -f /usr/lib/orangepi-config/functions.sh ]]; then source /usr/lib/orangepi-config/functions.sh;
|
||||
else exit 1;
|
||||
fi
|
||||
|
||||
if [[ -f ${BASH_SOURCE}-functions-network ]]; then source ${BASH_SOURCE}-functions-network;
|
||||
elif [[ -f /usr/lib/orangepi-config/functions-network.sh ]]; then source /usr/lib/orangepi-config/functions-network.sh;
|
||||
else exit 1;
|
||||
fi
|
||||
|
||||
|
||||
# Script parameters handling
|
||||
while [[ $1 == *=* ]]; do
|
||||
parameter=${1%%=*}
|
||||
value=${1##*=}
|
||||
shift
|
||||
echo "Command line: setting $parameter to ${value:-(empty)}"
|
||||
eval "$parameter=\"$value\""
|
||||
scripted=true
|
||||
done
|
||||
|
||||
# Display help
|
||||
if [[ $1 == "--help" ]]; then
|
||||
echo "Orange Pi config options:"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo ""
|
||||
echo "Install headers: ${BASH_SOURCE[0]} main=Sytem selection=Headers"
|
||||
echo "Update, upgrade and reboot: ${BASH_SOURCE[0]} main=System selection=Firmware"
|
||||
echo "Switch to nightly builds: ${BASH_SOURCE[0]} main=System selection=Nightly"
|
||||
echo "Switch to stable builds: ${BASH_SOURCE[0]} main=System selection=Stable"
|
||||
echo "Install default desktop: ${BASH_SOURCE[0]} main=System selection=Default"
|
||||
echo "Change to ZSH: ${BASH_SOURCE[0]} main=System selection=ZSH"
|
||||
echo "Change to BASH: ${BASH_SOURCE[0]} main=System selection=BASH"
|
||||
echo "Change to stable repository [branch=dev]: ${BASH_SOURCE[0]} main=System selection=Stable"
|
||||
echo "Change to nightly repository [branch=dev]: ${BASH_SOURCE[0]} main=System selection=Nightly"
|
||||
echo "Install headers: ${BASH_SOURCE[0]} main=Software selection=Headers_install"
|
||||
echo "Remove headers: ${BASH_SOURCE[0]} main=Software selection=Headers_remove"
|
||||
echo "Install kernel source: ${BASH_SOURCE[0]} main=Software selection=Source_install"
|
||||
echo "Remove kernel source: ${BASH_SOURCE[0]} main=Software selection=Source_remove"
|
||||
echo "Install Avahi mDNS/DNS-SD daemon: ${BASH_SOURCE[0]} main=Software selection=Avahi"
|
||||
exit
|
||||
fi
|
||||
|
||||
# collect info
|
||||
main "$@"
|
||||
|
||||
#
|
||||
# Main menu
|
||||
#
|
||||
while true
|
||||
do
|
||||
LIST=()
|
||||
|
||||
LIST+=( "System" "System and security settings" )
|
||||
LIST+=( "Network" "Wired, wireless, Bluetooth, access point" )
|
||||
LIST+=( "Personal" "Timezone, language, hostname" )
|
||||
LIST+=( "Software" "System and 3rd party software install" )
|
||||
LIST+=( "Help" "Documentation, support, sources" )
|
||||
|
||||
# count number of menu items to adjust window size
|
||||
LISTLENGTH="$((11+${#LIST[@]}/2))"
|
||||
BOXLENGTH=${#LIST[@]}
|
||||
MENUTITLE="Configure \Z1$DISTRO $DISTROID\Z0"
|
||||
|
||||
# read cpu speed
|
||||
POLICY="policy0"
|
||||
[[ $(grep -c '^processor' /proc/cpuinfo) -gt 4 ]] && POLICY="policy4"
|
||||
[[ ! -d /sys/devices/system/cpu/cpufreq/policy4 ]] && POLICY="policy0"
|
||||
num=$(cat /sys/devices/system/cpu/cpufreq/$POLICY/scaling_min_freq 2> /dev/null)
|
||||
if [[ -f /etc/default/cpufrequtils && ! -z "${num##*[!0-9]*}" ]]; then
|
||||
LISTLENGTH=$((LISTLENGTH + 2))
|
||||
MIN_CPU=$(($(cat /sys/devices/system/cpu/cpufreq/$POLICY/scaling_min_freq) / 1000))
|
||||
MAX_CPU=$(($(cat /sys/devices/system/cpu/cpufreq/$POLICY/scaling_max_freq) / 1000))
|
||||
GOVERNOR_CPU=$(cat /sys/devices/system/cpu/cpufreq/$POLICY/scaling_governor)
|
||||
FREQENCIES="\nSoC runs between \Z1${MIN_CPU}\Z0 and \Z1${MAX_CPU} MHz\Z0 using \Z1${GOVERNOR_CPU}\Z0 governor.\n"
|
||||
fi
|
||||
|
||||
[[ -n "${BOARD_NAME/ /}" ]] && MENUTITLE=$MENUTITLE" based \Z1OrangePi\Z0 for the \Z1${BOARD_NAME}\Z0 "
|
||||
|
||||
# main dialog routine
|
||||
DIALOG_CANCEL=1
|
||||
DIALOG_ESC=255
|
||||
TITLELENGTH=${#MENUTITLE}
|
||||
|
||||
[[ "$TITLELENGTH" -lt 60 ]] && TITLELENGTH="60"
|
||||
|
||||
if [[ -z $main ]]; then
|
||||
exec 3>&1
|
||||
main=$(dialog --colors --backtitle "$BACKTITLE" --title " orangepi-config " --clear \
|
||||
--cancel-label "Exit" --menu "\n$MENUTITLE \n$FREQENCIES\nSupport: \Z1http://www.orangepi.org\Z0\n " \
|
||||
$LISTLENGTH ${TITLELENGTH} $BOXLENGTH "${LIST[@]}" 2>&1 1>&3)
|
||||
exit_status=$?
|
||||
exec 3>&-
|
||||
|
||||
[[ $exit_status == $DIALOG_CANCEL || $exit_status == $DIALOG_ESC ]] && clear && exit
|
||||
|
||||
dialog --backtitle "$BACKTITLE" --title "Please wait" --infobox \
|
||||
"\nLoading ${main,,} submodule ... " 5 $((26+${#main}))
|
||||
fi
|
||||
case $main in
|
||||
|
||||
"System" )
|
||||
submenu_settings
|
||||
;;
|
||||
|
||||
"Network" )
|
||||
submenu_networking
|
||||
;;
|
||||
|
||||
"Personal" )
|
||||
submenu_personal
|
||||
;;
|
||||
|
||||
"Software" )
|
||||
submenu_software
|
||||
;;
|
||||
|
||||
"Help" )
|
||||
unset main
|
||||
t="This tool provides a straightforward way of configuring."
|
||||
t=$t"\n \nAlthough it can be run at any time, some of the"
|
||||
t=$t" options may have difficulties if you alter system settings manually.\n"
|
||||
t=$t"\n\Z1Documentation:\Z0 http://www.orangepi.org"
|
||||
t=$t"\n\n\Z1Support:\Z0 http://www.orangepi.org\n"
|
||||
t=$t"\n\Z1Sources:\Z0 https://github.com/orangepi-xunlong"
|
||||
show_box "Info" "$t" "18"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
819
external/cache/sources/orangepi-config/debian-config-functions
vendored
Normal file
819
external/cache/sources/orangepi-config/debian-config-functions
vendored
Normal file
@@ -0,0 +1,819 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) Authors: http://www.armbian.com/authors, info@armbian.com
|
||||
#
|
||||
# This file is licensed under the terms of the GNU General Public
|
||||
# License version 2. This program is licensed "as is" without any
|
||||
# warranty of any kind, whether express or implied.
|
||||
|
||||
# Functions:
|
||||
# main
|
||||
# check_desktop
|
||||
# exceptions
|
||||
# check_if_installed
|
||||
# is_package_manager_running
|
||||
# display_qr_code
|
||||
# beta_disclaimer
|
||||
# show_box
|
||||
# description
|
||||
# generic_select
|
||||
# reload_bsp
|
||||
# other_kernel_version
|
||||
# aval_dtbs
|
||||
# get_a20modes
|
||||
# get_h3modes
|
||||
# add_choose_user
|
||||
# google_token_allusers
|
||||
# configure_desktop
|
||||
|
||||
|
||||
#
|
||||
# gather info about the board and start with loading menu
|
||||
#
|
||||
function main(){
|
||||
|
||||
DIALOG_CANCEL=1
|
||||
DIALOG_ESC=255
|
||||
|
||||
# we have our own lsb_release which does not use Python. Others shell install it here
|
||||
if [[ ! -f /usr/bin/lsb_release ]]; then
|
||||
if is_package_manager_running; then
|
||||
sleep 3
|
||||
fi
|
||||
debconf-apt-progress -- apt-get update
|
||||
debconf-apt-progress -- apt -y -qq --allow-downgrades --no-install-recommends install lsb-release
|
||||
fi
|
||||
|
||||
[[ -f /etc/orangepi-release ]] && source /etc/orangepi-release && ORANGEPI="Orange Pi $VERSION $IMAGE_TYPE";
|
||||
DISTRO=$(lsb_release -is)
|
||||
DISTROID=$(lsb_release -sc)
|
||||
KERNELID=$(uname -r)
|
||||
[[ -z "${ORANGEPI// }" ]] && ORANGEPI="$DISTRO $DISTROID"
|
||||
DEFAULT_ADAPTER=$(ip -4 route ls | grep default | tail -1 | grep -Po '(?<=dev )(\S+)')
|
||||
LOCALIPADD=$(ip -4 addr show dev $DEFAULT_ADAPTER | awk '/inet/ {print $2}' | cut -d'/' -f1)
|
||||
BACKTITLE="Configuration utility, $ORANGEPI"
|
||||
[[ -n "$LOCALIPADD" ]] && BACKTITLE=$BACKTITLE", "$LOCALIPADD
|
||||
TITLE="$BOARD_NAME "
|
||||
[[ -z "${DEFAULT_ADAPTER// }" ]] && DEFAULT_ADAPTER="lo"
|
||||
OVERLAYDIR="/boot/dtb/overlay";
|
||||
[[ "$LINUXFAMILY" == "sunxi64" ]] && OVERLAYDIR="/boot/dtb/allwinner/overlay";
|
||||
[[ "$LINUXFAMILY" == "meson64" ]] && OVERLAYDIR="/boot/dtb/amlogic/overlay";
|
||||
[[ "$LINUXFAMILY" == "rockchip64" ]] && OVERLAYDIR="/boot/dtb/rockchip/overlay";
|
||||
# detect desktop
|
||||
check_desktop
|
||||
dialog --backtitle "$BACKTITLE" --title "Please wait" --infobox "\nLoading Orange Pi configuration utility ... " 5 45
|
||||
sleep 1
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# compare two strings in dot separated version format
|
||||
#
|
||||
vercomp () {
|
||||
|
||||
if [[ $1 == $2 ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
local IFS=.
|
||||
local i ver1=($1) ver2=($2)
|
||||
# fill empty fields in ver1 with zeros
|
||||
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
|
||||
do
|
||||
ver1[i]=0
|
||||
done
|
||||
for ((i=0; i<${#ver1[@]}; i++))
|
||||
do
|
||||
if [[ -z ${ver2[i]} ]]
|
||||
then
|
||||
# fill empty fields in ver2 with zeros
|
||||
ver2[i]=0
|
||||
fi
|
||||
if ((10#${ver1[i]} > 10#${ver2[i]}))
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
if ((10#${ver1[i]} < 10#${ver2[i]}))
|
||||
then
|
||||
return 2
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# test compare two strings $1="3.4.12" $2="5.4.2" $3="<" returns 0 if relation is correct
|
||||
#
|
||||
testvercomp () {
|
||||
|
||||
vercomp $1 $2
|
||||
case $? in
|
||||
0) op='=';;
|
||||
1) op='>';;
|
||||
2) op='<';;
|
||||
esac
|
||||
if [[ $op != $3 ]]
|
||||
then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# read desktop parameters
|
||||
#
|
||||
function check_desktop()
|
||||
{
|
||||
|
||||
DISPLAY_MANAGER=""; DESKTOP_INSTALLED=""
|
||||
check_if_installed nodm && DESKTOP_INSTALLED="nodm";
|
||||
check_if_installed lightdm && DESKTOP_INSTALLED="lightdm";
|
||||
check_if_installed gdm && DESKTOP_INSTALLED="gdm";
|
||||
[[ -n $(service lightdm status 2> /dev/null | grep -w active) ]] && DISPLAY_MANAGER="lightdm"
|
||||
[[ -n $(service nodm status 2> /dev/null | grep -w active) ]] && DISPLAY_MANAGER="nodm"
|
||||
[[ -n $(service gdm status 2> /dev/null | grep -w active) ]] && DISPLAY_MANAGER="gdm"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# naming exceptions for packages
|
||||
#
|
||||
function exceptions ()
|
||||
{
|
||||
|
||||
TARGET_FAMILY=$LINUXFAMILY
|
||||
UBOOT_BRANCH=$TARGET_BRANCH # uboot naming is different
|
||||
|
||||
if [[ $TARGET_BRANCH == "default" ]]; then TARGET_BRANCH=""; else TARGET_BRANCH="-"$TARGET_BRANCH; fi
|
||||
# pine64
|
||||
if [[ $TARGET_FAMILY == pine64 ]]; then
|
||||
TARGET_FAMILY="sunxi64"
|
||||
fi
|
||||
# allwinner legacy kernels
|
||||
if [[ $TARGET_FAMILY == sun*i ]]; then
|
||||
TARGET_FAMILY="sunxi"
|
||||
if [[ $UBOOT_BRANCH == "default" ]]; then
|
||||
TARGET_FAMILY=$(cat /proc/cpuinfo | grep "Hardware" | sed 's/^.*Allwinner //' | awk '{print $1;}')
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check dpkg status of $1 -- currently only 'not installed at all' case caught
|
||||
#
|
||||
check_if_installed (){
|
||||
|
||||
local DPKG_Status="$(dpkg -s "$1" 2>/dev/null | awk -F": " '/^Status/ {print $2}')"
|
||||
if [[ "X${DPKG_Status}" = "X" || "${DPKG_Status}" = *deinstall* ]]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check if package manager is doing something
|
||||
#
|
||||
function is_package_manager_running() {
|
||||
|
||||
if ps -C apt-get,apt,dpkg >/dev/null ; then
|
||||
[[ -z $scripted ]] && dialog --colors --title " \Z1Error\Z0 " --backtitle "$BACKTITLE" --no-collapse --msgbox \
|
||||
"\n\Z0Package manager is running in the background. \n\nCan't install dependencies. Try again later." 9 53
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# wget with dialog progress bar $1=URL $2=parameters
|
||||
#
|
||||
function fancy_wget()
|
||||
{
|
||||
|
||||
LANG=C wget $2 --progress=bar:force:noscroll $1 2>&1 | stdbuf -i0 -o0 -e0 tr '>' '\n' | \
|
||||
stdbuf -i0 -o0 -e0 sed -rn 's/^.*\<([0-9]+)%\[.*$/\1/p' | dialog --backtitle "$BACKTITLE" --title " Downloading " \
|
||||
--gauge "Please wait" 7 70 0
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# display qr code for authentication method
|
||||
#
|
||||
function display_qr_code()
|
||||
{
|
||||
|
||||
clear
|
||||
SECRET=$(head -1 /root/.google_authenticator)
|
||||
qrencode -m 2 -d 9 -8 -t ANSI256 "otpauth://totp/test?secret=$SECRET"
|
||||
echo -e "\nHow to setup your one type password generator?\n"
|
||||
echo -e "\nInstall a one-time password authenticator on your mobile device (e.g. FreeOTP) from the Android \
|
||||
market or F-Droid. \n\nIn the application menu, click the corresponding button to create a new account and either \
|
||||
scan the QR code or enter the secret key manually:\\n\n$SECRET \n\nYou should now see a new passcode token being \
|
||||
generated every 60 seconds on your phone.\n" | fold -sw 60
|
||||
read -n 1 -s -r -p "Press any key to continue"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# show disclaimer
|
||||
#
|
||||
function beta_disclaimer ()
|
||||
{
|
||||
|
||||
exec 3>&1
|
||||
ACKNOWLEDGEMENT=$(dialog --colors --nocancel --backtitle "$BACKTITLE" --no-collapse --title " Warning " \
|
||||
--clear \--radiolist "\n$1\n \n" 0 56 5 "Yes, I understand" "" off 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# show box
|
||||
#
|
||||
function show_box ()
|
||||
{
|
||||
|
||||
dialog --colors --backtitle "$BACKTITLE" --no-collapse --title " $1 " --clear --msgbox "\n$2\n \n" $3 56
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# show description for MOTD files
|
||||
#
|
||||
function description
|
||||
{
|
||||
case $1 in
|
||||
*header*)
|
||||
echo "Big board logo and kernel info"
|
||||
;;
|
||||
*sysinfo*)
|
||||
echo "Sysinfo - load, ip, memory, uptime, ..."
|
||||
;;
|
||||
*tips*)
|
||||
echo "Shows tip of the day"
|
||||
;;
|
||||
*updates*)
|
||||
echo "Display number of available updates"
|
||||
;;
|
||||
*orangepi-config*)
|
||||
echo "Show command for system configuration"
|
||||
;;
|
||||
*autoreboot-warn*)
|
||||
echo "Show warning when reboot is needed"
|
||||
;;
|
||||
*uk.armbian.com*)
|
||||
echo "United Kingdom"
|
||||
;;
|
||||
*mirrors.tuna.tsinghua.edu.cn/armbian/*)
|
||||
echo "China"
|
||||
;;
|
||||
*mirrors.netix.net/armbian/apt/*)
|
||||
echo "Bulgarija"
|
||||
;;
|
||||
*mirrors.dotsrc.org/armbian-apt/*)
|
||||
echo "Denmark"
|
||||
;;
|
||||
*.armbian.com*)
|
||||
echo "Estonia"
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Generic select box
|
||||
#
|
||||
function generic_select()
|
||||
{
|
||||
IFS=$' '
|
||||
PARAMETER=($1)
|
||||
local LIST=()
|
||||
for i in "${PARAMETER[@]}"
|
||||
do
|
||||
if [[ -n $3 ]]; then
|
||||
[[ ${i[0]} -ge $3 ]] && \
|
||||
LIST+=( "${i[0]//[[:blank:]]/}" "" )
|
||||
else
|
||||
LIST+=( "${i[0]//[[:blank:]]/}" "" )
|
||||
fi
|
||||
done
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
if [ "$LIST_LENGTH" -eq 1 ]; then
|
||||
PARAMETER=${PARAMETER[0]}
|
||||
else
|
||||
exec 3>&1
|
||||
PARAMETER=$(dialog --nocancel --backtitle "$BACKTITLE" --no-collapse \
|
||||
--title "$2" --clear --menu "" $((6+${LIST_LENGTH})) 0 $((1+${LIST_LENGTH})) "${LIST[@]}" 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# reload kernel, bsp and orangepi-config
|
||||
#
|
||||
function reload_bsp(){
|
||||
|
||||
# switch to defined branch
|
||||
[[ -n "$1" ]] && BRANCH=$1
|
||||
|
||||
# deal with exceptions
|
||||
if [[ $BRANCH == current || $BRANCH == dev ]]; then
|
||||
[[ ${LINUXFAMILY} == rk3399 ]] && LINUXFAMILY=rockchip64
|
||||
fi
|
||||
|
||||
clear
|
||||
debconf-apt-progress -- apt-get update
|
||||
|
||||
# must exits
|
||||
PACKAGE_INSTALL="linux-image-${BRANCH}-${LINUXFAMILY} linux-dtb-${BRANCH}-${LINUXFAMILY}"
|
||||
PACKAGE_PURGE="linux-image* linux-dtb*"
|
||||
|
||||
# create install and remove logic
|
||||
command=$(LC_ALL=C apt-get --download-only --simulate --allow-downgrades -y --no-install-recommends install linux-${DISTROID}-root-${BRANCH}-${BOARD} 2>/dev/null)
|
||||
if [[ $? -eq 0 && -z $(echo $command | grep "not possible") ]]; then
|
||||
PACKAGE_INSTALL+=" linux-${DISTROID}-root-${BRANCH}-${BOARD}"
|
||||
PACKAGE_PURGE+=" linux-${DISTROID}-root*"
|
||||
fi
|
||||
|
||||
command=$(LC_ALL=C apt-get --download-only --simulate --reinstall --allow-downgrades -y --no-install-recommends install linux-u-boot-${BOARD}-${BRANCH} 2>/dev/null)
|
||||
if [[ $? -eq 0 && -z $(echo $command | grep "not possible") ]]; then
|
||||
PACKAGE_INSTALL+=" linux-u-boot-${BOARD}-${BRANCH}"
|
||||
PACKAGE_PURGE+=" linux-u-boot-${BOARD}-*"
|
||||
fi
|
||||
|
||||
if check_if_installed orangepi-${DISTROID}-desktop ; then
|
||||
PACKAGE_INSTALL+=" orangepi-${DISTROID}-desktop"
|
||||
PACKAGE_PURGE+=" orangepi-${DISTROID}-desktop*"
|
||||
fi
|
||||
|
||||
if check_if_installed linux-headers-${BRANCH}-${FAMILY} ; then
|
||||
PACKAGE_INSTALL+=" linux-headers-${BRANCH}-${FAMILY}"
|
||||
PACKAGE_PURGE+=" linux-headers*"
|
||||
fi
|
||||
|
||||
debconf-apt-progress -- apt-get -o Dpkg::Options::="--force-confold" --force-yes --download-only --allow-downgrades -y --no-install-recommends install $PACKAGE_INSTALL
|
||||
# if download is ok, remove old packages
|
||||
if [[ $? = 0 ]]; then
|
||||
|
||||
debconf-apt-progress -- apt-get -y -qq purge $PACKAGE_PURGE
|
||||
find "/boot/" -name "System.map*" -type f -delete
|
||||
find "/boot/" -name "config*" -type f -delete
|
||||
find "/boot/" -name "vmlinuz*" -type f -delete
|
||||
find "/boot/" -name "*nitrd*" -type f -delete
|
||||
find "/boot/" -name "*Image" -type l -delete
|
||||
|
||||
# install packages
|
||||
echo $PACKAGE_INSTALL >> /var/log/upgrade.log
|
||||
debconf-apt-progress -- apt-get -y -qq --allow-downgrades --no-install-recommends --reinstall \
|
||||
-o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install $PACKAGE_INSTALL
|
||||
|
||||
if [[ $? -eq 1 ]]; then
|
||||
echo "Something went wrong ... check logs."; exit;
|
||||
else
|
||||
apt clean
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function other_kernel_version ()
|
||||
{
|
||||
|
||||
IFS=$'\r\n'
|
||||
GLOBIGNORE='*'
|
||||
local HIDDEN='hidden'
|
||||
|
||||
# get current kernel information
|
||||
CURRENT_VERSION_TEMP=$(dpkg -l | grep '^ii' | grep linux-image)
|
||||
CURRENT_VERSION=$(echo $CURRENT_VERSION_TEMP | awk '{print $2}')"="$(echo $CURRENT_VERSION_TEMP | awk '{print $3}')
|
||||
|
||||
# Merge families and handle exceptions
|
||||
[[ ${LINUXFAMILY} == sun*i ]] && LINUXFAMILY=sunxi
|
||||
[[ ${LINUXFAMILY} == pine64 ]] && LINUXFAMILY=sunxi64
|
||||
[[ ${LINUXFAMILY} == sun*iw* ]] && LINUXFAMILY=sunxi64
|
||||
[[ ${LINUXFAMILY} == cubox || ${LINUXFAMILY} == udoo ]] && LINUXFAMILY=imx6
|
||||
[[ ${BOARD} == odroidc2 || ${BOARD} == kvim1 || ${BOARD} == lafrite || ${BOARD} == lepotato || ${BOARD} == nanopik2-s905 ]] && HIDDEN="legacy"
|
||||
[[ ${LINUXFAMILY} == odroidn2 ]] && LINUXFAMILY=meson64
|
||||
|
||||
# check what is available from the repository
|
||||
debconf-apt-progress -- apt-get update
|
||||
LIST=($(apt-cache show linux-image*${LINUXFAMILY} | grep -E "Package:|Version:|version:" \
|
||||
| grep -v "Config-Version" | sed -n -e 's/^.*: //p' | sed 's/\.$//g'))
|
||||
new_list=()
|
||||
|
||||
# create a human readable menu
|
||||
for ((n=0;n<$((${#LIST[@]}));n++));
|
||||
do
|
||||
m=$(( $n + 1 ))
|
||||
prvi=$((3*$m - 3))
|
||||
drugi=$((3*$m - 2))
|
||||
tretji=$((3*$m - 1))
|
||||
[[ -z ${LIST[$prvi]} ]] && break
|
||||
if [[ $CURRENT_VERSION != "${LIST[$prvi]}=${LIST[$drugi]}" && ${LIST[$prvi]} != *${HIDDEN}* ]]; then
|
||||
new_list+=( "${LIST[$prvi]}=${LIST[$drugi]}" )
|
||||
new_list+=( ${LIST[$tretji]} )
|
||||
fi
|
||||
local tmp="${LIST[$prvi]}=${LIST[$drugi]}${LIST[$tretji]}"
|
||||
[[ ${#tmp} -gt $chrlen ]] && local chrlen=${#tmp}
|
||||
done
|
||||
|
||||
# copy back to main array
|
||||
LIST=("${new_list[@]}")
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
|
||||
if [ "$LIST_LENGTH" -eq 0 ]; then
|
||||
dialog --backtitle "$BACKTITLE" --title " Warning " --msgbox "\nNo other kernels available!" 7 32
|
||||
else
|
||||
beta_disclaimer "Switching between kernels might change functionality of your board or it might fail to boot. \
|
||||
\n\n\Z1In case of troubles expect no help!\Z0"
|
||||
if [[ -n $ACKNOWLEDGEMENT ]]; then
|
||||
exec 3>&1
|
||||
TARGET_VERSION=$(dialog --ok-label "Reboot" --cancel-label "Cancel" --backtitle "$BACKTITLE" --no-collapse \
|
||||
--title "Select kernel and reboot" --clear --menu "" $((6+${LIST_LENGTH})) $((7+${chrlen})) 25 "${LIST[@]}" 2>&1 1>&3)
|
||||
exitstatus=$?;
|
||||
exec 3>&-
|
||||
if [[ $exitstatus = 0 ]]; then
|
||||
IFS=" "
|
||||
|
||||
# determine upgrade packages
|
||||
UPGRADE_ROOT="default"
|
||||
UPGRADE_UBOOT=""
|
||||
[[ $TARGET_VERSION == *legacy* ]] && UPGRADE_ROOT="-legacy" && UPGRADE_UBOOT="legacy"
|
||||
[[ $TARGET_VERSION == *next* ]] && UPGRADE_ROOT="-next" && UPGRADE_UBOOT="next"
|
||||
[[ $TARGET_VERSION == *current* ]] && UPGRADE_ROOT="-current" && UPGRADE_UBOOT="current"
|
||||
[[ $TARGET_VERSION == *dev* ]] && UPGRADE_ROOT="-dev" && UPGRADE_UBOOT="dev"
|
||||
|
||||
# install packages
|
||||
PACKAGE_LIST="$TARGET_VERSION"
|
||||
TARGET_VERSION_DTB=${TARGET_VERSION/image/dtb}
|
||||
TARGET_VERSION_PRE=$(echo $TARGET_VERSION_DTB | cut -f1 -d"=")
|
||||
TARGET_VERSION_SUB=$(echo $TARGET_VERSION_DTB | cut -f2 -d"=")
|
||||
[[ -n $(apt-cache madison "$TARGET_VERSION_PRE" | grep $TARGET_VERSION_SUB ) ]] && \
|
||||
# installs u-boot only if exits
|
||||
apt-cache show linux-u-boot-${BOARD}-${UPGRADE_UBOOT} 2> /dev/null
|
||||
[[ $? -eq 0 ]] && PACKAGE_LIST=$PACKAGE_LIST" linux-u-boot-${BOARD}-${UPGRADE_UBOOT}"
|
||||
|
||||
PACKAGE_LIST=$PACKAGE_LIST" $TARGET_VERSION_DTB"
|
||||
echo $PACKAGE_LIST > /tmp/switch_kernel.log 2>&1
|
||||
debconf-apt-progress -- apt -o Dpkg::Options::="--force-confold" --force-yes --download-only --allow-downgrades -y --no-install-recommends install $PACKAGE_LIST
|
||||
|
||||
if [[ $? = 0 ]]; then
|
||||
dialog --backtitle "$BACKTITLE" --title "Please wait" --infobox "\nRemoving current kernel ..." 5 36
|
||||
|
||||
# remove old kernel
|
||||
debconf-apt-progress -- apt -y -qq purge linux-u-boot* linux-image* linux-dtb* linux-headers* linux-${DISTROID}-root*
|
||||
|
||||
# cleanup
|
||||
find "/boot/" -name "System.map*" -type f -delete; find "/boot/" -name "config*" -type f -delete
|
||||
find "/boot/" -name "vmlinuz*" -type f -delete; find "/boot/" -name "*nitrd*" -type f -delete
|
||||
apt clean
|
||||
# BSP must be installed separate otherwise it won't work
|
||||
debconf-apt-progress -- apt -o Dpkg::Options::="--force-confold" --force-yes -y -qq --allow-downgrades --no-install-recommends install linux-${DISTROID}-root${UPGRADE_ROOT}-${BOARD}
|
||||
debconf-apt-progress -- apt -o Dpkg::Options::="--force-confold" --force-yes -y -qq --allow-downgrades --no-install-recommends install $PACKAGE_LIST
|
||||
if [[ $? = 0 ]]; then
|
||||
# update boot loader
|
||||
[[ -f /usr/lib/u-boot/platform_install.sh ]] && source /usr/lib/u-boot/platform_install.sh
|
||||
#recognize_root
|
||||
root_uuid=$(sed -e 's/^.*root=//' -e 's/ .*$//' < /proc/cmdline)
|
||||
root_partition=$(blkid | tr -d '":' | grep "${root_uuid}" | awk '{print $1}')
|
||||
root_partition_device="${root_partition::-2}"
|
||||
write_uboot_platform "$DIR" "${root_partition_device}"
|
||||
reboot
|
||||
fi
|
||||
else
|
||||
dialog --backtitle "$BACKTITLE" --title "Warning" --msgbox \
|
||||
"\nTest install failed. Can't change firmware \n\nCheck /tmp/switch_kernel.log" 9 48
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check if board has alternative kernels
|
||||
#
|
||||
function aval_dtbs ()
|
||||
{
|
||||
|
||||
if [[ $LINUXFAMILY == cubox ]]; then
|
||||
local width=80
|
||||
LIST=("imx6dl-hummingboard.dtb" "HB Solo/DualLite" "imx6dl-hummingboard-emmc-som-v15.dtb" "HB Solo/DualLite v1.5 with eMMC" "imx6dl-hummingboard-som-v15.dtb" "HB Solo/DualLite v1.5" \
|
||||
"imx6dl-hummingboard2.dtb" "HB2 Solo/DualLite" "imx6dl-hummingboard2-emmc-som-v15.dtb" "HB2 Solo/DualLite v1.5 with eMMC" "imx6dl-hummingboard2-som-v15.dtb" "HB2 Solo/DualLite v1.5" \
|
||||
"imx6q-hummingboard.dtb" "HB Dual/Quad" "imx6q-hummingboard-emmc-som-v15.dtb" "HB Dual/Quad v1.5 with eMMC" "imx6q-hummingboard-som-v15.dtb" "HB Dual/Quad v1.5" \
|
||||
"imx6q-hummingboard2.dtb" "HB2 Dual/Quad" "imx6q-hummingboard2-emmc-som-v15.dtb" "HB2 Dual/Quad v1.5 with eMMC" "imx6q-hummingboard2-som-v15.dtb" "HB2 Dual/Quad v1.5" \
|
||||
"imx6dl-cubox-i.dtb" "Cubox-i Solo/DualLite" "imx6dl-cubox-i-emmc-som-v15.dtb" "Cubox-i Solo/DualLite v1.5 with eMMC" "imx6dl-cubox-i-som-v15.dtb" "Cubox-i Solo/DualLite v1.5" \
|
||||
"imx6q-cubox-i.dtb" "Cubox-i Dual/Quad" "imx6q-cubox-i-emmc-som-v15.dtb" "Cubox-i Dual/Quad v1.5 with eMMC" "imx6q-cubox-i-som-v15.dtb" "Cubox-i Dual/Quad v1.5")
|
||||
else
|
||||
local width=52
|
||||
LIST=("xu4" "Odroid XU4" "xu3" "Odroid XU3" "xu3l" "Odroid XU3 Lite" "hc1" "Odroid HC1/HC2")
|
||||
fi
|
||||
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
if [ "$LIST_LENGTH" -eq 1 ]; then
|
||||
TARGET_BOARD=${AVAL_KERNEL[0]}
|
||||
else
|
||||
exec 3>&1
|
||||
TARGET_BOARD=$(dialog --cancel-label "Cancel" --backtitle "$BACKTITLE" --no-collapse \
|
||||
--title "Select optimised board configuration" --clear --menu \
|
||||
"" $((6+${LIST_LENGTH})) ${width} 25 "${LIST[@]}" 2>&1 1>&3)
|
||||
exitstatus=$?;
|
||||
exec 3>&-
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# select video modes for a10 and a20
|
||||
#
|
||||
function get_a20modes ()
|
||||
{
|
||||
|
||||
IFS=$'\r'
|
||||
GLOBIGNORE='*'
|
||||
SCREEN_RESOLUTION=("1920x1080p60" "1280x720p60" "1920x1080p50" "1280x1024p60" "1024x768p60" "800x600p60" "640x480p60" "1360x768p60" "1440x900p60" "1680x1050p60")
|
||||
local LIST=()
|
||||
for i in "${SCREEN_RESOLUTION[@]}"
|
||||
do
|
||||
LIST+=( "${i[0]//[[:blank:]]/}" "" )
|
||||
done
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
#echo $LIST_LENGTH
|
||||
#exit
|
||||
if [ "$LIST_LENGTH" -eq 1 ]; then
|
||||
SCREEN_RESOLUTION=${SCREEN_RESOLUTION[0]}
|
||||
else
|
||||
exec 3>&1
|
||||
SCREEN_RESOLUTION=$(dialog --nocancel --backtitle "$BACKTITLE" --no-collapse \
|
||||
--title "Select video mode" --clear --menu \
|
||||
"" $((6+${LIST_LENGTH})) 25 $((1+${LIST_LENGTH})) "${LIST[@]}" 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# select video modes for odroid c1/c2
|
||||
#
|
||||
function get_odroidmodes ()
|
||||
{
|
||||
|
||||
IFS=$'\r\n'
|
||||
GLOBIGNORE='*'
|
||||
SCREEN_RESOLUTION=($(cat /boot/boot.ini | grep -w "# setenv" | grep "hz" | cut -d'"' -f 2))
|
||||
SCREEN_RESOLUTION=($(cat /boot/boot.ini | grep "Progressive" | grep -v "setenv" | cut -d'"' -f 2))
|
||||
local LIST=()
|
||||
for i in "${SCREEN_RESOLUTION[@]}"
|
||||
do
|
||||
LIST+=( "${i[0]//[[:blank:]]/}" "" )
|
||||
done
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
#echo $LIST_LENGTH
|
||||
#exit
|
||||
if [ "$LIST_LENGTH" -eq 1 ]; then
|
||||
SCREEN_RESOLUTION=${SCREEN_RESOLUTION[0]}
|
||||
else
|
||||
exec 3>&1
|
||||
SCREEN_RESOLUTION=$(dialog --nocancel --backtitle "$BACKTITLE" --no-collapse \
|
||||
--title "Select video mode" --clear --menu \
|
||||
"" $((6+${LIST_LENGTH})) 25 $((1+${LIST_LENGTH})) "${LIST[@]}" 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# select video modes for h3
|
||||
#
|
||||
function get_h3modes ()
|
||||
{
|
||||
|
||||
IFS=$'\r\n'
|
||||
GLOBIGNORE='*'
|
||||
SCREEN_RESOLUTION=($(h3disp -i clean))
|
||||
local LIST=()
|
||||
for i in "${SCREEN_RESOLUTION[@]}"
|
||||
do
|
||||
LIST+=( "${i[0]//[[:blank:]]/}" "" )
|
||||
done
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
#echo $LIST_LENGTH
|
||||
#exit
|
||||
if [ "$LIST_LENGTH" -eq 1 ]; then
|
||||
SCREEN_RESOLUTION=${SCREEN_RESOLUTION[0]}
|
||||
else
|
||||
exec 3>&1
|
||||
SCREEN_RESOLUTION=$(dialog --nocancel --backtitle "$BACKTITLE" --no-collapse \
|
||||
--title "Select video mode" --clear --menu \
|
||||
"" $((6+${LIST_LENGTH})) 25 $((1+${LIST_LENGTH})) "${LIST[@]}" 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# create or pick unprivileged user
|
||||
#
|
||||
function add_choose_user ()
|
||||
{
|
||||
|
||||
IFS=$'\r\n'
|
||||
GLOBIGNORE='*'
|
||||
|
||||
local USERS=($(awk -F'[/:]' '{if ($3 >= 1000 && $3 != 65534) print $1}' /etc/passwd))
|
||||
local LIST=()
|
||||
for i in "${USERS[@]}"
|
||||
do
|
||||
LIST+=( "${i[0]//[[:blank:]]/}" "" )
|
||||
done
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
|
||||
if [ "$LIST_LENGTH" -eq 0 ]; then
|
||||
dialog --backtitle "$BACKTITLE" --title " Notice " --msgbox \
|
||||
"\nWe didn't find any unprivileged user with sudo rights which is required to run this service.\
|
||||
\n\nPress enter to create one!" 10 48
|
||||
read -t 0 temp
|
||||
echo -e "\nPlease provide a username (eg. your forename) or leave blank for canceling user creation: \c"
|
||||
read -e username
|
||||
CHOSEN_USER="$(echo "$username" | tr '[:upper:]' '[:lower:]' | tr -d -c '[:alnum:]')"
|
||||
[ -z "$CHOSEN_USER" ] && return
|
||||
echo "Trying to add user $CHOSEN_USER"
|
||||
adduser $CHOSEN_USER || return
|
||||
elif [ "$LIST_LENGTH" -eq 1 ]; then
|
||||
CHOSEN_USER=${USERS[0]}
|
||||
else
|
||||
exec 3>&1
|
||||
CHOSEN_USER=$(dialog --nocancel --backtitle "$BACKTITLE" --no-collapse \
|
||||
--title "Select unprivileged user" --clear --menu "" $((6+${LIST_LENGTH})) 40 15 "${LIST[@]}" 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Copy Google token to all local users.
|
||||
#
|
||||
function google_token_allusers ()
|
||||
{
|
||||
|
||||
if [[ -f /root/.google_authenticator ]]; then
|
||||
local USERS=($(awk -F'[/:]' '{if ($3 >= 1000 && $3 != 65534) print $1}' /etc/passwd))
|
||||
for i in "${USERS[@]}"
|
||||
do
|
||||
USER=${i[0]//[[:blank:]]/}
|
||||
if [[ -d /home/$USER ]]; then
|
||||
cp /root/.google_authenticator /home/$USER/
|
||||
chown ${USER}:${USER} /home/${USER}/.google_authenticator
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# configure orangepi desktop
|
||||
#
|
||||
function configure_desktop ()
|
||||
{
|
||||
|
||||
add_choose_user
|
||||
|
||||
if [ -n "$CHOSEN_USER" ]; then
|
||||
|
||||
# update packages
|
||||
debconf-apt-progress -- apt-get update
|
||||
|
||||
# install new package if exists
|
||||
unset PACKAGE_SUFIX
|
||||
[[ -n $(apt-cache search --names-only "^orangepi-${DISTROID}-desktop-xfce$") ]] && PACKAGE_SUFIX="-xfce"
|
||||
|
||||
# remove desktop package to secure proper install
|
||||
if check_if_installed orangepi-${DISTROID}-desktop ; then
|
||||
debconf-apt-progress -- apt-get -y \
|
||||
remove orangepi-${DISTROID}-desktop${PACKAGE_SUFIX} lightdm lightdm-gtk-greeter
|
||||
fi
|
||||
|
||||
# install desktop package
|
||||
debconf-apt-progress -- apt-get --reinstall -o Dpkg::Options::="--force-confdef" \
|
||||
-o Dpkg::Options::="--force-confold" -y \
|
||||
install $1 orangepi-${DISTROID}-desktop${PACKAGE_SUFIX} lightdm lightdm-gtk-greeter
|
||||
|
||||
# in case previous install was interrupted
|
||||
[[ $? -eq 130 ]] && dpkg --configure -a
|
||||
|
||||
# clean apt cache
|
||||
apt clean
|
||||
|
||||
# add user to groups
|
||||
for additionalgroup in sudo netdev audio video dialout plugdev input bluetooth systemd-journal ssh; do
|
||||
usermod -aG ${additionalgroup} ${CHOSEN_USER} 2>/dev/null
|
||||
done
|
||||
|
||||
# Prevent loading paralel printer port drivers which we don't need here.
|
||||
# suppress boot error if kernel modules are absent
|
||||
if [[ -f /etc/modules-load.d/cups-filters.conf ]]; then
|
||||
sed "s/^lp/#lp/" -i /etc/modules-load.d/cups-filters.conf
|
||||
sed "s/^ppdev/#ppdev/" -i /etc/modules-load.d/cups-filters.conf
|
||||
sed "s/^parport_pc/#parport_pc/" -i /etc/modules-load.d/cups-filters.conf
|
||||
fi
|
||||
|
||||
# enable show windows content on stronger boards
|
||||
cpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')
|
||||
if [[ ${cpu_cores} -gt 2 && -f /etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml ]]; then
|
||||
sed -i 's/<property name="box_move" type="bool" value=".*/<property name="box_move" type="bool" value="false"\/>/g' \
|
||||
/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml
|
||||
fi
|
||||
|
||||
# fix for gksu in Xenial
|
||||
touch /home/${CHOSEN_USER}/.Xauthority
|
||||
cp -R /etc/skel/. /home/${CHOSEN_USER}
|
||||
|
||||
# set up profile sync daemon on desktop systems
|
||||
which psd >/dev/null 2>&1
|
||||
if [[ $? -eq 0 && -z $(grep overlay-helper /etc/sudoers) ]]; then
|
||||
echo "${CHOSEN_USER} ALL=(ALL) NOPASSWD: /usr/bin/psd-overlay-helper" >> /etc/sudoers
|
||||
touch /home/${CHOSEN_USER}/.activate_psd
|
||||
fi
|
||||
|
||||
mkdir -p /etc/lightdm/lightdm.conf.d
|
||||
echo "[Seat:*]" > /etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
|
||||
echo "autologin-user=$CHOSEN_USER" >> /etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
|
||||
echo "autologin-user-timeout=0" >> /etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
|
||||
echo "user-session=xfce" >> /etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
|
||||
ln -s /lib/systemd/system/lightdm.service /etc/systemd/system/display-manager.service >/dev/null 2>&1
|
||||
# fix permissions
|
||||
chown -R ${CHOSEN_USER}:${CHOSEN_USER} /home/${CHOSEN_USER}/.
|
||||
service lightdm start >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
}
|
||||
742
external/cache/sources/orangepi-config/debian-config-functions-network
vendored
Executable file
742
external/cache/sources/orangepi-config/debian-config-functions-network
vendored
Executable file
@@ -0,0 +1,742 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2017 Igor Pecovnik, igor.pecovnik@gma**.com
|
||||
#
|
||||
# This file is licensed under the terms of the GNU General Public
|
||||
# License version 2. This program is licensed "as is" without any
|
||||
# warranty of any kind, whether express or implied.
|
||||
|
||||
# Functions:
|
||||
# initialize_lte
|
||||
# function lte
|
||||
# check_hostapd
|
||||
# check_advanced_modes
|
||||
# create_if_config
|
||||
# reload-nety
|
||||
# check_port
|
||||
# check_ht_capab
|
||||
# check_vht_capab
|
||||
# check_channels
|
||||
# netmask_to_cidr
|
||||
# nm_ip_editor
|
||||
# systemd_ip_editor
|
||||
# ip_editor
|
||||
# wlan_edit_basic
|
||||
# wlan_edit
|
||||
# wlan_exceptions
|
||||
# check_and_warn
|
||||
# get_wlan_interface
|
||||
# select_default_interface
|
||||
# connect_bt_interface
|
||||
|
||||
|
||||
|
||||
#
|
||||
# 3G/4G general stuff
|
||||
#
|
||||
function initialize_lte ()
|
||||
{
|
||||
# This file defines udev rules for some 3G/UMTS/LTE modems. It
|
||||
# addresses the issue that the ttyUSB devices are numbered randomly, and
|
||||
# their numbering can vary between server reboots. These rules create
|
||||
# persistent symlinks which can be reliably used in WWAN interface
|
||||
# startup scripts.
|
||||
|
||||
# These rules assume that there is only one WWAN modem in the system. In
|
||||
# order to address multiple WWAN cards, the rules need to be more
|
||||
# specific and associate with serial numbers of the modems.
|
||||
|
||||
# Copyright (c) 2016 Stanislav Sinyagin <ssinyagin@k-open.com>.
|
||||
|
||||
# This content is published under Creative Commons Attribution 4.0
|
||||
# International (CC BY 4.0) license.
|
||||
# Source repository: https://github.com/ssinyagin/wwan_udev_rules
|
||||
|
||||
if ! check_if_installed ppp then; then
|
||||
apt-get -y -qq install ppp >/dev/null 2>&1
|
||||
fi
|
||||
cat >/etc/udev/rules.d/99-wwan.rules <<'EOT'
|
||||
|
||||
|
||||
# Source repository: https://github.com/ssinyagin/wwan_udev_rules
|
||||
|
||||
# Huawei ME909s-120 LTE modem
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="15c1", SYMLINK+="ttyWWAN%E{ID_USB_INTERFACE_NUM}"
|
||||
SUBSYSTEM=="net", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="15c1", NAME="lte0"
|
||||
|
||||
# Huawei MU709s-2 UMTS modem
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1c25", SYMLINK+="ttyWWAN%E{ID_USB_INTERFACE_NUM}"
|
||||
SUBSYSTEM=="net", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1c25", NAME="umts0"
|
||||
|
||||
# Qualcomm Gobi2000
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="251d", SYMLINK+="ttyWWAN%E{ID_USB_INTERFACE_NUM}"
|
||||
|
||||
# Sierra Wireless MC8775
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1e1d", SYMLINK+="ttyWWAN%E{.ID_PORT}"
|
||||
|
||||
# Novatel Wireless, Inc. Expedite E371
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="413c", ATTRS{idProduct}=="819b", SYMLINK+="ttyWWAN%E{ID_USB_INTERFACE_NUM}"
|
||||
|
||||
# SIMCom SIM7100
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="1e0e", ATTRS{idProduct}=="9001", SYMLINK+="ttyWWAN%E{ID_USB_INTERFACE_NUM}"
|
||||
SUBSYSTEM=="net", ATTRS{idVendor}=="1e0e", ATTRS{idProduct}=="9001", NAME="lte0"
|
||||
EOT
|
||||
|
||||
# reload udev rules
|
||||
udevadm control --reload-rules && udevadm trigger
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# 3G/4G init scripts add + remove
|
||||
#
|
||||
function lte ()
|
||||
{
|
||||
case $1 in
|
||||
"12d1:15c1" )
|
||||
# Huawei ME909s-120 LTE modem
|
||||
LTE_MODEM_ID=$1
|
||||
if [[ $2 == on && $(cat /sys/class/net/lte0/operstate) == "up" ]]; then
|
||||
show_box "Warning" "Huawei ME909s-120 LTE modem is up and running" 7
|
||||
elif [[ $2 == on ]]; then
|
||||
show_box "Info" "Huawei ME909s-120 LTE modem will try to connect" 7
|
||||
cat >/etc/chatscripts/sunrise.HUAWEI <<'EOT'
|
||||
ABORT BUSY
|
||||
ABORT 'NO CARRIER'
|
||||
ABORT ERROR
|
||||
TIMEOUT 10
|
||||
'' ATZ
|
||||
OK 'AT+CFUN=1'
|
||||
OK 'AT+CMEE=1'
|
||||
OK 'AT\^NDISDUP=1,1,"internet"'
|
||||
OK
|
||||
EOT
|
||||
cat >/etc/chatscripts/gsm_off.HUAWEI <<'EOT'
|
||||
ABORT ERROR
|
||||
TIMEOUT 5
|
||||
'' AT+CFUN=0 OK
|
||||
EOT
|
||||
|
||||
cat >/etc/network/interfaces.d/lte0 <<'EOT'
|
||||
allow-hotplug lte0
|
||||
iface lte0 inet dhcp
|
||||
pre-up /usr/sbin/chat -v -f /etc/chatscripts/sunrise.HUAWEI >/dev/ttyWWAN02 </dev/ttyWWAN02
|
||||
post-down /usr/sbin/chat -v -f /etc/chatscripts/gsm_off.HUAWEI >/dev/ttyWWAN02 </dev/ttyWWAN02
|
||||
EOT
|
||||
|
||||
# disable interface
|
||||
ifup lte0 2> /dev/null
|
||||
|
||||
elif [[ $2 == off ]]; then
|
||||
show_box "Warning" "Huawei ME909s-120 LTE will kill connection" 7
|
||||
# enable interface
|
||||
ifdown lte0 2> /dev/null
|
||||
rm /etc/chatscripts/sunrise.HUAWEI
|
||||
rm /etc/chatscripts/gsm_off.HUAWEI
|
||||
rm /etc/network/interfaces.d/lte0
|
||||
elif [[ $(cat /sys/class/net/lte0/operstate) == "up" ]]; then
|
||||
LTE_MODEM="Huawei ME909s-120 LTE modem is online"
|
||||
else
|
||||
LTE_MODEM="Huawei ME909s-120 LTE modem is offline"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check hostapd configuration. Return error or empty if o.k.
|
||||
#
|
||||
check_hostapd ()
|
||||
{
|
||||
|
||||
systemctl daemon-reload
|
||||
hostapd_error=""
|
||||
[[ -n $1 && -n $2 ]] && dialog --title " $1 " --backtitle "$BACKTITLE" --no-collapse --colors --infobox "$2" 5 $((${#2}-3))
|
||||
service hostapd stop
|
||||
rm -f /var/run/hostapd/*
|
||||
sleep 1
|
||||
service hostapd start
|
||||
sleep 6
|
||||
if [[ "$(hostapd_cli ping 2> /dev/null| grep PONG)" == "PONG" ]]; then
|
||||
hostapd_error=""
|
||||
else
|
||||
hostapd_error=$(hostapd /etc/hostapd.conf)
|
||||
sleep 6
|
||||
[[ -n $(echo $hostapd_error | grep "channel") ]] && hostapd_error="channel_restriction"
|
||||
[[ -n $(echo $hostapd_error | grep "does not support" | grep "hw_mode") ]] && hostapd_error="hw_mode"
|
||||
[[ -n $(echo $hostapd_error | grep "not found from the channel list" | grep "802.11g") ]] && hostapd_error="wrong_channel"
|
||||
[[ -n $(echo $hostapd_error | grep "VHT") ]] && hostapd_error="unsupported_vht"
|
||||
[[ -n $(echo $hostapd_error | grep " HT capability") ]] && hostapd_error="unsupported_ht"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check all possible wireless modes
|
||||
#
|
||||
function check_advanced_modes ()
|
||||
{
|
||||
|
||||
sed '/### IEEE 802.11n/,/^### IEEE 802.11n/ s/^# *//' -i /etc/hostapd.conf
|
||||
check_hostapd "Probing" "\n802.11n \Z1(150-300Mbps)\Z0"
|
||||
# check HT capability
|
||||
check_ht_capab
|
||||
if [[ -z "$hostapd_error" ]]; then
|
||||
sed '/### IEEE 802.11a\>/,/^### IEEE 802.11a\>/ s/^# *//' -i /etc/hostapd.conf
|
||||
sed -i "s/^channel=.*/channel=40/" /etc/hostapd.conf
|
||||
check_hostapd "Probing" "\n802.11a \Z1(5Ghz)\Z0"
|
||||
if [[ "$hostapd_error" == "channel_restriction" ]]; then check_channels; fi
|
||||
if [[ "$hostapd_error" == "channel_restriction" ]]; then
|
||||
# revering configuration
|
||||
sed -i "s/^channel=.*/channel=5/" /etc/hostapd.conf
|
||||
sed '/## IEEE 802.11a\>/,/^## IEEE 802.11a\>/ s/.*/#&/' -i /etc/hostapd.conf
|
||||
check_hostapd "Reverting" "\nWireless \Z1802.11a (5Ghz)\Z0 is not supported"
|
||||
else
|
||||
sed '/### IEEE 802.11ac\>/,/^### IEEE 802.11ac\>/ s/^# *//' -i /etc/hostapd.conf
|
||||
# check VHT capability
|
||||
check_vht_capab
|
||||
if [[ "$hostapd_error" == "unsupported_vht" || "$hostapd_error" == "channel_restriction" ]]; then
|
||||
# revering configuration
|
||||
sed '/## IEEE 802.11ac\>/,/^## IEEE 802.11ac\>/ s/.*/#&/' -i /etc/hostapd.conf
|
||||
check_hostapd "Reverting" "\nWireless 802.11ac \Z1(433Mbps x n @ 5Ghz)\Z0 is not supported"
|
||||
if [[ "$hostapd_error" == "channel_restriction" ]]; then check_channels; fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
sed '/## IEEE 802.11n/,/^## IEEE 802.11n/ s/.*/#&/' -i /etc/hostapd.conf
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# create interface configuration section
|
||||
#
|
||||
function create_if_config() {
|
||||
|
||||
address=$(ip -4 addr show dev $1 | awk '/inet/ {print $2}' | cut -d'/' -f1)
|
||||
netmask=$(ip -4 addr show dev $1 | awk '/inet/ {print $2}' | cut -d'/' -f2)
|
||||
gateway=$(route -n | grep 'UG[ \t]' | awk '{print $2}' | sed -n '1p')
|
||||
echo -e "# orangepi-config created"
|
||||
echo -e "source /etc/network/interfaces.d/*\n"
|
||||
if [[ "$3" == "fixed" ]]; then
|
||||
echo -e "# Local loopback\nauto lo\niface lo init loopback\n"
|
||||
echo -e "# Interface $2\nauto $2\nallow-hotplug $2"
|
||||
echo -e "iface $2 inet static\n\taddress $address\n\tnetmask $netmask\n\tgateway $gateway\n\tdns-nameservers 8.8.8.8"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# reload network related services
|
||||
#
|
||||
function reload-nety() {
|
||||
|
||||
systemctl daemon-reload
|
||||
if [[ "$1" == "reload" ]]; then WHATODO="Reloading services"; else WHATODO="Stopping services"; fi
|
||||
(service network-manager stop; echo 10; sleep 1; service hostapd stop; echo 20; sleep 1; service dnsmasq stop; echo 30; sleep 1;\
|
||||
[[ "$1" == "reload" ]] && service dnsmasq start && echo 60 && sleep 1 && service hostapd start && echo 80 && sleep 1;\
|
||||
service network-manager start; echo 90; sleep 5;) | dialog --backtitle "$BACKTITLE" --title " $WHATODO " --gauge "" 6 70 0
|
||||
systemctl restart systemd-resolved.service
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Check if something is running on port $1 and display info
|
||||
#
|
||||
function check_port ()
|
||||
{
|
||||
[[ -n $(netstat -lnt | awk '$6 == "LISTEN" && $4 ~ ".'$1'"') ]] && dialog --backtitle "$BACKTITLE" --title "Checking service" \
|
||||
--msgbox "\nIt looks good.\n\nThere is $2 service on port $1" 9 52
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check wifi high throughput
|
||||
#
|
||||
function check_ht_capab ()
|
||||
{
|
||||
declare -a arr=("[HT40+][LDPC][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1][DSSS_CCK-40][SMPS-STATIC]" \
|
||||
"[HT40-][SHORT-GI-40][SHORT-GI-40][DSSS_CCK-40]" "[SHORT-GI-20][SHORT-GI-40][HT40+]" "[DSSS_CK-40][HT20+]" "")
|
||||
local j=0
|
||||
for i in "${arr[@]}"
|
||||
do
|
||||
j=$((j+(100/${#arr[@]})))
|
||||
echo $j | dialog --title " Probing HT " --colors --gauge "\nSeeking for optimal \Z1high throughput\Z0 settings." 8 50 0
|
||||
sed -i "s/^ht_capab=.*/ht_capab=$i/" /etc/hostapd.conf
|
||||
check_hostapd
|
||||
if [[ "$hostapd_error" == "channel_restriction" ]]; then check_channels; fi
|
||||
if [[ "$hostapd_error" == "" ]]; then break; fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check wifi high throughput
|
||||
#
|
||||
function check_vht_capab ()
|
||||
{
|
||||
|
||||
declare -a arr=("[MAX-MPDU-11454][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][MAX-A-MPDU-LEN-EXP3]" "[MAX-MPDU-11454][SHORT-GI-80][RX-STBC-1][MAX-A-MPDU-LEN-EXP3]" "")
|
||||
local j=0
|
||||
for i in "${arr[@]}"
|
||||
do
|
||||
j=$((j+(100/${#arr[@]})))
|
||||
echo $j | dialog --title " Probing VHT " --colors --gauge "\nSeeking for optimal \Z1very high throughput\Z0 settings." 8 54 0
|
||||
sed -i "s/^vht_capab=.*/vht_capab=$i/" /etc/hostapd.conf
|
||||
check_hostapd
|
||||
if [[ "$hostapd_error" == "channel_restriction" ]]; then check_channels; fi
|
||||
if [[ "$hostapd_error" == "" ]]; then break; fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# check 5Ghz channels
|
||||
#
|
||||
function check_channels ()
|
||||
{
|
||||
|
||||
declare -a arr=("36" "40")
|
||||
for i in "${arr[@]}"
|
||||
do
|
||||
sed -i "s/^channel=.*/channel=$i/" /etc/hostapd.conf
|
||||
check_hostapd "Probing" "\nChannel:\Z1 ${i}\Z0"
|
||||
if [[ "$hostapd_error" != "channel_restriction" ]]; then break; fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# convert netmask to CIDR
|
||||
#
|
||||
function netmask_to_cidr ()
|
||||
{
|
||||
IFS=' '
|
||||
local bits=0
|
||||
for octet in $(echo $1| sed 's/\./ /g'); do
|
||||
binbits=$(echo "obase=2; ibase=10; ${octet}"| bc | sed 's/0//g')
|
||||
let bits+=${#binbits}
|
||||
done
|
||||
echo "${bits}"
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# edit ip address within network manager
|
||||
#
|
||||
function nm_ip_editor ()
|
||||
{
|
||||
|
||||
exec 3>&1
|
||||
dialog --title " Static IP configuration" --backtitle "$BACKTITLE" --form "\nAdapter: $1
|
||||
\n " 12 38 0 \
|
||||
"Address:" 1 1 "$address" 1 15 15 0 \
|
||||
"Netmask:" 2 1 "$netmask" 2 15 15 0 \
|
||||
"Gateway:" 3 1 "$gateway" 3 15 15 0 \
|
||||
2>&1 1>&3 | {
|
||||
read -r address;read -r netmask;read -r gateway
|
||||
if [[ $? = 0 ]]; then
|
||||
localuuid=$(LC_ALL=C nmcli -f UUID,DEVICE connection show | grep $1 | awk '{print $1}')
|
||||
# convert netmask value to CIDR if required
|
||||
if [[ $netmask =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||
CIDR=$(netmask_to_cidr ${netmask})
|
||||
else
|
||||
CIDR=${netmask}
|
||||
fi
|
||||
if [[ -n "$localuuid" ]]; then
|
||||
# adjust existing
|
||||
nmcli con mod $localuuid ipv4.method manual ipv4.addresses "$address/$CIDR" >/dev/null 2>&1
|
||||
nmcli con mod $localuuid ipv4.method manual ipv4.gateway "$gateway" >/dev/null 2>&1
|
||||
nmcli con mod $localuuid ipv4.dns "8.8.8.8,$gateway" >/dev/null 2>&1
|
||||
nmcli con down $localuuid >/dev/null 2>&1
|
||||
sleep 2
|
||||
nmcli con up $localuuid >/dev/null 2>&1
|
||||
else
|
||||
# create new
|
||||
nmcli con add con-name "orangepi" ifname "$1" type 802-3-ethernet ip4 "$address/$CIDR" gw4 "$gateway" >/dev/null 2>&1
|
||||
nmcli con mod "orangepi" ipv4.dns "8.8.8.8,$gateway" >/dev/null 2>&1
|
||||
nmcli con up "orangepi" >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# edit ip address
|
||||
#
|
||||
function systemd_ip_editor ()
|
||||
{
|
||||
|
||||
local filename="/etc/systemd/network/10-$1.network"
|
||||
if [[ -f $filename ]]; then
|
||||
sed -i '/Network/,$d' $filename
|
||||
exec 3>&1
|
||||
dialog --title " Static IP configuration" --backtitle "$BACKTITLE" --form "\nAdapter: $1
|
||||
\n " 12 38 0 \
|
||||
"Address:" 1 1 "$address" 1 15 15 0 \
|
||||
"Netmask:" 2 1 "$netmask" 2 15 15 0 \
|
||||
"Gateway:" 3 1 "$gateway" 3 15 15 0 \
|
||||
2>&1 1>&3 | {
|
||||
read -r address;read -r netmask;read -r gateway
|
||||
if [[ $? = 0 ]]; then
|
||||
echo -e "[Network]" >>$filename
|
||||
echo -e "Address=$address" >> $filename
|
||||
echo -e "Gateway=$gateway" >> $filename
|
||||
echo -e "DNS=8.8.8.8" >> $filename
|
||||
fi
|
||||
}
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# edit ip address
|
||||
#
|
||||
function ip_editor ()
|
||||
{
|
||||
|
||||
exec 3>&1
|
||||
dialog --title " Static IP configuration" --backtitle "$BACKTITLE" --form "\nAdapter: $1
|
||||
\n " 12 38 0 \
|
||||
"Address:" 1 1 "$address" 1 15 15 0 \
|
||||
"Netmask:" 2 1 "$netmask" 2 15 15 0 \
|
||||
"Gateway:" 3 1 "$gateway" 3 15 15 0 \
|
||||
2>&1 1>&3 | {
|
||||
read -r address;read -r netmask;read -r gateway
|
||||
if [[ $? = 0 ]]; then
|
||||
echo -e "# orangepi-config created\nsource /etc/network/interfaces.d/*\n" >$3
|
||||
echo -e "# Local loopback\nauto lo\niface lo inet loopback\n" >> $3
|
||||
echo -e "# Interface $2\nauto $2\nallow-hotplug $2\niface $2 inet static\
|
||||
\n\taddress $address\n\tnetmask $netmask\n\tgateway $gateway\n\tdns-nameservers 8.8.8.8" >> $3
|
||||
fi
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# edit hostapd parameters
|
||||
#
|
||||
function wlan_edit_basic ()
|
||||
{
|
||||
source /etc/hostapd.conf
|
||||
exec 3>&1
|
||||
dialog --title "AP configuration" --backtitle "$BACKTITLE" --form "\nWPA2 enabled, \
|
||||
advanced config: edit /etc/hostapd.conf\n " 12 58 0 \
|
||||
"SSID:" 1 1 "$ssid" 1 31 22 0 \
|
||||
"Password:" 2 1 "$wpa_passphrase" 2 31 22 0 \
|
||||
"Channel:" 3 1 "$channel" 3 31 3 0 \
|
||||
2>&1 1>&3 | {
|
||||
read -r ssid;read -r wpa_passphrase;read -r channel
|
||||
if [[ $? = 0 ]]; then
|
||||
sed -i "s/^ssid=.*/ssid=$ssid/" /etc/hostapd.conf
|
||||
sed -i "s/^wpa_passphrase=.*/wpa_passphrase=$wpa_passphrase/" /etc/hostapd.conf
|
||||
sed -i "s/^channel=.*/channel=$channel/" /etc/hostapd.conf
|
||||
wpa_psk=$(wpa_passphrase $ssid $wpa_passphrase | grep '^[[:blank:]]*[^[:blank:]#;]' | grep psk | cut -d= -f2-)
|
||||
sed -i "s/^wpa_psk=.*/wpa_psk=$wpa_psk/" /etc/hostapd.conf
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# edit hostapd parameters
|
||||
#
|
||||
function wlan_edit ()
|
||||
{
|
||||
|
||||
# select default interfaces if there is more than one
|
||||
select_interface "default"
|
||||
dialog --title " Configuration edit " --colors --backtitle "$BACKTITLE" --help-button --help-label "Cancel" --yes-label "Basic" \
|
||||
--no-label "Advanced" --yesno "\n\Z1Basic:\Z0 Change SSID, password and channel\n\n\Z1Advanced:\Z0 Edit /etc/hostapd.conf file" 9 70
|
||||
if [[ $? = 0 ]]; then
|
||||
wlan_edit_basic
|
||||
elif [[ $? = 1 ]]; then
|
||||
dialog --backtitle "$BACKTITLE" --title " Edit hostapd configuration /etc/hostapd.conf" --no-collapse \
|
||||
--ok-label "Save" --editbox /etc/hostapd.conf 30 0 2> /etc/hostapd.conf.out
|
||||
[[ $? = 0 ]] && mv /etc/hostapd.conf.out /etc/hostapd.conf && service hostapd restart
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# here we add wifi exceptions
|
||||
#
|
||||
function wlan_exceptions ()
|
||||
{
|
||||
|
||||
reboot_module=false
|
||||
[[ -n "$(lsmod | grep -w dhd)" && $1 = "on" ]] && \
|
||||
echo 'options dhd op_mode=2' >/etc/modprobe.d/ap6212.conf && rmmod dhd && modprobe dhd
|
||||
[[ -n "$(lsmod | grep -w dhd)" && $1 = "off" ]] && \
|
||||
rm /etc/modprobe.d/ap6212.conf && rmmod dhd && modprobe dhd
|
||||
# Cubietruck
|
||||
[[ -n "$(lsmod | grep -w ap6210)" && $1 = "on" ]] && \
|
||||
echo 'options ap6210 op_mode=2' >/etc/modprobe.d/ap6210.conf && reboot_module=true
|
||||
[[ -n "$(lsmod | grep -w ap6210)" && $1 = "off" ]] && \
|
||||
rm /etc/modprobe.d/ap6210.conf && reboot_module=true
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# here add shaddy wifi adaptors
|
||||
#
|
||||
function check_and_warn ()
|
||||
{
|
||||
|
||||
local shaddy=false
|
||||
# blacklist
|
||||
[[ "$LINUXFAMILY" == "sun8i" && $BOARD == "orangepizero" ]] && shaddy=true
|
||||
[[ -n "$(lsmod | grep mt7601u)" ]] && shaddy=true
|
||||
[[ -n "$(lsmod | grep r8188eu)" ]] && shaddy=true
|
||||
# blacklist
|
||||
if [[ "$shaddy" == "true" ]]; then
|
||||
dialog --title " Warning " --ok-label " Accept and proceed " --msgbox '\nOne of your wireless drivers are on a black list due to poor quality.\n\nAP mode might not be possible!' 9 73
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# search for wlan interfaces and provide a selection menu if there are more than one
|
||||
#
|
||||
function get_wlan_interface ()
|
||||
{
|
||||
|
||||
IFS=$'\r\n'
|
||||
GLOBIGNORE='*'
|
||||
|
||||
WLAN_INTERFACES=($(LC_ALL=C nmcli --wait 10 dev status | grep wifi | grep disconnected |awk '{print $1}'))
|
||||
local LIST=()
|
||||
for i in "${WLAN_INTERFACES[@]}"
|
||||
do
|
||||
LIST+=( "${i[0]//[[:blank:]]/}" "" )
|
||||
done
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
|
||||
if [ "$LIST_LENGTH" -eq 1 ]; then
|
||||
WIRELESS_ADAPTER=${WLAN_INTERFACES[0]}
|
||||
else
|
||||
exec 3>&1
|
||||
WIRELESS_ADAPTER=$(dialog --nocancel --backtitle "$BACKTITLE" --no-collapse \
|
||||
--title "Select interface" --clear --menu "" $((6+${LIST_LENGTH})) 40 15 "${LIST[@]}" 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function select_interface ()
|
||||
{
|
||||
IFS=$'\r\n'
|
||||
GLOBIGNORE='*'
|
||||
local ADAPTER=($(nmcli device status | grep ethernet | awk '{ print $1 }' | grep -v lo))
|
||||
local LIST=()
|
||||
for i in "${ADAPTER[@]}"
|
||||
do
|
||||
local IPADDR=$(LC_ALL=C ip -4 addr show dev ${i[0]} | awk '/inet/ {print $2}' | cut -d'/' -f1)
|
||||
ADD_SPEED=""
|
||||
[[ $i == eth* || $i == en* ]] && ADD_SPEED=$(ethtool $i | grep Speed)
|
||||
[[ $i == wl* ]] && ADD_SPEED=$(LC_ALL=C nmcli -f RATE,DEVICE,ACTIVE dev wifi list | grep $i | grep yes | awk 'NF==4{print $1""$2}NF==1' | sed -e 's/^/ Speed: /' | tail -1)
|
||||
LIST+=( "${i[0]//[[:blank:]]/}" "${IPADDR} ${ADD_SPEED}" )
|
||||
done
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
if [ "$LIST_LENGTH" -eq 0 ]; then
|
||||
SELECTED_ADAPTER="lo"
|
||||
elif [ "$LIST_LENGTH" -eq 1 ]; then
|
||||
SELECTED_ADAPTER=${ADAPTER[0]}
|
||||
else
|
||||
exec 3>&1
|
||||
SELECTED_ADAPTER=$(dialog --nocancel --backtitle "$BACKTITLE" --no-collapse --title "Select $1 interface" --clear \
|
||||
--menu "" $((6+${LIST_LENGTH})) 74 14 "${LIST[@]}" 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# select interface if there is more than one and adjust metric
|
||||
#
|
||||
# $1 = default | all
|
||||
#
|
||||
function select_default_interface ()
|
||||
{
|
||||
|
||||
ALREADY_DEFINED=$(cat /etc/iptables.ipv4.nat 2> /dev/null | grep "POSTROUTING -o" | tail -1 | awk '{ print $4 }')
|
||||
if [[ -n "${ALREADY_DEFINED}" ]]; then
|
||||
DEFAULT_ADAPTER=${ALREADY_DEFINED}
|
||||
else
|
||||
IFS=$'\r\n'
|
||||
GLOBIGNORE='*'
|
||||
if [[ $1 == "default" ]]; then
|
||||
local ADAPTER=($(nmcli -t -f DEVICE connection show --active))
|
||||
else
|
||||
local ADAPTER=($(nmcli device status | tail -n +2 | awk '{ print $1 }' | grep -v lo))
|
||||
fi
|
||||
local LIST=()
|
||||
for i in "${ADAPTER[@]}"
|
||||
do
|
||||
local IPADDR=$(LC_ALL=C ip -4 addr show dev ${i[0]} | awk '/inet/ {print $2}' | cut -d'/' -f1)
|
||||
ADD_SPEED=""
|
||||
[[ $i == eth* || $i == en* ]] && ADD_SPEED=$(ethtool $i | grep Speed)
|
||||
[[ $i == wl* ]] && ADD_SPEED=$(LC_ALL=C nmcli -f RATE,DEVICE,ACTIVE dev wifi list | grep $i | grep yes | awk 'NF==4{print $1""$2}NF==1' | sed -e 's/^/ Speed: /' | tail -1)
|
||||
if [[ $1 == "default" ]]; then
|
||||
[[ $IPADDR != "172.24.1.1" && -n $IPADDR ]] && LIST+=( "${i[0]//[[:blank:]]/}" "${IPADDR} ${ADD_SPEED}" )
|
||||
else
|
||||
[[ $IPADDR != "172.24.1.1" ]] && LIST+=( "${i[0]//[[:blank:]]/}" "${IPADDR} ${ADD_SPEED}" )
|
||||
fi
|
||||
done
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
if [ "$LIST_LENGTH" -eq 0 ]; then
|
||||
DEFAULT_ADAPTER="lo"
|
||||
elif [ "$LIST_LENGTH" -eq 1 ]; then
|
||||
DEFAULT_ADAPTER=${ADAPTER[0]}
|
||||
else
|
||||
exec 3>&1
|
||||
DEFAULT_ADAPTER=$(dialog --nocancel --backtitle "$BACKTITLE" --no-collapse \
|
||||
--title "Select $1 interface" --clear --menu "" $((6+${LIST_LENGTH})) 74 14 "${LIST[@]}" 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
fi
|
||||
fi
|
||||
|
||||
# set highest metric to default adaptor
|
||||
HIGHEST_METRIC=$(nmcli -t -f UUID,TYPE,DEVICE connection show --active | grep $DEFAULT_ADAPTER | sed 's/:.*$//')
|
||||
|
||||
# set metric to 50
|
||||
nmcli connection modify $HIGHEST_METRIC ipv4.route-metric 50 2> /dev/null
|
||||
|
||||
METRIC=77
|
||||
# set others wired
|
||||
REMAINING=( `nmcli -t -f UUID,TYPE,DEVICE connection show --active | grep ethernet | grep -v $DEFAULT_ADAPTER | sed 's/:.*$//'` )
|
||||
if [[ ${#REMAINING[@]} -ge 1 ]]; then
|
||||
for i in "${REMAINING[@]}"
|
||||
do
|
||||
METRIC=$(( $METRIC + 1 ))
|
||||
nmcli connection modify ${i} ipv4.route-metric $METRIC
|
||||
done
|
||||
fi
|
||||
|
||||
# set other wireless
|
||||
METRIC=88
|
||||
REMAINING=( `nmcli -t -f UUID,TYPE,DEVICE connection show --active | grep wireless | grep -v $DEFAULT_ADAPTER | sed 's/:.*$//'` )
|
||||
if [[ ${#REMAINING[@]} -ge 1 ]]; then
|
||||
for i in "${REMAINING[@]}"
|
||||
do
|
||||
METRIC=$(( $METRIC + 1 ))
|
||||
nmcli connection modify ${i} ipv4.route-metric $METRIC
|
||||
done
|
||||
fi
|
||||
|
||||
# create default metrics file
|
||||
cat <<-EOF > /etc/NetworkManager/conf.d/orangepi-default-metric.conf
|
||||
[connection-ethernet-gateway]
|
||||
match-device=interface-name:$DEFAULT_ADAPTER
|
||||
ipv4.route-metric=50
|
||||
|
||||
[connection-wifi-other]
|
||||
match-device=type:wifi
|
||||
ipv4.route-metric=88
|
||||
|
||||
[connection-ethernet-other]
|
||||
match-device=type:ethernet
|
||||
ipv4.route-metric=77
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# search and connect to Bluetooth devices
|
||||
#
|
||||
function connect_bt_interface ()
|
||||
{
|
||||
|
||||
IFS=$'\r\n'
|
||||
GLOBIGNORE='*'
|
||||
dialog --backtitle "$BACKTITLE" --title "Please wait" --infobox "\nDiscovering Bluetooth devices ... " 5 37
|
||||
BT_INTERFACES=($(hcitool scan | sed '1d'))
|
||||
|
||||
local LIST=()
|
||||
for i in "${BT_INTERFACES[@]}"
|
||||
do
|
||||
local a=$(echo ${i[0]//[[:blank:]]/} | sed -e 's/^\(.\{17\}\).*/\1/')
|
||||
local b=${i[0]//$a/}
|
||||
local b=$(echo $b | sed -e 's/^[ \t]*//')
|
||||
LIST+=( "$a" "$b")
|
||||
done
|
||||
|
||||
LIST_LENGTH=$((${#LIST[@]}/2));
|
||||
if [ "$LIST_LENGTH" -eq 0 ]; then
|
||||
BT_ADAPTER=${WLAN_INTERFACES[0]}
|
||||
dialog --backtitle "$BACKTITLE" --title "Bluetooth" --msgbox "\nNo nearby Bluetooth devices were found!" 7 43
|
||||
else
|
||||
exec 3>&1
|
||||
BT_ADAPTER=$(dialog --backtitle "$BACKTITLE" --no-collapse --title "Select interface" \
|
||||
--clear --menu "" $((6+${LIST_LENGTH})) 50 15 "${LIST[@]}" 2>&1 1>&3)
|
||||
exec 3>&-
|
||||
if [[ $BT_ADAPTER != "" ]]; then
|
||||
dialog --backtitle "$BACKTITLE" --title "Please wait" --infobox "\nConnecting to $BT_ADAPTER " 5 35
|
||||
BT_EXEC=$(
|
||||
expect -c 'set prompt "#";set address '$BT_ADAPTER';spawn bluetoothctl;expect -re $prompt;send "disconnect $address\r";
|
||||
sleep 1;send "remove $address\r";sleep 1;expect -re $prompt;send "scan on\r";sleep 8;send "scan off\r";
|
||||
expect "Controller";send "trust $address\r";sleep 2;send "pair $address\r";sleep 2;send "connect $address\r";
|
||||
send_user "\nShould be paired now.\r";sleep 2;send "quit\r";expect eof')
|
||||
echo "$BT_EXEC" > /tmp/bt-connect-debug.log
|
||||
if [[ $(echo "$BT_EXEC" | grep "Connection successful" ) != "" ]]; then
|
||||
dialog --backtitle "$BACKTITLE" --title "Bluetooth" --msgbox "\nYour device is ready to use!" 7 32
|
||||
else
|
||||
dialog --backtitle "$BACKTITLE" --title "Bluetooth" --msgbox "\nError connecting. Try again!" 7 32
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
1576
external/cache/sources/orangepi-config/debian-config-jobs
vendored
Normal file
1576
external/cache/sources/orangepi-config/debian-config-jobs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
438
external/cache/sources/orangepi-config/debian-config-submenu
vendored
Normal file
438
external/cache/sources/orangepi-config/debian-config-submenu
vendored
Normal file
@@ -0,0 +1,438 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2018 Igor Pecovnik, igor.pecovnik@gma**.com
|
||||
#
|
||||
# This file is licensed under the terms of the GNU General Public
|
||||
# License version 2. This program is licensed "as is" without any
|
||||
# warranty of any kind, whether express or implied.
|
||||
|
||||
# Functions:
|
||||
# submenu_settings
|
||||
# submenu_networking
|
||||
# submenu_personal
|
||||
# submenu_software
|
||||
|
||||
|
||||
|
||||
#
|
||||
# system settings
|
||||
#
|
||||
function submenu_settings ()
|
||||
{
|
||||
unset main
|
||||
while true; do
|
||||
|
||||
LIST=()
|
||||
DIALOG_CANCEL=1
|
||||
DIALOG_ESC=255
|
||||
|
||||
# detect desktop
|
||||
check_desktop
|
||||
|
||||
# check update status of BSP packages
|
||||
local mark=$(apt-mark showhold | egrep "linux|orangepi")
|
||||
|
||||
# check if eMMC/SD is on the system
|
||||
if [[ $(sed -n 's/^DEVNAME=//p' /sys/dev/block/$(mountpoint -d /)/uevent 2> /dev/null) == mmcblk* \
|
||||
&& -f /usr/sbin/nand-sata-install ]]; then
|
||||
LIST+=( "Install" "Install to/update boot loader" )
|
||||
fi
|
||||
|
||||
# orangepi specific function
|
||||
if [[ -f /etc/orangepi-release ]]; then
|
||||
if [[ -n "${mark}" ]]; then
|
||||
:
|
||||
#LIST+=( "Defreeze" "Enable Orange Pi upgrades " )
|
||||
else
|
||||
:
|
||||
#LIST+=( "Freeze" "Disable Orange Pi upgrades " )
|
||||
fi
|
||||
fi
|
||||
|
||||
# orangepi specific function, when upgrades are enabled
|
||||
if [[ -z ${mark} ]]; then
|
||||
[[ -f /etc/apt/sources.list.d/orangepi.list ]] && [[ -n $(grep -w apt /etc/apt/sources.list.d/orangepi.list) ]] \
|
||||
&& LIST+=( "Nightly" "Switch to nightly automated builds" )
|
||||
[[ -f /etc/apt/sources.list.d/orangepi.list ]] && [[ -n $(grep -w beta /etc/apt/sources.list.d/orangepi.list) ]] \
|
||||
&& LIST+=( "Stable" "Switch to stable builds" )
|
||||
fi
|
||||
|
||||
[[ -n $(grep -w "#kernel.printk" /etc/sysctl.conf ) ]] && LIST+=( "Lowlevel" "Stop low-level messages on console" )
|
||||
|
||||
[[ -f /boot/orangepiEnv.txt ]] && LIST+=( "Bootenv" "Edit boot environment" )
|
||||
[[ -f /boot/boot.ini ]] && LIST+=( "Bootscript" "Edit boot script" )
|
||||
|
||||
if [[ -f /etc/default/cpufrequtils ]]; then
|
||||
LIST+=( "CPU" "Set CPU speed and governor" )
|
||||
fi
|
||||
|
||||
AVAHIDSTATUS=$(service avahi-daemon status 2> /dev/null | grep -w active | grep -w running)
|
||||
if [[ -n "$AVAHIDSTATUS" ]]; then
|
||||
LIST+=( "Avahi" "Disable system announce in the network" )
|
||||
else
|
||||
LIST+=( "Avahi" "Announce system in the network" )
|
||||
fi
|
||||
|
||||
[[ -d ${OVERLAYDIR} ]] && \
|
||||
LIST+=( "Hardware" "Toggle hardware configuration: UART, I2C, etc." )
|
||||
[[ "$LINUXFAMILY" = cubox && "$BRANCH" = "next" ]] && LIST+=( "DTB" "Switch board .dtb configuration" )
|
||||
# this is avaliable only in kernel higher than 4.10
|
||||
testvercomp "$(uname -r | sed 's/-.*//')" "4.10.0" ">"
|
||||
[[ "$LINUXFAMILY" = odroidxu4 && $? == 0 ]] && LIST+=( "DTB" "Select optimised board configuration" )
|
||||
[[ -f /usr/bin/bin2fex && "$LINUXFAMILY" = sun*i && "$BRANCH" = "default" ]] && LIST+=( "Fexedit" "Board (fex) settings editor" )
|
||||
|
||||
[[ -z ${mark} ]] && [[ -f /etc/apt/sources.list.d/orangepi.list ]] && LIST+=( "Other" "Switch to other kernels" )
|
||||
|
||||
LIST+=( "SSH" "Reconfigure SSH daemon" )
|
||||
LIST+=( "Firmware" "Run apt update & apt upgrade" )
|
||||
|
||||
if [[ "$SHELL" != "/bin/bash" ]]; then
|
||||
LIST+=( "BASH" "Revert to stock BASH shell" )
|
||||
else
|
||||
LIST+=( "ZSH" "Install ZSH with plugins and tmux" )
|
||||
fi
|
||||
|
||||
|
||||
[[ "$LINUXFAMILY" = sun*i && "$BRANCH" = "default" && \
|
||||
-n $(bin2fex </boot/script.bin 2>/dev/null | grep -w "hdmi_used = 1") ]] && LIST+=( "Display" "Set the display resolution" )
|
||||
[[ "$LINUXFAMILY" = odroidc* || "$LINUXFAMILY" = odroidn2 && "$BRANCH" = "default" ]] && LIST+=( "Display" "Set the display resolution" )
|
||||
# desktop
|
||||
if [[ -n $DISPLAY_MANAGER ]]; then
|
||||
LIST+=( "Desktop" "Disable desktop or change login type" )
|
||||
else
|
||||
if [[ -n $DESKTOP_INSTALLED ]]; then
|
||||
LIST+=( "Desktop" "Enable desktop" )
|
||||
else
|
||||
:
|
||||
#LIST+=( "Default" "Install desktop with browser and extras" )
|
||||
fi
|
||||
fi
|
||||
|
||||
# overlayroot
|
||||
if [[ "$DISTRO" == "Ubuntu" && "$(modinfo overlay > /dev/null 2>&1; echo $?)" == "0" ]]; then
|
||||
if [ -n "$(mount | grep -w tmpfs-root)" ]; then
|
||||
:
|
||||
#LIST+=( "Overlayroot" "Disable virtual read-only root filesystem" )
|
||||
else
|
||||
:
|
||||
#LIST+=( "Overlayroot" "Enable virtual read-only root filesystem" )
|
||||
fi
|
||||
fi
|
||||
|
||||
# count number of menu items to adjust window size
|
||||
LISTLENGTH="$((6+${#LIST[@]}/2))"
|
||||
BOXLENGTH=${#LIST[@]}
|
||||
temp_rc=$(mktemp)
|
||||
if [[ -n ${mark} || -n $(grep -w beta /etc/apt/sources.list.d/orangepi.list 2> /dev/null) ]]; then
|
||||
cat <<-'EOF' > $temp_rc
|
||||
dialog_color = (RED,WHITE,OFF)
|
||||
screen_color = (WHITE,RED,ON)
|
||||
tag_color = (RED,WHITE,ON)
|
||||
item_selected_color = (WHITE,RED,ON)
|
||||
tag_selected_color = (WHITE,RED,ON)
|
||||
tag_key_selected_color = (WHITE,RED,ON)
|
||||
EOF
|
||||
[[ -n ${mark} ]] && local sys_title=" Warning - firmware packages frozen"
|
||||
[[ -n $(grep -w beta /etc/apt/sources.list.d/orangepi.list 2> /dev/null) ]] && \
|
||||
local sys_title=" Warning - attached to beta repository"
|
||||
[[ -n ${mark} && -n $(grep -w beta /etc/apt/sources.list.d/orangepi.list 2> /dev/null) ]] && \
|
||||
sys_title=" Warning - frozen & attached to beta repository"
|
||||
else
|
||||
local sys_title=" System settings "
|
||||
echo > $temp_rc
|
||||
fi
|
||||
|
||||
if [[ -z $selection ]]; then
|
||||
exec 3>&1
|
||||
selection=$(DIALOGRC=$temp_rc dialog --colors --backtitle "$BACKTITLE" --title " $sys_title " --clear \
|
||||
--cancel-label "Back" --menu "$disclaimer" $LISTLENGTH 0 $BOXLENGTH \
|
||||
"${LIST[@]}" 2>&1 1>&3)
|
||||
exit_status=$?
|
||||
exec 3>&-
|
||||
[[ $exit_status == $DIALOG_CANCEL || $exit_status == $DIALOG_ESC ]] && clear && break
|
||||
fi
|
||||
|
||||
# run main function
|
||||
jobs "$selection"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# menu for networking
|
||||
#
|
||||
function submenu_networking ()
|
||||
{
|
||||
|
||||
# select default interface if there is more than one connected
|
||||
#select_interface "default"
|
||||
unset main
|
||||
while true; do
|
||||
|
||||
LIST=()
|
||||
DIALOG_CANCEL=1
|
||||
DIALOG_ESC=255
|
||||
|
||||
# check if we have some LTE modems
|
||||
for i in $(lsusb | awk '{print $6}'); do lte "$i"; done;
|
||||
|
||||
# edit ip
|
||||
LIST+=( "IP" "Select dynamic or edit static IP address" )
|
||||
|
||||
# hostapd
|
||||
HOSTAPDBRIDGE=$(cat /etc/hostapd.conf 2> /dev/null | grep -w "^bridge=br0")
|
||||
HOSTAPDSTATUS=$(service hostapd status 2> /dev/null | grep -w active | grep -w running)
|
||||
if [[ -n "$HOSTAPDSTATUS" ]]; then
|
||||
HOSTAPDINFO=$(hostapd_cli get_config 2> /dev/null | grep ^ssid | sed 's/ssid=//g')
|
||||
HOSTAPDCLIENTS=$(hostapd_cli all_sta 2> /dev/null | grep connected_time | wc -l)
|
||||
#LIST+=( "Hotspot" "Manage active wireless access point" )
|
||||
else
|
||||
:
|
||||
#[[ -n $(LC_ALL=C nmcli device status 2> /dev/null | grep wifi | grep -w disconnected) ]] && \
|
||||
#LIST+=( "Hotspot" "Create WiFi access point" )
|
||||
|
||||
fi
|
||||
|
||||
# toggle IPv6
|
||||
if [[ $(cat /proc/sys/net/ipv6/conf/all/disable_ipv6) == 1 ]]; then
|
||||
LIST+=( "IPV6" "Enable IPv6 for APT and system" )
|
||||
else
|
||||
LIST+=( "IPV6" "Disable IPv6 for APT and system" )
|
||||
fi
|
||||
|
||||
# network throughput test
|
||||
if check_if_installed iperf3; then
|
||||
if pgrep -x "iperf3" > /dev/null
|
||||
then
|
||||
LIST+=( "Iperf3" "Disable network throughput tests daemon" )
|
||||
else
|
||||
LIST+=( "Iperf3" "Enable network throughput tests daemon" )
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n $(LC_ALL=C nmcli device status 2> /dev/null | grep wifi | grep -v unavailable | grep -v unmanaged) ]]; then
|
||||
LIST+=( "WiFi" "Manage wireless networking" )
|
||||
else
|
||||
LIST+=( "Clear" "Clear possible blocked interfaces" )
|
||||
fi
|
||||
|
||||
if [[ -n $LTE_MODEM ]]; then
|
||||
# apply udev rules
|
||||
initialize_lte
|
||||
LIST+=( "LTE" "$LTE_MODEM" )
|
||||
fi
|
||||
|
||||
check_if_installed lirc && LIST+=( "Remove IR" "Remove IR support" ) || LIST+=( "IR" "Install IR support" )
|
||||
if check_if_installed bluetooth then ; then
|
||||
LIST+=( "BT remove" "Remove Bluetooth support" )
|
||||
if [[ -n $(service bluetooth status | grep -w active | grep -w running) ]]; then
|
||||
[[ $(hcitool dev | sed '1d') != "" ]] && LIST+=( "BT discover" "Discover and connect Bluetooth devices" )
|
||||
fi
|
||||
else
|
||||
LIST+=( "BT install" "Install Bluetooth support" )
|
||||
fi
|
||||
|
||||
|
||||
|
||||
[[ -d /usr/local/vpnclient ]] && LIST+=( "VPN" "Manage Softether VPN client" ) && VPNSERVERIP=$(/usr/local/vpnclient/vpncmd /client localhost /cmd accountlist | grep "VPN Server" |grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | head -1)
|
||||
|
||||
LIST+=( "Advanced" "Edit /etc/network/interfaces" )
|
||||
[[ $(ls -1 /etc/NetworkManager/system-connections 2> /dev/null) ]] && \
|
||||
LIST+=( "Forget" "Disconnect and forget all wireless connections" )
|
||||
|
||||
# count number of menu items to adjust window size
|
||||
LISTLENGTH="$((12+${#LIST[@]}/2))"
|
||||
BOXLENGTH=${#LIST[@]}
|
||||
WIFICONNECTED=$(LC_ALL=C nmcli -f NAME,TYPE connection show --active 2> /dev/null | grep wireless | awk 'NF{NF-=1};1')
|
||||
|
||||
local disclaimer=""
|
||||
|
||||
local ipadd=$(ip -4 addr show dev $DEFAULT_ADAPTER | awk '/inet/ {print $2}' | cut -d'/' -f1)
|
||||
|
||||
|
||||
if [[ -n $(LC_ALL=C nmcli device status 2> /dev/null | grep $DEFAULT_ADAPTER | grep connected) ]]; then
|
||||
local ifup="\nIP ($DEFAULT_ADAPTER) via Network Manager: \Z1${ipadd}\n\Z0 "
|
||||
else
|
||||
if [[ -n $(service systemd-networkd status | grep -w active | grep -w running) ]]; then
|
||||
local ifup="\nIP ($DEFAULT_ADAPTER) via systemd-networkd: \Z1${ipadd}\n\Z0 "
|
||||
else
|
||||
local ifup="\nIP ($DEFAULT_ADAPTER) via IFUPDOWN: \Z1${ipadd}\n\Z0 "
|
||||
fi
|
||||
fi
|
||||
|
||||
disclaimer="$ifup"
|
||||
|
||||
if [[ -n $WIFICONNECTED ]]; then
|
||||
LISTLENGTH=$((LISTLENGTH+2))
|
||||
local connected="\n\Z0Connected to SSID: \Z1${WIFICONNECTED}\n\Z0 "
|
||||
disclaimer=$disclaimer"$connected"
|
||||
fi
|
||||
|
||||
if [[ -n $VPNSERVERIP ]]; then
|
||||
local vpnserverip="\n\Z0Connected to VPN server: \Z1${VPNSERVERIP}\n\Z0 "
|
||||
disclaimer=$disclaimer"$vpnserverip"
|
||||
LISTLENGTH=$((LISTLENGTH+2))
|
||||
fi
|
||||
|
||||
if [[ -n $HOSTAPDINFO && -n $HOSTAPDSTATUS ]]; then
|
||||
LISTLENGTH=$((LISTLENGTH+2))
|
||||
chpid=$(dmesg | grep $(grep ^interface /etc/hostapd.conf | sed 's/interface=//g') | head -1 | sed 's/\[.*\]//g' | awk '{print $1}')
|
||||
disclaimer=$disclaimer$"\n\Z0Hotspot SSID: \Z1$HOSTAPDINFO\Zn Band:";
|
||||
if [[ `grep ^hw_mode=a /etc/hostapd.conf` ]]; then local band="5Ghz"; else band="2.4Ghz"; fi
|
||||
if [[ `grep ^ieee80211n /etc/hostapd.conf` ]]; then local type="N"; fi
|
||||
if [[ `grep ^ieee80211ac /etc/hostapd.conf` ]]; then local type="AC"; fi
|
||||
disclaimer=$disclaimer$" \Z1${band} ${type}\Z0"
|
||||
[[ ! "$chpid" =~ .*IPv6.* ]] && disclaimer=$disclaimer$"\n\nChip: \Z1${chpid}\Z0";
|
||||
if [ "$HOSTAPDCLIENTS" -gt "0" ]; then disclaimer=$disclaimer$" Connected clients: \Z1$HOSTAPDCLIENTS\Zn"; fi
|
||||
if [[ ! "$chpid" =~ .*IPv6.* ]]; then LISTLENGTH=$((LISTLENGTH+2)); fi
|
||||
disclaimer=$disclaimer$"\n";
|
||||
fi
|
||||
disclaimer=$disclaimer"\n\Z1Note\Zn: This tool can be successful only when drivers are configured properly. If auto-detection fails, you are on your own.\n "
|
||||
|
||||
if [[ -z $selection ]]; then
|
||||
exec 3>&1
|
||||
selection=$(dialog --backtitle "$BACKTITLE" --colors --title " Wired, Wireless, Bluetooth, Hotspot " --clear \
|
||||
--cancel-label "Back" --menu "${disclaimer}" $LISTLENGTH 70 $BOXLENGTH \
|
||||
"${LIST[@]}" 2>&1 1>&3)
|
||||
exit_status=$?
|
||||
exec 3>&-
|
||||
[[ $exit_status == $DIALOG_CANCEL || $exit_status == $DIALOG_ESC ]] && clear && break
|
||||
fi
|
||||
# run main function
|
||||
jobs "$selection"
|
||||
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# personal
|
||||
#
|
||||
function submenu_personal ()
|
||||
{
|
||||
unset main
|
||||
while true; do
|
||||
|
||||
LIST=()
|
||||
LIST+=( "Timezone" "Change timezone \Z5($(LC_ALL=C timedatectl | grep zone | awk '{$1=$1;print}' | sed "s/Time zone: //"))\Z0" )
|
||||
LIST+=( "Locales" "Reconfigure language \Z5($(locale | grep LANGUAGE | cut -d= -f2 | cut -d_ -f1))\Z0 and character set" )
|
||||
LIST+=( "Keyboard" "Change console keyboard layout (\Z5$(cat /etc/default/keyboard | grep XKBLAYOUT | grep -o '".*"' | sed 's/"//g')\Z0)")
|
||||
LIST+=( "Hostname" "Change your hostname \Z5($(cat /etc/hostname))\Z0" )
|
||||
LIST+=( "Welcome" "Toggle welcome screen items" )
|
||||
|
||||
# count number of menu items to adjust window sizee
|
||||
LISTLENGTH="$((6+${#LIST[@]}/2))"
|
||||
BOXLENGTH=${#LIST[@]}
|
||||
|
||||
exec 3>&1
|
||||
selection=$(dialog --colors --backtitle "$BACKTITLE" --title "Personal settings" --clear \
|
||||
--cancel-label "Back" --menu "$disclaimer" $LISTLENGTH 70 $BOXLENGTH \
|
||||
"${LIST[@]}" 2>&1 1>&3)
|
||||
exit_status=$?
|
||||
exec 3>&-
|
||||
[[ $exit_status == $DIALOG_CANCEL || $exit_status == $DIALOG_ESC ]] && clear && break
|
||||
|
||||
# run main function
|
||||
jobs "$selection"
|
||||
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# software
|
||||
#
|
||||
function submenu_software ()
|
||||
{
|
||||
unset main
|
||||
while true; do
|
||||
|
||||
# detect desktop
|
||||
check_desktop
|
||||
|
||||
LIST=()
|
||||
[[ -f /usr/bin/softy || -f softy ]] && LIST+=( "Softy" "3rd party applications installer" )
|
||||
[[ -f /usr/bin/h3consumption && "$LINUXFAMILY" = "sun8i" && "$BRANCH" = "default" ]] && \
|
||||
LIST+=( "Consumption" "Control board consumption" )
|
||||
[[ -f /usr/bin/orangepimonitor ]] && LIST+=( "Monitor" "Simple CLI board monitoring" )
|
||||
LIST+=( "Benchmarking" "sbc-bench board benchmarking" )
|
||||
[[ -f /usr/bin/orangepimonitor ]] && LIST+=( "Diagnostics" "Send diagnostics" )
|
||||
|
||||
#if [[ -n $(dpkg -l | grep linux-headers) ]]; then LIST+=( "Headers_remove" "kernel headers" ); else \
|
||||
#LIST+=( "Headers_install" "kernel headers" ); fi
|
||||
|
||||
SOURCE_PKG_LIST=$(apt-cache --names-only search ^linux-source-* | awk '{ print $1 }' | grep -w ${BRANCH}-${LINUXFAMILY} | tail -n 5)
|
||||
if [[ -n $SOURCE_PKG_LIST ]]; then
|
||||
:
|
||||
#LIST+=( "Source_install" "kernel source" )
|
||||
fi
|
||||
SOURCE_PKG_LIST_INSTALLED=$(find /usr/src -maxdepth 1 -name "linux-source*")
|
||||
if [[ -n $SOURCE_PKG_LIST_INSTALLED ]]; then
|
||||
:
|
||||
#LIST+=( "Source_remove" "kernel source" );
|
||||
fi
|
||||
|
||||
if [[ -f /etc/orangepi.txt ]]; then
|
||||
if [[ -n $(dpkg -l | grep -w "orangepi-firmware-full ") ]]; then
|
||||
:
|
||||
#LIST+=( "Mini" "Install mini firmware package" );
|
||||
else
|
||||
:
|
||||
#LIST+=( "Full" "Install full firmware package" );
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n $DISPLAY_MANAGER ]]; then
|
||||
if [[ $(service xrdp status 2> /dev/null | grep -w active) ]]; then
|
||||
LIST+=( "RDP" "Disable remote desktop access from Windows" )
|
||||
else
|
||||
LIST+=( "RDP" "Enable remote desktop access from Windows" )
|
||||
fi
|
||||
if ! check_if_installed thunderbird ; then
|
||||
LIST+=( "Thunderbird" "Install full featured email client" )
|
||||
else
|
||||
LIST+=( "Thunderbird" "Remove full featured email client" )
|
||||
fi
|
||||
if ! check_if_installed gimp ; then
|
||||
LIST+=( "Gimp" "Install photo manipulation tool" )
|
||||
else
|
||||
LIST+=( "Gimp" "Remove photo manipulation tool" )
|
||||
fi
|
||||
if ! check_if_installed libreoffice-writer ; then
|
||||
LIST+=( "Writer" "Libreoffice: Writer only" )
|
||||
LIST+=( "Suite" "Libreoffice: Full suite" )
|
||||
else
|
||||
if ! check_if_installed libreoffice-base ; then
|
||||
LIST+=( "Suite" "Libreoffice: Full suite" )
|
||||
LIST+=( "Libre" "Remove Libre office packages" )
|
||||
else
|
||||
LIST+=( "Libre" "Remove Libre office packages" )
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# count number of menu items to adjust window sizee
|
||||
LISTLENGTH="$((6+${#LIST[@]}/2))"
|
||||
BOXLENGTH=${#LIST[@]}
|
||||
|
||||
if [[ -z $selection ]]; then
|
||||
exec 3>&1
|
||||
selection=$(dialog --backtitle "$BACKTITLE" --title "System and 3rd party software" --clear \
|
||||
--cancel-label "Back" --menu "$disclaimer" $LISTLENGTH 70 $BOXLENGTH \
|
||||
"${LIST[@]}" 2>&1 1>&3)
|
||||
exit_status=$?
|
||||
exec 3>&-
|
||||
[[ $exit_status == $DIALOG_CANCEL || $exit_status == $DIALOG_ESC ]] && clear && break
|
||||
fi
|
||||
|
||||
# run main function
|
||||
jobs "$selection"
|
||||
|
||||
done
|
||||
}
|
||||
1827
external/cache/sources/orangepi-config/debian-software
vendored
Normal file
1827
external/cache/sources/orangepi-config/debian-software
vendored
Normal file
File diff suppressed because it is too large
Load Diff
37
external/cache/sources/orangepi-config/scripts/smb.conf
vendored
Normal file
37
external/cache/sources/orangepi-config/scripts/smb.conf
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
[global]
|
||||
workgroup = SMBGROUP
|
||||
server string = %h server
|
||||
hosts allow = SUBNET
|
||||
log file = /var/log/samba/log.%m
|
||||
max log size = 1000
|
||||
syslog = 0
|
||||
panic action = /usr/share/samba/panic-action %d
|
||||
load printers = yes
|
||||
printing = cups
|
||||
printcap name = cups
|
||||
|
||||
[printers]
|
||||
comment = All Printers
|
||||
path = /var/spool/samba
|
||||
browseable = no
|
||||
public = yes
|
||||
guest ok = yes
|
||||
writable = no
|
||||
printable = yes
|
||||
printer admin = SMBUSER
|
||||
|
||||
[print$]
|
||||
comment = Printer Drivers
|
||||
path = /etc/samba/drivers
|
||||
browseable = yes
|
||||
guest ok = no
|
||||
read only = yes
|
||||
write list = SMBUSER
|
||||
|
||||
[ext]
|
||||
comment = Storage
|
||||
path = /ext
|
||||
writable = yes
|
||||
public = no
|
||||
valid users = SMBUSER
|
||||
force create mode = 0777
|
||||
55
external/cache/sources/orangepi-config/scripts/tv_grab_file
vendored
Normal file
55
external/cache/sources/orangepi-config/scripts/tv_grab_file
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
dflag=
|
||||
vflag=
|
||||
cflag=
|
||||
if (( $# < 1 ))
|
||||
then
|
||||
### URL of your XML file
|
||||
wget -qO - "http://xml.tv.data"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for arg
|
||||
do
|
||||
delim=""
|
||||
case "$arg" in
|
||||
#translate --gnu-long-options to -g (short options)
|
||||
--description) args="${args}-d ";;
|
||||
--version) args="${args}-v ";;
|
||||
--capabilities) args="${args}-c ";;
|
||||
#pass through anything else
|
||||
*) [[ "${arg:0:1}" == "-" ]] || delim="\""
|
||||
args="${args}${delim}${arg}${delim} ";;
|
||||
esac
|
||||
done
|
||||
|
||||
#Reset the positional parameters to the short options
|
||||
eval set -- $args
|
||||
|
||||
while getopts "dvc" option
|
||||
do
|
||||
case $option in
|
||||
d) dflag=1;;
|
||||
v) vflag=1;;
|
||||
c) cflag=1;;
|
||||
\?) printf "unknown option: -%s\n" $OPTARG
|
||||
printf "Usage: %s: [--description] [--version] [--capabilities] \n" $(basename $0)
|
||||
exit 2
|
||||
;;
|
||||
esac >&2
|
||||
done
|
||||
|
||||
if [ "$dflag" ]
|
||||
then
|
||||
printf "tv_grag_file is a simple grabber that just read the ~/.xmltv/tv_grab_file.xmltv file\n"
|
||||
fi
|
||||
if [ "$vflag" ]
|
||||
then
|
||||
printf "0.1\n"
|
||||
fi
|
||||
if [ "$cflag" ]
|
||||
then
|
||||
printf "baseline\n"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
1
external/cache/sources/orangepi-config/softy
vendored
Symbolic link
1
external/cache/sources/orangepi-config/softy
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
debian-software
|
||||
20
external/cache/sources/rtk_hciattach/Makefile
vendored
Normal file
20
external/cache/sources/rtk_hciattach/Makefile
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
CFLAGS := -Wall -g
|
||||
CC := $(CROSS_COMPILE)gcc
|
||||
all: rtk_hciattach
|
||||
OBJS := hciattach.o hciattach_rtk.o hciattach_h4.o rtb_fwc.o
|
||||
|
||||
rtk_hciattach: $(OBJS)
|
||||
$(CROSS_COMPILE)gcc -o rtk_hciattach $(OBJS)
|
||||
|
||||
%.o: %.c
|
||||
$(CROSS_COMPILE)gcc -c $< -o $@ $(CFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) rtk_hciattach
|
||||
|
||||
tags: FORCE
|
||||
ctags -R
|
||||
find ./ -name "*.h" -o -name "*.c" -o -name "*.cc" -o -name "*.cpp" > cscope.files
|
||||
cscope -bkq -i cscope.files
|
||||
PHONY += FORCE
|
||||
FORCE:
|
||||
39
external/cache/sources/rtk_hciattach/Readme.txt
vendored
Normal file
39
external/cache/sources/rtk_hciattach/Readme.txt
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
The document describes how to support Realtek UART Bluetooth driver in Linux system.
|
||||
|
||||
The supported kernel version is 2.6.32 - 4.15
|
||||
|
||||
The default serial protocol of Realtek Bluetooth chip is Three-wire (H5) protocol
|
||||
with flow control on, parity even and internel 32k clock.
|
||||
|
||||
The default baud rate is 115200.
|
||||
|
||||
To support Three-wire (H5) protocol, you need to install Realtek hci_uart driver
|
||||
and rtk_hciattach tool.
|
||||
|
||||
1. make sure your UART setting is correct.
|
||||
host tx - controller rx
|
||||
host rx - controller tx
|
||||
host rts - controller cts
|
||||
host cts - ground
|
||||
NC - controller rts
|
||||
|
||||
2. Install Bluetooth kernel driver and rtk_hciattach tool
|
||||
$ sudo make install
|
||||
If you encounter an error like "depmod: ERROR: Bad version passed /lib/modules/...",
|
||||
please change the lines "depmod -a $(MDL_DIR)" to "depmod -a $(shell uname -r)"
|
||||
|
||||
3. Initialize Realtek Bluetooth chip by rtk_hciattach
|
||||
$ sudo rtk_hciattach -n -s 115200 ttyUSB0 rtk_h5
|
||||
|
||||
for H4 protocol chip
|
||||
$ sudo rtk_hciattach -n -s 115200 ttyUSB0 rtk_h4
|
||||
|
||||
Tips: ttyUSB0 is serial port name in your system, you should change it
|
||||
according to hardware such as ttyS0.
|
||||
|
||||
4. Uninstall
|
||||
$ sudo make uninstall
|
||||
|
||||
If you want to change the parameter such as baud rate and pcm settings, you
|
||||
should modify rtl8xxx_config file.
|
||||
|
||||
631
external/cache/sources/rtk_hciattach/hciattach.c
vendored
Normal file
631
external/cache/sources/rtk_hciattach/hciattach.c
vendored
Normal file
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include "hciattach.h"
|
||||
|
||||
#define RFKILL_NODE "/sys/class/rfkill/rfkill0/state"
|
||||
|
||||
#ifdef NEED_PPOLL
|
||||
#include "ppoll.h"
|
||||
#endif
|
||||
|
||||
/* #define SCHED_ENABLE */
|
||||
|
||||
#ifdef SCHED_ENABLE
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
struct uart_t {
|
||||
char *type;
|
||||
int m_id;
|
||||
int p_id;
|
||||
int proto;
|
||||
int init_speed;
|
||||
int speed;
|
||||
int flags;
|
||||
int pm;
|
||||
char *bdaddr;
|
||||
int (*init) (int fd, struct uart_t *u, struct termios *ti);
|
||||
int (*post) (int fd, struct uart_t *u, struct termios *ti);
|
||||
};
|
||||
|
||||
#define FLOW_CTL 0x0001
|
||||
#define ENABLE_PM 1
|
||||
#define DISABLE_PM 0
|
||||
|
||||
static volatile sig_atomic_t __io_canceled = 0;
|
||||
|
||||
static void sig_hup(int sig)
|
||||
{
|
||||
RS_INFO("signal hup.");
|
||||
}
|
||||
|
||||
static void sig_term(int sig)
|
||||
{
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
RS_INFO("signal int.");
|
||||
break;
|
||||
case SIGTERM:
|
||||
RS_INFO("signal term.");
|
||||
break;
|
||||
}
|
||||
__io_canceled = 1;
|
||||
}
|
||||
|
||||
static void sig_alarm(int sig)
|
||||
{
|
||||
RS_ERR("Initialization timed out.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int uart_speed(int s)
|
||||
{
|
||||
switch (s) {
|
||||
case 9600:
|
||||
return B9600;
|
||||
case 19200:
|
||||
return B19200;
|
||||
case 38400:
|
||||
return B38400;
|
||||
case 57600:
|
||||
return B57600;
|
||||
case 115200:
|
||||
return B115200;
|
||||
case 230400:
|
||||
return B230400;
|
||||
case 460800:
|
||||
return B460800;
|
||||
case 500000:
|
||||
return B500000;
|
||||
case 576000:
|
||||
return B576000;
|
||||
case 921600:
|
||||
return B921600;
|
||||
case 1000000:
|
||||
return B1000000;
|
||||
case 1152000:
|
||||
return B1152000;
|
||||
case 1500000:
|
||||
return B1500000;
|
||||
case 2000000:
|
||||
return B2000000;
|
||||
#ifdef B2500000
|
||||
case 2500000:
|
||||
return B2500000;
|
||||
#endif
|
||||
#ifdef B3000000
|
||||
case 3000000:
|
||||
return B3000000;
|
||||
#endif
|
||||
#ifdef B3500000
|
||||
case 3500000:
|
||||
return B3500000;
|
||||
#endif
|
||||
#ifdef B4000000
|
||||
case 4000000:
|
||||
return B4000000;
|
||||
#endif
|
||||
default:
|
||||
return B57600;
|
||||
}
|
||||
}
|
||||
|
||||
int set_speed(int fd, struct termios *ti, int speed)
|
||||
{
|
||||
if (cfsetospeed(ti, uart_speed(speed)) < 0)
|
||||
return -errno;
|
||||
|
||||
if (cfsetispeed(ti, uart_speed(speed)) < 0)
|
||||
return -errno;
|
||||
|
||||
if (tcsetattr(fd, TCSANOW, ti) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int realtek_init(int fd, struct uart_t *u, struct termios *ti)
|
||||
{
|
||||
|
||||
RS_INFO("Realtek Bluetooth init uart with init speed:%d, type:HCI UART %s",
|
||||
u->init_speed,
|
||||
(u->proto == HCI_UART_H4) ? "H4" : "H5");
|
||||
return rtb_init(fd, u->proto, u->speed, ti);
|
||||
}
|
||||
|
||||
static int realtek_post(int fd, struct uart_t *u, struct termios *ti)
|
||||
{
|
||||
RS_INFO("Realtek Bluetooth post process");
|
||||
return rtb_post(fd, u->proto, ti);
|
||||
}
|
||||
|
||||
struct uart_t uart[] = {
|
||||
{ "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, DISABLE_PM, NULL, NULL},
|
||||
|
||||
/* Realtek Bluetooth H4 */
|
||||
{ "rtk_h4", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, 0, DISABLE_PM, NULL, realtek_init, realtek_post },
|
||||
|
||||
/* Realtek Bluetooth H5 */
|
||||
{ "rtk_h5", 0x0000, 0x0000, HCI_UART_3WIRE, 115200,115200, 0, DISABLE_PM, NULL, realtek_init, realtek_post },
|
||||
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static struct uart_t * get_by_id(int m_id, int p_id)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; uart[i].type; i++) {
|
||||
if (uart[i].m_id == m_id && uart[i].p_id == p_id)
|
||||
return &uart[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct uart_t * get_by_type(char *type)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; uart[i].type; i++) {
|
||||
if (!strcmp(uart[i].type, type))
|
||||
return &uart[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize UART driver */
|
||||
static int init_uart(char *dev, struct uart_t *u, int send_break, int raw)
|
||||
{
|
||||
struct termios ti;
|
||||
int fd, i;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (raw)
|
||||
flags |= 1 << HCI_UART_RAW_DEVICE;
|
||||
|
||||
fd = open(dev, O_RDWR | O_NOCTTY);
|
||||
if (fd < 0) {
|
||||
RS_ERR("Can't open serial port, %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (tcgetattr(fd, &ti) < 0) {
|
||||
RS_ERR("Can't get port settings, %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
cfmakeraw(&ti);
|
||||
|
||||
ti.c_cflag |= CLOCAL;
|
||||
if (u->flags & FLOW_CTL)
|
||||
ti.c_cflag |= CRTSCTS;
|
||||
else
|
||||
ti.c_cflag &= ~CRTSCTS;
|
||||
|
||||
if (tcsetattr(fd, TCSANOW, &ti) < 0) {
|
||||
RS_ERR("Can't set port settings, %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set initial baudrate */
|
||||
if (set_speed(fd, &ti, u->init_speed) < 0) {
|
||||
RS_ERR("Can't set initial baud rate, %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
if (send_break) {
|
||||
tcsendbreak(fd, 0);
|
||||
usleep(500000);
|
||||
}
|
||||
|
||||
if (u->init && u->init(fd, u, &ti) < 0)
|
||||
return -1;
|
||||
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
/* Set actual baudrate
|
||||
* There is no need to change baudrate after uart init
|
||||
* */
|
||||
/* if (set_speed(fd, &ti, u->speed) < 0) {
|
||||
* perror("Can't set baud rate");
|
||||
* return -1;
|
||||
* }
|
||||
*/
|
||||
|
||||
/* Set TTY to N_HCI line discipline */
|
||||
i = N_HCI;
|
||||
if (ioctl(fd, TIOCSETD, &i) < 0) {
|
||||
RS_ERR("Can't set line discipline %d, %s", errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags && ioctl(fd, HCIUARTSETFLAGS, flags) < 0) {
|
||||
RS_ERR("Can't set UART flags %d, %s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, HCIUARTSETPROTO, u->proto) < 0) {
|
||||
RS_ERR("Can't set device %d, %s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (u->post && u->post(fd, u, &ti) < 0)
|
||||
return -1;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int reset_bluetooth(void)
|
||||
{
|
||||
|
||||
int fd;
|
||||
char state[2];
|
||||
int result;
|
||||
|
||||
/* power off and power on BT */
|
||||
fd = open(RFKILL_NODE, O_RDWR);
|
||||
if (fd < 0) {
|
||||
RS_ERR("Cannot open %s, %d %s", RFKILL_NODE, errno,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
state[0] = '0';
|
||||
state[1] = '\0';
|
||||
result = write(fd, state, strlen(state) + 1);
|
||||
if (result != (strlen(state) + 1)) {
|
||||
RS_ERR("Cannot write 0 to rfkill state %d %s", errno,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
usleep(500000);
|
||||
|
||||
state[0] = '1';
|
||||
state[1] = '\0';
|
||||
result = write(fd, state, strlen(state) + 1);
|
||||
if (result != (strlen(state) + 1)) {
|
||||
RS_ERR("Cannot write 1 to rfkill state %d %s", errno,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
usleep(500000);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
RS_INFO("hciattach - HCI UART driver initialization utility");
|
||||
RS_INFO("Usage:");
|
||||
RS_INFO("\thciattach [-n] [-p] [-b] [-r] [-t timeout] [-s initial_speed] <tty> <type | id> [speed] [flow|noflow] [bdaddr]");
|
||||
RS_INFO("\thciattach -l");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct uart_t *u = NULL;
|
||||
int detach, printpid, raw, opt, i, n, ld, err;
|
||||
int to = 10;
|
||||
int init_speed = 0;
|
||||
int send_break = 0;
|
||||
pid_t pid;
|
||||
struct sigaction sa;
|
||||
struct pollfd p;
|
||||
sigset_t sigs;
|
||||
char dev[PATH_MAX];
|
||||
#ifdef SCHED_ENABLE
|
||||
struct sched_param sched_par;
|
||||
#endif
|
||||
|
||||
detach = 1;
|
||||
printpid = 0;
|
||||
raw = 0;
|
||||
|
||||
while ((opt=getopt(argc, argv, "bnpt:s:lr")) != EOF) {
|
||||
switch(opt) {
|
||||
case 'b':
|
||||
send_break = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
detach = 0;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
printpid = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
to = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
init_speed = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
for (i = 0; uart[i].type; i++) {
|
||||
RS_INFO("%-10s0x%04x,0x%04x", uart[i].type,
|
||||
uart[i].m_id, uart[i].p_id);
|
||||
}
|
||||
exit(0);
|
||||
|
||||
case 'r':
|
||||
raw = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
n = argc - optind;
|
||||
if (n < 2) {
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (n = 0; optind < argc; n++, optind++) {
|
||||
char *opt;
|
||||
|
||||
opt = argv[optind];
|
||||
|
||||
switch(n) {
|
||||
case 0:
|
||||
dev[0] = 0;
|
||||
if (!strchr(opt, '/'))
|
||||
strcpy(dev, "/dev/");
|
||||
strcat(dev, opt);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (strchr(argv[optind], ',')) {
|
||||
int m_id, p_id;
|
||||
sscanf(argv[optind], "%x,%x", &m_id, &p_id);
|
||||
u = get_by_id(m_id, p_id);
|
||||
} else {
|
||||
u = get_by_type(opt);
|
||||
}
|
||||
|
||||
if (!u) {
|
||||
RS_ERR("Unknown device type or id");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
u->speed = atoi(argv[optind]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (!strcmp("flow", argv[optind]))
|
||||
u->flags |= FLOW_CTL;
|
||||
else
|
||||
u->flags &= ~FLOW_CTL;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (!strcmp("sleep", argv[optind]))
|
||||
u->pm = ENABLE_PM;
|
||||
else
|
||||
u->pm = DISABLE_PM;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
u->bdaddr = argv[optind];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!u) {
|
||||
RS_ERR("Unknown device type or id");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
start:
|
||||
|
||||
#ifdef SCHED_ENABLE
|
||||
RS_INFO("Increase the priority of the process with set sched");
|
||||
memset(&sched_par, 0, sizeof(sched_par));
|
||||
sched_par.sched_priority = 99;
|
||||
err = sched_setscheduler(0, SCHED_FIFO, &sched_par);
|
||||
if (err == -1) {
|
||||
RS_ERR("Call sched_setscheduler error, %s",
|
||||
strerror(errno));
|
||||
}
|
||||
/* #else
|
||||
* RS_INFO("Increase the priority of the process with nice");
|
||||
* err = nice(-20);
|
||||
* if (err == -1) {
|
||||
* RS_ERR("Call nice error, %s", strerror(errno));
|
||||
* }
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* If user specified a initial speed, use that instead of
|
||||
the hardware's default */
|
||||
if (init_speed)
|
||||
u->init_speed = init_speed;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_flags = SA_NOCLDSTOP;
|
||||
sa.sa_handler = sig_alarm;
|
||||
sigaction(SIGALRM, &sa, NULL);
|
||||
|
||||
/* 10 seconds should be enough for initialization */
|
||||
alarm(to);
|
||||
|
||||
n = init_uart(dev, u, send_break, raw);
|
||||
if (n < 0) {
|
||||
RS_ERR("Can't initialize device %d, %s", errno,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
RS_INFO("Device setup complete");
|
||||
|
||||
alarm(0);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_flags = SA_NOCLDSTOP;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
sigaction(SIGPIPE, &sa, NULL);
|
||||
|
||||
sa.sa_handler = sig_term;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
|
||||
sa.sa_handler = sig_hup;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
|
||||
if (detach) {
|
||||
if ((pid = fork())) {
|
||||
if (printpid)
|
||||
RS_INFO("%d", pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
if (i != n)
|
||||
close(i);
|
||||
}
|
||||
|
||||
p.fd = n;
|
||||
p.events = POLLERR | POLLHUP;
|
||||
|
||||
sigfillset(&sigs);
|
||||
sigdelset(&sigs, SIGCHLD);
|
||||
sigdelset(&sigs, SIGPIPE);
|
||||
sigdelset(&sigs, SIGTERM);
|
||||
sigdelset(&sigs, SIGINT);
|
||||
sigdelset(&sigs, SIGHUP);
|
||||
|
||||
while (!__io_canceled) {
|
||||
p.revents = 0;
|
||||
err = ppoll(&p, 1, NULL, &sigs);
|
||||
if (err < 0 && errno == EINTR) {
|
||||
RS_INFO("Got EINTR.");
|
||||
continue;
|
||||
} if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
RS_INFO("err %d, p->revents %04x", err, p.revents);
|
||||
|
||||
/* Restore TTY line discipline */
|
||||
RS_INFO("Restore TTY line discipline");
|
||||
ld = N_TTY;
|
||||
if (ioctl(n, TIOCSETD, &ld) < 0) {
|
||||
RS_ERR("Can't restore line discipline %d, %s", errno,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (p.revents & (POLLERR | POLLHUP)) {
|
||||
RS_INFO("Recover...");
|
||||
reset_bluetooth();
|
||||
goto start;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void util_hexdump(const uint8_t *buf, size_t len)
|
||||
{
|
||||
static const char hexdigits[] = "0123456789abcdef";
|
||||
char str[16 * 3];
|
||||
size_t i;
|
||||
|
||||
if (!buf || !len)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
str[((i % 16) * 3)] = hexdigits[buf[i] >> 4];
|
||||
str[((i % 16) * 3) + 1] = hexdigits[buf[i] & 0xf];
|
||||
str[((i % 16) * 3) + 2] = ' ';
|
||||
if ((i + 1) % 16 == 0) {
|
||||
str[16 * 3 - 1] = '\0';
|
||||
RS_INFO("%s", str);
|
||||
}
|
||||
}
|
||||
|
||||
if (i % 16 > 0) {
|
||||
str[(i % 16) * 3 - 1] = '\0';
|
||||
RS_INFO("%s", str);
|
||||
}
|
||||
}
|
||||
|
||||
int timeout_set(int fd, unsigned int msec)
|
||||
{
|
||||
struct itimerspec itimer;
|
||||
unsigned int sec = msec / 1000;
|
||||
|
||||
memset(&itimer, 0, sizeof(itimer));
|
||||
itimer.it_interval.tv_sec = 0;
|
||||
itimer.it_interval.tv_nsec = 0;
|
||||
itimer.it_value.tv_sec = sec;
|
||||
itimer.it_value.tv_nsec = (msec - (sec * 1000)) * 1000 * 1000;
|
||||
|
||||
return timerfd_settime(fd, 0, &itimer, NULL);
|
||||
}
|
||||
|
||||
188
external/cache/sources/rtk_hciattach/hciattach.h
vendored
Normal file
188
external/cache/sources/rtk_hciattach/hciattach.h
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
*
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2003-2009 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
#include <stdint.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define cpu_to_le16(d) (d)
|
||||
#define cpu_to_le32(d) (d)
|
||||
#define le16_to_cpu(d) (d)
|
||||
#define le32_to_cpu(d) (d)
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define cpu_to_le16(d) bswap_16(d)
|
||||
#define cpu_to_le32(d) bswap_32(d)
|
||||
#define le16_to_cpu(d) bswap_16(d)
|
||||
#define le32_to_cpu(d) bswap_32(d)
|
||||
#else
|
||||
#error "Unknown byte order"
|
||||
#endif
|
||||
|
||||
#ifndef N_HCI
|
||||
#define N_HCI 15
|
||||
#endif
|
||||
|
||||
#define HCIUARTSETPROTO _IOW('U', 200, int)
|
||||
#define HCIUARTGETPROTO _IOR('U', 201, int)
|
||||
#define HCIUARTGETDEVICE _IOR('U', 202, int)
|
||||
#define HCIUARTSETFLAGS _IOW('U', 203, int)
|
||||
#define HCIUARTGETFLAGS _IOR('U', 204, int)
|
||||
|
||||
#define HCI_UART_H4 0
|
||||
#define HCI_UART_BCSP 1
|
||||
#define HCI_UART_3WIRE 2
|
||||
#define HCI_UART_H4DS 3
|
||||
#define HCI_UART_LL 4
|
||||
#define HCI_UART_RAW_DEVICE 0
|
||||
|
||||
extern uint8_t DBG_ON;
|
||||
|
||||
/* #define SYSLOG */
|
||||
|
||||
#define LOG_STR "Realtek Bluetooth"
|
||||
#ifdef SYSLOG
|
||||
#define RS_DBG(fmt, arg...) \
|
||||
do{ \
|
||||
if (DBG_ON) \
|
||||
syslog(LOG_DEBUG, "%s :" fmt "\n" , LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_INFO(fmt, arg...) \
|
||||
do{ \
|
||||
syslog(LOG_INFO, "%s :" fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_WARN(fmt, arg...) \
|
||||
do{ \
|
||||
syslog(LOG_WARNING, "%s WARN: " fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_ERR(fmt, arg...) \
|
||||
do{ \
|
||||
syslog(LOG_ERR, "%s ERROR: " fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
#else
|
||||
#define RS_DBG(fmt, arg...) \
|
||||
do{ \
|
||||
if (DBG_ON) \
|
||||
printf("%s :" fmt "\n" , LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_INFO(fmt, arg...) \
|
||||
do{ \
|
||||
printf("%s :" fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_WARN(fmt, arg...) \
|
||||
do{ \
|
||||
printf("%s WARN: " fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
|
||||
#define RS_ERR(fmt, arg...) \
|
||||
do{ \
|
||||
printf("%s ERROR: " fmt "\n", LOG_STR, ##arg); \
|
||||
}while(0)
|
||||
#endif
|
||||
|
||||
typedef enum _H5_RX_STATE {
|
||||
H5_W4_PKT_DELIMITER,
|
||||
H5_W4_PKT_START,
|
||||
H5_W4_HDR,
|
||||
H5_W4_DATA,
|
||||
H5_W4_CRC
|
||||
} H5_RX_STATE;
|
||||
|
||||
typedef enum _H5_RX_ESC_STATE {
|
||||
H5_ESCSTATE_NOESC,
|
||||
H5_ESCSTATE_ESC
|
||||
} H5_RX_ESC_STATE;
|
||||
|
||||
typedef enum _H5_LINK_STATE {
|
||||
H5_SYNC,
|
||||
H5_CONFIG,
|
||||
H5_INIT,
|
||||
H5_PATCH,
|
||||
H5_HCI_RESET,
|
||||
H5_ACTIVE
|
||||
} H5_LINK_STATE;
|
||||
|
||||
struct patch_info;
|
||||
typedef struct rtb_struct {
|
||||
/* three wire releated */
|
||||
uint8_t rxseq_txack; /* expected rx seq number */
|
||||
uint8_t rxack; /* last packet that the peer ack'ed */
|
||||
uint8_t use_crc;
|
||||
uint8_t is_txack_req; /* txack required */
|
||||
uint8_t msgq_txseq; /* next pkt seq */
|
||||
uint16_t message_crc;
|
||||
uint32_t rx_count; /* expected pkts to recv */
|
||||
|
||||
H5_RX_STATE rx_state;
|
||||
H5_RX_ESC_STATE rx_esc_state;
|
||||
H5_LINK_STATE link_estab_state;
|
||||
|
||||
struct sk_buff *rx_skb;
|
||||
|
||||
uint16_t num_of_cmd_sent;
|
||||
uint16_t lmp_subver;
|
||||
uint16_t hci_rev;
|
||||
uint8_t hci_ver;
|
||||
uint8_t eversion;
|
||||
uint8_t chip_type;
|
||||
|
||||
uint32_t vendor_baud;
|
||||
uint8_t dl_fw_flag;
|
||||
int serial_fd;
|
||||
int uart_flow_ctrl;
|
||||
uint32_t parenb: 16;
|
||||
uint32_t pareven: 16;
|
||||
int final_speed;
|
||||
int total_num; /* total pkt number */
|
||||
int tx_index; /* current sending pkt number */
|
||||
int rx_index; /* ack index from board */
|
||||
int fw_len; /* fw patch file len */
|
||||
int config_len; /* config patch file len */
|
||||
int total_len; /* fw & config extracted buf len */
|
||||
uint8_t *fw_buf; /* fw patch file buf */
|
||||
uint8_t *config_buf; /* config patch file buf */
|
||||
uint8_t *total_buf; /* fw & config extracted buf */
|
||||
#define CMD_STATE_UNKNOWN 0x00
|
||||
#define CMD_STATE_SUCCESS 0x01
|
||||
struct __cmd_state {
|
||||
uint16_t opcode;
|
||||
uint16_t state;
|
||||
} cmd_state;
|
||||
|
||||
struct patch_info *patch_ent;
|
||||
|
||||
int proto;
|
||||
int timerfd;
|
||||
int epollfd;
|
||||
} rtb_struct_t;
|
||||
extern struct rtb_struct rtb_cfg;
|
||||
int timeout_set(int fd, unsigned int msec);
|
||||
int set_speed(int fd, struct termios *ti, int speed);
|
||||
int rtb_init(int fd, int proto, int speed, struct termios *ti);
|
||||
int rtb_post(int fd, int proto, struct termios *ti);
|
||||
void util_hexdump(const uint8_t *buf, size_t len);
|
||||
295
external/cache/sources/rtk_hciattach/hciattach_h4.c
vendored
Normal file
295
external/cache/sources/rtk_hciattach/hciattach_h4.c
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ctype.h>
|
||||
#include <poll.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <sys/epoll.h>
|
||||
#include "hciattach.h"
|
||||
#include "hciattach_h4.h"
|
||||
|
||||
extern struct rtb_struct rtb_cfg;
|
||||
|
||||
static int start_xfer_wait(int fd, uint8_t *cmd, uint16_t len, uint32_t msec,
|
||||
int retry, uint8_t *resp, uint16_t *resp_len)
|
||||
{
|
||||
uint8_t buf[64];
|
||||
int result;
|
||||
int state = 1;
|
||||
int count = 0;
|
||||
int params_len;
|
||||
struct pollfd p[2];
|
||||
uint16_t opcode;
|
||||
|
||||
if (fd == -1 || !cmd || len < 4) {
|
||||
RS_ERR("%s: invalid parameter", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
opcode = ((uint16_t)cmd[2] << 8) + cmd[1];
|
||||
|
||||
start_xfer:
|
||||
result = write(fd, cmd, len);
|
||||
if (result != len) {
|
||||
RS_ERR("%s: Write cmd %04x error, %s", __func__, opcode,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
start_recv:
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(p, 0, sizeof(p));
|
||||
state = 1;
|
||||
count = 0;
|
||||
p[0].fd = fd;
|
||||
p[0].events = POLLERR | POLLHUP | POLLIN;
|
||||
for (;;) {
|
||||
p[0].revents = 0;
|
||||
result = poll(p, 1, msec);
|
||||
if (result < 0) {
|
||||
RS_ERR("Poll call error, %s", strerror(errno));
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
RS_WARN("%s: Timeout", __func__);
|
||||
if (retry <= 0) {
|
||||
RS_ERR("%s: Transfer exhausted", __func__);
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
retry--;
|
||||
goto start_xfer;
|
||||
}
|
||||
|
||||
if (p[0].revents & (POLLERR | POLLHUP)) {
|
||||
RS_ERR("POLLERR or POLLUP happens, %s",
|
||||
strerror(errno));
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (state == 1) {
|
||||
result = read(p[0].fd, buf, 1);
|
||||
if (result == -1 || result != 1) {
|
||||
RS_ERR("%s: Read pkt type error, %s", __func__,
|
||||
strerror(errno));
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
if (result == 1 && buf[0] == 0x04) {
|
||||
count = 1;
|
||||
state = 2;
|
||||
}
|
||||
} else if (state == 2) {
|
||||
result = read(p[0].fd, buf + count, 2);
|
||||
if (result == -1 || result != 2) {
|
||||
RS_ERR("%s: Read pkt header error, %s",
|
||||
__func__, strerror(errno));
|
||||
break;
|
||||
}
|
||||
count += result;
|
||||
state = 3;
|
||||
params_len = buf[2];
|
||||
if (params_len + 3 > sizeof(buf)) {
|
||||
result = -1;
|
||||
RS_ERR("%s: hci event too long", __func__);
|
||||
break;
|
||||
}
|
||||
} else if (state == 3) {
|
||||
result = read(p[0].fd, buf + count, params_len);
|
||||
if (result == -1) {
|
||||
RS_ERR("%s: Read pkt payload error, %s",
|
||||
__func__, strerror(errno));
|
||||
break;
|
||||
}
|
||||
count += result;
|
||||
params_len -= result;
|
||||
if (!params_len)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result >= 0) {
|
||||
if (buf[1] == 0x0e) {
|
||||
uint16_t tmp_opcode;
|
||||
|
||||
tmp_opcode = (uint16_t)buf[4] | buf[5] << 8;
|
||||
if (tmp_opcode == opcode) {
|
||||
RS_INFO("Cmd complete event for cmd %04x",
|
||||
opcode);
|
||||
/* Status is not zero indicating command not
|
||||
* succeeded */
|
||||
if (buf[6])
|
||||
return -1;
|
||||
if (!resp)
|
||||
return 0;
|
||||
if (*resp_len > count)
|
||||
*resp_len = count;
|
||||
memcpy(resp, buf, *resp_len);
|
||||
return 0;
|
||||
} else {
|
||||
RS_WARN("Unexpected cmd complete event, %04x",
|
||||
tmp_opcode);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
RS_INFO("%s: Unexpected hci event packet", __func__);
|
||||
util_hexdump(buf, count);
|
||||
/* Continue receiving */
|
||||
}
|
||||
goto start_recv;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int h4_download_patch(int fd, int index, uint8_t *data, int len)
|
||||
{
|
||||
uint8_t buf[257];
|
||||
uint16_t total_len;
|
||||
int result;
|
||||
uint8_t resp[8];
|
||||
uint16_t rlen = sizeof(resp);
|
||||
|
||||
RS_DBG("fd: %d, index: %d, len: %d", fd, index, len);
|
||||
|
||||
if (data)
|
||||
memcpy(&buf[5], data, len);
|
||||
buf[0] = 0x01;
|
||||
buf[1] = 0x20;
|
||||
buf[2] = 0xfc;
|
||||
buf[3] = len + 1;
|
||||
buf[4] = (uint8_t)index;
|
||||
total_len = len + 5;
|
||||
|
||||
result = start_xfer_wait(fd, buf, total_len, 1000, 0, resp, &rlen);
|
||||
if (result < 0) {
|
||||
RS_ERR("Transfer patch failed, index %d", index);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rlen != 8) {
|
||||
RS_ERR("%s: Unexpected length %u", __func__, rlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return resp[7];
|
||||
}
|
||||
|
||||
int h4_vendor_change_speed(int fd, uint32_t baudrate)
|
||||
{
|
||||
int res;
|
||||
uint8_t cmd[8] = { 0 };
|
||||
|
||||
cmd[0] = 1;
|
||||
cmd[1] = 0x17;
|
||||
cmd[2] = 0xfc;
|
||||
cmd[3] = 4;
|
||||
|
||||
baudrate = cpu_to_le32(baudrate);
|
||||
#ifdef BAUDRATE_4BYTES
|
||||
memcpy((uint16_t *) & cmd[4], &baudrate, 4);
|
||||
#else
|
||||
memcpy((uint16_t *) & cmd[4], &baudrate, 2);
|
||||
cmd[6] = 0;
|
||||
cmd[7] = 0;
|
||||
#endif
|
||||
|
||||
/* TODO: Wait for a while for device to up, just h4 need it */
|
||||
sleep(1);
|
||||
|
||||
RS_DBG("baudrate in change speed command: 0x%02x 0x%02x 0x%02x 0x%02x",
|
||||
cmd[4], cmd[5], cmd[6], cmd[7]);
|
||||
|
||||
res = start_xfer_wait(fd, cmd, 8, 1000, 0, NULL, 0);
|
||||
if (res < 0)
|
||||
RS_ERR("Change Controller baud failed");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int h4_hci_reset(int fd)
|
||||
{
|
||||
int result;
|
||||
uint8_t cmd[4] = { 0x01, 0x03, 0x0c, 0x00};
|
||||
|
||||
RS_INFO("%s: Issue hci reset cmd", __func__);
|
||||
|
||||
result = start_xfer_wait(fd, cmd, sizeof(cmd), 1000, 0, NULL, 0);
|
||||
if (result < 0) {
|
||||
RS_ERR("%s: Failed to send reset cmd", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int h4_read_local_ver(int fd)
|
||||
{
|
||||
uint8_t cmd[4] = { 0x01, 0x01, 0x10, 0x00 };
|
||||
uint8_t resp[16];
|
||||
uint16_t len = sizeof(resp);
|
||||
int result;
|
||||
|
||||
result = start_xfer_wait(fd, cmd, sizeof(cmd), 1000, 0,
|
||||
resp, &len);
|
||||
if (result < 0) {
|
||||
RS_ERR("HCI Read local version info error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len != 15) {
|
||||
RS_ERR("%s: Unexpected length %u", __func__, len);
|
||||
return -1;
|
||||
}
|
||||
rtb_cfg.hci_ver = resp[7];
|
||||
rtb_cfg.hci_rev = (uint32_t)resp[9] << 8 | resp[8];
|
||||
rtb_cfg.lmp_subver = (uint32_t)resp[14] << 8 | resp[13];
|
||||
RS_INFO("hci ver %02x, hci_rev %04x, lmp_subver %04x",
|
||||
rtb_cfg.hci_ver, rtb_cfg.hci_rev, rtb_cfg.lmp_subver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int h4_vendor_read_rom_ver(int fd)
|
||||
{
|
||||
uint8_t cmd[4] = { 0x01, 0x6d, 0xfc, 0x00 };
|
||||
uint8_t resp[16];
|
||||
uint16_t len = sizeof(resp);
|
||||
int result;
|
||||
|
||||
result = start_xfer_wait(fd, cmd, sizeof(cmd), 1000, 0,
|
||||
resp, &len);
|
||||
if (result < 0) {
|
||||
RS_ERR("HCI Read local version info error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len != 8) {
|
||||
RS_ERR("%s: Unexpected length %u", __func__, len);
|
||||
return -1;
|
||||
}
|
||||
rtb_cfg.eversion = resp[7];
|
||||
RS_INFO("eversion %02x", rtb_cfg.eversion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
7
external/cache/sources/rtk_hciattach/hciattach_h4.h
vendored
Normal file
7
external/cache/sources/rtk_hciattach/hciattach_h4.h
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <stdint.h>
|
||||
int h4_download_patch(int fd, int index, uint8_t *data, int len);
|
||||
int h4_vendor_change_speed(int fd, uint32_t baudrate);
|
||||
int h4_hci_reset(int fd);
|
||||
int h4_read_local_ver(int fd);
|
||||
int h4_vendor_read_rom_ver(int fd);
|
||||
2024
external/cache/sources/rtk_hciattach/hciattach_rtk.c
vendored
Normal file
2024
external/cache/sources/rtk_hciattach/hciattach_rtk.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1233
external/cache/sources/rtk_hciattach/rtb_fwc.c
vendored
Normal file
1233
external/cache/sources/rtk_hciattach/rtb_fwc.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
75
external/cache/sources/rtk_hciattach/rtb_fwc.h
vendored
Normal file
75
external/cache/sources/rtk_hciattach/rtb_fwc.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Realtek Semiconductor Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
struct rtb_struct;
|
||||
|
||||
#define BAUDRATE_4BYTES
|
||||
|
||||
#define ROM_LMP_NONE 0x0000
|
||||
#define ROM_LMP_8723a 0x1200
|
||||
#define ROM_LMP_8723b 0x8723
|
||||
#define ROM_LMP_8821a 0x8821
|
||||
#define ROM_LMP_8761a 0x8761
|
||||
#define ROM_LMP_8761btc 0x8763
|
||||
|
||||
#define ROM_LMP_8703a 0x87b3
|
||||
#define ROM_LMP_8763a 0x8763
|
||||
#define ROM_LMP_8703b 0x8703
|
||||
#define ROM_LMP_8723c 0x87c3 /* ??????? */
|
||||
#define ROM_LMP_8822b 0x8822
|
||||
#define ROM_LMP_8822c 0x8822
|
||||
#define ROM_LMP_8723cs_xx 0x8704
|
||||
#define ROM_LMP_8723cs_cg 0x8705
|
||||
#define ROM_LMP_8723cs_vf 0x8706
|
||||
|
||||
/* Chip type */
|
||||
#define CHIP_8703AS 1
|
||||
#define CHIP_8723CS_CG 3
|
||||
#define CHIP_8723CS_VF 4
|
||||
#define CHIP_8723CS_XX 5
|
||||
#define CHIP_8703BS 7
|
||||
|
||||
/* software id */
|
||||
#define CHIP_UNKNOWN 0x00
|
||||
#define CHIP_8761AT 0x1F
|
||||
#define CHIP_8761ATF 0x2F
|
||||
#define CHIP_8761BTC 0x3F
|
||||
#define CHIP_8761BH4 0x4F
|
||||
#define CHIP_8723BS 0x5F
|
||||
#define CHIP_BEFORE 0x6F
|
||||
#define CHIP_8822BS 0x70
|
||||
#define CHIP_8723DS 0x71
|
||||
#define CHIP_8821CS 0x72
|
||||
#define CHIP_8822CS 0x73
|
||||
#define CHIP_8761B 0x74
|
||||
|
||||
#define RTL_FW_MATCH_CHIP_TYPE (1 << 0)
|
||||
#define RTL_FW_MATCH_HCI_VER (1 << 1)
|
||||
#define RTL_FW_MATCH_HCI_REV (1 << 2)
|
||||
struct patch_info {
|
||||
uint32_t match_flags;
|
||||
uint8_t chip_type;
|
||||
uint16_t lmp_subver;
|
||||
uint16_t proj_id;
|
||||
uint8_t hci_ver;
|
||||
uint16_t hci_rev;
|
||||
char *patch_file;
|
||||
char *config_file;
|
||||
char *ic_name;
|
||||
};
|
||||
|
||||
struct patch_info *get_patch_entry(struct rtb_struct *btrtl);
|
||||
uint8_t *rtb_read_config(struct rtb_struct *btrtl, int *cfg_len);
|
||||
uint8_t *rtb_read_firmware(struct rtb_struct *btrtl, int *fw_len);
|
||||
uint8_t *rtb_get_final_patch(int fd, int proto, int *rlen);
|
||||
4
external/cache/sources/tinyalsa/.gitignore
vendored
Normal file
4
external/cache/sources/tinyalsa/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/libtinyalsa.so
|
||||
/tinycap
|
||||
/tinymix
|
||||
/tinyplay
|
||||
31
external/cache/sources/tinyalsa/Makefile
vendored
Normal file
31
external/cache/sources/tinyalsa/Makefile
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
CFLAGS := -c -fPIC $(CFLAGS)
|
||||
INC = include
|
||||
OBJECTS = mixer.o pcm.o
|
||||
LIB = libtinyalsa.so
|
||||
CC=gcc
|
||||
|
||||
all: $(LIB) tinyplay tinycap tinymix
|
||||
cp tinyplay tinycap tinymix /usr/local/bin
|
||||
cp libtinyalsa.so /usr/lib/
|
||||
|
||||
tinyplay: $(LIB) tinyplay.o
|
||||
$(CC) tinyplay.o -L. -ltinyalsa -o tinyplay
|
||||
|
||||
tinycap: $(LIB) tinycap.o
|
||||
$(CC) tinycap.o -L. -ltinyalsa -o tinycap
|
||||
|
||||
tinymix: $(LIB) tinymix.o
|
||||
$(CC) tinymix.o -L. -ltinyalsa -o tinymix
|
||||
|
||||
tinypcminfo: $(LIB) tinypcminfo.o
|
||||
$(CC) tinypcminfo.o -L. -ltinyalsa -o tinypcminfo
|
||||
|
||||
$(LIB): $(OBJECTS)
|
||||
$(CC) -shared $(OBJECTS) -o $(LIB)
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $< -I$(INC)
|
||||
|
||||
clean:
|
||||
-rm -f $(LIB) $(OBJECTS) tinyplay.o tinyplay tinycap.o tinycap \
|
||||
tinymix.o tinymix tinypcminfo.o tinypcminfo
|
||||
9
external/cache/sources/tinyalsa/README
vendored
Normal file
9
external/cache/sources/tinyalsa/README
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
tinyalsa: a small library to interface with ALSA in the Linux kernel
|
||||
|
||||
The aims are:
|
||||
|
||||
- Provide a basic pcm and mixer API
|
||||
- If it's not absolutely needed, don't add it to the API
|
||||
- Avoid supporting complex and unnecessary operations that could be
|
||||
dealt with at a higher level
|
||||
|
||||
821
external/cache/sources/tinyalsa/include/sound/asound.h
vendored
Normal file
821
external/cache/sources/tinyalsa/include/sound/asound.h
vendored
Normal file
@@ -0,0 +1,821 @@
|
||||
/****************************************************************************
|
||||
****************************************************************************
|
||||
***
|
||||
*** This header was automatically generated from a Linux kernel header
|
||||
*** of the same name, to make information necessary for userspace to
|
||||
*** call into the kernel available to libc. It contains only constants,
|
||||
*** structures, and macros generated from the original header, and thus,
|
||||
*** contains no copyrightable information.
|
||||
***
|
||||
****************************************************************************
|
||||
****************************************************************************/
|
||||
#ifndef __SOUND_ASOUND_H
|
||||
#define __SOUND_ASOUND_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define SNDRV_PROTOCOL_VERSION(major, minor, subminor) (((major)<<16)|((minor)<<8)|(subminor))
|
||||
#define SNDRV_PROTOCOL_MAJOR(version) (((version)>>16)&0xffff)
|
||||
#define SNDRV_PROTOCOL_MINOR(version) (((version)>>8)&0xff)
|
||||
#define SNDRV_PROTOCOL_MICRO(version) ((version)&0xff)
|
||||
#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion, uversion) (SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion)))
|
||||
|
||||
struct snd_aes_iec958 {
|
||||
unsigned char status[24];
|
||||
unsigned char subcode[147];
|
||||
unsigned char pad;
|
||||
unsigned char dig_subframe[4];
|
||||
};
|
||||
|
||||
#define SNDRV_HWDEP_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1)
|
||||
|
||||
enum {
|
||||
SNDRV_HWDEP_IFACE_OPL2 = 0,
|
||||
SNDRV_HWDEP_IFACE_OPL3,
|
||||
SNDRV_HWDEP_IFACE_OPL4,
|
||||
SNDRV_HWDEP_IFACE_SB16CSP,
|
||||
SNDRV_HWDEP_IFACE_EMU10K1,
|
||||
SNDRV_HWDEP_IFACE_YSS225,
|
||||
SNDRV_HWDEP_IFACE_ICS2115,
|
||||
SNDRV_HWDEP_IFACE_SSCAPE,
|
||||
SNDRV_HWDEP_IFACE_VX,
|
||||
SNDRV_HWDEP_IFACE_MIXART,
|
||||
SNDRV_HWDEP_IFACE_USX2Y,
|
||||
SNDRV_HWDEP_IFACE_EMUX_WAVETABLE,
|
||||
SNDRV_HWDEP_IFACE_BLUETOOTH,
|
||||
SNDRV_HWDEP_IFACE_USX2Y_PCM,
|
||||
SNDRV_HWDEP_IFACE_PCXHR,
|
||||
SNDRV_HWDEP_IFACE_SB_RC,
|
||||
SNDRV_HWDEP_IFACE_HDA,
|
||||
SNDRV_HWDEP_IFACE_USB_STREAM,
|
||||
|
||||
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM
|
||||
};
|
||||
|
||||
struct snd_hwdep_info {
|
||||
unsigned int device;
|
||||
int card;
|
||||
unsigned char id[64];
|
||||
unsigned char name[80];
|
||||
int iface;
|
||||
unsigned char reserved[64];
|
||||
};
|
||||
|
||||
struct snd_hwdep_dsp_status {
|
||||
unsigned int version;
|
||||
unsigned char id[32];
|
||||
unsigned int num_dsps;
|
||||
unsigned int dsp_loaded;
|
||||
unsigned int chip_ready;
|
||||
unsigned char reserved[16];
|
||||
};
|
||||
|
||||
struct snd_hwdep_dsp_image {
|
||||
unsigned int index;
|
||||
unsigned char name[64];
|
||||
unsigned char __user *image;
|
||||
size_t length;
|
||||
unsigned long driver_data;
|
||||
};
|
||||
|
||||
#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int)
|
||||
#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct snd_hwdep_info)
|
||||
#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status)
|
||||
#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image)
|
||||
|
||||
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 10)
|
||||
|
||||
typedef unsigned long snd_pcm_uframes_t;
|
||||
typedef signed long snd_pcm_sframes_t;
|
||||
|
||||
enum {
|
||||
SNDRV_PCM_CLASS_GENERIC = 0,
|
||||
SNDRV_PCM_CLASS_MULTI,
|
||||
SNDRV_PCM_CLASS_MODEM,
|
||||
SNDRV_PCM_CLASS_DIGITIZER,
|
||||
|
||||
SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER,
|
||||
};
|
||||
|
||||
enum {
|
||||
SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0,
|
||||
SNDRV_PCM_SUBCLASS_MULTI_MIX,
|
||||
|
||||
SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX,
|
||||
};
|
||||
|
||||
enum {
|
||||
SNDRV_PCM_STREAM_PLAYBACK = 0,
|
||||
SNDRV_PCM_STREAM_CAPTURE,
|
||||
SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
|
||||
};
|
||||
|
||||
typedef int __bitwise snd_pcm_access_t;
|
||||
#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((__force snd_pcm_access_t) 0)
|
||||
#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((__force snd_pcm_access_t) 1)
|
||||
#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((__force snd_pcm_access_t) 2)
|
||||
#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((__force snd_pcm_access_t) 3)
|
||||
#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((__force snd_pcm_access_t) 4)
|
||||
#define SNDRV_PCM_ACCESS_LAST SNDRV_PCM_ACCESS_RW_NONINTERLEAVED
|
||||
|
||||
typedef int __bitwise snd_pcm_format_t;
|
||||
#define SNDRV_PCM_FORMAT_S8 ((__force snd_pcm_format_t) 0)
|
||||
#define SNDRV_PCM_FORMAT_U8 ((__force snd_pcm_format_t) 1)
|
||||
#define SNDRV_PCM_FORMAT_S16_LE ((__force snd_pcm_format_t) 2)
|
||||
#define SNDRV_PCM_FORMAT_S16_BE ((__force snd_pcm_format_t) 3)
|
||||
#define SNDRV_PCM_FORMAT_U16_LE ((__force snd_pcm_format_t) 4)
|
||||
#define SNDRV_PCM_FORMAT_U16_BE ((__force snd_pcm_format_t) 5)
|
||||
#define SNDRV_PCM_FORMAT_S24_LE ((__force snd_pcm_format_t) 6)
|
||||
#define SNDRV_PCM_FORMAT_S24_BE ((__force snd_pcm_format_t) 7)
|
||||
#define SNDRV_PCM_FORMAT_U24_LE ((__force snd_pcm_format_t) 8)
|
||||
#define SNDRV_PCM_FORMAT_U24_BE ((__force snd_pcm_format_t) 9)
|
||||
#define SNDRV_PCM_FORMAT_S32_LE ((__force snd_pcm_format_t) 10)
|
||||
#define SNDRV_PCM_FORMAT_S32_BE ((__force snd_pcm_format_t) 11)
|
||||
#define SNDRV_PCM_FORMAT_U32_LE ((__force snd_pcm_format_t) 12)
|
||||
#define SNDRV_PCM_FORMAT_U32_BE ((__force snd_pcm_format_t) 13)
|
||||
#define SNDRV_PCM_FORMAT_FLOAT_LE ((__force snd_pcm_format_t) 14)
|
||||
#define SNDRV_PCM_FORMAT_FLOAT_BE ((__force snd_pcm_format_t) 15)
|
||||
#define SNDRV_PCM_FORMAT_FLOAT64_LE ((__force snd_pcm_format_t) 16)
|
||||
#define SNDRV_PCM_FORMAT_FLOAT64_BE ((__force snd_pcm_format_t) 17)
|
||||
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18)
|
||||
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19)
|
||||
#define SNDRV_PCM_FORMAT_MU_LAW ((__force snd_pcm_format_t) 20)
|
||||
#define SNDRV_PCM_FORMAT_A_LAW ((__force snd_pcm_format_t) 21)
|
||||
#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22)
|
||||
#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23)
|
||||
#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24)
|
||||
#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31)
|
||||
#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32)
|
||||
#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33)
|
||||
#define SNDRV_PCM_FORMAT_U24_3LE ((__force snd_pcm_format_t) 34)
|
||||
#define SNDRV_PCM_FORMAT_U24_3BE ((__force snd_pcm_format_t) 35)
|
||||
#define SNDRV_PCM_FORMAT_S20_3LE ((__force snd_pcm_format_t) 36)
|
||||
#define SNDRV_PCM_FORMAT_S20_3BE ((__force snd_pcm_format_t) 37)
|
||||
#define SNDRV_PCM_FORMAT_U20_3LE ((__force snd_pcm_format_t) 38)
|
||||
#define SNDRV_PCM_FORMAT_U20_3BE ((__force snd_pcm_format_t) 39)
|
||||
#define SNDRV_PCM_FORMAT_S18_3LE ((__force snd_pcm_format_t) 40)
|
||||
#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41)
|
||||
#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42)
|
||||
#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43)
|
||||
#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44)
|
||||
#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45)
|
||||
#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46)
|
||||
#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47)
|
||||
#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_G723_40_1B
|
||||
|
||||
#ifdef SNDRV_LITTLE_ENDIAN
|
||||
#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_LE
|
||||
#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_LE
|
||||
#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_LE
|
||||
#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_LE
|
||||
#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_LE
|
||||
#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_LE
|
||||
#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_LE
|
||||
#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_LE
|
||||
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
|
||||
#endif
|
||||
#ifdef SNDRV_BIG_ENDIAN
|
||||
#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_BE
|
||||
#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_BE
|
||||
#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_BE
|
||||
#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_BE
|
||||
#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_BE
|
||||
#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_BE
|
||||
#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_BE
|
||||
#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_BE
|
||||
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
|
||||
#endif
|
||||
|
||||
typedef int __bitwise snd_pcm_subformat_t;
|
||||
#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0)
|
||||
#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD
|
||||
|
||||
#define SNDRV_PCM_INFO_MMAP 0x00000001
|
||||
#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002
|
||||
#define SNDRV_PCM_INFO_DOUBLE 0x00000004
|
||||
#define SNDRV_PCM_INFO_BATCH 0x00000010
|
||||
#define SNDRV_PCM_INFO_INTERLEAVED 0x00000100
|
||||
#define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200
|
||||
#define SNDRV_PCM_INFO_COMPLEX 0x00000400
|
||||
#define SNDRV_PCM_INFO_BLOCK_TRANSFER 0x00010000
|
||||
#define SNDRV_PCM_INFO_OVERRANGE 0x00020000
|
||||
#define SNDRV_PCM_INFO_RESUME 0x00040000
|
||||
#define SNDRV_PCM_INFO_PAUSE 0x00080000
|
||||
#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000
|
||||
#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000
|
||||
#define SNDRV_PCM_INFO_SYNC_START 0x00400000
|
||||
#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000
|
||||
#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000
|
||||
|
||||
typedef int __bitwise snd_pcm_state_t;
|
||||
#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0)
|
||||
#define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1)
|
||||
#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2)
|
||||
#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3)
|
||||
#define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4)
|
||||
#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5)
|
||||
#define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6)
|
||||
#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7)
|
||||
#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8)
|
||||
#define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED
|
||||
|
||||
enum {
|
||||
SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
|
||||
SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000,
|
||||
SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000,
|
||||
};
|
||||
|
||||
union snd_pcm_sync_id {
|
||||
unsigned char id[16];
|
||||
unsigned short id16[8];
|
||||
unsigned int id32[4];
|
||||
};
|
||||
|
||||
struct snd_pcm_info {
|
||||
unsigned int device;
|
||||
unsigned int subdevice;
|
||||
int stream;
|
||||
int card;
|
||||
unsigned char id[64];
|
||||
unsigned char name[80];
|
||||
unsigned char subname[32];
|
||||
int dev_class;
|
||||
int dev_subclass;
|
||||
unsigned int subdevices_count;
|
||||
unsigned int subdevices_avail;
|
||||
union snd_pcm_sync_id sync;
|
||||
unsigned char reserved[64];
|
||||
};
|
||||
|
||||
typedef int snd_pcm_hw_param_t;
|
||||
#define SNDRV_PCM_HW_PARAM_ACCESS 0
|
||||
#define SNDRV_PCM_HW_PARAM_FORMAT 1
|
||||
#define SNDRV_PCM_HW_PARAM_SUBFORMAT 2
|
||||
#define SNDRV_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_ACCESS
|
||||
#define SNDRV_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_SUBFORMAT
|
||||
|
||||
#define SNDRV_PCM_HW_PARAM_SAMPLE_BITS 8
|
||||
#define SNDRV_PCM_HW_PARAM_FRAME_BITS 9
|
||||
#define SNDRV_PCM_HW_PARAM_CHANNELS 10
|
||||
#define SNDRV_PCM_HW_PARAM_RATE 11
|
||||
#define SNDRV_PCM_HW_PARAM_PERIOD_TIME 12
|
||||
#define SNDRV_PCM_HW_PARAM_PERIOD_SIZE 13
|
||||
#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES 14
|
||||
#define SNDRV_PCM_HW_PARAM_PERIODS 15
|
||||
#define SNDRV_PCM_HW_PARAM_BUFFER_TIME 16
|
||||
#define SNDRV_PCM_HW_PARAM_BUFFER_SIZE 17
|
||||
#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES 18
|
||||
#define SNDRV_PCM_HW_PARAM_TICK_TIME 19
|
||||
#define SNDRV_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_SAMPLE_BITS
|
||||
#define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME
|
||||
|
||||
#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0)
|
||||
#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1)
|
||||
#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2)
|
||||
|
||||
struct snd_interval {
|
||||
unsigned int min, max;
|
||||
unsigned int openmin:1,
|
||||
openmax:1,
|
||||
integer:1,
|
||||
empty:1;
|
||||
};
|
||||
|
||||
#define SNDRV_MASK_MAX 256
|
||||
|
||||
struct snd_mask {
|
||||
__u32 bits[(SNDRV_MASK_MAX+31)/32];
|
||||
};
|
||||
|
||||
struct snd_pcm_hw_params {
|
||||
unsigned int flags;
|
||||
struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
|
||||
SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
|
||||
struct snd_mask mres[5];
|
||||
struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
|
||||
SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
|
||||
struct snd_interval ires[9];
|
||||
unsigned int rmask;
|
||||
unsigned int cmask;
|
||||
unsigned int info;
|
||||
unsigned int msbits;
|
||||
unsigned int rate_num;
|
||||
unsigned int rate_den;
|
||||
snd_pcm_uframes_t fifo_size;
|
||||
unsigned char reserved[64];
|
||||
};
|
||||
|
||||
enum {
|
||||
SNDRV_PCM_TSTAMP_NONE = 0,
|
||||
SNDRV_PCM_TSTAMP_ENABLE,
|
||||
SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_ENABLE,
|
||||
};
|
||||
|
||||
struct snd_pcm_sw_params {
|
||||
int tstamp_mode;
|
||||
unsigned int period_step;
|
||||
unsigned int sleep_min;
|
||||
snd_pcm_uframes_t avail_min;
|
||||
snd_pcm_uframes_t xfer_align;
|
||||
snd_pcm_uframes_t start_threshold;
|
||||
snd_pcm_uframes_t stop_threshold;
|
||||
snd_pcm_uframes_t silence_threshold;
|
||||
snd_pcm_uframes_t silence_size;
|
||||
snd_pcm_uframes_t boundary;
|
||||
unsigned char reserved[64];
|
||||
};
|
||||
|
||||
struct snd_pcm_channel_info {
|
||||
unsigned int channel;
|
||||
__kernel_off_t offset;
|
||||
unsigned int first;
|
||||
unsigned int step;
|
||||
};
|
||||
|
||||
struct snd_pcm_status {
|
||||
snd_pcm_state_t state;
|
||||
struct timespec trigger_tstamp;
|
||||
struct timespec tstamp;
|
||||
snd_pcm_uframes_t appl_ptr;
|
||||
snd_pcm_uframes_t hw_ptr;
|
||||
snd_pcm_sframes_t delay;
|
||||
snd_pcm_uframes_t avail;
|
||||
snd_pcm_uframes_t avail_max;
|
||||
snd_pcm_uframes_t overrange;
|
||||
snd_pcm_state_t suspended_state;
|
||||
unsigned char reserved[60];
|
||||
};
|
||||
|
||||
struct snd_pcm_mmap_status {
|
||||
snd_pcm_state_t state;
|
||||
int pad1;
|
||||
snd_pcm_uframes_t hw_ptr;
|
||||
struct timespec tstamp;
|
||||
snd_pcm_state_t suspended_state;
|
||||
};
|
||||
|
||||
struct snd_pcm_mmap_control {
|
||||
snd_pcm_uframes_t appl_ptr;
|
||||
snd_pcm_uframes_t avail_min;
|
||||
};
|
||||
|
||||
#define SNDRV_PCM_SYNC_PTR_HWSYNC (1<<0)
|
||||
#define SNDRV_PCM_SYNC_PTR_APPL (1<<1)
|
||||
#define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2)
|
||||
|
||||
struct snd_pcm_sync_ptr {
|
||||
unsigned int flags;
|
||||
union {
|
||||
struct snd_pcm_mmap_status status;
|
||||
unsigned char reserved[64];
|
||||
} s;
|
||||
union {
|
||||
struct snd_pcm_mmap_control control;
|
||||
unsigned char reserved[64];
|
||||
} c;
|
||||
};
|
||||
|
||||
struct snd_xferi {
|
||||
snd_pcm_sframes_t result;
|
||||
void __user *buf;
|
||||
snd_pcm_uframes_t frames;
|
||||
};
|
||||
|
||||
struct snd_xfern {
|
||||
snd_pcm_sframes_t result;
|
||||
void __user * __user *bufs;
|
||||
snd_pcm_uframes_t frames;
|
||||
};
|
||||
|
||||
enum {
|
||||
SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0,
|
||||
SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,
|
||||
SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,
|
||||
};
|
||||
|
||||
#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int)
|
||||
#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info)
|
||||
#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int)
|
||||
#define SNDRV_PCM_IOCTL_TTSTAMP _IOW('A', 0x03, int)
|
||||
#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct snd_pcm_hw_params)
|
||||
#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct snd_pcm_hw_params)
|
||||
#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12)
|
||||
#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct snd_pcm_sw_params)
|
||||
#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct snd_pcm_status)
|
||||
#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, snd_pcm_sframes_t)
|
||||
#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22)
|
||||
#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct snd_pcm_sync_ptr)
|
||||
#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info)
|
||||
#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40)
|
||||
#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41)
|
||||
#define SNDRV_PCM_IOCTL_START _IO('A', 0x42)
|
||||
#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43)
|
||||
#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44)
|
||||
#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int)
|
||||
#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, snd_pcm_uframes_t)
|
||||
#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47)
|
||||
#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48)
|
||||
#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, snd_pcm_uframes_t)
|
||||
#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct snd_xferi)
|
||||
#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct snd_xferi)
|
||||
#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct snd_xfern)
|
||||
#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct snd_xfern)
|
||||
#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int)
|
||||
#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61)
|
||||
|
||||
#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0)
|
||||
|
||||
enum {
|
||||
SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
|
||||
SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
};
|
||||
|
||||
#define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001
|
||||
#define SNDRV_RAWMIDI_INFO_INPUT 0x00000002
|
||||
#define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004
|
||||
|
||||
struct snd_rawmidi_info {
|
||||
unsigned int device;
|
||||
unsigned int subdevice;
|
||||
int stream;
|
||||
int card;
|
||||
unsigned int flags;
|
||||
unsigned char id[64];
|
||||
unsigned char name[80];
|
||||
unsigned char subname[32];
|
||||
unsigned int subdevices_count;
|
||||
unsigned int subdevices_avail;
|
||||
unsigned char reserved[64];
|
||||
};
|
||||
|
||||
struct snd_rawmidi_params {
|
||||
int stream;
|
||||
size_t buffer_size;
|
||||
size_t avail_min;
|
||||
unsigned int no_active_sensing: 1;
|
||||
unsigned char reserved[16];
|
||||
};
|
||||
|
||||
struct snd_rawmidi_status {
|
||||
int stream;
|
||||
struct timespec tstamp;
|
||||
size_t avail;
|
||||
size_t xruns;
|
||||
unsigned char reserved[16];
|
||||
};
|
||||
|
||||
#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int)
|
||||
#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info)
|
||||
#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params)
|
||||
#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status)
|
||||
#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
|
||||
#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
|
||||
|
||||
#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
|
||||
|
||||
enum {
|
||||
SNDRV_TIMER_CLASS_NONE = -1,
|
||||
SNDRV_TIMER_CLASS_SLAVE = 0,
|
||||
SNDRV_TIMER_CLASS_GLOBAL,
|
||||
SNDRV_TIMER_CLASS_CARD,
|
||||
SNDRV_TIMER_CLASS_PCM,
|
||||
SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM,
|
||||
};
|
||||
|
||||
enum {
|
||||
SNDRV_TIMER_SCLASS_NONE = 0,
|
||||
SNDRV_TIMER_SCLASS_APPLICATION,
|
||||
SNDRV_TIMER_SCLASS_SEQUENCER,
|
||||
SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
|
||||
SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
|
||||
};
|
||||
|
||||
#define SNDRV_TIMER_GLOBAL_SYSTEM 0
|
||||
#define SNDRV_TIMER_GLOBAL_RTC 1
|
||||
#define SNDRV_TIMER_GLOBAL_HPET 2
|
||||
#define SNDRV_TIMER_GLOBAL_HRTIMER 3
|
||||
|
||||
#define SNDRV_TIMER_FLG_SLAVE (1<<0)
|
||||
|
||||
struct snd_timer_id {
|
||||
int dev_class;
|
||||
int dev_sclass;
|
||||
int card;
|
||||
int device;
|
||||
int subdevice;
|
||||
};
|
||||
|
||||
struct snd_timer_ginfo {
|
||||
struct snd_timer_id tid;
|
||||
unsigned int flags;
|
||||
int card;
|
||||
unsigned char id[64];
|
||||
unsigned char name[80];
|
||||
unsigned long reserved0;
|
||||
unsigned long resolution;
|
||||
unsigned long resolution_min;
|
||||
unsigned long resolution_max;
|
||||
unsigned int clients;
|
||||
unsigned char reserved[32];
|
||||
};
|
||||
|
||||
struct snd_timer_gparams {
|
||||
struct snd_timer_id tid;
|
||||
unsigned long period_num;
|
||||
unsigned long period_den;
|
||||
unsigned char reserved[32];
|
||||
};
|
||||
|
||||
struct snd_timer_gstatus {
|
||||
struct snd_timer_id tid;
|
||||
unsigned long resolution;
|
||||
unsigned long resolution_num;
|
||||
unsigned long resolution_den;
|
||||
unsigned char reserved[32];
|
||||
};
|
||||
|
||||
struct snd_timer_select {
|
||||
struct snd_timer_id id;
|
||||
unsigned char reserved[32];
|
||||
};
|
||||
|
||||
struct snd_timer_info {
|
||||
unsigned int flags;
|
||||
int card;
|
||||
unsigned char id[64];
|
||||
unsigned char name[80];
|
||||
unsigned long reserved0;
|
||||
unsigned long resolution;
|
||||
unsigned char reserved[64];
|
||||
};
|
||||
|
||||
#define SNDRV_TIMER_PSFLG_AUTO (1<<0)
|
||||
#define SNDRV_TIMER_PSFLG_EXCLUSIVE (1<<1)
|
||||
#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1<<2)
|
||||
|
||||
struct snd_timer_params {
|
||||
unsigned int flags;
|
||||
unsigned int ticks;
|
||||
unsigned int queue_size;
|
||||
unsigned int reserved0;
|
||||
unsigned int filter;
|
||||
unsigned char reserved[60];
|
||||
};
|
||||
|
||||
struct snd_timer_status {
|
||||
struct timespec tstamp;
|
||||
unsigned int resolution;
|
||||
unsigned int lost;
|
||||
unsigned int overrun;
|
||||
unsigned int queue;
|
||||
unsigned char reserved[64];
|
||||
};
|
||||
|
||||
#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int)
|
||||
#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id)
|
||||
#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int)
|
||||
#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo)
|
||||
#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct snd_timer_gparams)
|
||||
#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct snd_timer_gstatus)
|
||||
#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct snd_timer_select)
|
||||
#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct snd_timer_info)
|
||||
#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct snd_timer_params)
|
||||
#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct snd_timer_status)
|
||||
|
||||
#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0)
|
||||
#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1)
|
||||
#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2)
|
||||
#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3)
|
||||
|
||||
struct snd_timer_read {
|
||||
unsigned int resolution;
|
||||
unsigned int ticks;
|
||||
};
|
||||
|
||||
enum {
|
||||
SNDRV_TIMER_EVENT_RESOLUTION = 0,
|
||||
SNDRV_TIMER_EVENT_TICK,
|
||||
SNDRV_TIMER_EVENT_START,
|
||||
SNDRV_TIMER_EVENT_STOP,
|
||||
SNDRV_TIMER_EVENT_CONTINUE,
|
||||
SNDRV_TIMER_EVENT_PAUSE,
|
||||
SNDRV_TIMER_EVENT_EARLY,
|
||||
SNDRV_TIMER_EVENT_SUSPEND,
|
||||
SNDRV_TIMER_EVENT_RESUME,
|
||||
|
||||
SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10,
|
||||
SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10,
|
||||
SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10,
|
||||
SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10,
|
||||
SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10,
|
||||
SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10,
|
||||
};
|
||||
|
||||
struct snd_timer_tread {
|
||||
int event;
|
||||
struct timespec tstamp;
|
||||
unsigned int val;
|
||||
};
|
||||
|
||||
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
|
||||
|
||||
struct snd_ctl_card_info {
|
||||
int card;
|
||||
int pad;
|
||||
unsigned char id[16];
|
||||
unsigned char driver[16];
|
||||
unsigned char name[32];
|
||||
unsigned char longname[80];
|
||||
unsigned char reserved_[16];
|
||||
unsigned char mixername[80];
|
||||
unsigned char components[128];
|
||||
};
|
||||
|
||||
typedef int __bitwise snd_ctl_elem_type_t;
|
||||
#define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0)
|
||||
#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1)
|
||||
#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2)
|
||||
#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3)
|
||||
#define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4)
|
||||
#define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5)
|
||||
#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6)
|
||||
#define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64
|
||||
|
||||
typedef int __bitwise snd_ctl_elem_iface_t;
|
||||
#define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0)
|
||||
#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1)
|
||||
#define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2)
|
||||
#define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3)
|
||||
#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4)
|
||||
#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5)
|
||||
#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6)
|
||||
#define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER
|
||||
|
||||
#define SNDRV_CTL_ELEM_ACCESS_READ (1<<0)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<3)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1<<4)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1<<5)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND (1<<6)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1<<8)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_LOCK (1<<9)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK (1<<28)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_USER (1<<29)
|
||||
|
||||
#define SNDRV_CTL_POWER_D0 0x0000
|
||||
#define SNDRV_CTL_POWER_D1 0x0100
|
||||
#define SNDRV_CTL_POWER_D2 0x0200
|
||||
#define SNDRV_CTL_POWER_D3 0x0300
|
||||
#define SNDRV_CTL_POWER_D3hot (SNDRV_CTL_POWER_D3|0x0000)
|
||||
#define SNDRV_CTL_POWER_D3cold (SNDRV_CTL_POWER_D3|0x0001)
|
||||
|
||||
struct snd_ctl_elem_id {
|
||||
unsigned int numid;
|
||||
snd_ctl_elem_iface_t iface;
|
||||
unsigned int device;
|
||||
unsigned int subdevice;
|
||||
unsigned char name[44];
|
||||
unsigned int index;
|
||||
};
|
||||
|
||||
struct snd_ctl_elem_list {
|
||||
unsigned int offset;
|
||||
unsigned int space;
|
||||
unsigned int used;
|
||||
unsigned int count;
|
||||
struct snd_ctl_elem_id __user *pids;
|
||||
unsigned char reserved[50];
|
||||
};
|
||||
|
||||
struct snd_ctl_elem_info {
|
||||
struct snd_ctl_elem_id id;
|
||||
snd_ctl_elem_type_t type;
|
||||
unsigned int access;
|
||||
unsigned int count;
|
||||
__kernel_pid_t owner;
|
||||
union {
|
||||
struct {
|
||||
long min;
|
||||
long max;
|
||||
long step;
|
||||
} integer;
|
||||
struct {
|
||||
long long min;
|
||||
long long max;
|
||||
long long step;
|
||||
} integer64;
|
||||
struct {
|
||||
unsigned int items;
|
||||
unsigned int item;
|
||||
char name[64];
|
||||
} enumerated;
|
||||
unsigned char reserved[128];
|
||||
} value;
|
||||
union {
|
||||
unsigned short d[4];
|
||||
unsigned short *d_ptr;
|
||||
} dimen;
|
||||
unsigned char reserved[64-4*sizeof(unsigned short)];
|
||||
};
|
||||
|
||||
struct snd_ctl_elem_value {
|
||||
struct snd_ctl_elem_id id;
|
||||
unsigned int indirect: 1;
|
||||
union {
|
||||
union {
|
||||
long value[128];
|
||||
long *value_ptr;
|
||||
} integer;
|
||||
union {
|
||||
long long value[64];
|
||||
long long *value_ptr;
|
||||
} integer64;
|
||||
union {
|
||||
unsigned int item[128];
|
||||
unsigned int *item_ptr;
|
||||
} enumerated;
|
||||
union {
|
||||
unsigned char data[512];
|
||||
unsigned char *data_ptr;
|
||||
} bytes;
|
||||
struct snd_aes_iec958 iec958;
|
||||
} value;
|
||||
struct timespec tstamp;
|
||||
unsigned char reserved[128-sizeof(struct timespec)];
|
||||
};
|
||||
|
||||
struct snd_ctl_tlv {
|
||||
unsigned int numid;
|
||||
unsigned int length;
|
||||
unsigned int tlv[0];
|
||||
};
|
||||
|
||||
#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
|
||||
#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct snd_ctl_elem_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct snd_ctl_elem_value)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct snd_ctl_elem_value)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct snd_ctl_elem_id)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct snd_ctl_elem_id)
|
||||
#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct snd_ctl_elem_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct snd_ctl_elem_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct snd_ctl_elem_id)
|
||||
#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct snd_ctl_tlv)
|
||||
#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct snd_ctl_tlv)
|
||||
#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct snd_ctl_tlv)
|
||||
#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int)
|
||||
#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct snd_hwdep_info)
|
||||
#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int)
|
||||
#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct snd_pcm_info)
|
||||
#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int)
|
||||
#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
|
||||
#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info)
|
||||
#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
|
||||
#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int)
|
||||
#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int)
|
||||
|
||||
enum sndrv_ctl_event_type {
|
||||
SNDRV_CTL_EVENT_ELEM = 0,
|
||||
SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM,
|
||||
};
|
||||
|
||||
#define SNDRV_CTL_EVENT_MASK_VALUE (1<<0)
|
||||
#define SNDRV_CTL_EVENT_MASK_INFO (1<<1)
|
||||
#define SNDRV_CTL_EVENT_MASK_ADD (1<<2)
|
||||
#define SNDRV_CTL_EVENT_MASK_TLV (1<<3)
|
||||
#define SNDRV_CTL_EVENT_MASK_REMOVE (~0U)
|
||||
|
||||
struct snd_ctl_event {
|
||||
int type;
|
||||
union {
|
||||
struct {
|
||||
unsigned int mask;
|
||||
struct snd_ctl_elem_id id;
|
||||
} elem;
|
||||
unsigned char data8[60];
|
||||
} data;
|
||||
};
|
||||
|
||||
#define SNDRV_CTL_NAME_NONE ""
|
||||
#define SNDRV_CTL_NAME_PLAYBACK "Playback "
|
||||
#define SNDRV_CTL_NAME_CAPTURE "Capture "
|
||||
|
||||
#define SNDRV_CTL_NAME_IEC958_NONE ""
|
||||
#define SNDRV_CTL_NAME_IEC958_SWITCH "Switch"
|
||||
#define SNDRV_CTL_NAME_IEC958_VOLUME "Volume"
|
||||
#define SNDRV_CTL_NAME_IEC958_DEFAULT "Default"
|
||||
#define SNDRV_CTL_NAME_IEC958_MASK "Mask"
|
||||
#define SNDRV_CTL_NAME_IEC958_CON_MASK "Con Mask"
|
||||
#define SNDRV_CTL_NAME_IEC958_PRO_MASK "Pro Mask"
|
||||
#define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream"
|
||||
#define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what
|
||||
|
||||
#endif
|
||||
|
||||
261
external/cache/sources/tinyalsa/include/tinyalsa/asoundlib.h
vendored
Normal file
261
external/cache/sources/tinyalsa/include/tinyalsa/asoundlib.h
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
/* asoundlib.h
|
||||
**
|
||||
** Copyright 2011, The Android Open Source Project
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of The Android Open Source Project nor the names of
|
||||
** its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
|
||||
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
** DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ASOUNDLIB_H
|
||||
#define ASOUNDLIB_H
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PCM API
|
||||
*/
|
||||
|
||||
struct pcm;
|
||||
|
||||
#define PCM_OUT 0x00000000
|
||||
#define PCM_IN 0x10000000
|
||||
#define PCM_MMAP 0x00000001
|
||||
#define PCM_NOIRQ 0x00000002
|
||||
#define PCM_NORESTART 0x00000004 /* PCM_NORESTART - when set, calls to
|
||||
* pcm_write for a playback stream will not
|
||||
* attempt to restart the stream in the case
|
||||
* of an underflow, but will return -EPIPE
|
||||
* instead. After the first -EPIPE error, the
|
||||
* stream is considered to be stopped, and a
|
||||
* second call to pcm_write will attempt to
|
||||
* restart the stream.
|
||||
*/
|
||||
#define PCM_MONOTONIC 0x00000008 /* see pcm_get_htimestamp */
|
||||
|
||||
/* PCM runtime states */
|
||||
#define PCM_STATE_RUNNING 3
|
||||
#define PCM_STATE_XRUN 4
|
||||
#define PCM_STATE_DRAINING 5
|
||||
#define PCM_STATE_SUSPENDED 7
|
||||
#define PCM_STATE_DISCONNECTED 8
|
||||
|
||||
/* Bit formats */
|
||||
enum pcm_format {
|
||||
PCM_FORMAT_S16_LE = 0,
|
||||
PCM_FORMAT_S32_LE,
|
||||
PCM_FORMAT_S8,
|
||||
PCM_FORMAT_S24_LE,
|
||||
|
||||
PCM_FORMAT_MAX,
|
||||
};
|
||||
|
||||
/* Bitmask has 256 bits (32 bytes) in asound.h */
|
||||
struct pcm_mask {
|
||||
unsigned int bits[32 / sizeof(unsigned int)];
|
||||
};
|
||||
|
||||
/* Configuration for a stream */
|
||||
struct pcm_config {
|
||||
unsigned int channels;
|
||||
unsigned int rate;
|
||||
unsigned int period_size;
|
||||
unsigned int period_count;
|
||||
enum pcm_format format;
|
||||
|
||||
/* Values to use for the ALSA start, stop and silence thresholds. Setting
|
||||
* any one of these values to 0 will cause the default tinyalsa values to be
|
||||
* used instead. Tinyalsa defaults are as follows.
|
||||
*
|
||||
* start_threshold : period_count * period_size
|
||||
* stop_threshold : period_count * period_size
|
||||
* silence_threshold : 0
|
||||
*/
|
||||
unsigned int start_threshold;
|
||||
unsigned int stop_threshold;
|
||||
unsigned int silence_threshold;
|
||||
};
|
||||
|
||||
/* PCM parameters */
|
||||
enum pcm_param
|
||||
{
|
||||
/* mask parameters */
|
||||
PCM_PARAM_ACCESS,
|
||||
PCM_PARAM_FORMAT,
|
||||
PCM_PARAM_SUBFORMAT,
|
||||
/* interval parameters */
|
||||
PCM_PARAM_SAMPLE_BITS,
|
||||
PCM_PARAM_FRAME_BITS,
|
||||
PCM_PARAM_CHANNELS,
|
||||
PCM_PARAM_RATE,
|
||||
PCM_PARAM_PERIOD_TIME,
|
||||
PCM_PARAM_PERIOD_SIZE,
|
||||
PCM_PARAM_PERIOD_BYTES,
|
||||
PCM_PARAM_PERIODS,
|
||||
PCM_PARAM_BUFFER_TIME,
|
||||
PCM_PARAM_BUFFER_SIZE,
|
||||
PCM_PARAM_BUFFER_BYTES,
|
||||
PCM_PARAM_TICK_TIME,
|
||||
};
|
||||
|
||||
/* Mixer control types */
|
||||
enum mixer_ctl_type {
|
||||
MIXER_CTL_TYPE_BOOL,
|
||||
MIXER_CTL_TYPE_INT,
|
||||
MIXER_CTL_TYPE_ENUM,
|
||||
MIXER_CTL_TYPE_BYTE,
|
||||
MIXER_CTL_TYPE_IEC958,
|
||||
MIXER_CTL_TYPE_INT64,
|
||||
MIXER_CTL_TYPE_UNKNOWN,
|
||||
|
||||
MIXER_CTL_TYPE_MAX,
|
||||
};
|
||||
|
||||
/* Open and close a stream */
|
||||
struct pcm *pcm_open(unsigned int card, unsigned int device,
|
||||
unsigned int flags, struct pcm_config *config);
|
||||
int pcm_close(struct pcm *pcm);
|
||||
int pcm_is_ready(struct pcm *pcm);
|
||||
|
||||
/* Obtain the parameters for a PCM */
|
||||
struct pcm_params *pcm_params_get(unsigned int card, unsigned int device,
|
||||
unsigned int flags);
|
||||
void pcm_params_free(struct pcm_params *pcm_params);
|
||||
|
||||
struct pcm_mask *pcm_params_get_mask(struct pcm_params *pcm_params,
|
||||
enum pcm_param param);
|
||||
unsigned int pcm_params_get_min(struct pcm_params *pcm_params,
|
||||
enum pcm_param param);
|
||||
unsigned int pcm_params_get_max(struct pcm_params *pcm_params,
|
||||
enum pcm_param param);
|
||||
|
||||
/* Returns a human readable reason for the last error */
|
||||
const char *pcm_get_error(struct pcm *pcm);
|
||||
|
||||
/* Returns the sample size in bits for a PCM format.
|
||||
* As with ALSA formats, this is the storage size for the format, whereas the
|
||||
* format represents the number of significant bits. For example,
|
||||
* PCM_FORMAT_S24_LE uses 32 bits of storage.
|
||||
*/
|
||||
unsigned int pcm_format_to_bits(enum pcm_format format);
|
||||
|
||||
/* Returns the buffer size (int frames) that should be used for pcm_write. */
|
||||
unsigned int pcm_get_buffer_size(struct pcm *pcm);
|
||||
unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames);
|
||||
unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes);
|
||||
|
||||
/* Returns available frames in pcm buffer and corresponding time stamp.
|
||||
* The clock is CLOCK_MONOTONIC if flag PCM_MONOTONIC was specified in pcm_open,
|
||||
* otherwise the clock is CLOCK_REALTIME.
|
||||
* For an input stream, frames available are frames ready for the
|
||||
* application to read.
|
||||
* For an output stream, frames available are the number of empty frames available
|
||||
* for the application to write.
|
||||
*/
|
||||
int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
|
||||
struct timespec *tstamp);
|
||||
|
||||
/* Write data to the fifo.
|
||||
* Will start playback on the first write or on a write that
|
||||
* occurs after a fifo underrun.
|
||||
*/
|
||||
int pcm_write(struct pcm *pcm, const void *data, unsigned int count);
|
||||
int pcm_read(struct pcm *pcm, void *data, unsigned int count);
|
||||
|
||||
/*
|
||||
* mmap() support.
|
||||
*/
|
||||
int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count);
|
||||
int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count);
|
||||
int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset,
|
||||
unsigned int *frames);
|
||||
int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames);
|
||||
|
||||
int pcm_resume(struct pcm *pcm);
|
||||
/* Prepare the PCM substream to be triggerable */
|
||||
int pcm_prepare(struct pcm *pcm);
|
||||
/* Start and stop a PCM channel that doesn't transfer data */
|
||||
int pcm_start(struct pcm *pcm);
|
||||
int pcm_stop(struct pcm *pcm);
|
||||
|
||||
/* Interrupt driven API */
|
||||
int pcm_wait(struct pcm *pcm, int timeout);
|
||||
|
||||
|
||||
/*
|
||||
* MIXER API
|
||||
*/
|
||||
|
||||
struct mixer;
|
||||
struct mixer_ctl;
|
||||
|
||||
/* Open and close a mixer */
|
||||
struct mixer *mixer_open(unsigned int card);
|
||||
void mixer_close(struct mixer *mixer);
|
||||
|
||||
/* Get info about a mixer */
|
||||
const char *mixer_get_name(struct mixer *mixer);
|
||||
|
||||
/* Obtain mixer controls */
|
||||
unsigned int mixer_get_num_ctls(struct mixer *mixer);
|
||||
struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id);
|
||||
struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name);
|
||||
|
||||
/* Get info about mixer controls */
|
||||
const char *mixer_ctl_get_name(struct mixer_ctl *ctl);
|
||||
enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl);
|
||||
const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl);
|
||||
unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl);
|
||||
unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl);
|
||||
const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl,
|
||||
unsigned int enum_id);
|
||||
|
||||
/* Some sound cards update their controls due to external events,
|
||||
* such as HDMI EDID byte data changing when an HDMI cable is
|
||||
* connected. This API allows the count of elements to be updated.
|
||||
*/
|
||||
void mixer_ctl_update(struct mixer_ctl *ctl);
|
||||
|
||||
/* Set and get mixer controls */
|
||||
int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id);
|
||||
int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent);
|
||||
|
||||
int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id);
|
||||
int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count);
|
||||
int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value);
|
||||
int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count);
|
||||
int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string);
|
||||
|
||||
/* Determe range of integer mixer controls */
|
||||
int mixer_ctl_get_range_min(struct mixer_ctl *ctl);
|
||||
int mixer_ctl_get_range_max(struct mixer_ctl *ctl);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
503
external/cache/sources/tinyalsa/mixer.c
vendored
Normal file
503
external/cache/sources/tinyalsa/mixer.c
vendored
Normal file
@@ -0,0 +1,503 @@
|
||||
/* mixer.c
|
||||
**
|
||||
** Copyright 2011, The Android Open Source Project
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of The Android Open Source Project nor the names of
|
||||
** its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
|
||||
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
** DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#define __force
|
||||
#define __bitwise
|
||||
#define __user
|
||||
#include <sound/asound.h>
|
||||
|
||||
#include <tinyalsa/asoundlib.h>
|
||||
|
||||
struct mixer_ctl {
|
||||
struct mixer *mixer;
|
||||
struct snd_ctl_elem_info *info;
|
||||
char **ename;
|
||||
};
|
||||
|
||||
struct mixer {
|
||||
int fd;
|
||||
struct snd_ctl_card_info card_info;
|
||||
struct snd_ctl_elem_info *elem_info;
|
||||
struct mixer_ctl *ctl;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
void mixer_close(struct mixer *mixer)
|
||||
{
|
||||
unsigned int n,m;
|
||||
|
||||
if (!mixer)
|
||||
return;
|
||||
|
||||
if (mixer->fd >= 0)
|
||||
close(mixer->fd);
|
||||
|
||||
if (mixer->ctl) {
|
||||
for (n = 0; n < mixer->count; n++) {
|
||||
if (mixer->ctl[n].ename) {
|
||||
unsigned int max = mixer->ctl[n].info->value.enumerated.items;
|
||||
for (m = 0; m < max; m++)
|
||||
free(mixer->ctl[n].ename[m]);
|
||||
free(mixer->ctl[n].ename);
|
||||
}
|
||||
}
|
||||
free(mixer->ctl);
|
||||
}
|
||||
|
||||
if (mixer->elem_info)
|
||||
free(mixer->elem_info);
|
||||
|
||||
free(mixer);
|
||||
|
||||
/* TODO: verify frees */
|
||||
}
|
||||
|
||||
struct mixer *mixer_open(unsigned int card)
|
||||
{
|
||||
struct snd_ctl_elem_list elist;
|
||||
struct snd_ctl_elem_info tmp;
|
||||
struct snd_ctl_elem_id *eid = NULL;
|
||||
struct mixer *mixer = NULL;
|
||||
unsigned int n, m;
|
||||
int fd;
|
||||
char fn[256];
|
||||
|
||||
snprintf(fn, sizeof(fn), "/dev/snd/controlC%u", card);
|
||||
fd = open(fn, O_RDWR);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
memset(&elist, 0, sizeof(elist));
|
||||
if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
|
||||
goto fail;
|
||||
|
||||
mixer = calloc(1, sizeof(*mixer));
|
||||
if (!mixer)
|
||||
goto fail;
|
||||
|
||||
mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl));
|
||||
mixer->elem_info = calloc(elist.count, sizeof(struct snd_ctl_elem_info));
|
||||
if (!mixer->ctl || !mixer->elem_info)
|
||||
goto fail;
|
||||
|
||||
if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info) < 0)
|
||||
goto fail;
|
||||
|
||||
eid = calloc(elist.count, sizeof(struct snd_ctl_elem_id));
|
||||
if (!eid)
|
||||
goto fail;
|
||||
|
||||
mixer->count = elist.count;
|
||||
mixer->fd = fd;
|
||||
elist.space = mixer->count;
|
||||
elist.pids = eid;
|
||||
if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
|
||||
goto fail;
|
||||
|
||||
for (n = 0; n < mixer->count; n++) {
|
||||
struct snd_ctl_elem_info *ei = mixer->elem_info + n;
|
||||
ei->id.numid = eid[n].numid;
|
||||
if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, ei) < 0)
|
||||
goto fail;
|
||||
mixer->ctl[n].info = ei;
|
||||
mixer->ctl[n].mixer = mixer;
|
||||
if (ei->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
|
||||
char **enames = calloc(ei->value.enumerated.items, sizeof(char*));
|
||||
if (!enames)
|
||||
goto fail;
|
||||
mixer->ctl[n].ename = enames;
|
||||
for (m = 0; m < ei->value.enumerated.items; m++) {
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
tmp.id.numid = ei->id.numid;
|
||||
tmp.value.enumerated.item = m;
|
||||
if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0)
|
||||
goto fail;
|
||||
enames[m] = strdup(tmp.value.enumerated.name);
|
||||
if (!enames[m])
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(eid);
|
||||
return mixer;
|
||||
|
||||
fail:
|
||||
/* TODO: verify frees in failure case */
|
||||
if (eid)
|
||||
free(eid);
|
||||
if (mixer)
|
||||
mixer_close(mixer);
|
||||
else if (fd >= 0)
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *mixer_get_name(struct mixer *mixer)
|
||||
{
|
||||
return (const char *)mixer->card_info.name;
|
||||
}
|
||||
|
||||
unsigned int mixer_get_num_ctls(struct mixer *mixer)
|
||||
{
|
||||
if (!mixer)
|
||||
return 0;
|
||||
|
||||
return mixer->count;
|
||||
}
|
||||
|
||||
struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id)
|
||||
{
|
||||
if (mixer && (id < mixer->count))
|
||||
return mixer->ctl + id;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name)
|
||||
{
|
||||
unsigned int n;
|
||||
|
||||
if (!mixer)
|
||||
return NULL;
|
||||
|
||||
for (n = 0; n < mixer->count; n++)
|
||||
if (!strcmp(name, (char*) mixer->elem_info[n].id.name))
|
||||
return mixer->ctl + n;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mixer_ctl_update(struct mixer_ctl *ctl)
|
||||
{
|
||||
ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, ctl->info);
|
||||
}
|
||||
|
||||
const char *mixer_ctl_get_name(struct mixer_ctl *ctl)
|
||||
{
|
||||
if (!ctl)
|
||||
return NULL;
|
||||
|
||||
return (const char *)ctl->info->id.name;
|
||||
}
|
||||
|
||||
enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl)
|
||||
{
|
||||
if (!ctl)
|
||||
return MIXER_CTL_TYPE_UNKNOWN;
|
||||
|
||||
switch (ctl->info->type) {
|
||||
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return MIXER_CTL_TYPE_BOOL;
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER: return MIXER_CTL_TYPE_INT;
|
||||
case SNDRV_CTL_ELEM_TYPE_ENUMERATED: return MIXER_CTL_TYPE_ENUM;
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES: return MIXER_CTL_TYPE_BYTE;
|
||||
case SNDRV_CTL_ELEM_TYPE_IEC958: return MIXER_CTL_TYPE_IEC958;
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER64: return MIXER_CTL_TYPE_INT64;
|
||||
default: return MIXER_CTL_TYPE_UNKNOWN;
|
||||
};
|
||||
}
|
||||
|
||||
const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl)
|
||||
{
|
||||
if (!ctl)
|
||||
return "";
|
||||
|
||||
switch (ctl->info->type) {
|
||||
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return "BOOL";
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER: return "INT";
|
||||
case SNDRV_CTL_ELEM_TYPE_ENUMERATED: return "ENUM";
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES: return "BYTE";
|
||||
case SNDRV_CTL_ELEM_TYPE_IEC958: return "IEC958";
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER64: return "INT64";
|
||||
default: return "Unknown";
|
||||
};
|
||||
}
|
||||
|
||||
unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl)
|
||||
{
|
||||
if (!ctl)
|
||||
return 0;
|
||||
|
||||
return ctl->info->count;
|
||||
}
|
||||
|
||||
static int percent_to_int(struct snd_ctl_elem_info *ei, int percent)
|
||||
{
|
||||
if ((percent > 100) || (percent < 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int range = (ei->value.integer.max - ei->value.integer.min);
|
||||
|
||||
return ei->value.integer.min + (range * percent) / 100;
|
||||
}
|
||||
|
||||
static int int_to_percent(struct snd_ctl_elem_info *ei, int value)
|
||||
{
|
||||
int range = (ei->value.integer.max - ei->value.integer.min);
|
||||
|
||||
if (range == 0)
|
||||
return 0;
|
||||
|
||||
return ((value - ei->value.integer.min) / range) * 100;
|
||||
}
|
||||
|
||||
int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id)
|
||||
{
|
||||
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
|
||||
return -EINVAL;
|
||||
|
||||
return int_to_percent(ctl->info, mixer_ctl_get_value(ctl, id));
|
||||
}
|
||||
|
||||
int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent)
|
||||
{
|
||||
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
|
||||
return -EINVAL;
|
||||
|
||||
return mixer_ctl_set_value(ctl, id, percent_to_int(ctl->info, percent));
|
||||
}
|
||||
|
||||
int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id)
|
||||
{
|
||||
struct snd_ctl_elem_value ev;
|
||||
int ret;
|
||||
|
||||
if (!ctl || (id >= ctl->info->count))
|
||||
return -EINVAL;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.id.numid = ctl->info->id.numid;
|
||||
ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (ctl->info->type) {
|
||||
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
|
||||
return !!ev.value.integer.value[id];
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER:
|
||||
return ev.value.integer.value[id];
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
|
||||
return ev.value.enumerated.item[id];
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES:
|
||||
return ev.value.bytes.data[id];
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count)
|
||||
{
|
||||
struct snd_ctl_elem_value ev;
|
||||
int ret;
|
||||
size_t size;
|
||||
void *source;
|
||||
|
||||
if (!ctl || (count > ctl->info->count) || !count || !array)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.id.numid = ctl->info->id.numid;
|
||||
|
||||
ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (ctl->info->type) {
|
||||
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER:
|
||||
size = sizeof(ev.value.integer.value[0]);
|
||||
source = ev.value.integer.value;
|
||||
break;
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES:
|
||||
size = sizeof(ev.value.bytes.data[0]);
|
||||
source = ev.value.bytes.data;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(array, source, size * count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
|
||||
{
|
||||
struct snd_ctl_elem_value ev;
|
||||
int ret;
|
||||
|
||||
if (!ctl || (id >= ctl->info->count))
|
||||
return -EINVAL;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.id.numid = ctl->info->id.numid;
|
||||
ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (ctl->info->type) {
|
||||
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
|
||||
ev.value.integer.value[id] = !!value;
|
||||
break;
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER:
|
||||
if ((value < mixer_ctl_get_range_min(ctl)) ||
|
||||
(value > mixer_ctl_get_range_max(ctl))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ev.value.integer.value[id] = value;
|
||||
break;
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
|
||||
ev.value.enumerated.item[id] = value;
|
||||
break;
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES:
|
||||
ev.value.bytes.data[id] = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
|
||||
}
|
||||
|
||||
int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count)
|
||||
{
|
||||
struct snd_ctl_elem_value ev;
|
||||
size_t size;
|
||||
void *dest;
|
||||
|
||||
if (!ctl || (count > ctl->info->count) || !count || !array)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.id.numid = ctl->info->id.numid;
|
||||
|
||||
switch (ctl->info->type) {
|
||||
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER:
|
||||
size = sizeof(ev.value.integer.value[0]);
|
||||
dest = ev.value.integer.value;
|
||||
break;
|
||||
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES:
|
||||
size = sizeof(ev.value.bytes.data[0]);
|
||||
dest = ev.value.bytes.data;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(dest, array, size * count);
|
||||
|
||||
return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
|
||||
}
|
||||
|
||||
int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
|
||||
{
|
||||
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
|
||||
return -EINVAL;
|
||||
|
||||
return ctl->info->value.integer.min;
|
||||
}
|
||||
|
||||
int mixer_ctl_get_range_max(struct mixer_ctl *ctl)
|
||||
{
|
||||
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
|
||||
return -EINVAL;
|
||||
|
||||
return ctl->info->value.integer.max;
|
||||
}
|
||||
|
||||
unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl)
|
||||
{
|
||||
if (!ctl)
|
||||
return 0;
|
||||
|
||||
return ctl->info->value.enumerated.items;
|
||||
}
|
||||
|
||||
const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl,
|
||||
unsigned int enum_id)
|
||||
{
|
||||
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) ||
|
||||
(enum_id >= ctl->info->value.enumerated.items))
|
||||
return NULL;
|
||||
|
||||
return (const char *)ctl->ename[enum_id];
|
||||
}
|
||||
|
||||
int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string)
|
||||
{
|
||||
unsigned int i, num_enums;
|
||||
struct snd_ctl_elem_value ev;
|
||||
int ret;
|
||||
|
||||
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED))
|
||||
return -EINVAL;
|
||||
|
||||
num_enums = ctl->info->value.enumerated.items;
|
||||
for (i = 0; i < num_enums; i++) {
|
||||
if (!strcmp(string, ctl->ename[i])) {
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.value.enumerated.item[0] = i;
|
||||
ev.id.numid = ctl->info->id.numid;
|
||||
ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
1050
external/cache/sources/tinyalsa/pcm.c
vendored
Normal file
1050
external/cache/sources/tinyalsa/pcm.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
272
external/cache/sources/tinyalsa/tinycap.c
vendored
Normal file
272
external/cache/sources/tinyalsa/tinycap.c
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
/* tinycap.c
|
||||
**
|
||||
** Copyright 2011, The Android Open Source Project
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of The Android Open Source Project nor the names of
|
||||
** its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
|
||||
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
** DAMAGE.
|
||||
*/
|
||||
|
||||
#include <tinyalsa/asoundlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ID_RIFF 0x46464952
|
||||
#define ID_WAVE 0x45564157
|
||||
#define ID_FMT 0x20746d66
|
||||
#define ID_DATA 0x61746164
|
||||
|
||||
#define FORMAT_PCM 1
|
||||
|
||||
struct wav_header {
|
||||
uint32_t riff_id;
|
||||
uint32_t riff_sz;
|
||||
uint32_t riff_fmt;
|
||||
uint32_t fmt_id;
|
||||
uint32_t fmt_sz;
|
||||
uint16_t audio_format;
|
||||
uint16_t num_channels;
|
||||
uint32_t sample_rate;
|
||||
uint32_t byte_rate;
|
||||
uint16_t block_align;
|
||||
uint16_t bits_per_sample;
|
||||
uint32_t data_id;
|
||||
uint32_t data_sz;
|
||||
};
|
||||
|
||||
int loop_seconds = 0;
|
||||
int capturing = 1;
|
||||
int prinfo = 1;
|
||||
|
||||
unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
|
||||
unsigned int channels, unsigned int rate,
|
||||
enum pcm_format format, unsigned int period_size,
|
||||
unsigned int period_count);
|
||||
|
||||
void sigint_handler(int sig)
|
||||
{
|
||||
capturing = 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *file;
|
||||
struct wav_header header;
|
||||
unsigned int card = 0;
|
||||
unsigned int device = 0;
|
||||
unsigned int channels = 2;
|
||||
unsigned int rate = 44100;
|
||||
unsigned int bits = 16;
|
||||
unsigned int frames;
|
||||
unsigned int period_size = 1024;
|
||||
unsigned int period_count = 4;
|
||||
enum pcm_format format;
|
||||
int no_header = 0;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s {file.wav | --} [-D card] [-d device] [-c channels] "
|
||||
"[-t seconds] [-r rate] [-b bits] [-p period_size] [-n n_periods]\n\n"
|
||||
"Use -- for filename to send raw PCM to stdout\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1],"--") == 0) {
|
||||
file = stdout;
|
||||
prinfo = 0;
|
||||
no_header = 1;
|
||||
} else {
|
||||
file = fopen(argv[1], "wb");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Unable to create file '%s'\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse command line arguments */
|
||||
argv += 2;
|
||||
while (*argv) {
|
||||
if (strcmp(*argv, "-d") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
device = atoi(*argv);
|
||||
} else if (strcmp(*argv, "-c") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
channels = atoi(*argv);
|
||||
} else if (strcmp(*argv, "-r") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
rate = atoi(*argv);
|
||||
} else if (strcmp(*argv, "-b") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
bits = atoi(*argv);
|
||||
} else if (strcmp(*argv, "-D") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
card = atoi(*argv);
|
||||
} else if (strcmp(*argv, "-p") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
period_size = atoi(*argv);
|
||||
} else if (strcmp(*argv, "-n") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
period_count = atoi(*argv);
|
||||
} else if (strcmp(*argv, "-t") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
loop_seconds = atoi(*argv);
|
||||
}
|
||||
if (*argv)
|
||||
argv++;
|
||||
}
|
||||
|
||||
header.riff_id = ID_RIFF;
|
||||
header.riff_sz = 0;
|
||||
header.riff_fmt = ID_WAVE;
|
||||
header.fmt_id = ID_FMT;
|
||||
header.fmt_sz = 16;
|
||||
header.audio_format = FORMAT_PCM;
|
||||
header.num_channels = channels;
|
||||
header.sample_rate = rate;
|
||||
|
||||
switch (bits) {
|
||||
case 32:
|
||||
format = PCM_FORMAT_S32_LE;
|
||||
break;
|
||||
case 24:
|
||||
format = PCM_FORMAT_S24_LE;
|
||||
break;
|
||||
case 16:
|
||||
format = PCM_FORMAT_S16_LE;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%d bits is not supported.\n", bits);
|
||||
return 1;
|
||||
}
|
||||
|
||||
header.bits_per_sample = pcm_format_to_bits(format);
|
||||
header.byte_rate = (header.bits_per_sample / 8) * channels * rate;
|
||||
header.block_align = channels * (header.bits_per_sample / 8);
|
||||
header.data_id = ID_DATA;
|
||||
|
||||
/* leave enough room for header */
|
||||
if (!no_header) {
|
||||
fseek(file, sizeof(struct wav_header), SEEK_SET);
|
||||
}
|
||||
|
||||
/* install signal handler and begin capturing */
|
||||
signal(SIGINT, sigint_handler);
|
||||
frames = capture_sample(file, card, device, header.num_channels,
|
||||
header.sample_rate, format,
|
||||
period_size, period_count);
|
||||
if (prinfo) {
|
||||
printf("Captured %d frames\n", frames);
|
||||
}
|
||||
|
||||
/* write header now all information is known */
|
||||
if (!no_header) {
|
||||
header.data_sz = frames * header.block_align;
|
||||
header.riff_sz = header.data_sz + sizeof(header) - 8;
|
||||
fseek(file, 0, SEEK_SET);
|
||||
fwrite(&header, sizeof(struct wav_header), 1, file);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
|
||||
unsigned int channels, unsigned int rate,
|
||||
enum pcm_format format, unsigned int period_size,
|
||||
unsigned int period_count)
|
||||
{
|
||||
struct pcm_config config;
|
||||
struct pcm *pcm;
|
||||
char *buffer;
|
||||
unsigned int size;
|
||||
unsigned int frames;
|
||||
unsigned long long bytes_read = 0;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
long time_sec1;
|
||||
long time_sec2;
|
||||
long time_total;
|
||||
|
||||
config.channels = channels;
|
||||
config.rate = rate;
|
||||
config.period_size = period_size;
|
||||
config.period_count = period_count;
|
||||
config.format = format;
|
||||
config.start_threshold = 0;
|
||||
config.stop_threshold = 0;
|
||||
config.silence_threshold = 0;
|
||||
|
||||
pcm = pcm_open(card, device, PCM_IN, &config);
|
||||
if (!pcm || !pcm_is_ready(pcm)) {
|
||||
fprintf(stderr, "Unable to open PCM device (%s)\n",
|
||||
pcm_get_error(pcm));
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
|
||||
buffer = malloc(size);
|
||||
if (!buffer) {
|
||||
fprintf(stderr, "Unable to allocate %d bytes\n", size);
|
||||
free(buffer);
|
||||
pcm_close(pcm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (prinfo) {
|
||||
printf("Capturing sample: %u ch, %u hz, %u bit\n", channels, rate,
|
||||
pcm_format_to_bits(format));
|
||||
}
|
||||
|
||||
gettimeofday(&tv, &tz);
|
||||
time_sec1 = tv.tv_sec;
|
||||
while (capturing && !pcm_read(pcm, buffer, size)) {
|
||||
if (fwrite(buffer, 1, size, file) != size) {
|
||||
fprintf(stderr,"Error capturing sample\n");
|
||||
break;
|
||||
}
|
||||
gettimeofday(&tv, &tz);
|
||||
time_sec2 = tv.tv_sec;
|
||||
time_total = time_sec2 - time_sec1;
|
||||
if (time_total >= (loop_seconds)) {
|
||||
printf("time_total:%ld, loop_seconds:%d\n",
|
||||
time_total, loop_seconds);
|
||||
break;
|
||||
}
|
||||
bytes_read += size;
|
||||
}
|
||||
frames = pcm_bytes_to_frames(pcm, bytes_read);
|
||||
free(buffer);
|
||||
pcm_close(pcm);
|
||||
return frames;
|
||||
}
|
||||
|
||||
317
external/cache/sources/tinyalsa/tinymix.c
vendored
Normal file
317
external/cache/sources/tinyalsa/tinymix.c
vendored
Normal file
@@ -0,0 +1,317 @@
|
||||
/* tinymix.c
|
||||
**
|
||||
** Copyright 2011, The Android Open Source Project
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of The Android Open Source Project nor the names of
|
||||
** its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
|
||||
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
** DAMAGE.
|
||||
*/
|
||||
|
||||
#include <tinyalsa/asoundlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
static void tinymix_list_controls(struct mixer *mixer);
|
||||
static void tinymix_detail_control(struct mixer *mixer, const char *control,
|
||||
int print_all);
|
||||
static void tinymix_set_value(struct mixer *mixer, const char *control,
|
||||
char **values, unsigned int num_values);
|
||||
static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct mixer *mixer;
|
||||
int card = 0;
|
||||
|
||||
if ((argc > 2) && (strcmp(argv[1], "-D") == 0)) {
|
||||
argv++;
|
||||
if (argv[1]) {
|
||||
card = atoi(argv[1]);
|
||||
argv++;
|
||||
argc -= 2;
|
||||
} else {
|
||||
argc -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
mixer = mixer_open(card);
|
||||
if (!mixer) {
|
||||
fprintf(stderr, "Failed to open mixer\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
if (argc == 1) {
|
||||
printf("Mixer name: '%s'\n", mixer_get_name(mixer));
|
||||
tinymix_list_controls(mixer);
|
||||
} else if (argc == 2) {
|
||||
tinymix_detail_control(mixer, argv[1], 1);
|
||||
} else if (argc >= 3) {
|
||||
tinymix_set_value(mixer, argv[1], &argv[2], argc - 2);
|
||||
} else {
|
||||
printf("Usage: tinymix [-D card] [control id] [value to set]\n");
|
||||
}
|
||||
|
||||
mixer_close(mixer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tinymix_list_controls(struct mixer *mixer)
|
||||
{
|
||||
struct mixer_ctl *ctl;
|
||||
const char *name, *type;
|
||||
unsigned int num_ctls, num_values;
|
||||
unsigned int i;
|
||||
|
||||
num_ctls = mixer_get_num_ctls(mixer);
|
||||
|
||||
printf("Number of controls: %d\n", num_ctls);
|
||||
|
||||
printf("ctl\ttype\tnum\t%-40s value\n", "name");
|
||||
for (i = 0; i < num_ctls; i++) {
|
||||
ctl = mixer_get_ctl(mixer, i);
|
||||
|
||||
name = mixer_ctl_get_name(ctl);
|
||||
type = mixer_ctl_get_type_string(ctl);
|
||||
num_values = mixer_ctl_get_num_values(ctl);
|
||||
printf("%d\t%s\t%d\t%-40s", i, type, num_values, name);
|
||||
tinymix_detail_control(mixer, name, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all)
|
||||
{
|
||||
unsigned int num_enums;
|
||||
unsigned int i;
|
||||
const char *string;
|
||||
|
||||
num_enums = mixer_ctl_get_num_enums(ctl);
|
||||
|
||||
for (i = 0; i < num_enums; i++) {
|
||||
string = mixer_ctl_get_enum_string(ctl, i);
|
||||
if (print_all)
|
||||
printf("\t%s%s", mixer_ctl_get_value(ctl, 0) == (int)i ? ">" : "",
|
||||
string);
|
||||
else if (mixer_ctl_get_value(ctl, 0) == (int)i)
|
||||
printf(" %-s", string);
|
||||
}
|
||||
}
|
||||
|
||||
static void tinymix_detail_control(struct mixer *mixer, const char *control,
|
||||
int print_all)
|
||||
{
|
||||
struct mixer_ctl *ctl;
|
||||
enum mixer_ctl_type type;
|
||||
unsigned int num_values;
|
||||
unsigned int i;
|
||||
int min, max;
|
||||
int ret;
|
||||
char buf[512] = { 0 };
|
||||
size_t len;
|
||||
|
||||
if (isdigit(control[0]))
|
||||
ctl = mixer_get_ctl(mixer, atoi(control));
|
||||
else
|
||||
ctl = mixer_get_ctl_by_name(mixer, control);
|
||||
|
||||
if (!ctl) {
|
||||
fprintf(stderr, "Invalid mixer control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
type = mixer_ctl_get_type(ctl);
|
||||
num_values = mixer_ctl_get_num_values(ctl);
|
||||
|
||||
if (type == MIXER_CTL_TYPE_BYTE) {
|
||||
len = num_values;
|
||||
if (len > sizeof(buf)) {
|
||||
fprintf(stderr, "Truncating get to %zu bytes\n", sizeof(buf));
|
||||
len = sizeof(buf);
|
||||
}
|
||||
ret = mixer_ctl_get_array(ctl, buf, len);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to mixer_ctl_get_array\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (print_all)
|
||||
printf("%s:", mixer_ctl_get_name(ctl));
|
||||
|
||||
for (i = 0; i < num_values; i++) {
|
||||
switch (type)
|
||||
{
|
||||
case MIXER_CTL_TYPE_INT:
|
||||
printf(" %d", mixer_ctl_get_value(ctl, i));
|
||||
break;
|
||||
case MIXER_CTL_TYPE_BOOL:
|
||||
printf(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
|
||||
break;
|
||||
case MIXER_CTL_TYPE_ENUM:
|
||||
tinymix_print_enum(ctl, print_all);
|
||||
break;
|
||||
case MIXER_CTL_TYPE_BYTE:
|
||||
printf("%02x", buf[i]);
|
||||
break;
|
||||
default:
|
||||
printf(" unknown");
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
if (print_all) {
|
||||
if (type == MIXER_CTL_TYPE_INT) {
|
||||
min = mixer_ctl_get_range_min(ctl);
|
||||
max = mixer_ctl_get_range_max(ctl);
|
||||
printf(" (range %d->%d)", min, max);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void tinymix_set_byte_ctl(struct mixer_ctl *ctl, const char *control,
|
||||
char **values, unsigned int num_values)
|
||||
{
|
||||
int ret;
|
||||
char buf[512] = { 0 };
|
||||
char *end;
|
||||
int i;
|
||||
long n;
|
||||
|
||||
if (num_values > sizeof(buf)) {
|
||||
fprintf(stderr, "Truncating set to %zu bytes\n", sizeof(buf));
|
||||
num_values = sizeof(buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_values; i++) {
|
||||
errno = 0;
|
||||
n = strtol(values[i], &end, 0);
|
||||
if (*end) {
|
||||
fprintf(stderr, "%s not an integer\n", values[i]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (errno) {
|
||||
fprintf(stderr, "strtol: %s: %s\n", values[i],
|
||||
strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (n < 0 || n > 0xff) {
|
||||
fprintf(stderr, "%s should be between [0, 0xff]\n",
|
||||
values[i]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
buf[i] = n;
|
||||
}
|
||||
|
||||
ret = mixer_ctl_set_array(ctl, buf, num_values);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to set binary control\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static int is_int(char *value)
|
||||
{
|
||||
char* end;
|
||||
long int result;
|
||||
|
||||
errno = 0;
|
||||
result = strtol(value, &end, 10);
|
||||
|
||||
if (result == LONG_MIN || result == LONG_MAX)
|
||||
return 0;
|
||||
|
||||
return errno == 0 && *end == '\0';
|
||||
}
|
||||
|
||||
static void tinymix_set_value(struct mixer *mixer, const char *control,
|
||||
char **values, unsigned int num_values)
|
||||
{
|
||||
struct mixer_ctl *ctl;
|
||||
enum mixer_ctl_type type;
|
||||
unsigned int num_ctl_values;
|
||||
unsigned int i;
|
||||
|
||||
if (isdigit(control[0]))
|
||||
ctl = mixer_get_ctl(mixer, atoi(control));
|
||||
else
|
||||
ctl = mixer_get_ctl_by_name(mixer, control);
|
||||
|
||||
if (!ctl) {
|
||||
fprintf(stderr, "Invalid mixer control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
type = mixer_ctl_get_type(ctl);
|
||||
num_ctl_values = mixer_ctl_get_num_values(ctl);
|
||||
|
||||
if (type == MIXER_CTL_TYPE_BYTE) {
|
||||
tinymix_set_byte_ctl(ctl, control, values, num_values);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_int(values[0])) {
|
||||
if (num_values == 1) {
|
||||
/* Set all values the same */
|
||||
int value = atoi(values[0]);
|
||||
|
||||
for (i = 0; i < num_ctl_values; i++) {
|
||||
if (mixer_ctl_set_value(ctl, i, value)) {
|
||||
fprintf(stderr, "Error: invalid value\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Set multiple values */
|
||||
if (num_values > num_ctl_values) {
|
||||
fprintf(stderr,
|
||||
"Error: %d values given, but control only takes %d\n",
|
||||
num_values, num_ctl_values);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < num_values; i++) {
|
||||
if (mixer_ctl_set_value(ctl, i, atoi(values[i]))) {
|
||||
fprintf(stderr, "Error: invalid value for index %d\n", i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (type == MIXER_CTL_TYPE_ENUM) {
|
||||
if (num_values != 1) {
|
||||
fprintf(stderr, "Enclose strings in quotes and try again\n");
|
||||
return;
|
||||
}
|
||||
if (mixer_ctl_set_enum_by_string(ctl, values[0]))
|
||||
fprintf(stderr, "Error: invalid enum value\n");
|
||||
} else {
|
||||
fprintf(stderr, "Error: only enum types can be set with strings\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
203
external/cache/sources/tinyalsa/tinypcminfo.c
vendored
Normal file
203
external/cache/sources/tinyalsa/tinypcminfo.c
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/* tinypcminfo.c
|
||||
**
|
||||
** Copyright 2012, The Android Open Source Project
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of The Android Open Source Project nor the names of
|
||||
** its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
|
||||
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
** DAMAGE.
|
||||
*/
|
||||
|
||||
#include <tinyalsa/asoundlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/* The format_lookup is in order of SNDRV_PCM_FORMAT_##index and
|
||||
* matches the grouping in sound/asound.h. Note this is not
|
||||
* continuous and has an empty gap from (25 - 30).
|
||||
*/
|
||||
static const char *format_lookup[] = {
|
||||
/*[0] =*/ "S8",
|
||||
"U8",
|
||||
"S16_LE",
|
||||
"S16_BE",
|
||||
"U16_LE",
|
||||
"U16_BE",
|
||||
"S24_LE",
|
||||
"S24_BE",
|
||||
"U24_LE",
|
||||
"U24_BE",
|
||||
"S32_LE",
|
||||
"S32_BE",
|
||||
"U32_LE",
|
||||
"U32_BE",
|
||||
"FLOAT_LE",
|
||||
"FLOAT_BE",
|
||||
"FLOAT64_LE",
|
||||
"FLOAT64_BE",
|
||||
"IEC958_SUBFRAME_LE",
|
||||
"IEC958_SUBFRAME_BE",
|
||||
"MU_LAW",
|
||||
"A_LAW",
|
||||
"IMA_ADPCM",
|
||||
"MPEG",
|
||||
/*[24] =*/ "GSM",
|
||||
[31] = "SPECIAL",
|
||||
"S24_3LE",
|
||||
"S24_3BE",
|
||||
"U24_3LE",
|
||||
"U24_3BE",
|
||||
"S20_3LE",
|
||||
"S20_3BE",
|
||||
"U20_3LE",
|
||||
"U20_3BE",
|
||||
"S18_3LE",
|
||||
"S18_3BE",
|
||||
"U18_3LE",
|
||||
/*[43] =*/ "U18_3BE",
|
||||
#if 0
|
||||
/* recent additions, may not be present on local asound.h */
|
||||
"G723_24",
|
||||
"G723_24_1B",
|
||||
"G723_40",
|
||||
"G723_40_1B",
|
||||
"DSD_U8",
|
||||
"DSD_U16_LE",
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Returns a human readable name for the format associated with bit_index,
|
||||
* NULL if bit_index is not known.
|
||||
*/
|
||||
inline const char *pcm_get_format_name(unsigned bit_index)
|
||||
{
|
||||
return bit_index < ARRAY_SIZE(format_lookup) ? format_lookup[bit_index] : NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned int device = 0;
|
||||
unsigned int card = 0;
|
||||
int i;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s -D card -d device\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* parse command line arguments */
|
||||
argv += 1;
|
||||
while (*argv) {
|
||||
if (strcmp(*argv, "-D") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
card = atoi(*argv);
|
||||
}
|
||||
if (strcmp(*argv, "-d") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
device = atoi(*argv);
|
||||
}
|
||||
if (*argv)
|
||||
argv++;
|
||||
}
|
||||
|
||||
printf("Info for card %d, device %d:\n", card, device);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct pcm_params *params;
|
||||
struct pcm_mask *m;
|
||||
unsigned int min;
|
||||
unsigned int max;
|
||||
|
||||
printf("\nPCM %s:\n", i == 0 ? "out" : "in");
|
||||
|
||||
params = pcm_params_get(card, device, i == 0 ? PCM_OUT : PCM_IN);
|
||||
if (params == NULL) {
|
||||
printf("Device does not exist.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
m = pcm_params_get_mask(params, PCM_PARAM_ACCESS);
|
||||
if (m) { /* bitmask, refer to SNDRV_PCM_ACCESS_*, generally interleaved */
|
||||
printf(" Access:\t%#08x\n", m->bits[0]);
|
||||
}
|
||||
m = pcm_params_get_mask(params, PCM_PARAM_FORMAT);
|
||||
if (m) { /* bitmask, refer to: SNDRV_PCM_FORMAT_* */
|
||||
unsigned j, k, count = 0;
|
||||
const unsigned bitcount = sizeof(m->bits[0]) * 8;
|
||||
|
||||
/* we only check first two format masks (out of 8) - others are zero. */
|
||||
printf(" Format[0]:\t%#08x\n", m->bits[0]);
|
||||
printf(" Format[1]:\t%#08x\n", m->bits[1]);
|
||||
|
||||
/* print friendly format names, if they exist */
|
||||
for (k = 0; k < 2; ++k) {
|
||||
for (j = 0; j < bitcount; ++j) {
|
||||
const char *name;
|
||||
|
||||
if (m->bits[k] & (1 << j)) {
|
||||
name = pcm_get_format_name(j + k*bitcount);
|
||||
if (name) {
|
||||
if (count++ == 0) {
|
||||
printf(" Format Name:\t");
|
||||
} else {
|
||||
printf (", ");
|
||||
}
|
||||
printf("%s", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
m = pcm_params_get_mask(params, PCM_PARAM_SUBFORMAT);
|
||||
if (m) { /* bitmask, should be 1: SNDRV_PCM_SUBFORMAT_STD */
|
||||
printf(" Subformat:\t%#08x\n", m->bits[0]);
|
||||
}
|
||||
min = pcm_params_get_min(params, PCM_PARAM_RATE);
|
||||
max = pcm_params_get_max(params, PCM_PARAM_RATE);
|
||||
printf(" Rate:\tmin=%uHz\tmax=%uHz\n", min, max);
|
||||
min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
|
||||
max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
|
||||
printf(" Channels:\tmin=%u\t\tmax=%u\n", min, max);
|
||||
min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
|
||||
max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
|
||||
printf(" Sample bits:\tmin=%u\t\tmax=%u\n", min, max);
|
||||
min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE);
|
||||
max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE);
|
||||
printf(" Period size:\tmin=%u\t\tmax=%u\n", min, max);
|
||||
min = pcm_params_get_min(params, PCM_PARAM_PERIODS);
|
||||
max = pcm_params_get_max(params, PCM_PARAM_PERIODS);
|
||||
printf("Period count:\tmin=%u\t\tmax=%u\n", min, max);
|
||||
|
||||
pcm_params_free(params);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
313
external/cache/sources/tinyalsa/tinyplay.c
vendored
Normal file
313
external/cache/sources/tinyalsa/tinyplay.c
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
/* tinyplay.c
|
||||
**
|
||||
** Copyright 2011, The Android Open Source Project
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of The Android Open Source Project nor the names of
|
||||
** its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
|
||||
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
** DAMAGE.
|
||||
*/
|
||||
|
||||
#include <tinyalsa/asoundlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define ID_RIFF 0x46464952
|
||||
#define ID_WAVE 0x45564157
|
||||
#define ID_FMT 0x20746d66
|
||||
#define ID_DATA 0x61746164
|
||||
|
||||
struct riff_wave_header {
|
||||
uint32_t riff_id;
|
||||
uint32_t riff_sz;
|
||||
uint32_t wave_id;
|
||||
};
|
||||
|
||||
struct chunk_header {
|
||||
uint32_t id;
|
||||
uint32_t sz;
|
||||
};
|
||||
|
||||
struct chunk_fmt {
|
||||
uint16_t audio_format;
|
||||
uint16_t num_channels;
|
||||
uint32_t sample_rate;
|
||||
uint32_t byte_rate;
|
||||
uint16_t block_align;
|
||||
uint16_t bits_per_sample;
|
||||
};
|
||||
|
||||
static int close = 0;
|
||||
static unsigned int loop_num = 1;
|
||||
static unsigned int loop_minutes = 0;
|
||||
|
||||
void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
|
||||
unsigned int rate, unsigned int bits, unsigned int period_size,
|
||||
unsigned int period_count);
|
||||
|
||||
void stream_close(int sig)
|
||||
{
|
||||
/* allow the stream to be closed gracefully */
|
||||
signal(sig, SIG_IGN);
|
||||
close = 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *file;
|
||||
struct riff_wave_header riff_wave_header;
|
||||
struct chunk_header chunk_header;
|
||||
struct chunk_fmt chunk_fmt;
|
||||
unsigned int device = 0;
|
||||
unsigned int card = 0;
|
||||
unsigned int period_size = 1024;
|
||||
unsigned int period_count = 4;
|
||||
char *filename;
|
||||
int more_chunks = 1;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s file.wav [-D card] [-d device] "
|
||||
"[-m loop_minutes] [-i loop_num] "
|
||||
"[-p period_size] [-n period_count] \n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
file = fopen(filename, "rb");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Unable to open file '%s'\n", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fread(&riff_wave_header, sizeof(riff_wave_header), 1, file);
|
||||
if ((riff_wave_header.riff_id != ID_RIFF) ||
|
||||
(riff_wave_header.wave_id != ID_WAVE)) {
|
||||
fprintf(stderr, "Error: '%s' is not a riff/wave file\n", filename);
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
do {
|
||||
fread(&chunk_header, sizeof(chunk_header), 1, file);
|
||||
|
||||
switch (chunk_header.id) {
|
||||
case ID_FMT:
|
||||
fread(&chunk_fmt, sizeof(chunk_fmt), 1, file);
|
||||
/* If the format header is larger, skip the rest */
|
||||
if (chunk_header.sz > sizeof(chunk_fmt))
|
||||
fseek(file, chunk_header.sz - sizeof(chunk_fmt), SEEK_CUR);
|
||||
break;
|
||||
case ID_DATA:
|
||||
/* Stop looking for chunks */
|
||||
more_chunks = 0;
|
||||
break;
|
||||
default:
|
||||
/* Unknown chunk, skip bytes */
|
||||
fseek(file, chunk_header.sz, SEEK_CUR);
|
||||
}
|
||||
} while (more_chunks);
|
||||
|
||||
/* parse command line arguments */
|
||||
argv += 2;
|
||||
while (*argv) {
|
||||
if (strcmp(*argv, "-d") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
device = atoi(*argv);
|
||||
}
|
||||
if (strcmp(*argv, "-p") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
period_size = atoi(*argv);
|
||||
}
|
||||
if (strcmp(*argv, "-n") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
period_count = atoi(*argv);
|
||||
}
|
||||
if (strcmp(*argv, "-D") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
card = atoi(*argv);
|
||||
}
|
||||
if (strcmp(*argv, "-m") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
loop_minutes = atoi(*argv);
|
||||
}
|
||||
if (strcmp(*argv, "-i") == 0) {
|
||||
argv++;
|
||||
if (*argv)
|
||||
loop_num = atoi(*argv);
|
||||
}
|
||||
if (*argv)
|
||||
argv++;
|
||||
}
|
||||
|
||||
play_sample(file, card, device, chunk_fmt.num_channels, chunk_fmt.sample_rate,
|
||||
chunk_fmt.bits_per_sample, period_size, period_count);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int check_param(struct pcm_params *params, unsigned int param, unsigned int value,
|
||||
char *param_name, char *param_unit)
|
||||
{
|
||||
unsigned int min;
|
||||
unsigned int max;
|
||||
int is_within_bounds = 1;
|
||||
|
||||
min = pcm_params_get_min(params, param);
|
||||
if (value < min) {
|
||||
fprintf(stderr, "%s is %u%s, device only supports >= %u%s\n", param_name, value,
|
||||
param_unit, min, param_unit);
|
||||
is_within_bounds = 0;
|
||||
}
|
||||
|
||||
max = pcm_params_get_max(params, param);
|
||||
if (value > max) {
|
||||
fprintf(stderr, "%s is %u%s, device only supports <= %u%s\n", param_name, value,
|
||||
param_unit, max, param_unit);
|
||||
is_within_bounds = 0;
|
||||
}
|
||||
|
||||
return is_within_bounds;
|
||||
}
|
||||
|
||||
int sample_is_playable(unsigned int card, unsigned int device, unsigned int channels,
|
||||
unsigned int rate, unsigned int bits, unsigned int period_size,
|
||||
unsigned int period_count)
|
||||
{
|
||||
struct pcm_params *params;
|
||||
int can_play;
|
||||
|
||||
params = pcm_params_get(card, device, PCM_OUT);
|
||||
if (params == NULL) {
|
||||
fprintf(stderr, "Unable to open PCM device %u.\n", device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
can_play = check_param(params, PCM_PARAM_RATE, rate, "Sample rate", "Hz");
|
||||
can_play &= check_param(params, PCM_PARAM_CHANNELS, channels, "Sample", " channels");
|
||||
can_play &= check_param(params, PCM_PARAM_SAMPLE_BITS, bits, "Bitrate", " bits");
|
||||
can_play &= check_param(params, PCM_PARAM_PERIOD_SIZE, period_size, "Period size", "Hz");
|
||||
can_play &= check_param(params, PCM_PARAM_PERIODS, period_count, "Period count", "Hz");
|
||||
|
||||
pcm_params_free(params);
|
||||
|
||||
return can_play;
|
||||
}
|
||||
|
||||
void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
|
||||
unsigned int rate, unsigned int bits, unsigned int period_size,
|
||||
unsigned int period_count)
|
||||
{
|
||||
struct pcm_config config;
|
||||
struct pcm *pcm;
|
||||
char *buffer;
|
||||
int size;
|
||||
int num_read;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
long sec_start = 0;
|
||||
long sec_end = 0;
|
||||
int loop_count = 0;
|
||||
|
||||
config.channels = channels;
|
||||
config.rate = rate;
|
||||
config.period_size = period_size;
|
||||
config.period_count = period_count;
|
||||
if (bits == 32)
|
||||
config.format = PCM_FORMAT_S32_LE;
|
||||
else if (bits == 16)
|
||||
config.format = PCM_FORMAT_S16_LE;
|
||||
else if (bits == 24)
|
||||
config.format = PCM_FORMAT_S24_LE;
|
||||
config.start_threshold = 0;
|
||||
config.stop_threshold = 0;
|
||||
config.silence_threshold = 0;
|
||||
|
||||
if (!sample_is_playable(card, device, channels, rate, bits, period_size, period_count)) {
|
||||
return;
|
||||
}
|
||||
|
||||
pcm = pcm_open(card, device, PCM_OUT, &config);
|
||||
if (!pcm || !pcm_is_ready(pcm)) {
|
||||
fprintf(stderr, "Unable to open PCM device %u (%s)\n",
|
||||
device, pcm_get_error(pcm));
|
||||
return;
|
||||
}
|
||||
|
||||
size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
|
||||
buffer = malloc(size);
|
||||
if (!buffer) {
|
||||
fprintf(stderr, "Unable to allocate %d bytes\n", size);
|
||||
free(buffer);
|
||||
pcm_close(pcm);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits);
|
||||
|
||||
/* catch ctrl-c to shutdown cleanly */
|
||||
signal(SIGINT, stream_close);
|
||||
|
||||
gettimeofday(&tv, &tz);
|
||||
sec_start = tv.tv_sec;
|
||||
|
||||
printf("start --> loop_minutes = %d; loop_num = %d\n",
|
||||
loop_minutes, loop_num);
|
||||
|
||||
do {
|
||||
num_read = fread(buffer, 1, size, file);
|
||||
if (num_read > 0) {
|
||||
if (pcm_write(pcm, buffer, num_read)) {
|
||||
fprintf(stderr, "Error playing sample\n");
|
||||
break;
|
||||
}
|
||||
if (feof(file)) {
|
||||
printf("--> loop_count = %d\n", ++loop_count);
|
||||
fseek(file, 0L, SEEK_SET);
|
||||
}
|
||||
if (loop_minutes == 0) {
|
||||
if (loop_count >= loop_num)
|
||||
break;
|
||||
} else {
|
||||
gettimeofday(&tv, &tz);
|
||||
sec_end = tv.tv_sec;
|
||||
if ((sec_end - sec_start) > (loop_minutes * 60)) {
|
||||
printf("End loop_minutes: %ld\n", (sec_end - sec_start)/60);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!close && num_read > 0);
|
||||
|
||||
free(buffer);
|
||||
pcm_close(pcm);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user