Boston, MA 02111-1307, USA.
*/
#include "gnunet_config.h"
+#include "plugin_transport_wlan.h"
+#include "gnunet_protocols.h"
+
+#ifdef MINGW
+ #include "platform.h"
+ #include "gnunet_util_lib.h"
+ #include <bthdef.h>
+ #include <ws2bth.h>
+ #include "gnunet_protocols.h"
+#else
+ #include <bluetooth/bluetooth.h>
+ #include <bluetooth/hci.h>
+ #include <bluetooth/hci_lib.h>
+ #include <bluetooth/rfcomm.h>
+ #include <bluetooth/sdp.h>
+ #include <bluetooth/sdp_lib.h>
+ #include <errno.h>
+ #include <linux/if.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/ioctl.h>
+ #include <sys/param.h>
+ #include <sys/socket.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+#endif
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-#include <errno.h>
-#include <linux/if.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "gnunet_protocols.h"
-#include "plugin_transport_wlan.h"
+/**
+ * Maximum number of ports assignable for RFCOMMM protocol.
+ */
#define MAX_PORTS 30
/**
#define MAXLINE 4096
+/**
+ * Maximum number of loops without inquiring for new devices.
+ */
+#define MAX_LOOPS 5
+
+#ifdef MINGW
+ /* Maximum size of the interface's name */
+ #define IFNAMSIZ 16
+
+ #ifndef NS_BTH
+ #define NS_BTH 16
+ #endif
+ /**
+ * A copy of the MAC Address.
+ */
+ struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy
+ {
+ UINT8 mac[MAC_ADDR_SIZE];
+ };
+
+ /**
+ * The UUID used for the SDP service.
+ * {31191E56-FA7E-4517-870E-71B86BBCC52F}
+ */
+ #define GNUNET_BLUETOOTH_SDP_UUID \
+ { \
+ 0x31, 0x19, 0x1E, 0x56, \
+ 0xFA, 0x7E, \
+ 0x45, 0x17, \
+ 0x87, 0x0E, \
+ 0x71, 0xB8, 0x6B, 0xBC, 0xC5, 0x2F \
+ }
+#endif
+
/**
* struct for storing the information of the hardware. There is only
* one of these.
*/
struct HardwareInfos
{
-
/**
- * file descriptor for the rfcomm socket
+ * Name of the interface, not necessarily 0-terminated (!).
*/
- int fd_rfcomm;
+ char iface[IFNAMSIZ];
+ #ifdef MINGW
/**
- * Name of the interface, not necessarily 0-terminated (!).
+ * socket handle
+ */
+ struct GNUNET_NETWORK_Handle *handle;
+
+ /**
+ * MAC address of our own bluetooth interface.
*/
- char iface[IFNAMSIZ];
+ struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy pl_mac;
+ #else
+ /**
+ * file descriptor for the rfcomm socket
+ */
+ int fd_rfcomm;
/**
* MAC address of our own bluetooth interface.
* SDP session
*/
sdp_session_t *session ;
+ #endif
};
/**
char buf[MAXLINE * 2];
};
+#ifdef LINUX
+ /**
+ * 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];
+
+ /* 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;
+ };
+
+ /**
+ * Address used to identify the broadcast messages.
+ */
+ static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
+
+ /**
+ * Buffer with the discoverable devices.
+ */
+ static struct BroadcastMessages neighbours;
+
+ static int searching_devices_count = 0;
+#endif
/**
* Buffer for data read from stdin to be transmitted to the bluetooth device
static struct SendBuffer write_std;
-/* *********** specialized version of server_mst.c begins here ********** */
-/* ****** this is the same version as the one used in gnunet-helper-transport-wlan.c ****** */
+/* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
/**
* To what multiple do we align messages? 8 byte should suffice for everyone
* @param message the actual message
*/
typedef void (*MessageTokenizerCallback) (void *cls,
- const struct
- GNUNET_MessageHeader *
- message);
+ const struct
+ GNUNET_MessageHeader *
+ message);
/**
* Handle to a message stream tokenizer.
*/
static struct MessageStreamTokenizer *
mst_create (MessageTokenizerCallback cb,
- void *cb_cls)
+ void *cb_cls)
{
struct MessageStreamTokenizer *ret;
ret->curr_buf = MIN_BUFFER_SIZE;
ret->cb = cb;
ret->cb_cls = cb_cls;
+ ret->pos = 0;
+
return ret;
}
*/
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;
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)))
{
}
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];
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;
}
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;
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;
}
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);
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))
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... */
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;
if (mst->pos + size > mst->curr_buf)
{
fprintf (stderr,
- "Assertion failed\n");
+ "Assertion failed\n");
exit (1);
}
memcpy (&ibuf[mst->pos], buf, size);
return ret;
}
-
/**
* Destroys a tokenizer.
*
free (mst);
}
-/* ***************** end of server_mst.c clone ***************** **/
-
-
-/* ****** same crc version as the one used in gnunet-helper-transport-wlan.c ****** */
-
/**
* Calculate crc32, the start of the calculation
*
-/* ************** end of crc version ***************** */
+/* ************** end of clone ***************** */
+#ifdef MINGW
+ /**
+ * Function used to get the code of last error and to print the type of error.
+ */
+ static void
+ print_last_error()
+ {
+ LPVOID lpMsgBuf = NULL;
+ if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL))
+ fprintf (stderr, "%s\n", (char *)lpMsgBuf);
+ else
+ fprintf (stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
+ }
+ /**
+ * Function used to initialize the Windows Sockets
+ */
+ static void
+ initialize_windows_sockets()
+ {
+ WSADATA wsaData ;
+ WORD wVersionRequested = MAKEWORD (2, 0);
+ if (WSAStartup (wVersionRequested, &wsaData) != NO_ERROR)
+ {
+ fprintf (stderr , "Error initializing window sockets!\n");
+ print_last_error();
+ ExitProcess (2) ;
+ }
+ }
-/**
- * Function for assigning a port number
- * @param socket the socket used to bind
- * @param addr pointer to the rfcomm address
- * @return 0 on success
- */
-static int
-bind_socket (int socket, struct sockaddr_rc *addr)
-{
- int port, status;
-
- /* Bind every possible port (from 0 to 30) and stop when bind doesn't fail */
- //FIXME : it should start from port 1, but on my computer it doesn't work :)
- for (port = 3; port <= 30; port++)
+ /**
+ * Function used to convert the GUID.
+ * @param bytes the GUID represented as a char array
+ * @param uuid pointer to the GUID
+ */
+ static void
+ convert_guid(char *bytes, GUID * uuid)
{
- addr->rc_channel = port;
- status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
- if (status == 0)
- return 0;
+ int i;
+ uuid->Data1 = ((bytes[0] << 24) & 0xff000000) | ((bytes[1] << 16) & 0x00ff0000) | ((bytes[2] << 8) & 0x0000ff00) | (bytes[3] & 0x000000ff);
+ uuid->Data2 = ((bytes[4] << 8) & 0xff00) | (bytes[5] & 0x00ff);
+ uuid->Data3 = ((bytes[6] << 8) & 0xff00) | (bytes[7] & 0x00ff);
+
+ for (i = 0; i < 8; i++)
+ {
+ uuid->Data4[i] = bytes[i + 8];
+ }
}
-
- return -1;
-}
+#endif
+#ifdef LINUX
+ /**
+ * Function for assigning a port number
+ *
+ * @param socket the socket used to bind
+ * @param addr pointer to the rfcomm address
+ * @return 0 on success
+ */
+ static int
+ bind_socket (int socket, struct sockaddr_rc *addr)
+ {
+ int port, status;
+
+ /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
+ //FIXME : it should start from port 1, but on my computer it doesn't work :)
+ for (port = 3; port <= 30; port++)
+ {
+ addr->rc_channel = port;
+ status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
+ if (status == 0)
+ return 0;
+ }
+
+ return -1;
+ }
+#endif
-/**
- * Function used for creating the service record and registering it.
- * @param dev pointer to the device struct
- * @param rc_channel the rfcomm channel
- * @return 0 on success
- */
-static int
-register_service (struct HardwareInfos *dev, int rc_channel)
-{
+#ifdef MINGW
/**
- * 1. initializations
- * 2. set the service ID, class, profile information
- * 3. make the service record publicly nrowsable
- * 4. register the RFCOMM channel
- * 5. set the name, provider and description
- * 6. register the service record to the local SDP server
- * 7. cleanup
+ * Function used for creating the service record and registering it.
+ *
+ * @param dev pointer to the device struct
+ * @return 0 on success
*/
-
- //FIXME: probably this is not the best idea. I should find a different uuid
- uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
- dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
-// 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;
- sdp_record_t *record = 0;
- sdp_data_t *channel = 0;
-
- record = sdp_record_alloc();
-
- /* Set the general service ID */
- sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
- svc_list = sdp_list_append (0, &svc_uuid);
- sdp_set_service_classes (record, svc_list);
- sdp_set_service_id (record, svc_uuid);
-
- /* Make the service record publicly browsable */
- sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
- root_list = sdp_list_append (0, &root_uuid);
- sdp_set_browse_groups (record, root_list);
-
- /* Register the RFCOMM channel */
- sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
- channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
- rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
- 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);
-
- /* Set the name, provider, and description */
- sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
-
- /* Connect to the local SDP server */
- dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
-
- if (!dev->session)
+ static int
+ register_service (struct HardwareInfos *dev)
{
- fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
- IFNAMSIZ, dev->iface, strerror (errno));
- //FIXME exit?
- return 1;
+ /* advertise the service */
+ CSADDR_INFO addr_info;
+ WSAQUERYSET wqs;
+ GUID guid;
+ unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
+ SOCKADDR_BTH addr;
+ int addr_len = sizeof (SOCKADDR_BTH);
+ int fd;
+ /* get the port on which we are listening on */
+ memset (& addr, 0, sizeof (SOCKADDR_BTH));
+ fd = GNUNET_NETWORK_get_fd (dev->handle);
+ if (fd <= 0)
+ {
+ fprintf (stderr, "Failed to get the file descriptor\n");
+ return -1;
+ }
+ if (SOCKET_ERROR == getsockname (fd, (SOCKADDR*)&addr, &addr_len))
+ {
+ fprintf (stderr, "Failed to get the port on which we are listening on: \n");
+ print_last_error();
+ return -1;
+ }
+
+ /* save the device address */
+ memcpy (&dev->pl_mac, &addr.btAddr, sizeof (BTH_ADDR));
+
+ /* set the address information */
+ memset (&addr_info, 0, sizeof (CSADDR_INFO));
+ addr_info.iProtocol = BTHPROTO_RFCOMM;
+ addr_info.iSocketType = SOCK_STREAM;
+ addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
+ addr_info.LocalAddr.iSockaddrLength = sizeof (addr);
+ addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
+ addr_info.RemoteAddr.iSockaddrLength = sizeof (addr);
+
+ convert_guid((char *) uuid, &guid);
+
+ /* register the service */
+ memset (&wqs, 0, sizeof (WSAQUERYSET));
+ wqs.dwSize = sizeof (WSAQUERYSET);
+ wqs.dwNameSpace = NS_BTH;
+ wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
+ wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
+ wqs.lpServiceClassId = &guid;
+ wqs.dwNumberOfCsAddrs = 1;
+ wqs.lpcsaBuffer = &addr_info ;
+ wqs.lpBlob = 0;
+
+ if (SOCKET_ERROR == WSASetService (&wqs , RNRSERVICE_REGISTER, 0))
+ {
+ fprintf (stderr, "Failed to register the SDP service: ");
+ print_last_error();
+ return -1;
+ }
+ else
+ {
+ fprintf (stderr, "The SDP service was registered\n");
+ }
+
+ return 0;
}
-
- /* Register the service record */
- if (sdp_record_register (dev->session, record, 0) < 0)
+#else
+ /**
+ * Function used for creating the service record and registering it.
+ *
+ * @param dev pointer to the device struct
+ * @param rc_channel the rfcomm channel
+ * @return 0 on success
+ */
+ static int
+ register_service (struct HardwareInfos *dev, int rc_channel)
{
- fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
- IFNAMSIZ, dev->iface, strerror (errno));
- //FIXME exit?
- return 1;
+ /**
+ * 1. initializations
+ * 2. set the service ID, class, profile information
+ * 3. make the service record publicly browsable
+ * 4. register the RFCOMM channel
+ * 5. set the name, provider and description
+ * 6. register the service record to the local SDP server
+ * 7. cleanup
+ */
+ uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
+ dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
+ const char *service_dsc = "Bluetooth plugin services";
+ const char *service_prov = "GNUnet provider";
+ 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;
+
+ record = sdp_record_alloc();
+
+ /* Set the general service ID */
+ sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
+ svc_list = sdp_list_append (0, &svc_uuid);
+ sdp_set_service_classes (record, svc_list);
+ sdp_set_service_id (record, svc_uuid);
+
+ /* Make the service record publicly browsable */
+ sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
+ root_list = sdp_list_append (0, &root_uuid);
+ sdp_set_browse_groups (record, root_list);
+
+ /* Register the RFCOMM channel */
+ sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
+ channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
+ rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
+ sdp_list_append (rfcomm_list, channel);
+ proto_list = sdp_list_append (0, rfcomm_list);
+
+ /* Set protocol information */
+ access_proto_list = sdp_list_append (0, proto_list);
+ sdp_set_access_protos (record, access_proto_list);
+
+ /* Set the name, provider, and description */
+ sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
+
+ /* Connect to the local SDP server */
+ dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
+
+ if (!dev->session)
+ {
+ fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
+ IFNAMSIZ, dev->iface, strerror (errno));
+ //FIXME exit?
+ return 1;
+ }
+
+ /* Register the service record */
+ if (sdp_record_register (dev->session, record, 0) < 0)
+ {
+ fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
+ IFNAMSIZ, dev->iface, strerror (errno));
+ //FIXME exit?
+ return 1;
+ }
+
+ /* Cleanup */
+ sdp_data_free (channel);
+ sdp_list_free (root_list, 0);
+ sdp_list_free (rfcomm_list, 0);
+ sdp_list_free (proto_list, 0);
+ sdp_list_free (access_proto_list, 0);
+ sdp_list_free (svc_list, 0);
+ sdp_record_free (record);
+
+ return 0;
}
-
- /* Cleanup */
- 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);
- sdp_record_free (record);
-
- return 0;
-}
+#endif
-/**
- * Function for searching and browsing for a service. This will return the
- * port number on which the service is running.
- * @param dev pointer to the device struct
- * @param dest target address
- * @return channel
- */
-static int
-get_channel(struct HardwareInfos *dev, bdaddr_t dest)
-{
+#ifdef MINGW
/**
- * 1. detect all nearby devices //FIXME : Connect directly to the device with the service
- * 2. for each device:
- * 2.1. connect to the SDP server running
- * 2.2. get a list of service records with the specific UUID
- * 2.3. for each service record get a list of the protocol sequences and get
- * the port number
+ * Function for searching and browsing for a service. This will return the
+ * port number on which the service is running.
+ *
+ * @param dest target address
+ * @return channel
*/
- uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- dest.b[5], dest.b[4], dest.b[3],
- dest.b[2], dest.b[1], dest.b[0]};
- sdp_session_t *session = 0;
- sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
- uuid_t svc_uuid;
- uint32_t range = 0x0000ffff;
- uint8_t channel = -1;
-
- /* Connect to the local SDP server */
- session = sdp_connect (BDADDR_ANY, &dest, 0);
- if (!session)
+ static int
+ get_channel(const char *dest)
{
- fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
- IFNAMSIZ, dev->iface, strerror (errno));
- //FIXME exit?
- return -1;
+ HANDLE h;
+ WSAQUERYSET *wqs;
+ DWORD wqs_len = sizeof (WSAQUERYSET);
+ int done = 0;
+ int channel = -1;
+ GUID guid;
+ unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
+ convert_guid ((char *) uuid, &guid);
+
+ wqs = (WSAQUERYSET*)malloc (wqs_len);
+ ZeroMemory (wqs, wqs_len);
+
+ wqs->dwSize = sizeof (WSAQUERYSET) ;
+ wqs->lpServiceClassId = &guid;
+ wqs->dwNameSpace = NS_BTH;
+ wqs->dwNumberOfCsAddrs = 0;
+ wqs->lpszContext = (LPSTR)dest;
+
+ if (SOCKET_ERROR == WSALookupServiceBegin (wqs, LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
+ {
+ if (GetLastError() == WSASERVICE_NOT_FOUND)
+ {
+ fprintf (stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
+ return -1;
+ }
+ else
+ {
+ fprintf (stderr, "Failed to find the port number: ");
+ print_last_error();
+ ExitProcess (2);
+ return -1;
+ }
+ }
+
+ /* search the sdp service */
+ while (!done)
+ {
+ if (SOCKET_ERROR == WSALookupServiceNext (h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
+ {
+ int error = WSAGetLastError();
+
+ switch (error)
+ {
+ case WSAEFAULT:
+ free (wqs);
+ wqs = (WSAQUERYSET*)malloc (wqs_len);
+ break;
+ case WSANO_DATA:
+ fprintf (stderr, "Failed! The address was valid but there was no data record of requested type\n");
+ done = 1;
+ break;
+ case WSA_E_NO_MORE:
+ done = 1;
+ break;
+ default:
+ fprintf (stderr, "Failed to look over the services: ");
+ print_last_error();
+ WSALookupServiceEnd (h);
+ ExitProcess (2);
+ }
+ }
+ else
+ {
+ channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
+ }
+ }
+
+ free (wqs) ;
+ WSALookupServiceEnd (h);
+
+ return channel;
}
-
- sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
- search_list = sdp_list_append (0, &svc_uuid);
- attrid_list = sdp_list_append (0, &range);
-
- if (sdp_service_search_attr_req (session, search_list,
- SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
+#else
+ /**
+ * Function used for searching and browsing for a service. This will return the
+ * port number on which the service is running.
+ *
+ * @param dev pointer to the device struct
+ * @param dest target address
+ * @return channel
+ */
+ static int
+ get_channel(struct HardwareInfos *dev, bdaddr_t dest)
{
- for (it = response_list; it; it = it->next)
+ /**
+ * 1. detect all nearby devices
+ * 2. for each device:
+ * 2.1. connect to the SDP server running
+ * 2.2. get a list of service records with the specific UUID
+ * 2.3. for each service record get a list of the protocol sequences and get
+ * the port number
+ */
+ uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ dest.b[5], dest.b[4], dest.b[3],
+ dest.b[2], dest.b[1], dest.b[0]};
+ sdp_session_t *session = 0;
+ sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
+ uuid_t svc_uuid;
+ uint32_t range = 0x0000ffff;
+ uint8_t channel = -1;
+
+ /* Connect to the local SDP server */
+ session = sdp_connect (BDADDR_ANY, &dest, 0);
+ if (!session)
{
- sdp_record_t *record = (sdp_record_t*) it->data;
- //TODO print some record informations to be sure everything is good
- sdp_list_t *proto_list = 0;
- if (sdp_get_access_protos (record, &proto_list) == 0)
+ fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
+ IFNAMSIZ, dev->iface, strerror (errno));
+ return -1;
+ }
+
+ sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
+ search_list = sdp_list_append (0, &svc_uuid);
+ attrid_list = sdp_list_append (0, &range);
+
+ if (sdp_service_search_attr_req (session, search_list,
+ SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
+ {
+ for (it = response_list; it; it = it->next)
{
- channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
- sdp_list_free (proto_list, 0);
+ sdp_record_t *record = (sdp_record_t*) it->data;
+ sdp_list_t *proto_list = 0;
+ if (sdp_get_access_protos (record, &proto_list) == 0)
+ {
+ channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
+ sdp_list_free (proto_list, 0);
+ }
+ sdp_record_free (record);
}
- sdp_record_free (record);
}
+
+ sdp_list_free (search_list, 0);
+ sdp_list_free (attrid_list, 0);
+ sdp_list_free (response_list, 0);
+
+ sdp_close (session);
+
+ if (channel == -1)
+ fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
+ IFNAMSIZ, dev->iface, strerror (errno));
+
+ return channel;
}
-
- sdp_list_free (search_list, 0);
- sdp_list_free (attrid_list, 0);
- sdp_list_free (response_list, 0);
-
- sdp_close (session);
-
- if (channel == -1)
- fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
- IFNAMSIZ, dev->iface, strerror (errno));
-
- return channel;
-}
+#endif
/**
* Read from the socket and put the result into the buffer for transmission to 'stdout'.
+ *
* @param sock file descriptor for reading
* @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
* followed by the actual payload
* @return number of bytes written to 'buf'
*/
static ssize_t
-read_from_the_socket (int sock,
- unsigned char *buf, size_t buf_size,
+read_from_the_socket (void *sock,
+ unsigned char *buf, size_t buf_size,
struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
{
- /**
- * 1. Read from the socket in a temporary buffer (check for errors)
- * 2. Detect if the crc exists
- * 3. Write the result to the buffer
- */
unsigned char tmpbuf[buf_size];
ssize_t count;
- int len;
- struct sockaddr_rc rc_addr = { 0 };
-
- count = read (sock, tmpbuf, buf_size);
+ #ifdef MINGW
+ count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
+ #else
+ count = read (*((int *)sock), tmpbuf, buf_size);
+ #endif
+
if (0 > count)
{
if (EAGAIN == errno)
return 0;
-
- fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
- return -1;
- }
-
- /* Get the channel used */
- memset (&rc_addr, 0, sizeof (rc_addr));
- len = sizeof (rc_addr);
- if (0 > getsockname (sock, (struct sockaddr *) &rc_addr, (socklen_t *) &len))
- {
- fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
+ #if MINGW
+ print_last_error();
+ #else
+ fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
+ #endif
+
return -1;
}
- memset (ri, 0, sizeof (*ri));
- ri->ri_channel = rc_addr.rc_channel;
-
- /* detect CRC32 at the end */
+ #ifdef LINUX
+ /* Get the channel used */
+ int len;
+ struct sockaddr_rc rc_addr = { 0 };
+
+ memset (&rc_addr, 0, sizeof (rc_addr));
+ len = sizeof (rc_addr);
+ if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
+ {
+ fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
+ return -1;
+ }
+
+ memset (ri, 0, sizeof (*ri));
+ ri->ri_channel = rc_addr.rc_channel;
+ #endif
+
+ /* Detect CRC32 at the end */
if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
{
count -= sizeof(uint32_t);
*/
static int
open_device (struct HardwareInfos *dev)
-{
- /**
- * 1. Open a HCI socket (if RFCOMM protocol is used. If not, the HCI socket is
- * saved in dev->rfcomm).
- * 2. Find the device id (request a list with all the devices and find the one
- * with the dev->iface name)
- * 3. If the interface is down try to get it up
- * 4. Bind the RFCOMM socket to the interface using the bind_socket() method and register
- * a SDP service
- * 5. For now use a hard coded port number(channel) value
- * FIXME : if I use HCI sockets , should I enable RAW_SOCKET MODE?!?!?!
- */
-
- int i, dev_id = -1, fd_hci;
- struct
- {
- struct hci_dev_list_req list;
- struct hci_dev_req dev[HCI_MAX_DEV];
- } request; //used for detecting the local devices
- struct sockaddr_rc rc_addr = { 0 }; //used for binding
-
- fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+{
+ #ifdef MINGW
+ SOCKADDR_BTH addr;
- if (fd_hci < 0)
- {
- fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
- return -1;
- }
-
- memset (&request, 0, sizeof(request));
- request.list.dev_num = HCI_MAX_DEV;
+ /* bind the RFCOMM socket to the interface */
+ addr.addressFamily = AF_BTH;
+ addr.btAddr = 0;
+ addr.port = BT_PORT_ANY;
- if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
- {
- fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
- IFNAMSIZ, dev->iface, strerror (errno));
- return 1;
- }
-
- /* Search for a device with dev->iface name */
- for (i = 0; i < request.list.dev_num; i++)
- {
- struct hci_dev_info dev_info;
+ if (GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH), 0) != GNUNET_OK)
+ {
+ fprintf (stderr, "Failed to bind the socket: ");
+ if (GetLastError() == WSAENETDOWN)
+ {
+ fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
+ ExitProcess (2);
+ }
+ print_last_error();
+ return -1;
+ }
+
+ /* start listening on the socket */
+ if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
+ {
+ fprintf (stderr, "Failed to listen on the socket: ");
+ print_last_error();
+ return -1;
+ }
- memset (&dev_info, 0, sizeof(struct hci_dev_info));
- dev_info.dev_id = request.dev[i].dev_id;
- strncpy (dev_info.name, dev->iface, IFNAMSIZ);
+ /* register the sdp service */
+ if (register_service(dev) != 0)
+ {
+ fprintf (stderr, "Failed to register a service: ");
+ print_last_error();
+ return 1;
+ }
+ #else
+ int i, dev_id = -1, fd_hci;
+ struct
+ {
+ struct hci_dev_list_req list;
+ struct hci_dev_req dev[HCI_MAX_DEV];
+ } 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;
- if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
+ /* Open a HCI socket */
+ fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+
+ if (fd_hci < 0)
+ {
+ fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
+ return -1;
+ }
+
+ memset (&request, 0, sizeof(request));
+ request.list.dev_num = HCI_MAX_DEV;
+
+ if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
{
- fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
- IFNAMSIZ, dev->iface, strerror (errno));
+ fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
+ IFNAMSIZ, dev->iface, strerror (errno));
return 1;
}
- if (strcmp (dev_info.name, dev->iface) == 0)
+ /* Search for a device with dev->iface name */
+ for (i = 0; i < request.list.dev_num; i++)
{
- 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
- */
- memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
+ struct hci_dev_info dev_info;
+
+ memset (&dev_info, 0, sizeof(struct hci_dev_info));
+ dev_info.dev_id = request.dev[i].dev_id;
+ strncpy (dev_info.name, dev->iface, IFNAMSIZ);
- /* Check if the interface is UP */
- if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
+ if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
{
- /* Bring interface up */ //FIXME should I check if is HCI_RUNNING ?!?!??!
- if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
- {
- fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
- IFNAMSIZ, dev->iface, strerror (errno));
- return 1;
- }
+ fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
+ IFNAMSIZ, dev->iface, strerror (errno));
+ return 1;
}
- /* Check if the device is discoverable */
- if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
- hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
+ if (strcmp (dev_info.name, dev->iface) == 0)
{
- /* Set interface Page Scan and Inqury Scan ON */
- struct hci_dev_req dev_req;
-
- memset (&dev_req, 0, sizeof (dev_req));
- dev_req.dev_id = dev_info.dev_id;
- dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
- if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
- {
- fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
- IFNAMSIZ, dev->iface, strerror (errno));
- return 1;
+ dev_id = dev_info.dev_id; //the device was found
+ /**
+ * Copy the MAC address to the device structure
+ */
+ memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
+
+ /* Check if the interface is up */
+ if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
+ {
+ /* Bring the interface up */
+ if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
+ {
+ fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
+ IFNAMSIZ, dev->iface, strerror (errno));
+ return 1;
+ }
}
+ /* Check if the device is discoverable */
+ if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
+ hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
+ {
+ /* Set interface Page Scan and Inqury Scan ON */
+ struct hci_dev_req dev_req;
+
+ memset (&dev_req, 0, sizeof (dev_req));
+ dev_req.dev_id = dev_info.dev_id;
+ dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
+
+ if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
+ {
+ fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
+ IFNAMSIZ, dev->iface, strerror (errno));
+ return 1;
+ }
+
+ }
+ break;
}
- //FIXME : Sniff mode!?!
- //FIXME : RAW MODE?!?
-
- break;
}
- }
-
- /* Check if the interface was not found */
- if (dev_id == -1)
- {
- fprintf (stderr, "The interface %s was not found\n", dev->iface);
- return 1;
- }
-
- /* Close the hci socket */
- (void) close(fd_hci);
-
-
-
- /* Bind the rfcomm socket to the interface */
- memset (&rc_addr, 0, sizeof (rc_addr));
- rc_addr.rc_family = AF_BLUETOOTH;
- rc_addr.rc_bdaddr = *BDADDR_ANY;
-
- if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
- {
- fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
- dev->iface, strerror (errno));
- return 1;
- }
-
- /* Register a SDP service */
- if (register_service (dev, rc_addr.rc_channel) != 0)
- {
- fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
- dev->iface, strerror (errno));
- return 1;
- }
-
- /* Switch socket in listening mode */
- if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
- {
- fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
- dev->iface, strerror (errno));
- return 3;
- }
-
+ /* Check if the interface was not found */
+ if (dev_id == -1)
+ {
+ fprintf (stderr, "The interface %s was not found\n", dev->iface);
+ return 1;
+ }
+
+ /* Close the hci socket */
+ (void) close(fd_hci);
+
+
+
+ /* Bind the rfcomm socket to the interface */
+ memset (&rc_addr, 0, sizeof (rc_addr));
+ rc_addr.rc_family = AF_BLUETOOTH;
+ rc_addr.rc_bdaddr = *BDADDR_ANY;
+
+ if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
+ {
+ fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
+ dev->iface, strerror (errno));
+ return 1;
+ }
+
+ /* Register a SDP service */
+ if (register_service (dev, rc_addr.rc_channel) != 0)
+ {
+ fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
+ dev->iface, strerror (errno));
+ return 1;
+ }
+
+ /* Switch socket in listening mode */
+ if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
+ {
+ fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
+ dev->iface, strerror (errno));
+ return 1;
+ }
+ #endif
+
return 0;
}
mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
const struct HardwareInfos *dev)
{
- taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
- taIeeeHeader->addr2 = dev->pl_mac;
+ taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
taIeeeHeader->addr3 = mac_bssid_gnunet;
-}
-/**
- * Test if the given interface name really corresponds to a bluetooth
- * device.
- *
- * @param iface name of the interface
- * @return 0 on success, 1 on error
- **** similar with the one from gnunet-helper-transport-wlan.c ****
- */
-static int
-test_bluetooth_interface (const char *iface)
-{
- char strbuf[512];
- struct stat sbuf;
- int ret;
+ #ifdef MINGW
+ memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
+ #else
+ taIeeeHeader->addr2 = dev->pl_mac;
+ #endif
+}
- ret = snprintf (strbuf, sizeof (strbuf),
- "/sys/class/bluetooth/%s/subsystem",
- iface);
- if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
+#ifdef LINUX
+ /**
+ * Test if the given interface name really corresponds to a bluetooth
+ * device.
+ *
+ * @param iface name of the interface
+ * @return 0 on success, 1 on error
+ **** similar with the one from gnunet-helper-transport-wlan.c ****
+ */
+ static int
+ test_bluetooth_interface (const char *iface)
{
- fprintf (stderr,
- "Did not find 802.15.1 interface `%s'. Exiting.\n",
- iface);
- exit (1);
+ char strbuf[512];
+ struct stat sbuf;
+ int ret;
+
+ ret = snprintf (strbuf, sizeof (strbuf),
+ "/sys/class/bluetooth/%s/subsystem",
+ iface);
+ if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
+ {
+ fprintf (stderr,
+ "Did not find 802.15.1 interface `%s'. Exiting.\n",
+ iface);
+ exit (1);
+ }
+ return 0;
}
- return 0;
-}
+#endif
/**
* Test incoming packets mac for being our own.
/**
- * Process data from the stdin. Takes the message forces the sender MAC to be correct
- * and puts it into our buffer for transmission to the kernel. (the other device).
+ * Process data from the stdin. Takes the message, forces the sender MAC to be correct
+ * and puts it into our buffer for transmission to the receiver.
*
* @param cls pointer to the device struct ('struct HardwareInfos*')
* @param hdr pointer to the start of the packet
sendsize = ntohs (hdr->size);
if ( (sendsize <
- sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
+ sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
(GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
{
fprintf (stderr, "Received malformed message\n");
* overwrite it with OUR MAC address to prevent mischief */
mac_set (blueheader, dev);
memcpy (&blueheader->addr1, &header->frame.addr1,
- sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); //FIXME is this correct?
+ sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
write_pout.size = sendsize;
}
+#ifdef LINUX
+ /**
+ * 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 int
+ send_broadcast (struct HardwareInfos *dev, int *sendsocket)
+ {
+ 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 messages to all the devices from the list and I should search
+ * for new ones or that this is the first time when I do a search.
+ */
+ 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", IFNAMSIZ, 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", IFNAMSIZ,
+ 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", IFNAMSIZ,
+ 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", IFNAMSIZ, dev->iface);
+ return 1;
+ }
+
+ fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
+
+ if (responses == 0)
+ {
+ fprintf (stderr, "LOG : 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", IFNAMSIZ,
+ 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, "LOG : 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, "LOG : %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 already 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, "LOG : 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, "LOG : Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
+ if (errno != ECONNREFUSED) //FIXME be sure that this works
+ {
+ fprintf (stderr, "LOG : 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, "LOG : 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, "LOG : 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, "LOG : 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;
+ }
+#endif
/**
* Main function of the helper. This code accesses a bluetooth interface
* forwards traffic in both directions between the bluetooth interface and
- * stdin/stdout of this process. Error messages are written to stdout.
+ * stdin/stdout of this process. Error messages are written to stderr.
*
* @param argc number of arguments, must be 2
* @param argv arguments only argument is the name of the interface (i.e. 'hci0')
* @return 0 on success (never happens, as we don't return unless aborted), 1 on error
*
- **** same as the one from gnunet-helper-transport-wlan.c ****
+ **** similar to gnunet-helper-transport-wlan.c ****
*/
int
main (int argc, char *argv[])
-{
- struct HardwareInfos dev;
- char readbuf[MAXLINE];
- char dest[18];
- int maxfd;
- fd_set rfds;
- fd_set wfds;
- int stdin_open;
- 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];
-
- /* Assert privs so we can modify the firewall rules! */
- uid = getuid ();
-#ifdef HAVE_SETRESUID
- if (0 != setresuid (uid, 0, 0))
- {
- fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
- return 254;
- }
-#else
- if (0 != seteuid (0))
- {
- fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
- return 254;
- }
-#endif
-
- /* Make use of SGID capabilities on POSIX */
- memset (&dev, 0, sizeof (dev));
- dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- raw_eno = errno; /* remember for later */
+{
+#ifdef LINUX
+ struct HardwareInfos dev;
+ char readbuf[MAXLINE];
+ int maxfd;
+ fd_set rfds;
+ fd_set wfds;
+ int stdin_open;
+ struct MessageStreamTokenizer *stdin_mst;
+ int raw_eno, i;
+ uid_t uid;
+ 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
+ if (0 != setresuid (uid, 0, 0))
+ {
+ fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
+ return 254;
+ }
+ #else
+ if (0 != seteuid (0))
+ {
+ fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
+ return 254;
+ }
+ #endif
- /* Now that we've dropped root rights, we can do error checking */
- if (2 != argc)
- {
- fprintf (stderr, "You must specify the name of the interface as the first \
- and only argument to this program.\n");
- if (-1 != dev.fd_rfcomm)
- (void) close (dev.fd_rfcomm);
- return 1;
- }
+ /* Make use of SGID capabilities on POSIX */
+ memset (&dev, 0, sizeof (dev));
+ dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+ raw_eno = errno; /* remember for later */
- if (-1 == dev.fd_rfcomm)
- {
- fprintf (stderr, "Failed to create a HCI socket: %s\n", strerror (raw_eno));
- return 1;
- }
- if (dev.fd_rfcomm >= FD_SETSIZE)
- {
- fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
- dev.fd_rfcomm, FD_SETSIZE);
- (void) close (dev.fd_rfcomm);
- return 1;
- }
- if (0 != test_bluetooth_interface (argv[1]))
- {
- (void) close (dev.fd_rfcomm);
- return 1;
- }
- strncpy (dev.iface, argv[1], IFNAMSIZ);
- if (0 != open_device (&dev))
- {
- (void) close (dev.fd_rfcomm);
- return 1;
- }
-
- /* Drop privs */
- {
- uid_t uid = getuid ();
-#ifdef HAVE_SETRESUID
- if (0 != setresuid (uid, uid, uid))
+ /* Now that we've dropped root rights, we can do error checking */
+ if (2 != argc)
{
- fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
+ fprintf (stderr, "You must specify the name of the interface as the first \
+ and only argument to this program.\n");
if (-1 != dev.fd_rfcomm)
- (void) close (dev.fd_rfcomm);
+ (void) close (dev.fd_rfcomm);
return 1;
}
-#else
- if (0 != (setuid (uid) | seteuid (uid)))
+
+ if (-1 == dev.fd_rfcomm)
{
- fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
- if (-1 != dev.fd_rfcomm)
- (void) close (dev.fd_rfcomm);
+ fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
return 1;
}
-#endif
- }
-
-
- /* Send MAC address of the bluetooth interface to STDOUT first */
- {
- struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
-
- macmsg.hdr.size = htons (sizeof (macmsg));
- macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
- memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
- memcpy (write_std.buf, &macmsg, sizeof (macmsg));
- write_std.size = sizeof (macmsg);
- }
-
-
- stdin_mst = mst_create (&stdin_send_hw, &dev);
- stdin_open = 1;
- while (1)
- {
- maxfd = -1;
- FD_ZERO (&rfds);
- if ((0 == write_pout.size) && (1 == stdin_open))
+ if (dev.fd_rfcomm >= FD_SETSIZE)
{
- FD_SET (STDIN_FILENO, &rfds);
- maxfd = MAX (maxfd, STDIN_FILENO);
+ fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
+ dev.fd_rfcomm, FD_SETSIZE);
+ (void) close (dev.fd_rfcomm);
+ return 1;
}
- if (0 == write_std.size)
+ if (0 != test_bluetooth_interface (argv[1]))
{
- FD_SET (dev.fd_rfcomm, &rfds);
- maxfd = MAX (maxfd, dev.fd_rfcomm);
+ (void) close (dev.fd_rfcomm);
+ return 1;
}
- FD_ZERO (&wfds);
- if (0 < write_std.size)
+ strncpy (dev.iface, argv[1], IFNAMSIZ);
+ if (0 != open_device (&dev))
{
- FD_SET (STDOUT_FILENO, &wfds);
- maxfd = MAX (maxfd, STDOUT_FILENO);
+ (void) close (dev.fd_rfcomm);
+ return 1;
}
-
- for (i = 0; i < crt_rfds; i++)
+
+ /* Drop privs */
{
- FD_SET (rfds_list[i], &rfds);
- maxfd = MAX (maxfd, rfds_list[i]);
+ uid_t uid = getuid ();
+ #ifdef HAVE_SETRESUID
+ if (0 != setresuid (uid, uid, uid))
+ {
+ fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
+ if (-1 != dev.fd_rfcomm)
+ (void) close (dev.fd_rfcomm);
+ return 1;
+ }
+ #else
+ if (0 != (setuid (uid) | seteuid (uid)))
+ {
+ fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
+ if (-1 != dev.fd_rfcomm)
+ (void) close (dev.fd_rfcomm);
+ return 1;
+ }
+ #endif
}
- for (i = 0; i < crt_wfds; i++)
+ /* Send MAC address of the bluetooth interface to STDOUT first */
{
- FD_SET (wfds_list[i], &wfds);
- maxfd = MAX (maxfd, wfds_list[i]);
+ struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
+
+ macmsg.hdr.size = htons (sizeof (macmsg));
+ macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
+ memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
+ memcpy (write_std.buf, &macmsg, sizeof (macmsg));
+ write_std.size = sizeof (macmsg);
}
+
+
+ stdin_mst = mst_create (&stdin_send_hw, &dev);
+ stdin_open = 1;
- if (0 < write_pout.size)
+ /**
+ * TODO : 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)
{
- int sendsocket, status;
- struct sockaddr_rc addr = { 0 };
- struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
-
- memset (dest, 0, sizeof (dest));
-
- sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-
- if (sendsocket < 0)
+ maxfd = -1;
+ broadcast = 0;
+ sendsocket = -1;
+
+ FD_ZERO (&rfds);
+ if ((0 == write_pout.size) && (1 == stdin_open))
{
- fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
- strerror (errno));
- return -1;
+ FD_SET (STDIN_FILENO, &rfds);
+ maxfd = MAX (maxfd, STDIN_FILENO);
}
-
- /* Get the destination address */
- //FIXME : not sure if this is correct
- frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
- 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);
- */
- status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
- if (0 != status && errno != EAGAIN)
- {
- //fprintf (stderr, "connect error on %s\n", argv[1]);
- perror("Connect error");
- 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
+ if (0 == write_std.size)
{
- fprintf (stderr, "The limit for the write file descriptors list was \
- reached\n");
- break;
+ FD_SET (dev.fd_rfcomm, &rfds);
+ maxfd = MAX (maxfd, dev.fd_rfcomm);
}
- }
- {
- int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
- if ((-1 == retval) && (EINTR == errno))
- continue;
- if (0 > retval)
+
+ for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
{
- fprintf (stderr, "select failed: %s\n", strerror (errno));
- break;
+ FD_SET (rfds_list[i], &rfds);
+ maxfd = MAX (maxfd, rfds_list[i]);
}
- }
-
- for (i = 0; i <= maxfd; i++)
- {
- if (FD_ISSET (i , &wfds))
+ FD_ZERO (&wfds);
+ if (0 < write_std.size)
+ {
+ FD_SET (STDOUT_FILENO, &wfds);
+ maxfd = MAX (maxfd, STDOUT_FILENO);
+ }
+ 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 */
+ frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
+
+ if (memcmp (&frame->addr1, &dev.pl_mac,
+ sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
+ {
+ broadcast = 1;
+ memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
+ }
+ else if (memcmp (&frame->addr1, &broadcast_address,
+ sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
+ {
+ fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
+
+ 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, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
+ }
+ else
+ {
+ FD_SET (sendsocket, &wfds);
+ maxfd = MAX (maxfd, sendsocket);
+ }
+ }
+ else
+ {
+ int found = 0;
+ int pos = 0;
+ /* Search if the address already exists on the list */
+ for (i = 0; i < neighbours.size; i++)
+ {
+ if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
+ {
+ pos = i;
+ if (neighbours.fds[i] != -1)
+ {
+ found = 1; //save the position where it was found
+ 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 };
+
+ 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);
+
+ 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, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
+ tries++;
+ goto connect_retry;
+ }
+ else if (errno == EBADF)
+ {
+ fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
+ memset (&write_pout, 0, sizeof (write_pout));
+ broadcast = 1;
+ }
+ else
+ {
+ fprintf (stderr, "LOG : %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, "LOG : Connection successful\n");
+ if (pos != 0) // save the socket
+ {
+ neighbours.fds[pos] = sendsocket;
+ }
+ else
+ {
+ /* 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");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (broadcast == 0)
{
- if (i == STDOUT_FILENO)
+ /* Select a fd which is ready for action :) */
+ {
+ int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
+ 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;
+ }
+ }
+ if (FD_ISSET (STDOUT_FILENO , &wfds))
{
ssize_t ret =
write (STDOUT_FILENO, write_std.buf + write_std.pos,
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 first check the error type?
+ {
+ fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
+ strerror (errno));
+ for (i = 0; i < neighbours.size; i++)
+ {
+ if (neighbours.fds[i] == sendsocket)
+ {
+ (void) close(sendsocket);
+ neighbours.fds[i] = -1;
+ break;
+ }
+ }
+ /* Remove the message */
+ memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
+ write_pout.pos = 0 ;
+ write_pout.size = 0;
+ }
+ else
+ {
+ 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);
+ break;
+ }
+
+ if (write_pout.pos == write_pout.size)
+ {
+ write_pout.pos = 0;
+ write_pout.size = 0;
+ }
+ fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
+ }
+ }
+ }
+ for (i = 0; i <= maxfd; i++)
+ {
+ if (FD_ISSET (i, &rfds))
+ {
+ if (i == STDIN_FILENO)
+ {
+ ssize_t ret =
+ read (i, readbuf, sizeof (readbuf));
+ if (0 > ret)
+ {
+ fprintf (stderr,
+ "Read error from STDIN: %s\n",
+ strerror (errno));
+ break;
+ }
+ if (0 == ret)
+ {
+ /* stop reading... */
+ stdin_open = 0;
+ }
+ 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)
+ {
+ int readsocket;
+ struct sockaddr_rc addr = { 0 };
+ unsigned int opt = sizeof (addr);
+
+ readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
+ fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
+ if (readsocket == -1)
+ {
+ fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
+ strerror (errno));
+ break;
+ }
+ else
+ {
+ FD_SET (readsocket, &rfds);
+ maxfd = MAX (maxfd, readsocket);
+
+ if (crt_rfds < MAX_PORTS)
+ rfds_list[crt_rfds++] = readsocket;
+ else
+ {
+ fprintf (stderr, "The limit for the read file descriptors list was \
+ reached\n");
+ break;
+ }
+ }
+
+ }
+ else
+ {
+ 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 ((void *)&i, (unsigned char *) &rrm->frame,
+ sizeof (write_std.buf)
+ - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+ + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
+ rrm);
+ if (0 >= ret)
+ {
+ 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)))
+ {
+ write_std.size = ret
+ + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+ - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
+ rrm->header.size = htons (write_std.size);
+ rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
+ }
+ }
+ }
+ }
+ }
+ }
+ /* Error handling, try to clean up a bit at least */
+ mst_destroy (stdin_mst);
+ 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 < neighbours.size; i++)
+ (void) close (neighbours.fds[i]);
+ #else
+ struct HardwareInfos dev;
+ struct GNUNET_NETWORK_Handle *sendsocket;
+ struct GNUNET_NETWORK_FDSet *rfds;
+ struct GNUNET_NETWORK_FDSet *wfds;
+ struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
+ char readbuf[MAXLINE] = { 0 };
+ SOCKADDR_BTH acc_addr = { 0 };
+ int addr_len = sizeof (SOCKADDR_BTH);
+ int broadcast, i, stdin_open, crt_rfds = 0;
+ HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
+ HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
+ struct MessageStreamTokenizer *stdin_mst;
+
+ /* check the handles */
+ if (stdin_handle == INVALID_HANDLE_VALUE)
+ {
+ fprintf (stderr, "Failed to get the stdin handle\n");
+ ExitProcess (2);
+ }
+
+ if (stdout_handle == INVALID_HANDLE_VALUE)
+ {
+ fprintf (stderr, "Failed to get the stdout handle\n");
+ ExitProcess (2);
+ }
+
+ /* initialize windows sockets */
+ initialize_windows_sockets();
+
+ // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
+ // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
+ // {
+ // fprintf (stderr, "AF_BTH family is not supported\n");
+ // ExitProcess (2);
+ // }
+
+ /* create the socket */
+ dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
+ if (dev.handle == NULL)
+ {
+ fprintf (stderr, "Failed to create RFCOMM socket: ");
+ print_last_error();
+ ExitProcess (2);
+ }
+
+
+ if (open_device (&dev) == -1)
+ {
+ fprintf (stderr, "Failed to open the device\n");
+ print_last_error();
+ if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
+ {
+ fprintf (stderr, "Failed to close the socket!\n");
+ print_last_error();
+ }
+ ExitProcess (2);
+ }
+
+ if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
+ {
+ fprintf (stderr, "Failed to change the socket mode\n");
+ ExitProcess (2);
+ }
+
+ memset (&write_std, 0, sizeof (write_std));
+ memset (&write_pout, 0, sizeof (write_pout));
+ stdin_open = 1;
+
+ rfds = GNUNET_NETWORK_fdset_create ();
+ wfds = GNUNET_NETWORK_fdset_create ();
+
+ /* Send MAC address of the bluetooth interface to STDOUT first */
+ {
+ struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
+
+ macmsg.hdr.size = htons (sizeof (macmsg));
+ macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
+ memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
+ memcpy (write_std.buf, &macmsg, sizeof (macmsg));
+ write_std.size = sizeof (macmsg);
+ }
+
+
+ stdin_mst = mst_create (&stdin_send_hw, &dev);
+ stdin_open = 1;
+
+ int pos = 0;
+ int stdin_pos = -1;
+ int stdout_pos = -1;
+ while (1)
+ {
+ broadcast = 0;
+ pos = 0;
+ stdin_pos = -1;
+ stdout_pos = -1;
+ sendsocket = NULL; //FIXME ???memleaks
+
+ GNUNET_NETWORK_fdset_zero (rfds);
+ if ((0 == write_pout.size) && (1 == stdin_open))
+ {
+ stdin_pos = pos;
+ pos +=1;
+ GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
+ }
+
+ if (0 == write_std.size)
+ {
+ pos += 1;
+ GNUNET_NETWORK_fdset_set (rfds, dev.handle);
+ }
+
+ for (i = 0; i < crt_rfds; i++)
+ {
+ pos += 1;
+ GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
+ }
+
+ GNUNET_NETWORK_fdset_zero (wfds);
+ if (0 < write_std.size)
+ {
+ stdout_pos = pos;
+ GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
+ // printf ("%s\n", write_std.buf);
+ // memset (write_std.buf, 0, write_std.size);
+ // write_std.size = 0;
+ }
+
+ if (0 < write_pout.size)
+ {
+ if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
+ fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
+ // skip the message
+ broadcast = 1;
+ memset (write_pout.buf, 0, write_pout.size);
+ 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)
+ SOCKADDR_BTH addr;
+ fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
+ sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
+
+ if (sendsocket == NULL)
{
- fprintf (stderr, "Failed to write to bluetooth device: %s\n",
- strerror (errno));
- break;
+ fprintf (stderr, "Failed to create RFCOMM socket: \n");
+ print_last_error();
+ ExitProcess (2);
}
- write_pout.pos += ret;
- if ((write_pout.pos != write_pout.size) && (0 != ret))
+
+ memset (&addr, 0, sizeof (addr));
+ //addr.addressFamily = AF_BTH;
+ if (SOCKET_ERROR ==
+ WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
{
- /* 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);
- break;
+ fprintf (stderr, "Failed to translate the address: ");
+ print_last_error();
+ ExitProcess ( 2 ) ;
}
- if (write_pout.pos == write_pout.size)
+ addr.port = get_channel (argv[1]);
+ if (addr.port == -1)
{
- write_pout.pos = 0;
+ fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
+ memset (write_pout.buf, 0, write_pout.size);
write_pout.size = 0;
- (void) close (i);
+ broadcast = 1; //skipping the select part
+ }
+ else
+ {
+ if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
+ {
+ fprintf (stderr, "Failed to connect: ");
+ print_last_error();
+ ExitProcess (2);
+ }
+
+ if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
+ {
+ fprintf (stderr, "Failed to change the socket mode\n");
+ ExitProcess (2);
+ }
+
+ GNUNET_NETWORK_fdset_set (wfds, sendsocket);
}
}
}
-
- if (FD_ISSET (i, &rfds))
+
+ if (broadcast == 0)
{
- if (i == STDIN_FILENO)
+ int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
+ if (retval < 0)
{
- ssize_t ret =
- read (i, readbuf, sizeof (readbuf));
- if (0 > ret)
+ fprintf (stderr, "Select error\n");
+ ExitProcess (2);
+ }
+ //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
+ if (retval == stdout_pos)
+ {
+ fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
+ //ssize_t ret;
+ //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
+ //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
+ DWORD ret;
+ if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
{
- fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
+ fprintf (stderr, "Failed to write to STDOUT: ");
+ print_last_error();
+ break;
+ }
+
+ if (ret <= 0)
+ {
+ fprintf (stderr, "Failed to write to STDOUT\n");
+ ExitProcess (2);
+ }
+
+ write_std.pos += ret;
+ if (write_std.pos == write_std.size)
+ {
+ write_std.pos = 0;
+ write_std.size = 0;
+ }
+ }
+ if (sendsocket != NULL)
+ {
+ if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
+ {
+ ssize_t ret;
+ ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos,
+ write_pout.size - write_pout.pos);
+
+ if (GNUNET_SYSERR == ret)
+ {
+ fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
+ print_last_error();
+ if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
+ {
+ fprintf (stderr, "Failed to close the sendsocket!\n");
+ print_last_error();
+ }
+ ExitProcess (2);
+ }
+ else
+ {
+ 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);
+ break;
+ }
+
+ if (write_pout.pos == write_pout.size)
+ {
+ write_pout.pos = 0;
+ write_pout.size = 0;
+
+ }
+ fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
+ }
+ }
+ }
+
+ //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
+ if (retval == stdin_pos)
+ {
+ //ssize_t ret;
+ //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
+ //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
+ DWORD ret;
+ if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL)) /* do nothing asynchronous */
+ {
+ fprintf (stderr, "Read error from STDIN: ");
+ print_last_error();
break;
}
if (0 == ret)
{
/* stop reading... */
stdin_open = 0;
+ } else {
+ mst_receive (stdin_mst, readbuf, ret);
+ fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
}
- mst_receive (stdin_mst, readbuf, ret);
- }
- else if (i == dev.fd_rfcomm)
+ }
+ else
+ if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
{
- int readsocket;
- struct sockaddr_rc addr = { 0 };
- unsigned int opt = sizeof (addr);
-
- readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
-
- if (readsocket == -1)
+ fprintf (stderr, "LOG: accepting connection\n");
+ struct GNUNET_NETWORK_Handle *readsocket;
+ readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
+ if (readsocket == NULL)
{
- fprintf (stderr, "Failed to accept a connection on interface: %s\n",
- strerror (errno));
- return -1;
- } else {
- FD_SET (readsocket, &rfds);
- maxfd = MAX (maxfd, readsocket);
-
+ fprintf (stderr, "Accept error %d: ", GetLastError());
+ print_last_error();
+ ExitProcess (2);
+ }
+ else
+ {
+ if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
+ {
+ fprintf (stderr, "Failed to change the socket mode\n");
+ ExitProcess (2);
+ }
+ GNUNET_NETWORK_fdset_set (rfds, readsocket);
+
if (crt_rfds < MAX_PORTS)
rfds_list[crt_rfds++] = readsocket;
else
{
- fprintf (stderr, "The limit for the read file descriptors list was \
- reached\n");
+ fprintf (stderr, "The limit for the read file descriptors list was reached\n");
break;
}
}
-
- }
- else
+ }
+ else
+ for (i = 0; i < crt_rfds; i++)
{
- struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
- ssize_t ret;
-
- rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
- ret =
- read_from_the_socket (i, (unsigned char *) &rrm->frame,
- sizeof (write_std.buf)
- - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
- + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
- rrm);
- if (0 > ret)
+ if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
{
- fprintf (stderr, "Read error from rfcomm socket: %s\n", strerror (errno));
+ struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
+ ssize_t ret;
+ fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
+ rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
+ ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
+ sizeof (write_std.buf)
+ - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+ + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
+ rrm);
+ if (0 >= ret)
+ {
+
+ //TODO remove the socket from the list
+ if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
+ {
+ fprintf (stderr, "Failed to close the sendsocket!\n");
+ print_last_error();
+ }
+
+ fprintf (stderr, "Read error from raw socket: ");
+ print_last_error();
+ break;
+
+ }
+ if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
+ {
+ write_std.size = ret
+ + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+ - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
+ rrm->header.size = htons (write_std.size);
+ rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
+ }
break;
}
- if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
- {
- write_std.size = ret
- + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
- - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
- rrm->header.size = htons (write_std.size);
- rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
- }
- }
+ }
}
}
- }
- /* Error handling, try to clean up a bit at least */
- mst_destroy (stdin_mst);
- sdp_close (dev.session);
-
- (void) close (dev.fd_rfcomm);
- for (i = 0; i < crt_rfds; i++)
- (void) close (rfds_list[i]);
+
+ mst_destroy (stdin_mst);
+ stdin_mst = NULL;
- for (i = 0; i < crt_wfds; i++)
- (void) close (wfds_list[i]);
+ if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
+ {
+ fprintf (stderr, "Failed to close the socket!\n");
+ print_last_error();
+ }
+ for (i = 0; i < crt_rfds; i++)
+ {
+ if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
+ {
+ fprintf (stderr, "Failed to close the socket!\n");
+ print_last_error();
+ }
+ }
+
+ WSACleanup();
+ #endif
return 1; /* we never exit 'normally' */
-
- /**
- *TODO
- * 1. check if the rate from get_wlan_header (plugin_transport_bluetooth.c) is correct
- * 2.
- */
}
-
-
-