#include <stdio.h>
#include <sys/socket.h>
#include <signal.h>

#include "pcap.h"

#include "node.h"
#include "hash.h"
#include "batch_ipc.h"


#define WLAN_DEVNAMELEN_MAX 16

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef unsigned long long uint64_t;

typedef struct {
        uint32_t did __attribute__ ((packed));
        uint16_t status __attribute__ ((packed));
        uint16_t len __attribute__ ((packed));
        uint32_t data __attribute__ ((packed));
    } p80211item_uint32_t;

    typedef struct {
        uint32_t msgcode __attribute__ ((packed));
        uint32_t msglen __attribute__ ((packed));
        uint8_t devname[WLAN_DEVNAMELEN_MAX] __attribute__ ((packed));
        p80211item_uint32_t hosttime __attribute__ ((packed));
        p80211item_uint32_t mactime __attribute__ ((packed));
        p80211item_uint32_t channel __attribute__ ((packed));
        p80211item_uint32_t rssi __attribute__ ((packed));
        p80211item_uint32_t sq __attribute__ ((packed));
        p80211item_uint32_t signal __attribute__ ((packed));
        p80211item_uint32_t noise __attribute__ ((packed));
        p80211item_uint32_t rate __attribute__ ((packed));
        p80211item_uint32_t istx __attribute__ ((packed));
        p80211item_uint32_t frmlen __attribute__ ((packed));
    } wlan_ng_prism2_header;


/* Current hash */
Hash curWifi;
/* Calibrated hash */
Hash clbrWifi;


void gotPacket(u_char* args, const struct pcap_pkthdr *header, const u_char* packet){
int offset;
wlan_ng_prism2_header *hdr;
signed char* buf;
WifiPair pair;

	memset(&pair, 0, sizeof(WifiPair));

	offset = sizeof(wlan_ng_prism2_header)+4+6;
	hdr = (wlan_ng_prism2_header*)packet;

	pair.S = hdr->signal.data;
	pair.tx.mac.str[0] = *((unsigned char*)hdr+offset);
	pair.tx.mac.str[1] = *((unsigned char*)hdr+offset+1);
	pair.tx.mac.str[2] = *((unsigned char*)hdr+offset+2);
	pair.tx.mac.str[3] = *((unsigned char*)hdr+offset+3);
	pair.tx.mac.str[4] = *((unsigned char*)hdr+offset+4);
	pair.tx.mac.str[5] = *((unsigned char*)hdr+offset+5);

	
	upsertHash(&curWifi, &pair);
	 
/*
	buf = (char*)&hdr->signal.data;
	printf("\nPacket len %i, signal %i mac ", header->len, hdr->signal.data);
	while(offset<sizeof(wlan_ng_prism2_header)+4+6+6){
		printf("%02X:",*((unsigned char*)hdr+offset));
		++offset;
	}
*/

}


int main(int argc, char* argv[]){
  int stat;
  pcap_t *handle;
  char errbuf[PCAP_ERRBUF_SIZE];

  struct sigaction act;

  float k, n;


	if(argc<3){
		fprintf(stderr, "Usage: awacs <interface> <timeout> (awacs wlan0 1)\n");
		exit(-1);
	}

	act.sa_handler = outputResult;
	if( sigaction(SIGALRM, &act, NULL) )
		fprintf(stderr, "Can't set SIGALARM handler\n");


	/* Initialize current hash */
	curWifi.hFn = getTxHashFn;
	curWifi.eqFn = isEqTxRx;
	curWifi.newFn = newWifiPair;
	curWifi.cpFn = ctorWifiPairLoad;
	
	/* Initialize calibrated hash */
	clbrWifi.hFn = getTxHashFn;
	clbrWifi.eqFn = isEqTxRxTime;
	clbrWifi.newFn = newWifiPair;
	clbrWifi.cpFn = ctorWifiPairLoad;

	if( (stat = initLoad()) )
		return stat;

	/* Assign mean strength calculation cctor */
	curWifi.newFn = newWifiPairCur;
	curWifi.cpFn = ctorWifiPairCur;


	handle = pcap_open_live(argv[1], BUFSIZ, 1, 0, errbuf);
	
	alarm(atol(argv[2]));

	pcap_loop( handle, -1, gotPacket, NULL);

	pcap_close(handle);

return 0;
}

