X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fgnunet-helper-transport-bluetooth.c;h=2170221907192f37780006c8b99698cd2daa5a2c;hb=5268a6fed72de00832cf075f480c03fe86952bb6;hp=48e63dd7599c092219eae30ba0e08d1ad151ef5a;hpb=b276d3ef3ab34b24cd45ad3a10391929482607b0;p=oweals%2Fgnunet.git diff --git a/src/transport/gnunet-helper-transport-bluetooth.c b/src/transport/gnunet-helper-transport-bluetooth.c index 48e63dd75..217022190 100644 --- a/src/transport/gnunet-helper-transport-bluetooth.c +++ b/src/transport/gnunet-helper-transport-bluetooth.c @@ -1,45 +1,54 @@ /* This file is part of GNUnet. - (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors) + Copyright (C) 2010, 2011, 2012 GNUnet e.V. Copyright (c) 2007, 2008, Andy Green - Copyright (C) 2009 Thomas d'Otreppe + Copyright Copyright (C) 2009 Thomas d'Otreppe - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + SPDX-License-Identifier: AGPL3.0-or-later */ #include "gnunet_config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#ifdef MINGW + #include "platform.h" + #include "gnunet_util_lib.h" + #include + #include +#else + #define SOCKTYPE int + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +#endif -#include "gnunet_protocols.h" #include "plugin_transport_wlan.h" +#include "gnunet_protocols.h" + /** * Maximum number of ports assignable for RFCOMMM protocol. @@ -54,9 +63,43 @@ /** - * Maximum number of loops without inquiring for a new devices. + * 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 + +/** + * In bluez library, the maximum name length of a device is 8 */ -#define MAX_LOOPS 3 +#define BLUEZ_DEVNAME_SIZE 8 /** * struct for storing the information of the hardware. There is only @@ -64,26 +107,37 @@ */ struct HardwareInfos { + /** + * Name of the interface, not necessarily 0-terminated (!). + */ + char iface[IFNAMSIZ]; + #ifdef MINGW /** - * file descriptor for the rfcomm socket + * socket handle */ - int fd_rfcomm; + struct GNUNET_NETWORK_Handle *handle; /** - * Name of the interface, not necessarily 0-terminated (!). + * 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. */ struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac; - + /** * SDP session */ sdp_session_t *session ; + #endif }; /** @@ -102,7 +156,7 @@ struct SendBuffer * destination? Always smaller than 'size'. */ size_t pos; - + /** * Buffered data; twice the maximum allowed message size as we add some * headers. @@ -110,29 +164,42 @@ struct SendBuffer 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]; +#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; -}; + /* 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 @@ -144,20 +211,8 @@ static struct SendBuffer write_pout; */ 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}}; - -/** - * 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 ****** */ +/* ****** 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 @@ -178,10 +233,10 @@ static int searching_devices_count = 0; * @param cls closure * @param message the actual message */ -typedef void (*MessageTokenizerCallback) (void *cls, - const struct - GNUNET_MessageHeader * - message); +typedef void (*MessageTokenizerCallback) (void *cls, + const struct + GNUNET_MessageHeader * + message); /** * Handle to a message stream tokenizer. @@ -231,7 +286,7 @@ struct MessageStreamTokenizer */ static struct MessageStreamTokenizer * mst_create (MessageTokenizerCallback cb, - void *cb_cls) + void *cb_cls) { struct MessageStreamTokenizer *ret; @@ -251,7 +306,7 @@ mst_create (MessageTokenizerCallback cb, ret->cb = cb; ret->cb_cls = cb_cls; ret->pos = 0; - + return ret; } @@ -285,7 +340,7 @@ mst_receive (struct MessageStreamTokenizer *mst, do_align: if (mst->pos < mst->off) { - fprintf (stderr, "We processed too many bytes!\n"); + //fprintf (stderr, "We processed too many bytes!\n"); return GNUNET_SYSERR; } if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) || @@ -301,7 +356,7 @@ do_align: delta = GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) - (mst->pos - mst->off), size); - memcpy (&ibuf[mst->pos], buf, delta); + GNUNET_memcpy (&ibuf[mst->pos], buf, delta); mst->pos += delta; buf += delta; size -= delta; @@ -354,7 +409,7 @@ do_align: fprintf (stderr, "The size of the buffer will be exceeded!\n"); return GNUNET_SYSERR; } - memcpy (&ibuf[mst->pos], buf, delta); + GNUNET_memcpy (&ibuf[mst->pos], buf, delta); mst->pos += delta; buf += delta; size -= delta; @@ -431,14 +486,12 @@ do_align: "Assertion failed\n"); exit (1); } - memcpy (&ibuf[mst->pos], buf, size); + GNUNET_memcpy (&ibuf[mst->pos], buf, size); mst->pos += size; } return ret; } - - /** * Destroys a tokenizer. * @@ -451,11 +504,6 @@ mst_destroy (struct MessageStreamTokenizer *mst) 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 * @@ -559,205 +607,415 @@ check_crc_buf_osdep (const unsigned char *buf, size_t len) if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]) return 0; - return 1; + return 1; } -/* ************** 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 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 initialize the Windows Sockets + */ + static void + initialize_windows_sockets() { - addr->rc_channel = port; - status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc)); - if (status == 0) - return 0; + 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) ; + } } - - return -1; -} + /** + * 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) + { + 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); -/** - * 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) -{ + for (i = 0; i < 8; i++) + { + uuid->Data4[i] = bytes[i + 8]; + } + } +#endif + +#ifdef LINUX /** - * 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 + * 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; - //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, 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) + /* 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 + +#ifdef MINGW + /** + * Function used for creating the service record and registering it. + * + * @param dev pointer to the device struct + * @return 0 on success + */ + 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 */ + GNUNET_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 (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; + int channel = -1; + + /* Connect to the local SDP server */ + session = sdp_connect (BDADDR_ANY, &dest, 0); + if (!session) + { + 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) { - 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) + 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 (-1 == channel) + 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 @@ -765,214 +1023,269 @@ get_channel(struct HardwareInfos *dev, bdaddr_t dest) * @param ri where to write radiotap_rx info * @return number of bytes written to 'buf' */ -static ssize_t -read_from_the_socket (int sock, - unsigned char *buf, size_t buf_size, +static ssize_t +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); } - - memcpy (buf, tmpbuf, count); - + + GNUNET_memcpy (buf, tmpbuf, count); + return count; } + /** * Open the bluetooth interface for reading/writing * * @param dev pointer to the device struct - * @return 0 on success + * @return 0 on success, non-zero on error */ 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 - - /* 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); + #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_OK != + GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH))) + { + 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); - - if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info)) + /* register the sdp service */ + if (register_service(dev) != 0) { - fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n", - IFNAMSIZ, dev->iface, strerror (errno)); + fprintf (stderr, "Failed to register a service: "); + print_last_error(); return 1; } - - if (strcmp (dev_info.name, dev->iface) == 0) + #else + int i, dev_id = -1, fd_hci; + struct { - - dev_id = dev_info.dev_id; //the device was found - /** - * 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)); - - /* Check if the interface is UP */ - if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0) + 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; + + /* 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(HCIGETDEVLIST) on interface `%.*s' failed: %s\n", + IFNAMSIZ, + dev->iface, + strerror (errno)); + (void) close (fd_hci); + 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; + + memset (&dev_info, 0, sizeof(struct hci_dev_info)); + dev_info.dev_id = request.dev[i].dev_id; + strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE); + + 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)); + (void) close (fd_hci); + 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 (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 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 + */ + GNUNET_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)); + (void) close (fd_hci); + 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)); + (void) close (fd_hci); + 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 (-1 == dev_id) + { + fprintf (stderr, + "The interface %s was not found\n", + dev->iface); + (void) close (fd_hci); + 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; } @@ -990,37 +1303,44 @@ 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->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 + GNUNET_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. @@ -1051,8 +1371,8 @@ mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, /** - * 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 @@ -1069,13 +1389,13 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) sendsize = ntohs (hdr->size); if ( (sendsize < - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) || - (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) || + (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) { fprintf (stderr, "Received malformed message\n"); exit (1); } - sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - + sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame)); if (MAXLINE < sendsize) { @@ -1083,716 +1403,1100 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) exit (1); } header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr; - memcpy (&write_pout.buf, &header->frame, sendsize); + GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize); blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf; /* payload contains MAC address, but we don't trust it, so we'll * 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? + GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); write_pout.size = sendsize; } -/** - * 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 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; - } +#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; - /* 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) + search_for_devices: + if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0) { - fprintf (stderr, "No devices discoverable\n"); - return 1; - } - - for (i = 0; i < responses; i++) - { - int j; - int found = 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 check */ - if (i >= MAX_PORTS) + /* sanity checks */ + if (neighbours.size >= MAX_PORTS) { - fprintf (stderr, "%s reached the top limit for the discoverable devices (after inquiry)\n", dev->iface); + fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface); return 2; } - - /* Search if the address already exists on the list */ - for (j = 0; j < neighbours.size; j++) + + /* Get the device id */ + if (neighbours.dev_id == -1) { - if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0) + 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) { - found = 1; - fprintf (stderr, "the device already exists on the list\n"); //FIXME debugging message - break; + fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ, + dev->iface, strerror (errno)); + return 1; } } - if (found == 0) + devices = malloc (max_responses * sizeof (inquiry_info)); + if (devices == NULL) { - char addr[19] = { 0 }; + fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ, + dev->iface); + return 1; + } - 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)); + 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; } - } - - 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) - { + fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage - 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) + if (responses == 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; + fprintf (stderr, "LOG : No devices discoverable\n"); + return 1; } - else + + for (i = 0; i < responses; i++) { - 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! + int j; + int found = 0; + + /* sanity check */ + if (i >= MAX_PORTS) { - 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; + fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ, + dev->iface); + return 2; } - neighbours.pos += 1; + /* 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 (neighbours.pos >= neighbours.size) - neighbours.pos = 0; + if (found == 0) + { + char addr[19] = { 0 }; - loops += 1; + ba2str (&(devices +i)->bdaddr, addr); + fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message + GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t)); + } + } - if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device - return 1; + free (devices); } } - else + + 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) { - fprintf (stderr, "Search for a new device\n"); //FIXME debugging message - neighbours.pos += 1; + /* 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)); + GNUNET_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 ( (-1 < *sendsocket) && + (0 == connect (*sendsocket, + (struct sockaddr *) &addr_rc, + sizeof (addr_rc))) ) + { + 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 + + if (-1 != *sendsocket) + { + (void) close (*sendsocket); + *sendsocket = -1; + } + 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 */ + GNUNET_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) + /* Cycle on the list */ + if (neighbours.pos == neighbours.size) { - fprintf (stderr, "Force to inquiry for new devices\n"); - searching_devices_count = 0; - goto inquiry_devices; + 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 a new device wasn't found, search an old one */ + if (connection_successful == 0) { - if (neighbours.pos == neighbours.size) - neighbours.pos = 0; - - if (neighbours.pos == loop_check) + int loop_check = neighbours.pos; + while (neighbours.fds[neighbours.pos] == -1) { - 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 + if (neighbours.pos == neighbours.size) + neighbours.pos = 0; + + if (neighbours.pos == loop_check) { - return 1; // Skip the broadcast message + 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; } - neighbours.pos += 1; + *sendsocket = neighbours.fds[neighbours.pos++]; } - *sendsocket = neighbours.fds[neighbours.pos++]; + return 0; } - - 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. + * forwards traffic in both directions between the bluetooth interface and + * 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]; - 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 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; + int crt_rfds = 0, rfds_list[MAX_PORTS]; + int broadcast, sendsocket; + + /* Assert privs so we can modify the firewall rules! */ + { #ifdef HAVE_SETRESUID - if (0 != setresuid (uid, 0, 0)) - { - fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno)); - return 254; - } + uid_t uid = getuid (); + + 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; - } + 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 */ - - /* 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; - } - - 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; - } + /* 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 */ - /* 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; - - 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)) + if (dev.fd_rfcomm >= FD_SETSIZE) { - // fprintf (stderr, "LOG : %s adds STDIN to rfds\n", dev.iface); //FIXME: debugging message - 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])) { - // 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); + (void) close (dev.fd_rfcomm); + return 1; } - - for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices + strncpy (dev.iface, argv[1], IFNAMSIZ); + if (0 != open_device (&dev)) { - // 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]); + (void) close (dev.fd_rfcomm); + return 1; } - FD_ZERO (&wfds); - if (0 < write_std.size) + + /* Drop privs */ { - // fprintf (stderr, "LOG : %s adds STDOUT to wfds\n", dev.iface); //FIXME: debugging message - 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 */ - //FIXME : not sure if this is correct - frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf; - - if (memcmp (&frame->addr1, &dev.pl_mac, - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) + uid_t uid = getuid (); + #ifdef HAVE_SETRESUID + if (0 != setresuid (uid, uid, uid)) { - 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_address, - sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) + 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, "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 + fprintf (stderr, "Failed to setuid: %s\n", strerror (errno)); + if (-1 != dev.fd_rfcomm) + (void) close (dev.fd_rfcomm); + 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); + GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); + GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg)); + write_std.size = sizeof (macmsg); + } + + + stdin_mst = mst_create (&stdin_send_hw, &dev); + stdin_open = 1; + + /** + * 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) + { + maxfd = -1; + broadcast = 0; + sendsocket = -1; + + FD_ZERO (&rfds); + if ((0 == write_pout.size) && (1 == stdin_open)) + { + FD_SET (STDIN_FILENO, &rfds); + maxfd = MAX (maxfd, STDIN_FILENO); + } + if (0 == write_std.size) + { + 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 + { + FD_SET (rfds_list[i], &rfds); + maxfd = MAX (maxfd, rfds_list[i]); + } + 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) { - FD_SET (sendsocket, &wfds); - maxfd = MAX (maxfd, sendsocket); + broadcast = 1; + memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer } - } - else - { - int found = 0; - /* Search if the address already exists on the list */ - for (i = 0; i < neighbours.size; i++) + else if (memcmp (&frame->addr1, &broadcast_address, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) { - if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0 && neighbours.fds[i] != -1) + 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 { - 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; + 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); } } - if (found == 0) + else { - 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) + int found = 0; + int pos = 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; - } - - 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) + if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0) { - fprintf (stderr, "%s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno)); - memset (&write_pout, 0, sizeof (write_pout)); - broadcast = 1; + 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; + } } - else + } + 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, "%s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno)); - memset (&write_pout, 0, sizeof (write_pout)); - broadcast = 1; + fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n", + strerror (errno)); + return -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) + + GNUNET_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) { - neighbours.fds[neighbours.size] = sendsocket; - memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t)); + 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 { - fprintf (stderr, "The top limit for the discovarable devices' list was reached\n"); + 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; + GNUNET_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) - { - /* Select a fd which is ready for action :) */ + if (broadcast == 0) { - 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 + /* 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); + 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.size - write_std.pos); - if (0 > ret) + if (FD_ISSET (STDOUT_FILENO , &wfds)) { - fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno)); - break; + 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 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 + } - write_std.pos += ret; - if (write_std.pos == write_std.size) + if (-1 != sendsocket) { - write_std.pos = 0; - write_std.size = 0; + 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 + } + } } - fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message - - } - if (sendsocket != -1) - { - if (FD_ISSET (sendsocket , &wfds)) + for (i = 0; i <= maxfd; i++) { - 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? + if (FD_ISSET (i, &rfds)) { - fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n", - strerror (errno)); - - for (i = 0; i < neighbours.size; i++) + if (i == STDIN_FILENO) { - if (neighbours.fds[i] == sendsocket) + ssize_t ret = + read (i, readbuf, sizeof (readbuf)); + if (0 > ret) { - (void) close(sendsocket); - neighbours.fds[i] = -1; + 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); + } } - //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; + } + } + } + } + /* 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); + if (-1 != sendsocket) + (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); + GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy)); + GNUNET_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 + { + 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 create RFCOMM socket: \n"); + print_last_error(); + ExitProcess (2); + } + + memset (&addr, 0, sizeof (addr)); + //addr.addressFamily = AF_BTH; + if (SOCKET_ERROR == + WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len)) + { + fprintf (stderr, "Failed to translate the address: "); + print_last_error(); + ExitProcess ( 2 ) ; + } + addr.port = get_channel (argv[1]); + if (addr.port == -1) + { + 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; + broadcast = 1; //skipping the select part } else { - write_pout.pos += ret; - if ((write_pout.pos != write_pout.size) && (0 != ret)) + if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (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 connect: "); + print_last_error(); + ExitProcess (2); } - - if (write_pout.pos == write_pout.size) + + if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) ) { - write_pout.pos = 0; - write_pout.size = 0; + fprintf (stderr, "Failed to change the socket mode\n"); + ExitProcess (2); } - fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message + + GNUNET_NETWORK_fdset_set (wfds, sendsocket); } } } - for (i = 0; i <= maxfd; i++) //FIXME it should be incremented + + if (broadcast == 0) { - if (FD_ISSET (i, &rfds)) + int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_()); + if (retval < 0) + { + fprintf (stderr, "Select error\n"); + ExitProcess (2); + } + //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle)) + if (retval == stdout_pos) { - if (i == STDIN_FILENO) + 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)) { - 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) + 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) { - /* stop reading... */ - stdin_open = 0; + 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 { - mst_receive (stdin_mst, readbuf, ret); - fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message + 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 } - } - else if (i == dev.fd_rfcomm) + } + } + + //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 */ { - 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, "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 + } + } + else + if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle)) + { + 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, "Accept error %d: ", GetLastError()); + print_last_error(); + ExitProcess (2); + } + else + { + if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) ) { - fprintf (stderr, "Failed to accept a connection on interface: %s\n", - strerror (errno)); - return -1; //FIXME probably I should ignore the error and keep the process alive + 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 { - 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; - } + fprintf (stderr, "The limit for the read file descriptors list was reached\n"); + break; } - - } - else + } + } + else + for (i = 0; i < crt_rfds; i++) + { + if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i])) { struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm; ssize_t ret; - fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message + 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 (i, (unsigned char *) &rrm->frame, - sizeof (write_std.buf) - - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) - + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), - rrm); + 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) { - int j; - FD_CLR (i, &rfds); - close (i); - /* Remove the socket from the list */ - for (j = 0; j < crt_rfds; j++) + + //TODO remove the socket from the list + if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK) { - 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, "Failed to close the sendsocket!\n"); + print_last_error(); } - fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno)); + 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); + 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); - - /* 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; - } - } } + break; } } } } - } - /* 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]); - return 1; /* we never exit 'normally' */ -} + mst_destroy (stdin_mst); + stdin_mst = NULL; + 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' */ +}