12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285 |
- /*
- This file is part of GNUnet.
- Copyright (C) 2010, 2011, 2012 GNUnet e.V.
- Copyright (C) 2007, 2008, Andy Green <andy@warmcat.com>
- Copyright (C) 2009 Thomas d'Otreppe
- 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
- 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 <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: AGPL3.0-or-later
- */
- #include "gnunet_config.h"
- #include <bluetooth/bluetooth.h>
- #include <bluetooth/hci.h>
- #include <bluetooth/hci_lib.h>
- #include <bluetooth/rfcomm.h>
- #include <bluetooth/sdp.h>
- #include <bluetooth/sdp_lib.h>
- #include <errno.h>
- #include <linux/if.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/ioctl.h>
- #include <sys/param.h>
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include "plugin_transport_wlan.h"
- #include "gnunet_protocols.h"
- /**
- * Maximum number of ports assignable for RFCOMMM protocol.
- */
- #define MAX_PORTS 30
- /**
- * Maximum size of a message allowed in either direction
- * (used for our receive and sent buffers).
- */
- #define MAXLINE 4096
- /**
- * Maximum number of loops without inquiring for new devices.
- */
- #define MAX_LOOPS 5
- /**
- * In bluez library, the maximum name length of a device is 8
- */
- #define BLUEZ_DEVNAME_SIZE 8
- /**
- * struct for storing the information of the hardware. There is only
- * one of these.
- */
- struct HardwareInfos
- {
- /**
- * Name of the interface, not necessarily 0-terminated (!).
- */
- char iface[IFNAMSIZ];
- /**
- * 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;
- };
- /**
- * IO buffer used for buffering data in transit (to wireless or to stdout).
- */
- struct SendBuffer
- {
- /**
- * How many bytes of data are stored in 'buf' for transmission right now?
- * Data always starts at offset 0 and extends to 'size'.
- */
- size_t size;
- /**
- * How many bytes that were stored in 'buf' did we already write to the
- * destination? Always smaller than 'size'.
- */
- size_t pos;
- /**
- * Buffered data; twice the maximum allowed message size as we add some
- * headers.
- */
- char buf[MAXLINE * 2];
- };
- #ifdef __linux__
- /**
- * Devices buffer used to keep a list with all the discoverable devices in
- * order to send them HELLO messages one by one when it receive a broadcast message.
- */
- struct BroadcastMessages
- {
- /* List with the discoverable devices' addresses */
- bdaddr_t devices[MAX_PORTS];
- /* List with the open sockets */
- int fds[MAX_PORTS];
- /* The number of the devices */
- int size;
- /* The current position */
- int pos;
- /* The device id */
- int dev_id;
- };
- /**
- * Address used to identify the broadcast messages.
- */
- static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = { { 255, 255,
- 255, 255,
- 255,
- 255 } };
- /**
- * Buffer with the discoverable devices.
- */
- static struct BroadcastMessages neighbours;
- static int searching_devices_count = 0;
- #endif
- /**
- * Buffer for data read from stdin to be transmitted to the bluetooth device
- */
- static struct SendBuffer write_pout;
- /**
- * Buffer for data read from the bluetooth device to be transmitted to stdout.
- */
- static struct SendBuffer write_std;
- /* ****** 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
- * for now.
- */
- #define ALIGN_FACTOR 8
- /**
- * Smallest supported message.
- */
- #define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
- /**
- * Functions with this signature are called whenever a
- * complete message is received by the tokenizer.
- *
- * @param cls closure
- * @param message the actual message
- */
- typedef void (*MessageTokenizerCallback) (void *cls,
- const struct
- GNUNET_MessageHeader *
- message);
- /**
- * Handle to a message stream tokenizer.
- */
- struct MessageStreamTokenizer
- {
- /**
- * Function to call on completed messages.
- */
- MessageTokenizerCallback cb;
- /**
- * Closure for cb.
- */
- void *cb_cls;
- /**
- * Size of the buffer (starting at 'hdr').
- */
- size_t curr_buf;
- /**
- * How many bytes in buffer have we already processed?
- */
- size_t off;
- /**
- * How many bytes in buffer are valid right now?
- */
- size_t pos;
- /**
- * Beginning of the buffer. Typed like this to force alignment.
- */
- struct GNUNET_MessageHeader *hdr;
- };
- /**
- * Create a message stream tokenizer.
- *
- * @param cb function to call on completed messages
- * @param cb_cls closure for cb
- * @return handle to tokenizer
- */
- static struct MessageStreamTokenizer *
- mst_create (MessageTokenizerCallback cb,
- void *cb_cls)
- {
- struct MessageStreamTokenizer *ret;
- ret = malloc (sizeof(struct MessageStreamTokenizer));
- if (NULL == ret)
- {
- fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
- exit (1);
- }
- ret->hdr = malloc (MIN_BUFFER_SIZE);
- if (NULL == ret->hdr)
- {
- fprintf (stderr, "Failed to allocate buffer for alignment\n");
- exit (1);
- }
- ret->curr_buf = MIN_BUFFER_SIZE;
- ret->cb = cb;
- ret->cb_cls = cb_cls;
- ret->pos = 0;
- return ret;
- }
- /**
- * Add incoming data to the receive buffer and call the
- * callback for all complete messages.
- *
- * @param mst tokenizer to use
- * @param buf input data to add
- * @param size number of bytes in buf
- * @return GNUNET_OK if we are done processing (need more data)
- * GNUNET_SYSERR if the data stream is corrupt
- */
- static int
- mst_receive (struct MessageStreamTokenizer *mst,
- const char *buf, size_t size)
- {
- const struct GNUNET_MessageHeader *hdr;
- size_t delta;
- uint16_t want;
- char *ibuf;
- int need_align;
- unsigned long offset;
- int ret;
- ret = GNUNET_OK;
- ibuf = (char *) mst->hdr;
- while (mst->pos > 0)
- {
- do_align:
- if (mst->pos < mst->off)
- {
- // fprintf (stderr, "We processed too many bytes!\n");
- return GNUNET_SYSERR;
- }
- if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
- (0 != (mst->off % ALIGN_FACTOR)))
- {
- /* need to align or need more space */
- mst->pos -= mst->off;
- memmove (ibuf, &ibuf[mst->off], mst->pos);
- mst->off = 0;
- }
- if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
- {
- delta =
- GNUNET_MIN (sizeof(struct GNUNET_MessageHeader)
- - (mst->pos - mst->off), size);
- GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
- mst->pos += delta;
- buf += delta;
- size -= delta;
- }
- if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
- {
- // FIXME should I reset ??
- // mst->off = 0;
- // mst->pos = 0;
- return GNUNET_OK;
- }
- hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
- want = ntohs (hdr->size);
- if (want < sizeof(struct GNUNET_MessageHeader))
- {
- fprintf (stderr,
- "Received invalid message from stdin\n");
- return GNUNET_SYSERR;
- }
- if ((mst->curr_buf - mst->off < want) &&
- (mst->off > 0))
- {
- /* need more space */
- mst->pos -= mst->off;
- memmove (ibuf, &ibuf[mst->off], mst->pos);
- mst->off = 0;
- }
- if (want > mst->curr_buf)
- {
- if (mst->off != 0)
- {
- fprintf (stderr, "Error! We should proceeded 0 bytes\n");
- return GNUNET_SYSERR;
- }
- mst->hdr = realloc (mst->hdr, want);
- if (NULL == mst->hdr)
- {
- fprintf (stderr, "Failed to allocate buffer for alignment\n");
- exit (1);
- }
- ibuf = (char *) mst->hdr;
- mst->curr_buf = want;
- }
- hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
- if (mst->pos - mst->off < want)
- {
- delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
- if (mst->pos + delta > mst->curr_buf)
- {
- fprintf (stderr, "The size of the buffer will be exceeded!\n");
- return GNUNET_SYSERR;
- }
- GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
- mst->pos += delta;
- buf += delta;
- size -= delta;
- }
- if (mst->pos - mst->off < want)
- {
- // FIXME should I use this?
- // mst->off = 0;
- // mst->pos = 0;
- return GNUNET_OK;
- }
- mst->cb (mst->cb_cls, hdr);
- mst->off += want;
- if (mst->off == mst->pos)
- {
- /* reset to beginning of buffer, it's free right now! */
- mst->off = 0;
- mst->pos = 0;
- }
- }
- if (0 != mst->pos)
- {
- fprintf (stderr,
- "There should some valid bytes in the buffer on this stage\n");
- return GNUNET_SYSERR;
- }
- while (size > 0)
- {
- if (size < sizeof(struct GNUNET_MessageHeader))
- break;
- offset = (unsigned long) buf;
- need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
- if (GNUNET_NO == need_align)
- {
- /* can try to do zero-copy and process directly from original buffer */
- hdr = (const struct GNUNET_MessageHeader *) buf;
- want = ntohs (hdr->size);
- if (want < sizeof(struct GNUNET_MessageHeader))
- {
- fprintf (stderr,
- "Received invalid message from stdin\n");
- // exit (1);
- mst->off = 0;
- return GNUNET_SYSERR;
- }
- if (size < want)
- break; /* or not, buffer incomplete, so copy to private buffer... */
- mst->cb (mst->cb_cls, hdr);
- buf += want;
- size -= want;
- }
- else
- {
- /* need to copy to private buffer to align;
- * yes, we go a bit more spagetti than usual here */
- goto do_align;
- }
- }
- if (size > 0)
- {
- if (size + mst->pos > mst->curr_buf)
- {
- mst->hdr = realloc (mst->hdr, size + mst->pos);
- if (NULL == mst->hdr)
- {
- fprintf (stderr, "Failed to allocate buffer for alignment\n");
- exit (1);
- }
- ibuf = (char *) mst->hdr;
- mst->curr_buf = size + mst->pos;
- }
- if (mst->pos + size > mst->curr_buf)
- {
- fprintf (stderr,
- "Assertion failed\n");
- exit (1);
- }
- GNUNET_memcpy (&ibuf[mst->pos], buf, size);
- mst->pos += size;
- }
- return ret;
- }
- /**
- * Destroys a tokenizer.
- *
- * @param mst tokenizer to destroy
- */
- static void
- mst_destroy (struct MessageStreamTokenizer *mst)
- {
- free (mst->hdr);
- free (mst);
- }
- /**
- * Calculate crc32, the start of the calculation
- *
- * @param buf buffer to calc the crc
- * @param len len of the buffer
- * @return crc sum
- */
- static unsigned long
- calc_crc_osdep (const unsigned char *buf, size_t len)
- {
- static const unsigned long int crc_tbl_osdep[256] = {
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
- 0xE963A535, 0x9E6495A3,
- 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
- 0xE7B82D07, 0x90BF1D91,
- 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
- 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
- 0xFA0F3D63, 0x8D080DF5,
- 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
- 0xD20D85FD, 0xA50AB56B,
- 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
- 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
- 0xCFBA9599, 0xB8BDA50F,
- 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
- 0xC1611DAB, 0xB6662D3D,
- 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
- 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
- 0x91646C97, 0xE6635C01,
- 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
- 0x8208F4C1, 0xF50FC457,
- 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
- 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
- 0xA4D1C46D, 0xD3D6F4FB,
- 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
- 0xAA0A4C5F, 0xDD0D7CC9,
- 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
- 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
- 0xB7BD5C3B, 0xC0BA6CAD,
- 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
- 0x04DB2615, 0x73DC1683,
- 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
- 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
- 0x196C3671, 0x6E6B06E7,
- 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
- 0x17B7BE43, 0x60B08ED5,
- 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
- 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
- 0x316E8EEF, 0x4669BE79,
- 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
- 0x220216B9, 0x5505262F,
- 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
- 0x2CD99E8B, 0x5BDEAE1D,
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
- 0x72076785, 0x05005713,
- 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
- 0x7CDCEFB7, 0x0BDBDF21,
- 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
- 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
- 0x616BFFD3, 0x166CCF45,
- 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
- 0x4969474D, 0x3E6E77DB,
- 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
- 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
- 0x54DE5729, 0x23D967BF,
- 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
- 0x5A05DF1B, 0x2D02EF8D
- };
- unsigned long crc = 0xFFFFFFFF;
- for (; len > 0; len--, buf++)
- crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
- return(~crc);
- }
- /**
- * Calculate and check crc of the bluetooth packet
- *
- * @param buf buffer of the packet, with len + 4 bytes of data,
- * the last 4 bytes being the checksum
- * @param len length of the payload in data
- * @return 0 on success (checksum matches), 1 on error
- */
- static int
- check_crc_buf_osdep (const unsigned char *buf, size_t len)
- {
- unsigned long crc;
- crc = calc_crc_osdep (buf, len);
- buf += 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;
- }
- /* ************** end of clone ***************** */
- #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)
- {
- /**
- * 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;
- }
- /**
- * 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)
- {
- /**
- * 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)
- {
- for (it = response_list; it; it = it->next)
- {
- 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_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;
- }
- /**
- * 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
- * @param buf_size size of the buffer
- * @param ri where to write radiotap_rx info
- * @return number of bytes written to 'buf'
- */
- static ssize_t
- 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;
- count = read (*((int *) sock), tmpbuf, buf_size);
- if (0 > count)
- {
- if (EAGAIN == errno)
- return 0;
- fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (
- errno));
- return -1;
- }
- #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);
- }
- 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, non-zero on error
- */
- 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);
- 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))
- {
- fprintf (stderr,
- "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
- IFNAMSIZ,
- dev->iface,
- strerror (errno));
- (void) close (fd_hci);
- return 1;
- }
- if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
- {
- 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;
- }
- }
- /* 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;
- }
- return 0;
- }
- /**
- * Set the header to sane values to make attacks more difficult
- *
- * @param taIeeeHeader pointer to the header of the packet
- * @param dev pointer to the Hardware_Infos struct
- *
- **** copy from gnunet-helper-transport-wlan.c ****
- */
- static void
- mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
- const struct HardwareInfos *dev)
- {
- taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
- taIeeeHeader->addr3 = mac_bssid_gnunet;
- taIeeeHeader->addr2 = dev->pl_mac;
- }
- #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)
- {
- 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;
- }
- #endif
- /**
- * Test incoming packets mac for being our own.
- *
- * @param taIeeeHeader buffer of the packet
- * @param dev the Hardware_Infos struct
- * @return 0 if mac belongs to us, 1 if mac is for another target
- *
- **** same as the one from gnunet-helper-transport-wlan.c ****
- */
- static int
- mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
- const struct HardwareInfos *dev)
- {
- static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
- if ((0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
- (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)))
- return 0; /* some drivers set no Macs, then assume it is all for us! */
- if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
- return 1; /* not a GNUnet ad-hoc package */
- if ((0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
- (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)))
- return 0; /* for us, or broadcast */
- return 1; /* not for us */
- }
- /**
- * 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
- *
- **** same as the one from gnunet-helper-transport-wlan.c ****
- */
- static void
- stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
- {
- struct HardwareInfos *dev = cls;
- const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
- struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
- size_t sendsize;
- sendsize = ntohs (hdr->size);
- if ((sendsize <
- 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)
- - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
- if (MAXLINE < sendsize)
- {
- fprintf (stderr, "Packet too big for buffer\n");
- exit (1);
- }
- header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
- 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);
- GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
- sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
- write_pout.size = sendsize;
- }
- #ifdef __linux__
- /**
- * Broadcast a HELLO message for peer discovery
- *
- * @param dev pointer to the device struct
- * @param dev pointer to the socket which was added to the set
- * @return 0 on success
- */
- static int
- send_broadcast (struct HardwareInfos *dev, int *sendsocket)
- {
- int new_device = 0;
- int loops = 0;
- search_for_devices:
- if (((neighbours.size == neighbours.pos) && (new_device == 1)) ||
- (neighbours.size == 0) )
- {
- inquiry_devices: // skip the conditions and force a inquiry for new devices
- {
- /**
- * It means that I sent HELLO messages to all the devices from the list and I should search
- * for new ones or that this is the first time when I do a search.
- */
- inquiry_info *devices = NULL;
- int i, responses, max_responses = MAX_PORTS;
- /* sanity checks */
- if (neighbours.size >= MAX_PORTS)
- {
- fprintf (stderr,
- "%.*s reached the top limit for the discovarable devices\n",
- IFNAMSIZ,
- dev->iface);
- return 2;
- }
- /* Get the device id */
- if (neighbours.dev_id == -1)
- {
- char addr[19] = { 0 }; // the device MAC address
- ba2str ((bdaddr_t *) &dev->pl_mac, addr);
- neighbours.dev_id = hci_devid (addr);
- if (neighbours.dev_id < 0)
- {
- fprintf (stderr,
- "Failed to get the device id for interface %.*s : %s\n",
- IFNAMSIZ,
- dev->iface, strerror (errno));
- return 1;
- }
- }
- devices = malloc (max_responses * sizeof(inquiry_info));
- if (devices == NULL)
- {
- fprintf (stderr,
- "Failed to allocate memory for inquiry info list on interface %.*s\n",
- IFNAMSIZ,
- dev->iface);
- return 1;
- }
- responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL,
- &devices, IREQ_CACHE_FLUSH);
- if (responses < 0)
- {
- fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ,
- dev->iface);
- return 1;
- }
- fprintf (stderr, "LOG : Found %d devices\n", responses); // FIXME delete it after debugging stage
- if (responses == 0)
- {
- fprintf (stderr, "LOG : No devices discoverable\n");
- return 1;
- }
- for (i = 0; i < responses; i++)
- {
- int j;
- int found = 0;
- /* sanity check */
- if (i >= MAX_PORTS)
- {
- fprintf (stderr,
- "%.*s reached the top limit for the discoverable devices (after inquiry)\n",
- IFNAMSIZ,
- dev->iface);
- return 2;
- }
- /* Search if the address already exists on the list */
- for (j = 0; j < neighbours.size; j++)
- {
- if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]),
- sizeof(bdaddr_t)) == 0)
- {
- found = 1;
- fprintf (stderr, "LOG : the device already exists on the list\n"); // FIXME debugging message
- break;
- }
- }
- if (found == 0)
- {
- char addr[19] = { 0 };
- ba2str (&(devices + i)->bdaddr, addr);
- fprintf (stderr, "LOG : %s was added to the list\n", addr); // FIXME debugging message
- GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices
- + i)->
- bdaddr, sizeof(bdaddr_t));
- }
- }
- free (devices);
- }
- }
- int connection_successful = 0;
- struct sockaddr_rc addr_rc = { 0 };
- int errno_copy = 0;
- addr_rc.rc_family = AF_BLUETOOTH;
- /* Try to connect to a new device from the list */
- while (neighbours.pos < neighbours.size)
- {
- /* Check if we are already connected to this device */
- if (neighbours.fds[neighbours.pos] == -1)
- {
- memset (&addr_rc.rc_bdaddr, 0, sizeof(addr_rc.rc_bdaddr));
- 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)
- {
- fprintf (stderr, "LOG : Force to inquiry for new devices\n");
- searching_devices_count = 0;
- goto inquiry_devices;
- }
- }
- /* If a new device wasn't found, search an old one */
- if (connection_successful == 0)
- {
- int loop_check = neighbours.pos;
- while (neighbours.fds[neighbours.pos] == -1)
- {
- if (neighbours.pos == neighbours.size)
- neighbours.pos = 0;
- if (neighbours.pos == loop_check)
- {
- if (errno_copy == ECONNREFUSED)
- {
- fprintf (stderr, "LOG : No device found. Go back and search again\n"); // FIXME debugging message
- new_device = 1;
- loops += 1;
- goto search_for_devices;
- }
- else
- {
- return 1; // Skip the broadcast message
- }
- }
- neighbours.pos += 1;
- }
- *sendsocket = neighbours.fds[neighbours.pos++];
- }
- return 0;
- }
- #endif
- /**
- * Main function of the helper. This code accesses a bluetooth interface
- * forwards traffic in both directions between the bluetooth interface and
- * stdin/stdout of this process. Error messages are written to 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
- *
- **** similar to gnunet-helper-transport-wlan.c ****
- */
- int
- main (int argc, char *argv[])
- {
- #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
- 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;
- }
- #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 RFCOMM 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))
- {
- 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
- }
- /* 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)
- {
- broadcast = 1;
- memset (&write_pout, 0, sizeof(write_pout)); // clear the buffer
- }
- else if (memcmp (&frame->addr1, &broadcast_address,
- sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
- {
- fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n",
- dev.iface, neighbours.pos, neighbours.size); // FIXME: debugging message
- if (send_broadcast (&dev, &sendsocket) != 0) // if the searching wasn't successful don't get stuck on the select stage
- {
- broadcast = 1;
- memset (&write_pout, 0, sizeof(write_pout)); // remove the message
- fprintf (stderr,
- "LOG : Skipping the broadcast message (pos %d, size %d)\n",
- neighbours.pos, neighbours.size);
- }
- else
- {
- FD_SET (sendsocket, &wfds);
- maxfd = MAX (maxfd, sendsocket);
- }
- }
- else
- {
- int found = 0;
- int pos = 0;
- /* Search if the address already exists on the list */
- for (i = 0; i < neighbours.size; i++)
- {
- if (memcmp (&frame->addr1, &(neighbours.devices[i]),
- sizeof(bdaddr_t)) == 0)
- {
- pos = i;
- if (neighbours.fds[i] != -1)
- {
- found = 1; // save the position where it was found
- FD_SET (neighbours.fds[i], &wfds);
- maxfd = MAX (maxfd, neighbours.fds[i]);
- sendsocket = neighbours.fds[i];
- fprintf (stderr, "LOG: the address was found in the list\n");
- break;
- }
- }
- }
- if (found == 0)
- {
- int status;
- struct sockaddr_rc addr = { 0 };
- fprintf (stderr,
- "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n",
- dev.iface,
- frame->addr1.mac[5], frame->addr1.mac[4],
- frame->addr1.mac[3],
- frame->addr1.mac[2], frame->addr1.mac[1],
- frame->addr1.mac[0]); // FIXME: debugging message
- sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- if (sendsocket < 0)
- {
- fprintf (stderr,
- "Failed to create a RFCOMM socket (sending stage): %s\n",
- strerror (errno));
- return -1;
- }
- 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) )
- {
- if ((errno == ECONNREFUSED) && (tries < 2) )
- {
- fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n",
- IFNAMSIZ, dev.iface);
- tries++;
- goto connect_retry;
- }
- else if (errno == EBADF)
- {
- fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n",
- dev.iface, strerror (errno));
- memset (&write_pout, 0, sizeof(write_pout));
- broadcast = 1;
- }
- else
- {
- fprintf (stderr,
- "LOG : %s failed to connect : %s. Try again later!\n",
- dev.iface,
- strerror (errno));
- memset (&write_pout, 0, sizeof(write_pout));
- broadcast = 1;
- }
- }
- else
- {
- FD_SET (sendsocket, &wfds);
- maxfd = MAX (maxfd, sendsocket);
- fprintf (stderr, "LOG : Connection successful\n");
- if (pos != 0) // save the socket
- {
- neighbours.fds[pos] = sendsocket;
- }
- else
- {
- /* Add the new device to the discovered devices list */
- if (neighbours.size < MAX_PORTS)
- {
- neighbours.fds[neighbours.size] = sendsocket;
- 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 :) */
- {
- 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)
- {
- 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 (-1 != sendsocket)
- {
- if (FD_ISSET (sendsocket, &wfds))
- {
- ssize_t ret = write (sendsocket,
- write_pout.buf + write_std.pos,
- write_pout.size - write_pout.pos);
- if (0 > ret) // FIXME should I first check the error type?
- {
- fprintf (stderr,
- "Failed to write to bluetooth device: %s. Closing the socket!\n",
- strerror (errno));
- for (i = 0; i < neighbours.size; i++)
- {
- if (neighbours.fds[i] == sendsocket)
- {
- (void) close (sendsocket);
- neighbours.fds[i] = -1;
- break;
- }
- }
- /* Remove the message */
- memset (&write_pout.buf + write_std.pos, 0, (write_pout.size
- - write_pout.pos));
- write_pout.pos = 0;
- write_pout.size = 0;
- }
- else
- {
- write_pout.pos += ret;
- if ((write_pout.pos != write_pout.size) && (0 != ret))
- {
- /* We should not get partial sends with packet-oriented devices... */
- fprintf (stderr, "Write error, partial send: %u/%u\n",
- (unsigned int) write_pout.pos,
- (unsigned int) write_pout.size);
- break;
- }
- if (write_pout.pos == write_pout.size)
- {
- write_pout.pos = 0;
- write_pout.size = 0;
- }
- fprintf (stderr, "LOG : %s sends a message to a DEVICE\n",
- dev.iface); // FIXME: debugging message
- }
- }
- }
- for (i = 0; i <= maxfd; i++)
- {
- if (FD_ISSET (i, &rfds))
- {
- if (i == STDIN_FILENO)
- {
- ssize_t ret =
- read (i, readbuf, sizeof(readbuf));
- if (0 > ret)
- {
- fprintf (stderr,
- "Read error from STDIN: %s\n",
- strerror (errno));
- break;
- }
- if (0 == ret)
- {
- /* stop reading... */
- stdin_open = 0;
- }
- else
- {
- mst_receive (stdin_mst, readbuf, ret);
- fprintf (stderr, "LOG : %s receives a message from STDIN\n",
- dev.iface); // FIXME: debugging message
- }
- }
- else if (i == dev.fd_rfcomm)
- {
- int readsocket;
- struct sockaddr_rc addr = { 0 };
- unsigned int opt = sizeof(addr);
- readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr,
- &opt);
- fprintf (stderr, "LOG : %s accepts a message\n", dev.iface); // FIXME: debugging message
- if (readsocket == -1)
- {
- fprintf (stderr,
- "Failed to accept a connection on interface: %.*s\n",
- IFNAMSIZ,
- strerror (errno));
- break;
- }
- else
- {
- FD_SET (readsocket, &rfds);
- maxfd = MAX (maxfd, readsocket);
- if (crt_rfds < MAX_PORTS)
- rfds_list[crt_rfds++] = readsocket;
- else
- {
- fprintf (stderr,
- "The limit for the read file descriptors list was \
- reached\n");
- break;
- }
- }
- }
- else
- {
- struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
- ssize_t ret;
- fprintf (stderr, "LOG : %s reads something from the socket\n",
- dev.iface); // FIXME : debugging message
- rrm = (struct
- GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
- ret =
- read_from_the_socket ((void *) &i, (unsigned char *) &rrm->frame,
- sizeof(write_std.buf)
- - sizeof(struct
- GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
- + sizeof(struct
- GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
- rrm);
- if (0 >= ret)
- {
- int j;
- FD_CLR (i, &rfds);
- close (i);
- /* Remove the socket from the list */
- for (j = 0; j < crt_rfds; j++)
- {
- if (rfds_list[j] == i)
- {
- rfds_list[j] ^= rfds_list[crt_rfds - 1];
- rfds_list[crt_rfds - 1] ^= rfds_list[j];
- rfds_list[j] ^= rfds_list[crt_rfds - 1];
- crt_rfds -= 1;
- break;
- }
- }
- fprintf (stderr, "Read error from raw socket: %s\n", strerror (
- errno));
- break;
- }
- if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
- {
- write_std.size = ret
- + sizeof(struct
- GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
- - sizeof(struct
- GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
- rrm->header.size = htons (write_std.size);
- rrm->header.type = htons (
- GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
- }
- }
- }
- }
- }
- }
- /* Error handling, try to clean up a bit at least */
- mst_destroy (stdin_mst);
- stdin_mst = NULL;
- sdp_close (dev.session);
- (void) close (dev.fd_rfcomm);
- 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
- {
- if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket,
- (LPSOCKADDR) &addr,
- addr_len))
- {
- fprintf (stderr, "Failed to connect: ");
- print_last_error ();
- ExitProcess (2);
- }
- if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1))
- {
- fprintf (stderr, "Failed to change the socket mode\n");
- ExitProcess (2);
- }
- GNUNET_NETWORK_fdset_set (wfds, sendsocket);
- }
- }
- }
- if (broadcast == 0)
- {
- 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)
- {
- fprintf (stderr, "LOG : sends a message to STDOUT\n"); // FIXME: debugging message
- // ssize_t ret;
- // ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
- // ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
- DWORD ret;
- if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos,
- write_std.size - write_std.pos, &ret, NULL))
- {
- fprintf (stderr, "Failed to write to STDOUT: ");
- print_last_error ();
- break;
- }
- if (ret <= 0)
- {
- fprintf (stderr, "Failed to write to STDOUT\n");
- ExitProcess (2);
- }
- write_std.pos += ret;
- if (write_std.pos == write_std.size)
- {
- write_std.pos = 0;
- write_std.size = 0;
- }
- }
- if (sendsocket != NULL)
- {
- if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
- {
- ssize_t ret;
- ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf
- + write_pout.pos,
- write_pout.size - write_pout.pos);
- if (GNUNET_SYSERR == ret)
- {
- fprintf (stderr,
- "Failed to send to the socket. Closing the socket. Error: \n");
- print_last_error ();
- if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
- {
- fprintf (stderr, "Failed to close the sendsocket!\n");
- print_last_error ();
- }
- ExitProcess (2);
- }
- else
- {
- write_pout.pos += ret;
- if ((write_pout.pos != write_pout.size) && (0 != ret))
- {
- /* we should not get partial sends with packet-oriented devices... */
- fprintf (stderr, "Write error, partial send: %u/%u\n",
- (unsigned int) write_pout.pos,
- (unsigned int) write_pout.size);
- break;
- }
- if (write_pout.pos == write_pout.size)
- {
- write_pout.pos = 0;
- write_pout.size = 0;
- }
- fprintf (stderr, "LOG : sends a message to a DEVICE\n"); // FIXME: debugging message
- }
- }
- }
- // if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
- if (retval == stdin_pos)
- {
- // ssize_t ret;
- // ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
- // ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
- DWORD ret;
- if (FALSE == ReadFile (stdin_handle, readbuf, sizeof(readbuf), &ret,
- NULL)) /* do nothing asynchronous */
- {
- fprintf (stderr, "Read error from STDIN: ");
- print_last_error ();
- break;
- }
- if (0 == ret)
- {
- /* stop reading... */
- stdin_open = 0;
- }
- else
- {
- mst_receive (stdin_mst, readbuf, ret);
- fprintf (stderr, "LOG : receives a message from STDIN\n"); // FIXME: debugging message
- }
- }
- 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 change the socket mode\n");
- ExitProcess (2);
- }
- GNUNET_NETWORK_fdset_set (rfds, readsocket);
- if (crt_rfds < MAX_PORTS)
- rfds_list[crt_rfds++] = readsocket;
- else
- {
- fprintf (stderr,
- "The limit for the read file descriptors list was reached\n");
- break;
- }
- }
- }
- 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: reading something from the socket\n"); // FIXME : debugging message
- rrm = (struct
- GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
- ret = read_from_the_socket (rfds_list[i], (unsigned
- char *) &rrm->frame,
- sizeof(write_std.buf)
- - sizeof(struct
- GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
- + sizeof(struct
- GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
- rrm);
- if (0 >= ret)
- {
- // TODO remove the socket from the list
- if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
- {
- fprintf (stderr, "Failed to close the sendsocket!\n");
- print_last_error ();
- }
- fprintf (stderr, "Read error from raw socket: ");
- print_last_error ();
- break;
- }
- if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
- {
- write_std.size = ret
- + sizeof(struct
- GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
- - sizeof(struct
- GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
- rrm->header.size = htons (write_std.size);
- rrm->header.type = htons (
- GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
- }
- break;
- }
- }
- }
- }
- 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' */
- }
|