From: Claudiu Olteanu Date: Wed, 18 Sep 2013 12:53:30 +0000 (+0000) Subject: Adding W32 functionality X-Git-Tag: initial-import-from-subversion-38251~7243 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=2b74f7a94df138bd6f732334033574bdc1727250;p=oweals%2Fgnunet.git Adding W32 functionality --- diff --git a/configure.ac b/configure.ac index 8646b095c..40dd0bbf5 100644 --- a/configure.ac +++ b/configure.ac @@ -368,6 +368,10 @@ then else AM_CONDITIONAL(HAVE_LIBBLUETOOTH, false) fi +if test "$build_target" = "mingw" +then + bluetooth=1 +fi # libcurl diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 9bc58bf04..9e257f068 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -68,7 +68,17 @@ endif if LINUX if HAVE_LIBBLUETOOTH - AM_LDFLAGS = -lbluetooth + BT_BIN = gnunet-helper-transport-bluetooth + BT_PLUGIN_LA = libgnunet_plugin_transport_bluetooth.la + BT_PLUGIN_TEST = test_plugin_bluetooth + BT_API_TEST = test_transport_api_bluetooth + BT_REL_TEST = test_transport_api_reliability_bluetooth + BT_UREL_TEST = test_transport_api_unreliability_bluetooth + BT_QUOTA_TEST = test_quota_compliance_bluetooth \ + test_quota_compliance_bluetooth_asymmetric +endif +else +if MINGW BT_BIN = gnunet-helper-transport-bluetooth BT_PLUGIN_LA = libgnunet_plugin_transport_bluetooth.la BT_PLUGIN_TEST = test_plugin_bluetooth @@ -175,6 +185,13 @@ gnunet_transport_wlan_receiver_LDADD = \ gnunet_helper_transport_bluetooth_SOURCES = \ gnunet-helper-transport-bluetooth.c +if MINGW + gnunet_helper_transport_bluetooth_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la + gnunet_helper_transport_bluetooth_LDFLAGS = -lws2_32 +else + gnunet_helper_transport_bluetooth_LDFLAGS = -lbluetooth +endif gnunet_transport_SOURCES = \ gnunet-transport.c diff --git a/src/transport/gnunet-helper-transport-bluetooth.c b/src/transport/gnunet-helper-transport-bluetooth.c index 3eb17de42..f171e64fa 100644 --- a/src/transport/gnunet-helper-transport-bluetooth.c +++ b/src/transport/gnunet-helper-transport-bluetooth.c @@ -20,26 +20,35 @@ 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 + #include + #include "gnunet_protocols.h" +#else + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "gnunet_protocols.h" -#include "plugin_transport_wlan.h" /** * Maximum number of ports assignable for RFCOMMM protocol. @@ -58,22 +67,55 @@ */ #define MAX_LOOPS 5 +#ifdef MINGW + /* Maximum size of the interface's name */ + #define IFNAMSIZ 16 + + /** + * A copy of the MAC Address. + */ + struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy + { + UINT8 mac[MAC_ADDR_SIZE]; + }; + + // {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. @@ -84,6 +126,7 @@ struct HardwareInfos * SDP session */ sdp_session_t *session ; + #endif }; /** @@ -110,29 +153,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 +200,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 @@ -179,9 +223,9 @@ static int searching_devices_count = 0; * @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. @@ -231,7 +275,7 @@ struct MessageStreamTokenizer */ static struct MessageStreamTokenizer * mst_create (MessageTokenizerCallback cb, - void *cb_cls) + void *cb_cls) { struct MessageStreamTokenizer *ret; @@ -437,8 +481,6 @@ do_align: return ret; } - - /** * Destroys a tokenizer. * @@ -451,11 +493,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 * @@ -564,197 +601,407 @@ check_crc_buf_osdep (const unsigned char *buf, size_t len) -/* ************** 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; + 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) ; + //FIXME : it crashes + // if (lpMsgBuf) + // free (lpMsgBuf); + } + /** + * 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 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++) + /** + * 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 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 used for creating the service record and registering it. + * + * @param dev pointer to the device struct + * @return 0 on success */ - 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) + 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; //FIXME it should be 0 for a new entry + + 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 - * 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); + //fprintf (stderr, "WSAFAULT error! (the memory allocated wasn't enought\n"); + 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; + // fprintf (stderr, "No matching service found\n"); + 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) + { + fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + //FIXME exit? + 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; + //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) + { + 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'. @@ -767,38 +1014,49 @@ get_channel(struct HardwareInfos *dev, bdaddr_t dest) * @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) { 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 */ //FIXME probably not needed anymore - 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; - + #ifdef LINUX + /* Get the channel used */ //FIXME probably not needed anymore + 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))) { @@ -818,141 +1076,174 @@ read_from_the_socket (int sock, */ static int open_device (struct HardwareInfos *dev) -{ - 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; - - /* Open a HCI socket */ - 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 hci 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; + //FIXME flags parameter + if (GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH), 0) != GNUNET_OK) + { + fprintf (stderr, "Failed to bind the socket: "); + 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++) { + 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); - 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) + if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info)) { - /* 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; - } + 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; } - 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 1; - } - + /* 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; } @@ -969,38 +1260,45 @@ static void 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. @@ -1049,7 +1347,7 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) 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"); @@ -1074,222 +1372,224 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) 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; +#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; + 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; - } + /* 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; + /* 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) + devices = malloc (max_responses * sizeof (inquiry_info)); + if (devices == NULL) { - fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ, + fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ, dev->iface); - return 2; + 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; } - /* Search if the address already exists on the list */ - for (j = 0; j < neighbours.size; j++) + for (i = 0; i < responses; i++) { - if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0) + int j; + int found = 0; + + /* sanity check */ + if (i >= MAX_PORTS) { - found = 1; - fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message - break; + 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 }; + 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)); + 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); } - } - - free (devices); } - } - - int connection_successful = 0; - struct sockaddr_rc addr_rc = { 0 }; - int errno_copy = 0; - addr_rc.rc_family = AF_BLUETOOTH; + + 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) + /* Try to connect to a new device from the list */ + while (neighbours.pos < neighbours.size) { - - 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) + /* Check if we are already connected to this device */ + if (neighbours.fds[neighbours.pos] == -1) { - 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 + 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) { - 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.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; + neighbours.pos += 1; - if (neighbours.pos >= neighbours.size) - neighbours.pos = 0; + if (neighbours.pos >= neighbours.size) + neighbours.pos = 0; - loops += 1; + loops += 1; - if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device - return 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; } } - else + + /* Cycle on the list */ + if (neighbours.pos == neighbours.size) { - 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; + 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 (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, "LOG : 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 @@ -1304,465 +1604,861 @@ send_broadcast (struct HardwareInfos *dev, int *sendsocket) */ 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 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 +{ +#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 - /* 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 */ + /* 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; - } - - /* 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 HCI 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) { - 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; + } + strncpy (dev.iface, argv[1], IFNAMSIZ); + if (0 != open_device (&dev)) + { + (void) close (dev.fd_rfcomm); + return 1; } - for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices + /* 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 } - FD_ZERO (&wfds); - if (0 < write_std.size) + + /* Send MAC address of the bluetooth interface to STDOUT first */ { - FD_SET (STDOUT_FILENO, &wfds); - maxfd = MAX (maxfd, STDOUT_FILENO); + 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); } - 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) + + 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)) + { + 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 { - 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) + FD_SET (rfds_list[i], &rfds); + maxfd = MAX (maxfd, rfds_list[i]); + } + FD_ZERO (&wfds); + if (0 < write_std.size) { - 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 + 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)); //remove the message - fprintf (stderr, "LOG : Skip the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size); - } - else + memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer + } + else if (memcmp (&frame->addr1, &broadcast_address, + sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) { - 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++) + 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, "LOG : Skip the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size); + } + else + { + FD_SET (sendsocket, &wfds); + maxfd = MAX (maxfd, sendsocket); + } + } + else { - if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0) + int found = 0; + int pos = 0; + /* Search if the address already exists on the list */ + for (i = 0; i < neighbours.size; i++) { - pos = i; - if (neighbours.fds[i] != -1) + if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0) { - 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; + 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) + if (found == 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 status; + struct sockaddr_rc addr = { 0 }; - 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 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, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface); - tries++; - goto connect_retry; + fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n", + strerror (errno)); + return -1; } - else if (errno == EBADF) + + 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) { - fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno)); - memset (&write_pout, 0, sizeof (write_pout)); - broadcast = 1; + 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, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno)); - memset (&write_pout, 0, sizeof (write_pout)); - broadcast = 1; + 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"); + } + } } - - } - else + } + } + } + + if (broadcast == 0) + { + /* 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 { - FD_SET (sendsocket, &wfds); - maxfd = MAX (maxfd, sendsocket); - fprintf (stderr, "LOG : Connection successful\n"); - if (pos != 0) // save the socket + 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) + { + fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno)); + break; + } + write_std.pos += ret; + if (write_std.pos == write_std.size) + { + write_std.pos = 0; + write_std.size = 0; + } + fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message + + } + if (sendsocket != -1) + { + if (FD_ISSET (sendsocket , &wfds)) + { + ssize_t ret = + write (sendsocket, write_pout.buf + write_std.pos, + write_pout.size - write_pout.pos); + if (0 > ret) //FIXME should I first check the error type? { - neighbours.fds[pos] = sendsocket; + 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 { - /* Add the new device to the discovered devices list */ - if (neighbours.size < MAX_PORTS) + 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) { - neighbours.fds[neighbours.size] = sendsocket; - memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t)); + fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno)); + break; 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 { - fprintf (stderr, "The top limit for the discovarable devices' list was reached\n"); + 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(); - if (broadcast == 0) + // /* 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) { - /* Select a fd which is ready for action :) */ + 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) { - 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; - } + fprintf (stderr, "Failed to close the socket!\n"); + print_last_error(); } - if (FD_ISSET (STDOUT_FILENO , &wfds)) + 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; + + fprintf (stderr, "\n-----------------------------------------------\n Check if the program exits\n-----------------------------------------------\n"); + + 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 + fprintf (stderr, "---------------------------------------------------\n"); + + GNUNET_NETWORK_fdset_zero (rfds); + if ((0 == write_pout.size) && (1 == stdin_open)) { - 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 - - } - if (sendsocket != -1) + stdin_pos = pos; + pos +=1; + fprintf (stderr, "LOG: set STDIN_FILENO\n"); + GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle); //FIXME create a GNUNET_STRUCT handle for stdin + } + + if (0 == write_std.size) { - if (FD_ISSET (sendsocket , &wfds)) + pos += 1; + fprintf (stderr, "LOG: set the listening socket %d\n", GNUNET_NETWORK_get_fd (dev.handle)); + GNUNET_NETWORK_fdset_set (rfds, dev.handle); + } + + for (i = 0; i < crt_rfds; i++) + { + pos += 1; + fprintf (stderr, "LOG: adding %d read socket\n", i); + GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]); + } + + GNUNET_NETWORK_fdset_zero (wfds); + if (0 < write_std.size) + { + stdout_pos = pos; + fprintf (stderr, "LOG: set STDOUT_FILENO\n"); + GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle); + fprintf (stderr, "LOG: after setting STDOUT_FILENO\n"); + // 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, "BROADCAST\n"); + // skip the message + broadcast = 1; + memset (write_pout.buf, 0, write_pout.size); + write_pout.size = 0; + } + else { - 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? + 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. 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 ; + 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]); //crapa aici + 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)) + fprintf (stderr, "got the channel %d\n", addr.port); + + 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++) + + if (broadcast == 0) { - if (FD_ISSET (i, &rfds)) + fprintf (stderr, "before select\n"); + int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_()); + fprintf (stderr, "after select %d\n", retval); + if (retval < 0) { - if (i == STDIN_FILENO) + 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, "-------------STDOUT------------\n"); + 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; break; - } - if (0 == ret) + fprintf (stderr, "Failed to write to STDOUT: "); + print_last_error(); + break; + } + fprintf (stderr, "--->sended: %d\n", ret); + Sleep(5000); + 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)) + { + fprintf (stderr, "-------------SEND------------\n"); + 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); + //break; } 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) //FALSEEE!!!! NUUUUU EEE VOOIEE!!_----------------------------------------------------------? + { + fprintf (stderr, "-------------STDIN------------\n"); + //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, "-------------ACCEPT------------\n"); + 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", IFNAMSIZ, - strerror (errno)); - break; + 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; + 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); + fprintf (stderr, "MESSAGE: %s\n", readbuf); 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); + + 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; } - } + } } } - } - /* 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' */ +} \ No newline at end of file diff --git a/src/transport/plugin_transport_wlan.h b/src/transport/plugin_transport_wlan.h index b7f22de71..c6f990058 100644 --- a/src/transport/plugin_transport_wlan.h +++ b/src/transport/plugin_transport_wlan.h @@ -32,7 +32,12 @@ /** * Number fo bytes in a mac address. */ -#define MAC_ADDR_SIZE 6 +#ifdef MINGW + #define MAC_ADDR_SIZE 8 + typedef uint8_t u_int8_t; +#else + #define MAC_ADDR_SIZE 6 +#endif /** * Value for "Management" in the 'frame_control' field of the