[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r28329 - gnunet/src/transport
From: |
gnunet |
Subject: |
[GNUnet-SVN] r28329 - gnunet/src/transport |
Date: |
Sun, 28 Jul 2013 13:11:14 +0200 |
Author: claudiu
Date: 2013-07-28 13:11:14 +0200 (Sun, 28 Jul 2013)
New Revision: 28329
Modified:
gnunet/src/transport/gnunet-helper-transport-bluetooth.c
gnunet/src/transport/plugin_transport_bluetooth.c
Log:
Implementing broadcast functionality; Resolving the 'security block' errors;
Handling select and send errors
Modified: gnunet/src/transport/gnunet-helper-transport-bluetooth.c
===================================================================
--- gnunet/src/transport/gnunet-helper-transport-bluetooth.c 2013-07-27
07:50:45 UTC (rev 28328)
+++ gnunet/src/transport/gnunet-helper-transport-bluetooth.c 2013-07-28
11:11:14 UTC (rev 28329)
@@ -41,6 +41,9 @@
#include "gnunet_protocols.h"
#include "plugin_transport_wlan.h"
+/**
+ * Maximum number of ports assignable for RFCOMMM protocol.
+ */
#define MAX_PORTS 30
/**
@@ -51,6 +54,11 @@
/**
+ * Maximum number of loops without inquiring for a new devices.
+ */
+#define MAX_LOOPS 3
+
+/**
* struct for storing the information of the hardware. There is only
* one of these.
*/
@@ -102,7 +110,30 @@
char buf[MAXLINE * 2];
};
+/**
+ * Devices buffer used to keep a list with all the discoverable devices in
+ * order to send them HELLO messages one by one when it receive a broadcast
message.
+ */
+struct BroadcastMessages
+{
+ /* List with the discoverable devices' addresses */
+ bdaddr_t devices[MAX_PORTS]; //FIXME I should use a linked list but 30 isn't
such a big number
+
+ /* List with the open sockets */
+ int fds[MAX_PORTS];
+
+ /* The number of the devices */
+ int size;
+
+ /* The current position */
+ int pos;
+
+ /* The device id */
+ int dev_id;
+};
+
+
/**
* Buffer for data read from stdin to be transmitted to the bluetooth device
*/
@@ -113,9 +144,18 @@
*/
static struct SendBuffer write_std;
+/**
+ * Address used to identify the broadcast messages.
+ */
+static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255,
255, 255, 255, 255}};
-static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast = {{255, 255, 255,
255, 255, 255}};
+/**
+ * Buffer with the discoverable devices.
+ */
+static struct BroadcastMessages neighbours;
+static int searching_devices_count = 0;
+
/* *********** specialized version of server_mst.c begins here ********** */
/* ****** this is the same version as the one used in
gnunet-helper-transport-wlan.c ****** */
@@ -228,7 +268,7 @@
*/
static int
mst_receive (struct MessageStreamTokenizer *mst,
- const char *buf, size_t size)
+ const char *buf, size_t size)
{
const struct GNUNET_MessageHeader *hdr;
size_t delta;
@@ -240,10 +280,14 @@
ret = GNUNET_OK;
ibuf = (char *) mst->hdr;
-
while (mst->pos > 0)
{
do_align:
+ if (mst->pos < mst->off)
+ {
+ fprintf (stderr, "We processed too many bytes!\n");
+ return GNUNET_SYSERR;
+ }
if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
(0 != (mst->off % ALIGN_FACTOR)))
{
@@ -264,6 +308,9 @@
}
if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
{
+ //FIXME should I reset ??
+ // mst->off = 0;
+ // mst->pos = 0;
return GNUNET_OK;
}
hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
@@ -271,10 +318,11 @@
if (want < sizeof (struct GNUNET_MessageHeader))
{
fprintf (stderr,
- "Received invalid message from stdin\n");
- exit (1);
+ "Received invalid message from stdin\n");
+ return GNUNET_SYSERR;
}
- if (mst->curr_buf - mst->off < want)
+ if ((mst->curr_buf - mst->off < want) &&
+ (mst->off > 0))
{
/* need more space */
mst->pos -= mst->off;
@@ -283,11 +331,16 @@
}
if (want > mst->curr_buf)
{
+ if (mst->off != 0)
+ {
+ fprintf (stderr, "Error! We should proceeded 0 bytes\n");
+ return GNUNET_SYSERR;
+ }
mst->hdr = realloc (mst->hdr, want);
if (NULL == mst->hdr)
{
- fprintf (stderr, "Failed to allocate buffer for alignment\n");
- exit (1);
+ fprintf (stderr, "Failed to allocate buffer for alignment\n");
+ exit (1);
}
ibuf = (char *) mst->hdr;
mst->curr_buf = want;
@@ -296,6 +349,11 @@
if (mst->pos - mst->off < want)
{
delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
+ if (mst->pos + delta > mst->curr_buf)
+ {
+ fprintf (stderr, "The size of the buffer will be exceeded!\n");
+ return GNUNET_SYSERR;
+ }
memcpy (&ibuf[mst->pos], buf, delta);
mst->pos += delta;
buf += delta;
@@ -303,6 +361,9 @@
}
if (mst->pos - mst->off < want)
{
+ //FIXME should I use this?
+ // mst->off = 0;
+ // mst->pos = 0;
return GNUNET_OK;
}
mst->cb (mst->cb_cls, hdr);
@@ -314,7 +375,11 @@
mst->pos = 0;
}
}
-
+ if (0 != mst->pos)
+ {
+ fprintf (stderr, "There should some valid bytes in the buffer on this
stage\n");
+ return GNUNET_SYSERR;
+ }
while (size > 0)
{
if (size < sizeof (struct GNUNET_MessageHeader))
@@ -328,9 +393,11 @@
want = ntohs (hdr->size);
if (want < sizeof (struct GNUNET_MessageHeader))
{
- fprintf (stderr,
- "Received invalid message from stdin\n");
- exit (1);
+ fprintf (stderr,
+ "Received invalid message from stdin\n");
+ //exit (1);
+ mst->off = 0;
+ return GNUNET_SYSERR;
}
if (size < want)
break; /* or not, buffer incomplete, so copy to
private buffer... */
@@ -352,8 +419,8 @@
mst->hdr = realloc (mst->hdr, size + mst->pos);
if (NULL == mst->hdr)
{
- fprintf (stderr, "Failed to allocate buffer for alignment\n");
- exit (1);
+ fprintf (stderr, "Failed to allocate buffer for alignment\n");
+ exit (1);
}
ibuf = (char *) mst->hdr;
mst->curr_buf = size + mst->pos;
@@ -361,7 +428,7 @@
if (mst->pos + size > mst->curr_buf)
{
fprintf (stderr,
- "Assertion failed\n");
+ "Assertion failed\n");
exit (1);
}
memcpy (&ibuf[mst->pos], buf, size);
@@ -553,9 +620,9 @@
// const char *service_name = "GNUnet";
const char *service_dsc = "Bluetooth plugin services";
const char *service_prov = "GNUnet provider";
- uuid_t root_uuid, rfcomm_uuid, l2cap_uuid, svc_uuid;
- sdp_list_t *root_list = 0, *rfcomm_list = 0, *l2cap_list = 0,
- *proto_list = 0, *access_proto_list = 0, *svc_list = 0;
+ uuid_t root_uuid, rfcomm_uuid, svc_uuid;
+ sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
+ *access_proto_list = 0, *svc_list = 0;
sdp_record_t *record = 0;
sdp_data_t *channel = 0;
@@ -579,11 +646,6 @@
sdp_list_append (rfcomm_list, channel);
proto_list = sdp_list_append (0, rfcomm_list);
- /* Set L2CAP information FIXME: probably not needed */
- // sdp_uuid16_create (&l2cap_uuid, L2CAP_UUID);
- // l2cap_list = sdp_list_append (0, &l2cap_uuid);
- //sdp_list_append (proto_list, l2cap_list);
-
/* Set protocol information */
access_proto_list = sdp_list_append (0, proto_list);
sdp_set_access_protos (record, access_proto_list);
@@ -615,7 +677,6 @@
sdp_data_free (channel);
sdp_list_free (root_list, 0);
sdp_list_free (rfcomm_list, 0);
- sdp_list_free (l2cap_list, 0);
sdp_list_free (proto_list, 0);
sdp_list_free (access_proto_list, 0);
sdp_list_free (svc_list, 0);
@@ -782,6 +843,11 @@
} request; //used for detecting the local devices
struct sockaddr_rc rc_addr = { 0 }; //used for binding
+ /* Initialize the neighbour structure */
+ neighbours.dev_id = -1;
+ for (i = 0; i < MAX_PORTS; i++)
+ neighbours.fds[i] = -1;
+
fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (fd_hci < 0)
@@ -818,11 +884,8 @@
if (strcmp (dev_info.name, dev->iface) == 0)
{
- //char addr[19] = { 0 }; //the device MAC address
dev_id = dev_info.dev_id; //the device was found
-
- // ba2str (&dev_info.bdaddr, addr); //get the device's MAC address
/**
* Copy the MAC address to the device structure
* FIXME: probably this is not the best solution
@@ -1031,16 +1094,222 @@
write_pout.size = sendsize;
}
-
-//TODO
/**
* Broadcast a HELLO message for peer discovery
+ * @param dev pointer to the device struct
+ * @param dev pointer to the socket which was added to the set
+ * @return 0 on success
*/
-static void
-send_broadcast ()
+static int
+send_broadcast (struct HardwareInfos *dev, int *sendsocket)
{
- // Use a hard coded port number to send hello messages to all the
neighbours
+ int new_device = 0;
+ int loops = 0;
+
+ search_for_devices:
+ if ((neighbours.size == neighbours.pos && new_device == 1) ||
neighbours.size == 0)
+ {
+ inquiry_devices: //skip the conditions and force a inquiry for new devices
+ {
+ /**
+ * It means that I sent HELLO message to all the devices from the list so
I should search
+ * for another devices or that this is the first time when I do a search
for devices.
+ */
+ inquiry_info *devices = NULL;
+ int i, responses, max_responses = MAX_PORTS;
+
+ /* sanity checks */
+ if (neighbours.size >= MAX_PORTS)
+ {
+ fprintf (stderr, "%s reached the top limit for the discovarable
devices\n", dev->iface);
+ return 2;
+ }
+
+ /* Get the device id */
+ if (neighbours.dev_id == -1)
+ {
+ char addr[19] = { 0 }; //the device MAC address
+
+ ba2str ((bdaddr_t *) &dev->pl_mac, addr);
+ neighbours.dev_id = hci_devid (addr);
+ if (neighbours.dev_id < 0)
+ {
+ fprintf (stderr, "Failed to get the device id for interface %s : %s\n",
+ dev->iface, strerror (errno));
+ return 1;
+ }
+ }
+
+ devices = malloc (max_responses * sizeof (inquiry_info));
+ if (devices == NULL)
+ {
+ fprintf (stderr, "Failed to allocate memory for inquiry info list on
interface %s\n",
+ dev->iface);
+ return 1;
+ }
+
+ responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL,
&devices, IREQ_CACHE_FLUSH);
+ if (responses < 0)
+ {
+ fprintf (stderr, "Failed to inquiry on interface %s\n", dev->iface);
+ return 1;
+ }
+
+ fprintf (stderr, "Found %d devices\n", responses); //FIXME delete it after
debugging stage
+
+ if (responses == 0)
+ {
+ fprintf (stderr, "No devices discoverable\n");
+ return 1;
+ }
+
+ for (i = 0; i < responses; i++)
+ {
+ int j;
+ int found = 0;
+
+ /* sanity check */
+ if (i >= MAX_PORTS)
+ {
+ fprintf (stderr, "%s reached the top limit for the discoverable
devices (after inquiry)\n", dev->iface);
+ return 2;
+ }
+
+ /* Search if the address already exists on the list */
+ for (j = 0; j < neighbours.size; j++)
+ {
+ if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof
(bdaddr_t)) == 0)
+ {
+ found = 1;
+ fprintf (stderr, "the device already exists on the list\n"); //FIXME
debugging message
+ break;
+ }
+ }
+
+ if (found == 0)
+ {
+ char addr[19] = { 0 };
+
+ ba2str (&(devices +i)->bdaddr, addr);
+ fprintf (stderr, "%s was added to the list\n", addr); //FIXME
debugging message
+ memcpy (&(neighbours.devices[neighbours.size++]), &(devices +
i)->bdaddr, sizeof (bdaddr_t));
+ }
+ }
+
+ free (devices);
+ }
+ }
+
+ int connection_successful = 0;
+ struct sockaddr_rc addr_rc = { 0 };
+ int errno_copy = 0;
+ addr_rc.rc_family = AF_BLUETOOTH;
+
+ /* Try to connect to a new device from the list */
+ while (neighbours.pos < neighbours.size)
+ {
+ /* Check if we are connected to this device */
+ if (neighbours.fds[neighbours.pos] == -1)
+ {
+
+ memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
+ memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]),
sizeof (addr_rc.rc_bdaddr));
+
+ addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
+
+ *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+
+ if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc))
== 0)
+ {
+ neighbours.fds[neighbours.pos++] = *sendsocket;
+ connection_successful = 1;
+ char addr[19] = { 0 };
+ ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
+ fprintf (stderr, "Connected to %s\n", addr);
+
+ break;
+ }
+ else
+ {
+ char addr[19] = { 0 };
+ errno_copy = errno; //Save a copy for later
+ ba2str (&(neighbours.devices[neighbours.pos]), addr);
+ fprintf (stderr, "Couldn't connect on device %s, error : %s\n", addr,
strerror(errno));
+ if (errno != ECONNREFUSED) //FIXME nu merge!
+ {
+ fprintf (stderr, "Removes %d device from the list\n",
neighbours.pos);
+ /* Remove the device from the list */
+ memcpy (&neighbours.devices[neighbours.pos],
&neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
+ memset (&neighbours.devices[neighbours.size - 1], 0, sizeof
(bdaddr_t));
+ neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
+ neighbours.fds[neighbours.size - 1] = -1;
+ neighbours.size -= 1;
+ }
+
+ neighbours.pos += 1;
+
+ if (neighbours.pos >= neighbours.size)
+ neighbours.pos = 0;
+
+ loops += 1;
+
+ if (loops == MAX_LOOPS) //don't get stuck trying to connect to one
device
+ return 1;
+ }
+ }
+ else
+ {
+ fprintf (stderr, "Search for a new device\n"); //FIXME debugging message
+ neighbours.pos += 1;
+ }
+ }
+
+ /* Cycle on the list */
+ if (neighbours.pos == neighbours.size)
+ {
+ neighbours.pos = 0;
+ searching_devices_count += 1;
+
+ if (searching_devices_count == MAX_LOOPS)
+ {
+ fprintf (stderr, "Force to inquiry for new devices\n");
+ searching_devices_count = 0;
+ goto inquiry_devices;
+ }
+ }
+ /* If a new device wasn't found, search an old one */
+ if (connection_successful == 0)
+ {
+ int loop_check = neighbours.pos;
+ while (neighbours.fds[neighbours.pos] == -1)
+ {
+ if (neighbours.pos == neighbours.size)
+ neighbours.pos = 0;
+
+ if (neighbours.pos == loop_check)
+ {
+ if (errno_copy == ECONNREFUSED)
+ {
+ fprintf (stderr, "No device found. Go back and search again\n");
//FIXME debugging message
+ new_device = 1;
+ loops += 1;
+ goto search_for_devices;
+ }
+ else
+ {
+ return 1; // Skip the broadcast message
+ }
+ }
+
+ neighbours.pos += 1;
+ }
+
+ *sendsocket = neighbours.fds[neighbours.pos++];
+ }
+
+ return 0;
}
+
/**
* Main function of the helper. This code accesses a bluetooth interface
* forwards traffic in both directions between the bluetooth interface and
@@ -1064,8 +1333,8 @@
struct MessageStreamTokenizer *stdin_mst;
int raw_eno, i;
uid_t uid;
- int crt_rfds = 0, crt_wfds = 0, rfds_list[MAX_PORTS], wfds_list[MAX_PORTS];
-
+ int crt_rfds = 0, rfds_list[MAX_PORTS];
+ int broadcast, sendsocket;
/* Assert privs so we can modify the firewall rules! */
uid = getuid ();
#ifdef HAVE_SETRESUID
@@ -1157,50 +1426,50 @@
stdin_mst = mst_create (&stdin_send_hw, &dev);
stdin_open = 1;
- int ok = 0;
- fprintf (stderr, "Check if the program exits\n");
+
+ fprintf (stderr, "\n-----------------------------------------------\n
Check if the program exits\n-----------------------------------------------\n");
+ /**
+ * TODO : When a connection fails I should ignore only the CONTROL messages.
+ * For DATA messages I should retry to send the message until it doesn't fail
+ * Also I should make the time out of a mac endpoint smaller and check if the
rate
+ * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
+ */
while (1)
{
maxfd = -1;
+ broadcast = 0;
+ sendsocket = -1;
+
FD_ZERO (&rfds);
if ((0 == write_pout.size) && (1 == stdin_open))
{
- // fprintf(stderr, "LOG : %s adds STDIN to rfds\n", dev.iface); //FIXME:
debugging message
+ // fprintf (stderr, "LOG : %s adds STDIN to rfds\n", dev.iface); //FIXME:
debugging message
FD_SET (STDIN_FILENO, &rfds);
maxfd = MAX (maxfd, STDIN_FILENO);
}
if (0 == write_std.size)
{
- // fprintf(stderr, "LOG : %s adds fd_rfcomm to rfds\n", dev.iface);
//FIXME: debugging message
+ // fprintf (stderr, "LOG : %s adds fd_rfcomm to rfds\n", dev.iface);
//FIXME: debugging message
FD_SET (dev.fd_rfcomm, &rfds);
maxfd = MAX (maxfd, dev.fd_rfcomm);
}
+
+ for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple
devices
+ {
+ // fprintf (stderr, "LOG : %s adds extra fds to rfds\n", dev.iface);
//FIXME: debugging message
+ FD_SET (rfds_list[i], &rfds);
+ maxfd = MAX (maxfd, rfds_list[i]);
+ }
FD_ZERO (&wfds);
if (0 < write_std.size)
{
- // fprintf(stderr, "LOG : %s adds STDOUT to wfds\n", dev.iface); //FIXME:
debugging message
+ // fprintf (stderr, "LOG : %s adds STDOUT to wfds\n", dev.iface);
//FIXME: debugging message
FD_SET (STDOUT_FILENO, &wfds);
maxfd = MAX (maxfd, STDOUT_FILENO);
}
-
- for (i = 0; i < crt_rfds; i++)
- {
- // fprintf(stderr, "LOG : %s adds extra fds to rfds\n", dev.iface);
//FIXME: debugging message
- FD_SET (rfds_list[i], &rfds);
- maxfd = MAX (maxfd, rfds_list[i]);
- }
-
- for (i = 0; i < crt_wfds; i++)
- {
- // fprintf(stderr, "LOG : %s adds extra fds to wfds\n", dev.iface);
//FIXME: debugging message
- FD_SET (wfds_list[i], &wfds);
- maxfd = MAX (maxfd, wfds_list[i]);
- }
-
- if (0 < write_pout.size)
+ if (0 < write_pout.size) //it can send messages only to one device per loop
{
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
-
/* Get the destination address */
//FIXME : not sure if this is correct
frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
@@ -1208,131 +1477,195 @@
if (memcmp (&frame->addr1, &dev.pl_mac,
sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
{
- // fprintf (stderr, "LOG : %s has a message for him:)\n", dev.iface);
//FIXME: debugging message
+ fprintf (stderr, "LOG : %s has a message for him:)\n", dev.iface);
//FIXME: debugging message
memset (&write_pout, 0, sizeof (write_pout)); // clear the buffer
}
- else if (memcmp (&frame->addr1, &broadcast,
+ else if (memcmp (&frame->addr1, &broadcast_address,
sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
{
- // fprintf (stderr, "LOG : %s has a broadcast message\n", dev.iface);
//FIXME: debugging message
- memset (&write_pout, 0, sizeof (write_pout)); //FIXME for now just
clear the buffer
- send_broadcast();
- ok = 1;
+ fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size
%d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
+ // broadcast = 1; // IF I HAVE A BROADCAST MESSAGE I skip.
+ // memset (&write_pout, 0, sizeof (write_pout));
+
+ if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't
successful don't get stuck on the select stage
+ {
+ broadcast = 1;
+ memset (&write_pout, 0, sizeof (write_pout)); //remove the message
+ fprintf (stderr, "Skip the broadcast message (pos %d, size %d)\n",
neighbours.pos, neighbours.size);
+ }
+ else
+ {
+ FD_SET (sendsocket, &wfds);
+ maxfd = MAX (maxfd, sendsocket);
+ }
}
else
{
- int sendsocket, status;
- struct sockaddr_rc addr = { 0 };
-
- fprintf (stderr, "LOG : %s has a new message for
%.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", dev.iface,
- frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
- frame->addr1.mac[2], frame->addr1.mac[1],
frame->addr1.mac[0]); //FIXME: debugging message
-
- memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
-
- sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-
- if (sendsocket < 0)
+ int found = 0;
+ /* Search if the address already exists on the list */
+ for (i = 0; i < neighbours.size; i++)
{
- fprintf (stderr, "Failed to create a RFCOMM socket (sending stage):
%s\n",
- strerror (errno));
- return -1;
+ if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof
(bdaddr_t)) == 0 && neighbours.fds[i] != -1)
+ {
+ found = 1;
+ FD_SET (neighbours.fds[i], &wfds);
+ maxfd = MAX (maxfd, neighbours.fds[i]);
+ sendsocket = neighbours.fds[i];
+ fprintf (stderr, "LOG: the address was found in the list\n");
+ break;
+ }
}
-
+ if (found == 0)
+ {
+ int status;
+ struct sockaddr_rc addr = { 0 };
- addr.rc_family = AF_BLUETOOTH;
- addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
-
- /*TODO: use a NON-BLOCKING socket
- * sock_flags = fcntl (sendsocket, F_GETFL, 0);
- * fcntl( sendsocket, F_SETFL, sock_flags | O_NONBLOCK);
- */
- status = connect (sendsocket, (struct sockaddr *) &addr, sizeof
(addr));
- if (0 != status && errno != EAGAIN)
- {
- fprintf (stderr, "%s failed to connect : %s\n", dev.iface,
strerror (errno));
- return -1;
- }
-
- FD_SET (sendsocket, &wfds);
- maxfd = MAX (maxfd, sendsocket);
-
- if (crt_wfds < MAX_PORTS)
- wfds_list[crt_wfds++] = sendsocket; //add the socket to the list
- else
- {
- fprintf (stderr, "The limit for the write file descriptors list was \
- reached\n");
- break;
+ 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,
+ frame->addr1.mac[5], frame->addr1.mac[4],
frame->addr1.mac[3],
+ frame->addr1.mac[2], frame->addr1.mac[1],
frame->addr1.mac[0]); //FIXME: debugging message
+
+ sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+
+ if (sendsocket < 0)
+ {
+ fprintf (stderr, "Failed to create a RFCOMM socket (sending
stage): %s\n",
+ strerror (errno));
+ return -1;
+ }
+
+ memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
+ addr.rc_family = AF_BLUETOOTH;
+ addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
+
+ /***
+ *TODO: use a NON-BLOCKING socket
+ * sock_flags = fcntl (sendsocket, F_GETFL, 0);
+ * fcntl( sendsocket, F_SETFL, sock_flags | O_NONBLOCK);
+ */
+ int tries = 0;
+ connect_retry:
+ status = connect (sendsocket, (struct sockaddr *) &addr, sizeof
(addr));
+ if (0 != status && errno != EAGAIN)
+ {
+ if (errno == ECONNREFUSED && tries < 2)
+ {
+ fprintf (stderr, "%s failed to connect. Trying again!\n",
dev.iface);
+ tries++;
+ goto connect_retry;
+ }
+ else if (errno == EBADF)
+ {
+ fprintf (stderr, "%s failed to connect : %s. Skip it!\n",
dev.iface, strerror (errno));
+ memset (&write_pout, 0, sizeof (write_pout));
+ broadcast = 1;
+ }
+ else
+ {
+ fprintf (stderr, "%s failed to connect : %s. Try again
later!\n", dev.iface, strerror (errno));
+ memset (&write_pout, 0, sizeof (write_pout));
+ broadcast = 1;
+ }
+
+ }
+ else
+ {
+ FD_SET (sendsocket, &wfds);
+ maxfd = MAX (maxfd, sendsocket);
+ fprintf (stderr, "Connection successful\n");
+ /* Add the new device to the discovered devices list */
+ if (neighbours.size < MAX_PORTS)
+ {
+ neighbours.fds[neighbours.size] = sendsocket;
+ memcpy (&(neighbours.devices[neighbours.size++]),
&addr.rc_bdaddr, sizeof (bdaddr_t));
+ }
+ else
+ {
+ fprintf (stderr, "The top limit for the discovarable devices'
list was reached\n");
+ }
+ }
}
}
}
- //fprintf (stderr, "inainte de select\n");
- if (ok == 0)
+
+ if (broadcast == 0)
{
- int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
- if ((-1 == retval) && (EINTR == errno))
- continue;
- if (0 > retval)
+ /* Select a fd which is ready for action :) */
{
- fprintf (stderr, "select failed: %s\n", strerror (errno));
- break;
+ int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); //FIXME :
when a device close the connection remove the socket from the list
+ if ((-1 == retval) && (EINTR == errno))
+ continue;
+ if (0 > retval && errno != EBADF) // we handle BADF errors later
+ {
+ fprintf (stderr, "select failed: %s\n", strerror (errno));
+ break;
+ }
}
-
- // fprintf (stderr, "dupa select\n");
- for (i = 0; i <= maxfd; i++) //FIXME it should be incremented
+ if (FD_ISSET (STDOUT_FILENO , &wfds))
{
- if (FD_ISSET (i , &wfds))
+ ssize_t ret =
+ write (STDOUT_FILENO, write_std.buf + write_std.pos,
+ write_std.size - write_std.pos);
+ if (0 > ret)
{
- if (i == STDOUT_FILENO)
+ fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror
(errno));
+ break;
+ }
+ write_std.pos += ret;
+ if (write_std.pos == write_std.size)
+ {
+ write_std.pos = 0;
+ write_std.size = 0;
+ }
+ fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface);
//FIXME: debugging message
+
+ }
+ if (sendsocket != -1)
+ {
+ if (FD_ISSET (sendsocket , &wfds))
+ {
+ ssize_t ret =
+ write (sendsocket, write_pout.buf + write_std.pos,
+ write_pout.size - write_pout.pos);
+ if (0 > ret) //FIXME should I check first the error type?
{
- ssize_t ret =
- write (STDOUT_FILENO, write_std.buf + write_std.pos,
- write_std.size - write_std.pos);
- if (0 > ret)
+ fprintf (stderr, "Failed to write to bluetooth device: %s. Closing
the socket!\n",
+ strerror (errno));
+
+ for (i = 0; i < neighbours.size; i++)
{
- fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror
(errno));
- break;
+ if (neighbours.fds[i] == sendsocket)
+ {
+ (void) close(sendsocket);
+ neighbours.fds[i] = -1;
+ break;
+ }
}
- write_std.pos += ret;
- if (write_std.pos == write_std.size)
- {
- write_std.pos = 0;
- write_std.size = 0;
- }
- // fprintf(stderr, "LOG : %s sends a message to STDOUT\n",
dev.iface); //FIXME: debugging message
- }
- else
+ //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
+ //write_pour.pos = 0 ; write_pout.size = 0;
+ }
+ else
{
- ssize_t ret =
- write (i, write_pout.buf + write_std.pos,
- write_pout.size - write_pout.pos);
- if (0 > ret)
- {
- fprintf (stderr, "Failed to write to bluetooth device: %s\n",
- strerror (errno));
- break;
- }
write_pout.pos += ret;
if ((write_pout.pos != write_pout.size) && (0 != ret))
{
/* we should not get partial sends with packet-oriented
devices... */
fprintf (stderr, "Write error, partial send: %u/%u\n",
- (unsigned int) write_pout.pos,
- (unsigned int) write_pout.size);
+ (unsigned int) write_pout.pos,
+ (unsigned int) write_pout.size);
break;
}
+
if (write_pout.pos == write_pout.size)
{
write_pout.pos = 0;
write_pout.size = 0;
- //(void) close (i);
}
- // fprintf(stderr, "LOG : %s sends a message to a DEVICE\n",
dev.iface); //FIXME: debugging message
+ fprintf (stderr, "LOG : %s sends a message to a DEVICE\n",
dev.iface); //FIXME: debugging message
}
-
}
-
+ }
+ for (i = 0; i <= maxfd; i++) //FIXME it should be incremented
+ {
if (FD_ISSET (i, &rfds))
{
if (i == STDIN_FILENO)
@@ -1349,8 +1682,11 @@
/* stop reading... */
stdin_open = 0;
}
- // fprintf(stderr, "LOG : %s receives a message from STDIN\n",
dev.iface); //FIXME: debugging message
- mst_receive (stdin_mst, readbuf, ret);
+ else
+ {
+ mst_receive (stdin_mst, readbuf, ret);
+ fprintf (stderr, "LOG : %s receives a message from STDIN\n",
dev.iface); //FIXME: debugging message
+ }
}
else if (i == dev.fd_rfcomm)
{
@@ -1364,8 +1700,10 @@
{
fprintf (stderr, "Failed to accept a connection on interface:
%s\n",
strerror (errno));
- return -1;
- } else {
+ return -1; //FIXME probably I should ignore the error and
keep the process alive
+ }
+ else
+ {
FD_SET (readsocket, &rfds);
maxfd = MAX (maxfd, readsocket);
@@ -1384,7 +1722,7 @@
{
struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
ssize_t ret;
-
+ fprintf (stderr, "LOG : %s reads something from the socket\n",
dev.iface);//FIXME : debugging message
rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *)
write_std.buf;
ret =
read_from_the_socket (i, (unsigned char *) &rrm->frame,
@@ -1392,10 +1730,25 @@
- sizeof (struct
GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+ sizeof (struct
GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
rrm);
- fprintf (stderr, "LOG: %s reads something from the socket\n",
dev.iface);//FIXME : debugging message
- if (0 > ret)
+ if (0 >= ret)
{
- fprintf (stderr, "Read error from rfcomm socket: %s\n", strerror
(errno));
+ int j;
+ FD_CLR (i, &rfds);
+ close (i);
+ /* Remove the socket from the list */
+ for (j = 0; j < crt_rfds; j++)
+ {
+ if (rfds_list[j] == i)
+ {
+ rfds_list[j] ^= rfds_list[crt_rfds - 1];
+ rfds_list[crt_rfds - 1] ^= rfds_list[j];
+ rfds_list[j] ^= rfds_list[crt_rfds - 1];
+ crt_rfds -= 1;
+ break;
+ }
+ }
+
+ fprintf (stderr, "Read error from raw socket: %s\n", strerror
(errno));
break;
}
if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
@@ -1405,12 +1758,24 @@
- sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
rrm->header.size = htons (write_std.size);
rrm->header.type = htons
(GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
+
+ /* Remove the socket from the list */
+ int j;
+ for (j = 0; j < crt_rfds; j++)
+ {
+ if (i == rfds_list[crt_rfds])
+ {
+ rfds_list[j] ^= rfds_list[crt_rfds];
+ rfds_list[crt_rfds] ^= rfds_list[j];
+ rfds_list[j] ^= rfds_list[crt_rfds];
+ crt_rfds -= 1;
+ break;
+ }
+ }
}
}
}
}
- } else {
- ok = 0;
}
}
/* Error handling, try to clean up a bit at least */
@@ -1418,19 +1783,15 @@
stdin_mst = NULL;
sdp_close (dev.session);
(void) close (dev.fd_rfcomm);
+ (void) close (sendsocket);
+
for (i = 0; i < crt_rfds; i++)
(void) close (rfds_list[i]);
- for (i = 0; i < crt_wfds; i++)
- (void) close (wfds_list[i]);
+ for (i = 0; i < neighbours.size; i++)
+ (void) close (neighbours.fds[i]);
return 1; /* we never exit 'normally' */
-
- /**
- *TODO
- * 1. check if the rate from get_wlan_header (plugin_transport_bluetooth.c)
is correct
- * 2.
- */
}
Modified: gnunet/src/transport/plugin_transport_bluetooth.c
===================================================================
--- gnunet/src/transport/plugin_transport_bluetooth.c 2013-07-27 07:50:45 UTC
(rev 28328)
+++ gnunet/src/transport/plugin_transport_bluetooth.c 2013-07-28 11:11:14 UTC
(rev 28329)
@@ -51,14 +51,14 @@
/**
* time out of a mac endpoint
*/
-#define MACENDPOINT_TIMEOUT GNUNET_TIME_relative_multiply
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2)
+#define MACENDPOINT_TIMEOUT GNUNET_TIME_relative_multiply
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 60)
/**
* We reduce the frequence of HELLO beacons in relation to
* the number of MAC addresses currently visible to us.
* This is the multiplication factor.
*/
-#define HELLO_BEACON_SCALING_FACTOR GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 2)
+#define HELLO_BEACON_SCALING_FACTOR GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 60)
/**
* Maximum number of messages in defragmentation queue per MAC
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r28329 - gnunet/src/transport,
gnunet <=