Skip to content

Commit de199bf

Browse files
committed
New version with improvements
1 parent 2c0018f commit de199bf

File tree

12 files changed

+606
-167
lines changed

12 files changed

+606
-167
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ CC = gcc
22

33
INC =
44
LIB = -lbluetooth
5-
OLD_LIB = -lbluetooth -lsdp
5+
OLD_LIB = -lbluetooth -lsdp -lsdp_lib
66
INSTALL = /usr/local/bin
77

88
#FLAGS = $(CFLAGS) -Wall -g -DDEBUG -DDEBUG_INFO -DDEBUG_MAIN -DDEBUG_BT -DDEBUG_NET -DDEBUG_BT_DISCOVER -DDEBUG_BTNET -DDEBUG_NET_INFO
99
#FLAGS = $(CFLAGS) -Wall -g -DDEBUG -DDEBUG_INFO -DDEBUG_MAIN -DDEBUG_BT -DDEBUG_NET -DDEBUG_BT_DISCOVER -DDEBUG_BTNET -DDEBUG_BTNET_INFO -DDEBUG_BT_INFO -DDEBUG_BTNET_INFO2
1010
FLAGS = $(CFLAGS) -Wall -g -DDEBUG -DDEBUG_INFO -DDEBUG_MAIN -DDEBUG_BT -DDEBUG_NET -DDEBUG_BT_DISCOVER -DDEBUG_BTNET -DDEBUG_BTNET_INFO -DDEBUG_BT_INFO -DDEBUG_BTNET_INFO2
1111

12-
OBJ = main.o rfcomm-server.o rfcomm-client.o rfcomm-register.o
12+
OBJ = main.o rfcomm-server.o rfcomm-client.o hciscan.o service-register.o
1313
EXEC = rfcomm
1414

1515
all: $(OBJ)

hciscan.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* hciscan.c
3+
*
4+
* Created on: 6 марта 2016 г.
5+
* Author: bakulev
6+
*/
7+
8+
#include <stdlib.h>
9+
#include <bluetooth/bluetooth.h>
10+
#include <bluetooth/hci.h>
11+
#include <bluetooth/hci_lib.h>
12+
13+
#include "hciscan.h"
14+
15+
void hciscan(bdaddr_t *target_bdaddr)
16+
{
17+
inquiry_info *devices = NULL;
18+
int max_rsp, num_rsp;
19+
int adapter_id, sock, len, flags;
20+
int i;
21+
char addr[19] = {0};
22+
char name[248] = {0};
23+
adapter_id = hci_get_route(NULL);
24+
sock = hci_open_dev(adapter_id);
25+
if (adapter_id < 0 || sock < 0)
26+
{
27+
perror("opening socket");
28+
exit(EXIT_FAILURE);
29+
}
30+
31+
len = 8;
32+
max_rsp = 255;
33+
flags = IREQ_CACHE_FLUSH;
34+
devices =(inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));
35+
36+
num_rsp = hci_inquiry(adapter_id, len, max_rsp, NULL, &devices, flags);
37+
if (num_rsp < 0) perror("hci_inquiry");
38+
39+
printf("Select device to send data:\n");
40+
for (i = 0; i < num_rsp; i++)
41+
{
42+
ba2str(&(devices + i)->bdaddr, addr);
43+
memset(name, 0, sizeof(name));
44+
if (0 != hci_read_remote_name(sock, &(devices + i)->bdaddr, sizeof(name), name, 0))
45+
{
46+
// allocate a socket
47+
strcpy(name, "[unknown]");
48+
}
49+
printf("%d: %s %s\n", i, addr, name);
50+
}
51+
do scanf("%d", &i); while (i < 0 || i > num_rsp);
52+
if (i >= 0 && i < num_rsp) bacpy(target_bdaddr, &(devices + i)->bdaddr);
53+
54+
free(devices);
55+
}

hciscan.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* hciscan.h
3+
*
4+
* Created on: 6 марта 2016 г.
5+
* Author: bakulev
6+
*/
7+
8+
#ifndef HCISCAN_H_
9+
#define HCISCAN_H_
10+
11+
#include <bluetooth/bluetooth.h>
12+
void hciscan(bdaddr_t *target_addr);
13+
14+
#endif /* HCISCAN_H_ */

main.c

Lines changed: 144 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,167 @@
11
#include <unistd.h>
22
#include <stdlib.h>
33
#include <stdio.h>
4+
#include <getopt.h>
5+
#include <bluetooth/bluetooth.h>
6+
#include <bluetooth/sdp.h>
7+
#include <bluetooth/sdp_lib.h> // for sdp_session_t in start_server
48

59
#include "rfcomm-server.h"
610
#include "rfcomm-client.h"
7-
#include "rfcomm-register.h"
11+
#include "hciscan.h"
12+
#include "service-register.h"
13+
#include "main.h"
14+
#include "service-register.h"
815

916
int main(int argc, char *argv[])
1017
{
11-
int flags, opt;
18+
int opt;//, flags;
1219

13-
flags = 0;
14-
sdp_session_t *session;
20+
// Service class variables. Default value is 0xABCD.
21+
uuid_t service_uuid_short = {SDP_UUID16, {0xABCD} };
22+
uuid_t *service_uuid = NULL;
1523

16-
while ((opt = getopt(argc, argv, "scr")) != -1) {
24+
// Bluetooth address to connect and send data. Default is 00:00:00:00:00:00.
25+
bdaddr_t target_bdaddr = {{0, 0, 0, 0, 0, 0}};
26+
27+
// Two types of program operation. Default is receiver (server).
28+
typedef enum {
29+
OPERATION_MODE_SERVER = 1,
30+
OPERATION_MODE_CLIENT
31+
} operation_mode_t;
32+
operation_mode_t operation_mode = OPERATION_MODE_SERVER;
33+
34+
const char *short_opt = "sa:ru:h";
35+
struct option long_opt[] =
36+
{
37+
{"sender", no_argument, NULL, 's'},
38+
{"address", required_argument, NULL, 'a'},
39+
{"receiver", no_argument, NULL, 'r'},
40+
{"uuid", required_argument, NULL, 'u'},
41+
{"help", no_argument, NULL, 'h'},
42+
{NULL, 0, NULL, 0 }
43+
};
44+
while ((opt = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
1745
switch (opt) {
18-
case 's':
19-
flags = 1;
46+
case -1: /* no more arguments */
47+
case 0: /* long options toggles */
2048
break;
21-
case 'c':
22-
flags = 2;
49+
case 's':
50+
printf("Sender (client) mode switched.\n");
51+
operation_mode = OPERATION_MODE_CLIENT;
52+
break;
53+
case 'a':
54+
// Checking and setting address to send data.
55+
str2ba(optarg, &target_bdaddr);
2356
break;
2457
case 'r':
25-
flags = 4;
58+
printf("Receiver (server) mode switched.\n");
59+
operation_mode = OPERATION_MODE_SERVER;
2660
break;
27-
default: /* ''?'' */
28-
fprintf(stderr, "Usage: %s [-s] [-c] [-r]\n",
29-
argv[0]);
30-
exit(EXIT_FAILURE);
31-
}
61+
case 'u':
62+
sdp_uuid16_create(&service_uuid_short, (uint16_t)strtoul(optarg, NULL, 16));
63+
break;
64+
case 'h':
65+
printf("Usage: %s [OPTIONS]\n", argv[0]);
66+
printf(" -s start program as sender (address and service class\n\
67+
may be specified)\n");
68+
printf(" -a address bluetooth address for sender to connect. if not\n\
69+
specified you'll be able to choose from list of\n\
70+
available devices.\n");
71+
printf(" -r start program as receiver (server)\n");
72+
printf(" -u, --uuid specify UUID of service class (default is 0xABCD)\n");
73+
printf(" -h, --help print this help and exit\n");
74+
printf("\n");
75+
exit(EXIT_SUCCESS);
76+
case ':':
77+
case '?':
78+
fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
79+
exit(EXIT_FAILURE);
80+
default:
81+
fprintf(stderr, "%s: invalid option -- %c\n", argv[0], opt);
82+
fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
83+
exit(EXIT_FAILURE);
84+
}
3285
}
3386

34-
printf("flags=%d\n", flags);
35-
36-
switch (flags) {
37-
case 1:
38-
fprintf(stdout, "Starting server.\n");
39-
session = register_service();
40-
rfcomm_server();
41-
sdp_close( session );
42-
break;
43-
case 2:
44-
fprintf(stdout, "Starting client.\n");
45-
rfcomm_client();
46-
break;
47-
case 4:
48-
fprintf(stdout, "Registering action.\n");
49-
register_service();
50-
break;
87+
// Initialize full length service uuid from short service uuid.
88+
service_uuid = sdp_uuid_to_uuid128 (&service_uuid_short);
89+
90+
switch( operation_mode ) {
91+
case OPERATION_MODE_SERVER:
92+
printf("Operating as receiver (server).\n");
93+
show_service_uuid(service_uuid);
94+
printf("Starting receiver (server)...\n");
95+
server_register_and_start(service_uuid);
96+
break;
97+
case OPERATION_MODE_CLIENT:
98+
printf("Operating as sender (client).\n");
99+
show_service_uuid(service_uuid);
100+
show_bdaddr(&target_bdaddr);
101+
if (bacmp(&target_bdaddr, BDADDR_ANY) == 0)
102+
{
103+
printf("Scanning started...\n");
104+
hciscan(&target_bdaddr);
105+
}
106+
printf("You choose address.\n");
107+
show_bdaddr(&target_bdaddr);
108+
client_start(&target_bdaddr, service_uuid);
109+
break;
51110
default:
52-
fprintf(stderr, "no action\n");
111+
printf("Unknown operation mode \"%d\".\n", operation_mode);
112+
exit(EXIT_FAILURE);
53113
}
54-
fprintf(stdout, "Done.\n");
55114

56115
exit(EXIT_SUCCESS);
57116
}
117+
118+
void show_service_uuid(uuid_t *service_uuid)
119+
{
120+
char service_uuid_str[MAX_LEN_UUID_STR];
121+
sdp_uuid2strn(service_uuid, service_uuid_str, MAX_LEN_UUID_STR);
122+
printf("Service class UUID is \"%s\".\n", service_uuid_str);
123+
}
124+
125+
void show_bdaddr(bdaddr_t *target_bdaddr)
126+
{
127+
char target_addr[32] = {0};
128+
ba2str(target_bdaddr, target_addr);
129+
if (bacmp(target_bdaddr, BDADDR_ANY) == 0)
130+
printf("Address isn't specified.\n");
131+
else
132+
printf("Address is \"%s\".\n", target_addr);
133+
}
134+
135+
void server_register_and_start(uuid_t *service_uuid)
136+
{
137+
sdp_session_t *session = 0;
138+
uint8_t port = 0; // Port of service.
139+
140+
printf("Binding listening server.\n");
141+
int s = rfcomm_server(&port); // Open server on socket and get binded port.
142+
// Register service on binded port.
143+
printf("Registering service.\n");
144+
session = service_register(session, service_uuid, port);
145+
printf("Accepting connections.\n");
146+
accept_connection(s);
147+
printf("Unregistering service.\n");
148+
sdp_close( session );
149+
printf("Closing server socket.\n");
150+
close(s); // Close socket.
151+
}
152+
153+
void client_start(bdaddr_t *target, uuid_t *service_uuid)
154+
{
155+
uint8_t port = 0; // Port of service.
156+
157+
port = service_search(target, service_uuid);
158+
if (port > 0)
159+
{
160+
printf("Starting client...\n");
161+
rfcomm_client(target, port);
162+
}
163+
else
164+
{
165+
printf("Service port not found, exiting...\n");
166+
}
167+
}

main.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* main.h
3+
*
4+
* Created on: 6 марта 2016 г.
5+
* Author: bakulev
6+
*/
7+
8+
#ifndef MAIN_H_
9+
#define MAIN_H_
10+
11+
#include <bluetooth/bluetooth.h>
12+
#include <bluetooth/sdp.h>
13+
14+
void show_service_uuid(uuid_t *service_uuid);
15+
void show_bdaddr(bdaddr_t *target_bdaddr);
16+
void server_register_and_start(uuid_t *service_uuid);
17+
void client_start(bdaddr_t *target, uuid_t *service_uuid);
18+
19+
#endif /* MAIN_H_ */

0 commit comments

Comments
 (0)