aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-helper-transport-bluetooth.c
diff options
context:
space:
mode:
authorClaudiu Olteanu <claudiu@140774ce-b5e7-0310-ab8b-a85725594a96>2013-07-28 11:11:14 +0000
committerClaudiu Olteanu <claudiu@140774ce-b5e7-0310-ab8b-a85725594a96>2013-07-28 11:11:14 +0000
commitb276d3ef3ab34b24cd45ad3a10391929482607b0 (patch)
tree5701f07a704f8102aa14480a4fc959f0fa299652 /src/transport/gnunet-helper-transport-bluetooth.c
parentde32d367db0fccdcc66a386b16570471e09ee55b (diff)
downloadgnunet-b276d3ef3ab34b24cd45ad3a10391929482607b0.tar.gz
gnunet-b276d3ef3ab34b24cd45ad3a10391929482607b0.zip
Implementing broadcast functionality; Resolving the 'security block' errors; Handling select and send errors
Diffstat (limited to 'src/transport/gnunet-helper-transport-bluetooth.c')
-rw-r--r--src/transport/gnunet-helper-transport-bluetooth.c687
1 files changed, 524 insertions, 163 deletions
diff --git a/src/transport/gnunet-helper-transport-bluetooth.c b/src/transport/gnunet-helper-transport-bluetooth.c
index a8819c8d6..48e63dd75 100644
--- a/src/transport/gnunet-helper-transport-bluetooth.c
+++ b/src/transport/gnunet-helper-transport-bluetooth.c
@@ -41,6 +41,9 @@
41#include "gnunet_protocols.h" 41#include "gnunet_protocols.h"
42#include "plugin_transport_wlan.h" 42#include "plugin_transport_wlan.h"
43 43
44/**
45 * Maximum number of ports assignable for RFCOMMM protocol.
46 */
44#define MAX_PORTS 30 47#define MAX_PORTS 30
45 48
46/** 49/**
@@ -51,6 +54,11 @@
51 54
52 55
53/** 56/**
57 * Maximum number of loops without inquiring for a new devices.
58 */
59#define MAX_LOOPS 3
60
61/**
54 * struct for storing the information of the hardware. There is only 62 * struct for storing the information of the hardware. There is only
55 * one of these. 63 * one of these.
56 */ 64 */
@@ -102,6 +110,29 @@ struct SendBuffer
102 char buf[MAXLINE * 2]; 110 char buf[MAXLINE * 2];
103}; 111};
104 112
113/**
114 * Devices buffer used to keep a list with all the discoverable devices in
115 * order to send them HELLO messages one by one when it receive a broadcast message.
116 */
117struct BroadcastMessages
118{
119 /* List with the discoverable devices' addresses */
120 bdaddr_t devices[MAX_PORTS]; //FIXME I should use a linked list but 30 isn't such a big number
121
122 /* List with the open sockets */
123 int fds[MAX_PORTS];
124
125
126 /* The number of the devices */
127 int size;
128
129 /* The current position */
130 int pos;
131
132 /* The device id */
133 int dev_id;
134};
135
105 136
106/** 137/**
107 * Buffer for data read from stdin to be transmitted to the bluetooth device 138 * Buffer for data read from stdin to be transmitted to the bluetooth device
@@ -113,8 +144,17 @@ static struct SendBuffer write_pout;
113 */ 144 */
114static struct SendBuffer write_std; 145static struct SendBuffer write_std;
115 146
147/**
148 * Address used to identify the broadcast messages.
149 */
150static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
116 151
117static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast = {{255, 255, 255, 255, 255, 255}}; 152/**
153 * Buffer with the discoverable devices.
154 */
155static struct BroadcastMessages neighbours;
156
157static int searching_devices_count = 0;
118 158
119/* *********** specialized version of server_mst.c begins here ********** */ 159/* *********** specialized version of server_mst.c begins here ********** */
120/* ****** this is the same version as the one used in gnunet-helper-transport-wlan.c ****** */ 160/* ****** this is the same version as the one used in gnunet-helper-transport-wlan.c ****** */
@@ -228,7 +268,7 @@ mst_create (MessageTokenizerCallback cb,
228 */ 268 */
229static int 269static int
230mst_receive (struct MessageStreamTokenizer *mst, 270mst_receive (struct MessageStreamTokenizer *mst,
231 const char *buf, size_t size) 271 const char *buf, size_t size)
232{ 272{
233 const struct GNUNET_MessageHeader *hdr; 273 const struct GNUNET_MessageHeader *hdr;
234 size_t delta; 274 size_t delta;
@@ -240,10 +280,14 @@ mst_receive (struct MessageStreamTokenizer *mst,
240 280
241 ret = GNUNET_OK; 281 ret = GNUNET_OK;
242 ibuf = (char *) mst->hdr; 282 ibuf = (char *) mst->hdr;
243
244 while (mst->pos > 0) 283 while (mst->pos > 0)
245 { 284 {
246do_align: 285do_align:
286 if (mst->pos < mst->off)
287 {
288 fprintf (stderr, "We processed too many bytes!\n");
289 return GNUNET_SYSERR;
290 }
247 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) || 291 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
248 (0 != (mst->off % ALIGN_FACTOR))) 292 (0 != (mst->off % ALIGN_FACTOR)))
249 { 293 {
@@ -264,6 +308,9 @@ do_align:
264 } 308 }
265 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader)) 309 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
266 { 310 {
311 //FIXME should I reset ??
312 // mst->off = 0;
313 // mst->pos = 0;
267 return GNUNET_OK; 314 return GNUNET_OK;
268 } 315 }
269 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; 316 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
@@ -271,10 +318,11 @@ do_align:
271 if (want < sizeof (struct GNUNET_MessageHeader)) 318 if (want < sizeof (struct GNUNET_MessageHeader))
272 { 319 {
273 fprintf (stderr, 320 fprintf (stderr,
274 "Received invalid message from stdin\n"); 321 "Received invalid message from stdin\n");
275 exit (1); 322 return GNUNET_SYSERR;
276 } 323 }
277 if (mst->curr_buf - mst->off < want) 324 if ((mst->curr_buf - mst->off < want) &&
325 (mst->off > 0))
278 { 326 {
279 /* need more space */ 327 /* need more space */
280 mst->pos -= mst->off; 328 mst->pos -= mst->off;
@@ -283,11 +331,16 @@ do_align:
283 } 331 }
284 if (want > mst->curr_buf) 332 if (want > mst->curr_buf)
285 { 333 {
334 if (mst->off != 0)
335 {
336 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
337 return GNUNET_SYSERR;
338 }
286 mst->hdr = realloc (mst->hdr, want); 339 mst->hdr = realloc (mst->hdr, want);
287 if (NULL == mst->hdr) 340 if (NULL == mst->hdr)
288 { 341 {
289 fprintf (stderr, "Failed to allocate buffer for alignment\n"); 342 fprintf (stderr, "Failed to allocate buffer for alignment\n");
290 exit (1); 343 exit (1);
291 } 344 }
292 ibuf = (char *) mst->hdr; 345 ibuf = (char *) mst->hdr;
293 mst->curr_buf = want; 346 mst->curr_buf = want;
@@ -296,6 +349,11 @@ do_align:
296 if (mst->pos - mst->off < want) 349 if (mst->pos - mst->off < want)
297 { 350 {
298 delta = GNUNET_MIN (want - (mst->pos - mst->off), size); 351 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
352 if (mst->pos + delta > mst->curr_buf)
353 {
354 fprintf (stderr, "The size of the buffer will be exceeded!\n");
355 return GNUNET_SYSERR;
356 }
299 memcpy (&ibuf[mst->pos], buf, delta); 357 memcpy (&ibuf[mst->pos], buf, delta);
300 mst->pos += delta; 358 mst->pos += delta;
301 buf += delta; 359 buf += delta;
@@ -303,6 +361,9 @@ do_align:
303 } 361 }
304 if (mst->pos - mst->off < want) 362 if (mst->pos - mst->off < want)
305 { 363 {
364 //FIXME should I use this?
365 // mst->off = 0;
366 // mst->pos = 0;
306 return GNUNET_OK; 367 return GNUNET_OK;
307 } 368 }
308 mst->cb (mst->cb_cls, hdr); 369 mst->cb (mst->cb_cls, hdr);
@@ -314,7 +375,11 @@ do_align:
314 mst->pos = 0; 375 mst->pos = 0;
315 } 376 }
316 } 377 }
317 378 if (0 != mst->pos)
379 {
380 fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
381 return GNUNET_SYSERR;
382 }
318 while (size > 0) 383 while (size > 0)
319 { 384 {
320 if (size < sizeof (struct GNUNET_MessageHeader)) 385 if (size < sizeof (struct GNUNET_MessageHeader))
@@ -328,9 +393,11 @@ do_align:
328 want = ntohs (hdr->size); 393 want = ntohs (hdr->size);
329 if (want < sizeof (struct GNUNET_MessageHeader)) 394 if (want < sizeof (struct GNUNET_MessageHeader))
330 { 395 {
331 fprintf (stderr, 396 fprintf (stderr,
332 "Received invalid message from stdin\n"); 397 "Received invalid message from stdin\n");
333 exit (1); 398 //exit (1);
399 mst->off = 0;
400 return GNUNET_SYSERR;
334 } 401 }
335 if (size < want) 402 if (size < want)
336 break; /* or not, buffer incomplete, so copy to private buffer... */ 403 break; /* or not, buffer incomplete, so copy to private buffer... */
@@ -352,8 +419,8 @@ do_align:
352 mst->hdr = realloc (mst->hdr, size + mst->pos); 419 mst->hdr = realloc (mst->hdr, size + mst->pos);
353 if (NULL == mst->hdr) 420 if (NULL == mst->hdr)
354 { 421 {
355 fprintf (stderr, "Failed to allocate buffer for alignment\n"); 422 fprintf (stderr, "Failed to allocate buffer for alignment\n");
356 exit (1); 423 exit (1);
357 } 424 }
358 ibuf = (char *) mst->hdr; 425 ibuf = (char *) mst->hdr;
359 mst->curr_buf = size + mst->pos; 426 mst->curr_buf = size + mst->pos;
@@ -361,7 +428,7 @@ do_align:
361 if (mst->pos + size > mst->curr_buf) 428 if (mst->pos + size > mst->curr_buf)
362 { 429 {
363 fprintf (stderr, 430 fprintf (stderr,
364 "Assertion failed\n"); 431 "Assertion failed\n");
365 exit (1); 432 exit (1);
366 } 433 }
367 memcpy (&ibuf[mst->pos], buf, size); 434 memcpy (&ibuf[mst->pos], buf, size);
@@ -553,9 +620,9 @@ register_service (struct HardwareInfos *dev, int rc_channel)
553// const char *service_name = "GNUnet"; 620// const char *service_name = "GNUnet";
554 const char *service_dsc = "Bluetooth plugin services"; 621 const char *service_dsc = "Bluetooth plugin services";
555 const char *service_prov = "GNUnet provider"; 622 const char *service_prov = "GNUnet provider";
556 uuid_t root_uuid, rfcomm_uuid, l2cap_uuid, svc_uuid; 623 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
557 sdp_list_t *root_list = 0, *rfcomm_list = 0, *l2cap_list = 0, 624 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
558 *proto_list = 0, *access_proto_list = 0, *svc_list = 0; 625 *access_proto_list = 0, *svc_list = 0;
559 sdp_record_t *record = 0; 626 sdp_record_t *record = 0;
560 sdp_data_t *channel = 0; 627 sdp_data_t *channel = 0;
561 628
@@ -579,11 +646,6 @@ register_service (struct HardwareInfos *dev, int rc_channel)
579 sdp_list_append (rfcomm_list, channel); 646 sdp_list_append (rfcomm_list, channel);
580 proto_list = sdp_list_append (0, rfcomm_list); 647 proto_list = sdp_list_append (0, rfcomm_list);
581 648
582 /* Set L2CAP information FIXME: probably not needed */
583 // sdp_uuid16_create (&l2cap_uuid, L2CAP_UUID);
584 // l2cap_list = sdp_list_append (0, &l2cap_uuid);
585 //sdp_list_append (proto_list, l2cap_list);
586
587 /* Set protocol information */ 649 /* Set protocol information */
588 access_proto_list = sdp_list_append (0, proto_list); 650 access_proto_list = sdp_list_append (0, proto_list);
589 sdp_set_access_protos (record, access_proto_list); 651 sdp_set_access_protos (record, access_proto_list);
@@ -615,7 +677,6 @@ register_service (struct HardwareInfos *dev, int rc_channel)
615 sdp_data_free (channel); 677 sdp_data_free (channel);
616 sdp_list_free (root_list, 0); 678 sdp_list_free (root_list, 0);
617 sdp_list_free (rfcomm_list, 0); 679 sdp_list_free (rfcomm_list, 0);
618 sdp_list_free (l2cap_list, 0);
619 sdp_list_free (proto_list, 0); 680 sdp_list_free (proto_list, 0);
620 sdp_list_free (access_proto_list, 0); 681 sdp_list_free (access_proto_list, 0);
621 sdp_list_free (svc_list, 0); 682 sdp_list_free (svc_list, 0);
@@ -782,6 +843,11 @@ open_device (struct HardwareInfos *dev)
782 } request; //used for detecting the local devices 843 } request; //used for detecting the local devices
783 struct sockaddr_rc rc_addr = { 0 }; //used for binding 844 struct sockaddr_rc rc_addr = { 0 }; //used for binding
784 845
846 /* Initialize the neighbour structure */
847 neighbours.dev_id = -1;
848 for (i = 0; i < MAX_PORTS; i++)
849 neighbours.fds[i] = -1;
850
785 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); 851 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
786 852
787 if (fd_hci < 0) 853 if (fd_hci < 0)
@@ -818,11 +884,8 @@ open_device (struct HardwareInfos *dev)
818 884
819 if (strcmp (dev_info.name, dev->iface) == 0) 885 if (strcmp (dev_info.name, dev->iface) == 0)
820 { 886 {
821 //char addr[19] = { 0 }; //the device MAC address
822 887
823 dev_id = dev_info.dev_id; //the device was found 888 dev_id = dev_info.dev_id; //the device was found
824
825 // ba2str (&dev_info.bdaddr, addr); //get the device's MAC address
826 /** 889 /**
827 * Copy the MAC address to the device structure 890 * Copy the MAC address to the device structure
828 * FIXME: probably this is not the best solution 891 * FIXME: probably this is not the best solution
@@ -1031,16 +1094,222 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1031 write_pout.size = sendsize; 1094 write_pout.size = sendsize;
1032} 1095}
1033 1096
1034
1035//TODO
1036/** 1097/**
1037 * Broadcast a HELLO message for peer discovery 1098 * Broadcast a HELLO message for peer discovery
1099 * @param dev pointer to the device struct
1100 * @param dev pointer to the socket which was added to the set
1101 * @return 0 on success
1038 */ 1102 */
1039static void 1103static int
1040send_broadcast () 1104send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1041{ 1105{
1042 // Use a hard coded port number to send hello messages to all the neighbours 1106 int new_device = 0;
1107 int loops = 0;
1108
1109 search_for_devices:
1110 if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1111 {
1112 inquiry_devices: //skip the conditions and force a inquiry for new devices
1113 {
1114 /**
1115 * It means that I sent HELLO message to all the devices from the list so I should search
1116 * for another devices or that this is the first time when I do a search for devices.
1117 */
1118 inquiry_info *devices = NULL;
1119 int i, responses, max_responses = MAX_PORTS;
1120
1121 /* sanity checks */
1122 if (neighbours.size >= MAX_PORTS)
1123 {
1124 fprintf (stderr, "%s reached the top limit for the discovarable devices\n", dev->iface);
1125 return 2;
1126 }
1127
1128 /* Get the device id */
1129 if (neighbours.dev_id == -1)
1130 {
1131 char addr[19] = { 0 }; //the device MAC address
1132
1133 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1134 neighbours.dev_id = hci_devid (addr);
1135 if (neighbours.dev_id < 0)
1136 {
1137 fprintf (stderr, "Failed to get the device id for interface %s : %s\n",
1138 dev->iface, strerror (errno));
1139 return 1;
1140 }
1141 }
1142
1143 devices = malloc (max_responses * sizeof (inquiry_info));
1144 if (devices == NULL)
1145 {
1146 fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %s\n",
1147 dev->iface);
1148 return 1;
1149 }
1150
1151 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1152 if (responses < 0)
1153 {
1154 fprintf (stderr, "Failed to inquiry on interface %s\n", dev->iface);
1155 return 1;
1156 }
1157
1158 fprintf (stderr, "Found %d devices\n", responses); //FIXME delete it after debugging stage
1159
1160 if (responses == 0)
1161 {
1162 fprintf (stderr, "No devices discoverable\n");
1163 return 1;
1164 }
1165
1166 for (i = 0; i < responses; i++)
1167 {
1168 int j;
1169 int found = 0;
1170
1171 /* sanity check */
1172 if (i >= MAX_PORTS)
1173 {
1174 fprintf (stderr, "%s reached the top limit for the discoverable devices (after inquiry)\n", dev->iface);
1175 return 2;
1176 }
1177
1178 /* Search if the address already exists on the list */
1179 for (j = 0; j < neighbours.size; j++)
1180 {
1181 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1182 {
1183 found = 1;
1184 fprintf (stderr, "the device already exists on the list\n"); //FIXME debugging message
1185 break;
1186 }
1187 }
1188
1189 if (found == 0)
1190 {
1191 char addr[19] = { 0 };
1192
1193 ba2str (&(devices +i)->bdaddr, addr);
1194 fprintf (stderr, "%s was added to the list\n", addr); //FIXME debugging message
1195 memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1196 }
1197 }
1198
1199 free (devices);
1200 }
1201 }
1202
1203 int connection_successful = 0;
1204 struct sockaddr_rc addr_rc = { 0 };
1205 int errno_copy = 0;
1206 addr_rc.rc_family = AF_BLUETOOTH;
1207
1208 /* Try to connect to a new device from the list */
1209 while (neighbours.pos < neighbours.size)
1210 {
1211 /* Check if we are connected to this device */
1212 if (neighbours.fds[neighbours.pos] == -1)
1213 {
1214
1215 memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1216 memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1217
1218 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1219
1220 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1221
1222 if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
1223 {
1224 neighbours.fds[neighbours.pos++] = *sendsocket;
1225 connection_successful = 1;
1226 char addr[19] = { 0 };
1227 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1228 fprintf (stderr, "Connected to %s\n", addr);
1229
1230 break;
1231 }
1232 else
1233 {
1234 char addr[19] = { 0 };
1235 errno_copy = errno; //Save a copy for later
1236 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1237 fprintf (stderr, "Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
1238 if (errno != ECONNREFUSED) //FIXME nu merge!
1239 {
1240 fprintf (stderr, "Removes %d device from the list\n", neighbours.pos);
1241 /* Remove the device from the list */
1242 memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1243 memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1244 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1245 neighbours.fds[neighbours.size - 1] = -1;
1246 neighbours.size -= 1;
1247 }
1248
1249 neighbours.pos += 1;
1250
1251 if (neighbours.pos >= neighbours.size)
1252 neighbours.pos = 0;
1253
1254 loops += 1;
1255
1256 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1257 return 1;
1258 }
1259 }
1260 else
1261 {
1262 fprintf (stderr, "Search for a new device\n"); //FIXME debugging message
1263 neighbours.pos += 1;
1264 }
1265 }
1266
1267 /* Cycle on the list */
1268 if (neighbours.pos == neighbours.size)
1269 {
1270 neighbours.pos = 0;
1271 searching_devices_count += 1;
1272
1273 if (searching_devices_count == MAX_LOOPS)
1274 {
1275 fprintf (stderr, "Force to inquiry for new devices\n");
1276 searching_devices_count = 0;
1277 goto inquiry_devices;
1278 }
1279 }
1280 /* If a new device wasn't found, search an old one */
1281 if (connection_successful == 0)
1282 {
1283 int loop_check = neighbours.pos;
1284 while (neighbours.fds[neighbours.pos] == -1)
1285 {
1286 if (neighbours.pos == neighbours.size)
1287 neighbours.pos = 0;
1288
1289 if (neighbours.pos == loop_check)
1290 {
1291 if (errno_copy == ECONNREFUSED)
1292 {
1293 fprintf (stderr, "No device found. Go back and search again\n"); //FIXME debugging message
1294 new_device = 1;
1295 loops += 1;
1296 goto search_for_devices;
1297 }
1298 else
1299 {
1300 return 1; // Skip the broadcast message
1301 }
1302 }
1303
1304 neighbours.pos += 1;
1305 }
1306
1307 *sendsocket = neighbours.fds[neighbours.pos++];
1308 }
1309
1310 return 0;
1043} 1311}
1312
1044/** 1313/**
1045 * Main function of the helper. This code accesses a bluetooth interface 1314 * Main function of the helper. This code accesses a bluetooth interface
1046 * forwards traffic in both directions between the bluetooth interface and 1315 * forwards traffic in both directions between the bluetooth interface and
@@ -1064,8 +1333,8 @@ main (int argc, char *argv[])
1064 struct MessageStreamTokenizer *stdin_mst; 1333 struct MessageStreamTokenizer *stdin_mst;
1065 int raw_eno, i; 1334 int raw_eno, i;
1066 uid_t uid; 1335 uid_t uid;
1067 int crt_rfds = 0, crt_wfds = 0, rfds_list[MAX_PORTS], wfds_list[MAX_PORTS]; 1336 int crt_rfds = 0, rfds_list[MAX_PORTS];
1068 1337 int broadcast, sendsocket;
1069 /* Assert privs so we can modify the firewall rules! */ 1338 /* Assert privs so we can modify the firewall rules! */
1070 uid = getuid (); 1339 uid = getuid ();
1071#ifdef HAVE_SETRESUID 1340#ifdef HAVE_SETRESUID
@@ -1157,50 +1426,50 @@ main (int argc, char *argv[])
1157 1426
1158 stdin_mst = mst_create (&stdin_send_hw, &dev); 1427 stdin_mst = mst_create (&stdin_send_hw, &dev);
1159 stdin_open = 1; 1428 stdin_open = 1;
1160 int ok = 0; 1429
1161 fprintf (stderr, "Check if the program exits\n"); 1430 fprintf (stderr, "\n-----------------------------------------------\n Check if the program exits\n-----------------------------------------------\n");
1431 /**
1432 * TODO : When a connection fails I should ignore only the CONTROL messages.
1433 * For DATA messages I should retry to send the message until it doesn't fail
1434 * Also I should make the time out of a mac endpoint smaller and check if the rate
1435 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1436 */
1162 while (1) 1437 while (1)
1163 { 1438 {
1164 maxfd = -1; 1439 maxfd = -1;
1440 broadcast = 0;
1441 sendsocket = -1;
1442
1165 FD_ZERO (&rfds); 1443 FD_ZERO (&rfds);
1166 if ((0 == write_pout.size) && (1 == stdin_open)) 1444 if ((0 == write_pout.size) && (1 == stdin_open))
1167 { 1445 {
1168 // fprintf(stderr, "LOG : %s adds STDIN to rfds\n", dev.iface); //FIXME: debugging message 1446 // fprintf (stderr, "LOG : %s adds STDIN to rfds\n", dev.iface); //FIXME: debugging message
1169 FD_SET (STDIN_FILENO, &rfds); 1447 FD_SET (STDIN_FILENO, &rfds);
1170 maxfd = MAX (maxfd, STDIN_FILENO); 1448 maxfd = MAX (maxfd, STDIN_FILENO);
1171 } 1449 }
1172 if (0 == write_std.size) 1450 if (0 == write_std.size)
1173 { 1451 {
1174 // fprintf(stderr, "LOG : %s adds fd_rfcomm to rfds\n", dev.iface); //FIXME: debugging message 1452 // fprintf (stderr, "LOG : %s adds fd_rfcomm to rfds\n", dev.iface); //FIXME: debugging message
1175 FD_SET (dev.fd_rfcomm, &rfds); 1453 FD_SET (dev.fd_rfcomm, &rfds);
1176 maxfd = MAX (maxfd, dev.fd_rfcomm); 1454 maxfd = MAX (maxfd, dev.fd_rfcomm);
1177 } 1455 }
1178 FD_ZERO (&wfds); 1456
1179 if (0 < write_std.size) 1457 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1180 {
1181 // fprintf(stderr, "LOG : %s adds STDOUT to wfds\n", dev.iface); //FIXME: debugging message
1182 FD_SET (STDOUT_FILENO, &wfds);
1183 maxfd = MAX (maxfd, STDOUT_FILENO);
1184 }
1185
1186 for (i = 0; i < crt_rfds; i++)
1187 { 1458 {
1188 // fprintf(stderr, "LOG : %s adds extra fds to rfds\n", dev.iface); //FIXME: debugging message 1459 // fprintf (stderr, "LOG : %s adds extra fds to rfds\n", dev.iface); //FIXME: debugging message
1189 FD_SET (rfds_list[i], &rfds); 1460 FD_SET (rfds_list[i], &rfds);
1190 maxfd = MAX (maxfd, rfds_list[i]); 1461 maxfd = MAX (maxfd, rfds_list[i]);
1191 } 1462 }
1192 1463 FD_ZERO (&wfds);
1193 for (i = 0; i < crt_wfds; i++) 1464 if (0 < write_std.size)
1194 { 1465 {
1195 // fprintf(stderr, "LOG : %s adds extra fds to wfds\n", dev.iface); //FIXME: debugging message 1466 // fprintf (stderr, "LOG : %s adds STDOUT to wfds\n", dev.iface); //FIXME: debugging message
1196 FD_SET (wfds_list[i], &wfds); 1467 FD_SET (STDOUT_FILENO, &wfds);
1197 maxfd = MAX (maxfd, wfds_list[i]); 1468 maxfd = MAX (maxfd, STDOUT_FILENO);
1198 } 1469 }
1199 1470 if (0 < write_pout.size) //it can send messages only to one device per loop
1200 if (0 < write_pout.size)
1201 { 1471 {
1202 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame; 1472 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1203
1204 /* Get the destination address */ 1473 /* Get the destination address */
1205 //FIXME : not sure if this is correct 1474 //FIXME : not sure if this is correct
1206 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf; 1475 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
@@ -1208,131 +1477,195 @@ main (int argc, char *argv[])
1208 if (memcmp (&frame->addr1, &dev.pl_mac, 1477 if (memcmp (&frame->addr1, &dev.pl_mac,
1209 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) 1478 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1210 { 1479 {
1211 // fprintf (stderr, "LOG : %s has a message for him:)\n", dev.iface); //FIXME: debugging message 1480 fprintf (stderr, "LOG : %s has a message for him:)\n", dev.iface); //FIXME: debugging message
1212 memset (&write_pout, 0, sizeof (write_pout)); // clear the buffer 1481 memset (&write_pout, 0, sizeof (write_pout)); // clear the buffer
1213 } 1482 }
1214 else if (memcmp (&frame->addr1, &broadcast, 1483 else if (memcmp (&frame->addr1, &broadcast_address,
1215 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) 1484 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1216 { 1485 {
1217 // fprintf (stderr, "LOG : %s has a broadcast message\n", dev.iface); //FIXME: debugging message 1486 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1218 memset (&write_pout, 0, sizeof (write_pout)); //FIXME for now just clear the buffer 1487 // broadcast = 1; // IF I HAVE A BROADCAST MESSAGE I skip.
1219 send_broadcast(); 1488 // memset (&write_pout, 0, sizeof (write_pout));
1220 ok = 1; 1489
1490 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1491 {
1492 broadcast = 1;
1493 memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1494 fprintf (stderr, "Skip the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1495 }
1496 else
1497 {
1498 FD_SET (sendsocket, &wfds);
1499 maxfd = MAX (maxfd, sendsocket);
1500 }
1221 } 1501 }
1222 else 1502 else
1223 { 1503 {
1224 int sendsocket, status; 1504 int found = 0;
1225 struct sockaddr_rc addr = { 0 }; 1505 /* Search if the address already exists on the list */
1226 1506 for (i = 0; i < neighbours.size; i++)
1227 fprintf (stderr, "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", dev.iface,
1228 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1229 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1230
1231 memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1232
1233 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1234
1235 if (sendsocket < 0)
1236 { 1507 {
1237 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n", 1508 if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0 && neighbours.fds[i] != -1)
1238 strerror (errno)); 1509 {
1239 return -1; 1510 found = 1;
1511 FD_SET (neighbours.fds[i], &wfds);
1512 maxfd = MAX (maxfd, neighbours.fds[i]);
1513 sendsocket = neighbours.fds[i];
1514 fprintf (stderr, "LOG: the address was found in the list\n");
1515 break;
1516 }
1240 } 1517 }
1241 1518 if (found == 0)
1242
1243 addr.rc_family = AF_BLUETOOTH;
1244 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1245
1246 /*TODO: use a NON-BLOCKING socket
1247 * sock_flags = fcntl (sendsocket, F_GETFL, 0);
1248 * fcntl( sendsocket, F_SETFL, sock_flags | O_NONBLOCK);
1249 */
1250 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1251 if (0 != status && errno != EAGAIN)
1252 {
1253 fprintf (stderr, "%s failed to connect : %s\n", dev.iface, strerror (errno));
1254 return -1;
1255 }
1256
1257 FD_SET (sendsocket, &wfds);
1258 maxfd = MAX (maxfd, sendsocket);
1259
1260 if (crt_wfds < MAX_PORTS)
1261 wfds_list[crt_wfds++] = sendsocket; //add the socket to the list
1262 else
1263 { 1519 {
1264 fprintf (stderr, "The limit for the write file descriptors list was \ 1520 int status;
1265 reached\n"); 1521 struct sockaddr_rc addr = { 0 };
1266 break; 1522
1523 fprintf (stderr, "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n", dev.iface,
1524 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1525 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1526
1527 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1528
1529 if (sendsocket < 0)
1530 {
1531 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1532 strerror (errno));
1533 return -1;
1534 }
1535
1536 memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1537 addr.rc_family = AF_BLUETOOTH;
1538 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1539
1540 /***
1541 *TODO: use a NON-BLOCKING socket
1542 * sock_flags = fcntl (sendsocket, F_GETFL, 0);
1543 * fcntl( sendsocket, F_SETFL, sock_flags | O_NONBLOCK);
1544 */
1545 int tries = 0;
1546 connect_retry:
1547 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1548 if (0 != status && errno != EAGAIN)
1549 {
1550 if (errno == ECONNREFUSED && tries < 2)
1551 {
1552 fprintf (stderr, "%s failed to connect. Trying again!\n", dev.iface);
1553 tries++;
1554 goto connect_retry;
1555 }
1556 else if (errno == EBADF)
1557 {
1558 fprintf (stderr, "%s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1559 memset (&write_pout, 0, sizeof (write_pout));
1560 broadcast = 1;
1561 }
1562 else
1563 {
1564 fprintf (stderr, "%s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1565 memset (&write_pout, 0, sizeof (write_pout));
1566 broadcast = 1;
1567 }
1568
1569 }
1570 else
1571 {
1572 FD_SET (sendsocket, &wfds);
1573 maxfd = MAX (maxfd, sendsocket);
1574 fprintf (stderr, "Connection successful\n");
1575 /* Add the new device to the discovered devices list */
1576 if (neighbours.size < MAX_PORTS)
1577 {
1578 neighbours.fds[neighbours.size] = sendsocket;
1579 memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1580 }
1581 else
1582 {
1583 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1584 }
1585 }
1267 } 1586 }
1268 } 1587 }
1269 } 1588 }
1270 //fprintf (stderr, "inainte de select\n"); 1589
1271 if (ok == 0) 1590 if (broadcast == 0)
1272 { 1591 {
1273 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); 1592 /* Select a fd which is ready for action :) */
1274 if ((-1 == retval) && (EINTR == errno))
1275 continue;
1276 if (0 > retval)
1277 { 1593 {
1278 fprintf (stderr, "select failed: %s\n", strerror (errno)); 1594 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); //FIXME : when a device close the connection remove the socket from the list
1279 break; 1595 if ((-1 == retval) && (EINTR == errno))
1596 continue;
1597 if (0 > retval && errno != EBADF) // we handle BADF errors later
1598 {
1599 fprintf (stderr, "select failed: %s\n", strerror (errno));
1600 break;
1601 }
1280 } 1602 }
1281 1603 if (FD_ISSET (STDOUT_FILENO , &wfds))
1282 // fprintf (stderr, "dupa select\n");
1283 for (i = 0; i <= maxfd; i++) //FIXME it should be incremented
1284 { 1604 {
1285 if (FD_ISSET (i , &wfds)) 1605 ssize_t ret =
1606 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1607 write_std.size - write_std.pos);
1608 if (0 > ret)
1609 {
1610 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1611 break;
1612 }
1613 write_std.pos += ret;
1614 if (write_std.pos == write_std.size)
1286 { 1615 {
1287 if (i == STDOUT_FILENO) 1616 write_std.pos = 0;
1617 write_std.size = 0;
1618 }
1619 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1620
1621 }
1622 if (sendsocket != -1)
1623 {
1624 if (FD_ISSET (sendsocket , &wfds))
1625 {
1626 ssize_t ret =
1627 write (sendsocket, write_pout.buf + write_std.pos,
1628 write_pout.size - write_pout.pos);
1629 if (0 > ret) //FIXME should I check first the error type?
1288 { 1630 {
1289 ssize_t ret = 1631 fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1290 write (STDOUT_FILENO, write_std.buf + write_std.pos, 1632 strerror (errno));
1291 write_std.size - write_std.pos); 1633
1292 if (0 > ret) 1634 for (i = 0; i < neighbours.size; i++)
1293 {
1294 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1295 break;
1296 }
1297 write_std.pos += ret;
1298 if (write_std.pos == write_std.size)
1299 { 1635 {
1300 write_std.pos = 0; 1636 if (neighbours.fds[i] == sendsocket)
1301 write_std.size = 0; 1637 {
1638 (void) close(sendsocket);
1639 neighbours.fds[i] = -1;
1640 break;
1641 }
1302 } 1642 }
1303 // fprintf(stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message 1643 //memset (&(write_pout.buf + write_std.pos), 0, (write_pout.size - write_pout.pos)) // FIXME should I remove the message? or try to resend it
1304 } 1644 //write_pour.pos = 0 ; write_pout.size = 0;
1305 else 1645 }
1646 else
1306 { 1647 {
1307 ssize_t ret =
1308 write (i, write_pout.buf + write_std.pos,
1309 write_pout.size - write_pout.pos);
1310 if (0 > ret)
1311 {
1312 fprintf (stderr, "Failed to write to bluetooth device: %s\n",
1313 strerror (errno));
1314 break;
1315 }
1316 write_pout.pos += ret; 1648 write_pout.pos += ret;
1317 if ((write_pout.pos != write_pout.size) && (0 != ret)) 1649 if ((write_pout.pos != write_pout.size) && (0 != ret))
1318 { 1650 {
1319 /* we should not get partial sends with packet-oriented devices... */ 1651 /* we should not get partial sends with packet-oriented devices... */
1320 fprintf (stderr, "Write error, partial send: %u/%u\n", 1652 fprintf (stderr, "Write error, partial send: %u/%u\n",
1321 (unsigned int) write_pout.pos, 1653 (unsigned int) write_pout.pos,
1322 (unsigned int) write_pout.size); 1654 (unsigned int) write_pout.size);
1323 break; 1655 break;
1324 } 1656 }
1657
1325 if (write_pout.pos == write_pout.size) 1658 if (write_pout.pos == write_pout.size)
1326 { 1659 {
1327 write_pout.pos = 0; 1660 write_pout.pos = 0;
1328 write_pout.size = 0; 1661 write_pout.size = 0;
1329 //(void) close (i);
1330 } 1662 }
1331 // fprintf(stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message 1663 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1332 } 1664 }
1333
1334 } 1665 }
1335 1666 }
1667 for (i = 0; i <= maxfd; i++) //FIXME it should be incremented
1668 {
1336 if (FD_ISSET (i, &rfds)) 1669 if (FD_ISSET (i, &rfds))
1337 { 1670 {
1338 if (i == STDIN_FILENO) 1671 if (i == STDIN_FILENO)
@@ -1349,8 +1682,11 @@ main (int argc, char *argv[])
1349 /* stop reading... */ 1682 /* stop reading... */
1350 stdin_open = 0; 1683 stdin_open = 0;
1351 } 1684 }
1352 // fprintf(stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message 1685 else
1353 mst_receive (stdin_mst, readbuf, ret); 1686 {
1687 mst_receive (stdin_mst, readbuf, ret);
1688 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1689 }
1354 } 1690 }
1355 else if (i == dev.fd_rfcomm) 1691 else if (i == dev.fd_rfcomm)
1356 { 1692 {
@@ -1364,8 +1700,10 @@ main (int argc, char *argv[])
1364 { 1700 {
1365 fprintf (stderr, "Failed to accept a connection on interface: %s\n", 1701 fprintf (stderr, "Failed to accept a connection on interface: %s\n",
1366 strerror (errno)); 1702 strerror (errno));
1367 return -1; 1703 return -1; //FIXME probably I should ignore the error and keep the process alive
1368 } else { 1704 }
1705 else
1706 {
1369 FD_SET (readsocket, &rfds); 1707 FD_SET (readsocket, &rfds);
1370 maxfd = MAX (maxfd, readsocket); 1708 maxfd = MAX (maxfd, readsocket);
1371 1709
@@ -1384,7 +1722,7 @@ main (int argc, char *argv[])
1384 { 1722 {
1385 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm; 1723 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1386 ssize_t ret; 1724 ssize_t ret;
1387 1725 fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
1388 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf; 1726 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1389 ret = 1727 ret =
1390 read_from_the_socket (i, (unsigned char *) &rrm->frame, 1728 read_from_the_socket (i, (unsigned char *) &rrm->frame,
@@ -1392,10 +1730,25 @@ main (int argc, char *argv[])
1392 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 1730 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1393 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), 1731 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
1394 rrm); 1732 rrm);
1395 fprintf (stderr, "LOG: %s reads something from the socket\n", dev.iface);//FIXME : debugging message 1733 if (0 >= ret)
1396 if (0 > ret)
1397 { 1734 {
1398 fprintf (stderr, "Read error from rfcomm socket: %s\n", strerror (errno)); 1735 int j;
1736 FD_CLR (i, &rfds);
1737 close (i);
1738 /* Remove the socket from the list */
1739 for (j = 0; j < crt_rfds; j++)
1740 {
1741 if (rfds_list[j] == i)
1742 {
1743 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1744 rfds_list[crt_rfds - 1] ^= rfds_list[j];
1745 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1746 crt_rfds -= 1;
1747 break;
1748 }
1749 }
1750
1751 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1399 break; 1752 break;
1400 } 1753 }
1401 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev))) 1754 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
@@ -1405,12 +1758,24 @@ main (int argc, char *argv[])
1405 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame); 1758 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1406 rrm->header.size = htons (write_std.size); 1759 rrm->header.size = htons (write_std.size);
1407 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER); 1760 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1761
1762 /* Remove the socket from the list */
1763 int j;
1764 for (j = 0; j < crt_rfds; j++)
1765 {
1766 if (i == rfds_list[crt_rfds])
1767 {
1768 rfds_list[j] ^= rfds_list[crt_rfds];
1769 rfds_list[crt_rfds] ^= rfds_list[j];
1770 rfds_list[j] ^= rfds_list[crt_rfds];
1771 crt_rfds -= 1;
1772 break;
1773 }
1774 }
1408 } 1775 }
1409 } 1776 }
1410 } 1777 }
1411 } 1778 }
1412 } else {
1413 ok = 0;
1414 } 1779 }
1415 } 1780 }
1416 /* Error handling, try to clean up a bit at least */ 1781 /* Error handling, try to clean up a bit at least */
@@ -1418,19 +1783,15 @@ main (int argc, char *argv[])
1418 stdin_mst = NULL; 1783 stdin_mst = NULL;
1419 sdp_close (dev.session); 1784 sdp_close (dev.session);
1420 (void) close (dev.fd_rfcomm); 1785 (void) close (dev.fd_rfcomm);
1786 (void) close (sendsocket);
1787
1421 for (i = 0; i < crt_rfds; i++) 1788 for (i = 0; i < crt_rfds; i++)
1422 (void) close (rfds_list[i]); 1789 (void) close (rfds_list[i]);
1423 1790
1424 for (i = 0; i < crt_wfds; i++) 1791 for (i = 0; i < neighbours.size; i++)
1425 (void) close (wfds_list[i]); 1792 (void) close (neighbours.fds[i]);
1426 1793
1427 return 1; /* we never exit 'normally' */ 1794 return 1; /* we never exit 'normally' */
1428
1429 /**
1430 *TODO
1431 * 1. check if the rate from get_wlan_header (plugin_transport_bluetooth.c) is correct
1432 * 2.
1433 */
1434} 1795}
1435 1796
1436 1797