This code is from project: OpenWrt antenna rotator
main.h
#ifndef _H_MAIN_H #define _H_MAIN_H #endif
main.c
#include <stdio.h> #include <pcap.h> #include <errno.h> #include <signal.h> #include <getopt.h> #include <iwlib.h> #include <pthread.h> #include "packet.h" #include "print.h" #include "utils.h" #include "track.h" #include "serial.h" pcap_t* descr = 0; int sock = 0; /****************************************************************************/ /* Cleaning function. Closing descriptors, deleting sockets etc. l */ /****************************************************************************/ void cleanup(int signum) { if(signum == 0) printf("Quit after track\n"); else printf("Caught signal %d\n",signum); if (descr != 0) pcap_close(descr); if (sock != 0) iw_sockets_close(sock); // dodac ifa closeThread(THREAD_CLOSE); closeSerial(); exit(0); } /****************************************************************************/ /* Main */ /****************************************************************************/ int main(int argc, char **argv) { char errbuf[PCAP_ERRBUF_SIZE] = ""; char bssid_filter[BSSID_LEN] = ""; char dev[8] = ""; unsigned char *packet; unsigned char *packet_free; struct pcap_pkthdr hdr; // pcap.h struct packetShortInfo pSI; int channel = 0; int delay = 1000; static int nofollow_flag = 1; static int track_signal = 0; static struct option long_options[] = { {"bssid", required_argument, 0, 'b'}, {"interface", required_argument, 0, 'i'}, {"channel", required_argument, 0, 'c'}, {"delay", required_argument, 0, 'd'}, {"nofollow", no_argument, &nofollow_flag, 0}, {"track", no_argument, &track_signal, 1} }; int option_index = 0; int c; int thrRes = 0; pthread_t stepThread; // init serial port if (initSerial(SERIAL_DEVICE) != 0) { exit(1); } // parse options while ( (c = getopt_long(argc, argv, "i:b:c:", long_options, &option_index) ) != -1) switch (c) { case 0: if (long_options[option_index].flag != 0) break; printf("Unknown option\n"); exit(2); // bssid case 'b': if (strlen(optarg) != BSSID_LEN) { printf("Wrong len of bssid\n"); exit(3); } strcpy(bssid_filter, optarg); break; // interface name case 'i': strcpy(dev, optarg); break; // channel case 'c': channel = atoi(optarg); break; // scan delay case 'd': delay = atoi(optarg); break; case '?': exit(2); break; default: printf("aborting %d \n", c); exit(2); } // if channel was in the command line, set dedicated channel if (channel > 0) { setChannel(&sock, dev, channel); } if(strlen(dev) == 0) { printf("Interface name is not set\n"); exit(3); } // open pcap capture if ((descr = pcap_open_live(dev, BUFSIZ, 0, 1000, errbuf)) == NULL) { printf("pcap_open_live(): %s\n",errbuf); } // attach own function on CTRL-C or kill -2 signal(SIGINT, cleanup); // if track signal is enabled, start thread to control stepper motor if(track_signal) { thrRes = pthread_create(&stepThread, NULL, changeAntPosThr, (void *) delay); if (thrRes) { perror("Thraed Create"); cleanup(-2); } } while(1) { // if there is no signal, then write info on console if ((packet = (unsigned char *) pcap_next(descr,&hdr)) == NULL) { printf("No signal\n"); continue; } // if we had some packet and it's a good one, start to process if(packetProc(packet, hdr.len, bssid_filter, &pSI) == 1) { // store signal levels if (track_signal) track(&pSI); // print packet info, bssid, channel, power, etc. packetStatPrint(&pSI); /* We can also change channel dynamicaly but this sometimes * is not working as it suppose to. Somtetimes channel * section of packet, can be malformed (broken packet) */ if(strlen(bssid_filter) > 0 && nofollow_flag) { // different channel if (*pSI.channel != channel) { channel = *pSI.channel; printf("\nChanging to channel %d " "from beacon frame.\n\n", channel); // set new channel, found in current packet setChannel(&sock, dev, channel); } } } // at the end we do cleanup if(track_signal && getStatus() == MOVE_END) cleanup(0); } pthread_exit(NULL); return 0; }
packet.h
#ifndef _H_PACKET_H #define _H_PACKET_H #define FRAME_BEACON 0x80 #define BEACON_SIZE 24 #define MGT_SIZE_WITH_SID_ONLY 14 #define MAX_SID_LEN 32 #define BSSID_LEN 17 // different manufacture has // other monitor packet headers #ifdef REALTEK // realtek #define RADIOTAP_SIZE 24 struct radiotap { unsigned char dummy_1[10]; unsigned char channel[2]; unsigned char dummy_2[2]; signed char signal; unsigned char dummy_3[9]; }; #else // atheros #define RADIOTAP_SIZE 26 struct radiotap { unsigned char dummy_1[18]; unsigned char channel[2]; unsigned char dummy_2[2]; signed char signal; unsigned char dummy_3[3]; }; #endif struct beacon { unsigned char dummy_1[4]; unsigned char dst[6]; unsigned char src[6]; unsigned char bssid[6]; unsigned char dummy_2[2]; }; struct management { unsigned char dummy_1[12]; unsigned char sid_flag; unsigned char sid_len; unsigned char tag; unsigned char tag_len; unsigned char channel; }; struct packetShortInfo { char bssid[BSSID_LEN]; signed char *signal; unsigned char *channel; unsigned char *sid_len; char sid[MAX_SID_LEN + 1]; }; int packetProc(unsigned char *, unsigned int, char *, struct packetShortInfo *); #endif
packet.c
#include <stdio.h> #include <string.h> #include "packet.h" #include "print.h" // Frequency channel array, currently useless int freq[14] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, -1 }; /****************************************************************************/ /* Here, parsing packets is made. */ /* We look only for BEACON frames. */ /****************************************************************************/ int packetProc(unsigned char *ptr, unsigned int len, char *bssid_filter, struct packetShortInfo *pSI) { // set valid flag to 0 -> packet invalid int valid = 0; struct radiotap *rt; struct beacon *bc; struct management *mgt; // debug // packetPrint(ptr, len); // getting radiotap header bzero(pSI, sizeof(struct packetShortInfo)); rt = (struct radiotap *) ptr; // moving forward ptr = ptr + RADIOTAP_SIZE; // check type of packet switch(*ptr) { case FRAME_BEACON: // getting beacon header bc = (struct beacon *) ptr; // moving forward ptr = ptr + BEACON_SIZE; setMac(pSI->bssid, bc->bssid); if( strlen(bssid_filter) > 0 && (strstr(pSI->bssid, bssid_filter) == NULL) ) { return valid; } mgt = (struct management *) ptr; ptr = ptr + MGT_SIZE_WITH_SID_ONLY; if (mgt->sid_flag == 0) setSid(pSI->sid, ptr, mgt->sid_len); // checking for broken packets if (mgt->sid_len > MAX_SID_LEN) { return valid; } // moving forward - after whole ESSID name ptr = ptr + mgt->sid_len; // getting tag mgt->tag = *ptr; // moving forward behind tag ptr = ptr + 1; mgt->tag_len = *ptr; // moving forward behind tag length and // network capabilities (transfer modes) ptr = ptr + mgt->tag_len + 3; // getting channel mgt->channel = *ptr; // chechking for broken packets if (mgt->channel > 13 || mgt->channel < 1) { return valid; } // debug // printf("%s;%d;%d;%d;%s\n", pSI->bssid, rt->signal, // mgt->channel, mgt->sid_len, sid); // // fill packet info structure (by pointer) pSI->signal = &rt->signal; pSI->channel = &mgt->channel; pSI->sid_len = &mgt->sid_len; // set packet as valid valid = 1; break; }; return valid; }
print.h
#ifndef _H_PRINT_H #define _H_PRINT_H #include "packet.h" void packetStatPrint(struct packetShortInfo *); void packetPrint(unsigned char *, unsigned int); #endif
print.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "print.h" #include "packet.h" /****************************************************************************/ /* Prints packet in hexadecimal */ /****************************************************************************/ void packetPrint(unsigned char *ptr, unsigned int len) { int i; for(i=1; i <= len; i++) { printf("%02x ", ptr[i-1]); if (i % 8 == 0) printf(" "); if (i % 16 == 0) printf("\n"); } printf("\n"); } /****************************************************************************/ /* Prints network information */ /****************************************************************************/ void packetStatPrint(struct packetShortInfo *pSI) { printf("%s;%d;%d;%d;%s\n", pSI->bssid, *pSI->signal, *pSI->channel, *pSI->sid_len, pSI->sid); }
serial.h
#ifndef _H_SERIAL_H #define _H_SERIAL_H #define SERIAL_DEVICE "/dev/ttyATH0" #define SERIAL_SPEED B9600 #define RECV_RST 1 #define RECV_ERR 2 #define RECV_OK 3 #define RECV_TIMEOUT 4 int initSerial(char *); int writeCmd(char *); int readAnswer(int); int closeSerial(void); int serialCmd(unsigned char, unsigned char); #endif
serial.c
#include <stdio.h> #include <string.h> #include <termios.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h> #include "serial.h" static int devHandle = -2; /****************************************************************************/ /* Init serial port */ /****************************************************************************/ int initSerial(char *device) { struct termios opt; devHandle = open(device, O_RDWR| O_NOCTTY | O_NDELAY | O_SYNC); if (devHandle == -1) { perror("Unable to open device"); return 1; } fcntl(devHandle, F_SETFL, FNDELAY); if (tcgetattr(devHandle, &opt) == -1) { perror("Unable to obtain device info"); return 1; } if (cfsetispeed(&opt, SERIAL_SPEED) !=0 ) { perror("Unable to set RX speed"); return 1; } if (cfsetospeed(&opt, SERIAL_SPEED) != 0) { perror("Unable to set TX speed"); return 1; } opt.c_cflag |= (CLOCAL | CREAD); opt.c_cflag &= ~PARENB; opt.c_cflag &= ~CSTOPB; opt.c_cflag &= ~CSIZE; opt.c_cflag |= CS8; opt.c_lflag &= ~(ICANON | ECHO); opt.c_oflag &= ~OPOST; if (tcsetattr(devHandle, TCSANOW, &opt) == -1) { perror("Unable to setup port"); return 1; } // cleaning rs232 buffer printf("Cleaning buffer, timeout is ok.\n"); readAnswer(2); return 0; } /****************************************************************************/ /* Write string to port */ /****************************************************************************/ int writeCmd(char *s) { if (write(devHandle, s, strlen(s)) == -1) { perror("Write error"); return 1; } return 0; } /****************************************************************************/ /* Read answers from RS232 port */ /****************************************************************************/ int readAnswer(int readSecWait) { char recvBuff = ' '; int readBytes= 0; time_t startTime; time_t currentTime; time(&startTime); time(¤tTime); while(1) { recvBuff = ' '; readBytes = read(devHandle, &recvBuff, 1); if (readBytes > 0) { switch(recvBuff) { case 'R': { return RECV_RST; } break; case 'O': { return RECV_OK; } break; case 'E': { printf("Communication error\n"); return RECV_ERR; } break; default: { printf("Unknown answer\n"); return RECV_ERR; } }; } if (difftime(currentTime, startTime) >= readSecWait) break; time(¤tTime); } printf("Read timeout\n"); return RECV_TIMEOUT; } /****************************************************************************/ /* Sending command to device connected to RS232 */ /****************************************************************************/ int serialCmd(unsigned char x, unsigned char readWait) { char cmdBuff[4]; // send 'R' - start transmission writeCmd("R"); if(readAnswer(readWait) == RECV_RST) { // prepare and send position information sprintf(cmdBuff, "%02dH", x); writeCmd(cmdBuff); if(readAnswer(readWait) == RECV_OK) return 0; else printf("Without position confirmation !\n"); } else printf("Without restet confirmation !\n"); return 1; } /****************************************************************************/ /* Cleanup */ /****************************************************************************/ int closeSerial() { if(devHandle != -2 && close(devHandle) != 0) { perror("Closing device handle"); return 1; } return 0; }
track.h
#ifndef _H_TRACK_H #define _H_TRACK_H #define MAX_X_POS 90 #define MOVE_BUSY 0 #define MOVE_IDLE 1 #define MOVE_END 2 #define MIN_SIGNAL -100 #define THREAD_CLOSE 1 #define THREAD_STATUS 0 #define P_FACTOR 3 #include "packet.h" struct sigInfo { char signal; unsigned short cnt; }; int track(struct packetShortInfo *); int setX(void); void *changeAntPosThr(void *); void setBestXPos(void); void initSigArray(void); unsigned char getStatus(); unsigned char closeThread(unsigned char); #endif
track.c
#include <stdio.h> #include <stdlib.h> #include <string.h> // bzero #include <unistd.h> #include <pthread.h> #include "track.h" #include "packet.h" #include "serial.h" static unsigned char xPos; static unsigned char statusFlag = MOVE_BUSY; static struct sigInfo si[MAX_X_POS]; /****************************************************************************/ /* Prepare signal array */ /****************************************************************************/ void initSigArray() { for(xPos = 0; xPos < MAX_X_POS; xPos++) si[xPos].signal = MIN_SIGNAL; } /****************************************************************************/ /* Tracking signal function */ /****************************************************************************/ int track(struct packetShortInfo *pSI) { // if currently antenna is on the move, quit if(getStatus() == MOVE_BUSY) return 1; // fetch signal at ritght possition in signal array. if (si[xPos].signal = -100) si[xPos].signal = *pSI->signal; else si[xPos].signal = (si[xPos].signal + *pSI->signal) / 3; // update packet counter si[xPos].cnt++; return 0; } /****************************************************************************/ /* Setting antenna position -> sending data to RS232 port */ /****************************************************************************/ int setX() { if (serialCmd(xPos, 10) != 0) return 1; printf("Set X: %d\n", xPos); return 0; } /****************************************************************************/ /* Thread, which changes antenna position with given delay. */ /****************************************************************************/ void *changeAntPosThr(void *dPtr) { int *delay = (int *) &dPtr; initSigArray(); xPos = 0; setX(); for(xPos = 0; xPos < MAX_X_POS; xPos++) { statusFlag = MOVE_BUSY; setX(); statusFlag = MOVE_IDLE; usleep(*delay * 1000); if(closeThread(THREAD_STATUS) == THREAD_CLOSE) { pthread_exit(NULL); return; } } setBestXPos(); pthread_exit(NULL); } /****************************************************************************/ /* Thread cleanup */ /****************************************************************************/ unsigned char closeThread(unsigned char cmd) { static unsigned char running; if(cmd == THREAD_CLOSE && running == 0) { running = THREAD_STATUS; } return running; } /****************************************************************************/ /* Calculating best antenna position function, by data saved in signal */ /* array. */ /****************************************************************************/ void setBestXPos() { // for signal and packet count criterium char globSigMax = -100; unsigned char globSigMaxPos = 0; unsigned short globCntMax = 0; unsigned short globCntAvg = 0; unsigned char globCntAvgCnt = 0; unsigned int globCntAvgSum = 0; unsigned char globCntMaxPos = 0; // for static range criterium unsigned char range = 0; unsigned char mRange = 0; unsigned char eRangePos = 0; unsigned char bRangePos = 0; unsigned char cRangePos = 0; // find global maximum and max packiet count for(xPos = 0; xPos < MAX_X_POS; xPos++) { if (globSigMax < si[xPos].signal) { globSigMax = si[xPos].signal; globSigMaxPos = xPos; } if (globCntMax < si[xPos].cnt) { globCntMax = si[xPos].cnt; globCntMaxPos = xPos; } globCntAvgSum+=si[xPos].cnt; if(si[xPos].cnt > 0) { globCntAvgCnt++; } printf("signal at %d is %d, count %d\n", xPos, si[xPos].signal, si[xPos].cnt); } globCntAvg = globCntAvgSum / globCntAvgCnt; printf("Best signal %d at %d\n", globSigMax, globSigMaxPos); printf("Packet sum %d, avg %d\n", globCntAvgSum, globCntAvg); // once again check global maximum, but focus on cnt over avg // find global maximum and max packiet count globSigMax = -100; globSigMaxPos = 0; for(xPos = 0; xPos < MAX_X_POS; xPos++) { if (si[xPos].cnt >= globCntAvg) if (globSigMax < si[xPos].signal) { globSigMax = si[xPos].signal; globSigMaxPos = xPos; } } printf("After correction, best signal %d at %d\n", globSigMax, globSigMaxPos); // find local max static signal for(xPos = 0; xPos < MAX_X_POS -1; xPos++) { if (si[xPos].signal != -100 && si[xPos].signal == si[xPos +1].signal ) { range++; if(mRange <= range) { mRange = range; eRangePos = xPos + 1; } } else range = 0; } bRangePos = eRangePos - mRange; cRangePos = bRangePos + ((eRangePos - bRangePos) / 2); printf("Widest range from %d, to %d, center is %d\n", bRangePos, eRangePos, cRangePos); // cheking signal strength, not position if(si[eRangePos].signal == globSigMax) { printf("Maximum is in the widest range\n"); printf("Setting center from the widest range\n"); xPos = cRangePos; } else { printf("Maximum is in the outer range\n"); printf("Setting best pos from global maximum\n"); xPos = globSigMaxPos; } setX(); printf("Sleepping for 5 sec.\n"); sleep(5); statusFlag = MOVE_END; } /****************************************************************************/ /* Retrun status */ /****************************************************************************/ unsigned char getStatus() { return statusFlag; }
utils.h
#ifndef _H_UTILS_H #define _H_UTILS_H int setChannel(int *, char *, int); void setMac(char *, unsigned char *); void setSid(char *, unsigned char *, unsigned char); // int parseChannel(unsigned char *ptr) { #endif
utils.c
#include <stdio.h> #include <iwlib.h> #include "utils.h" #include "packet.h" /****************************************************************************/ /* Setting channel on given interface */ /****************************************************************************/ int setChannel(int *sock, char *dev, int channel) { struct iwreq wrq; iw_float2freq(channel, &wrq.u.freq); wrq.u.freq.flags = IW_FREQ_FIXED; *sock = iw_sockets_open(); if(iw_set_ext(*sock, dev, SIOCSIWFREQ, &wrq)) return 1; else return 0; return 1; } /****************************************************************************/ /* Setting global bssid */ /****************************************************************************/ void setMac(char *bssid, unsigned char *ptr) { sprintf(bssid, "%02X:%02X:%02X:%02X:%02X:%02X", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); } /****************************************************************************/ /* Setting global essid name */ /****************************************************************************/ void setSid(char *sid, unsigned char *ptr, unsigned char len) { bzero(sid, MAX_SID_LEN + 1); strncpy(sid, ptr, len); sid[len] = '\0'; } /****************************************************************************/ /* Parsing radiotap header channel, useless */ /****************************************************************************/ // int parseChannel(unsigned char *ptr) { // int chan; // // for(chan=0; chan<15; chan++) // if(freq[chan] == (int) (ptr[1] * 16 * 16 + ptr[0])) // break; // // if (chan == 14) // chan = -1; // return chan+1; // }
Makefile
PROJECT_NAME=chanmon OBJECTS=main.o packet.o print.o utils.o track.o serial.o INCLUDES= LIBS=-lpcap -liw -lpthread MACROS = -D$(REALTEK) all: clean cls $(PROJECT_NAME) $(PROJECT_NAME): $(OBJECTS) $(CC) -o $(PROJECT_NAME) $(OBJECTS) $(LDFLAGS) $(LIBS) $(MARCOS) $(INCLUDES) main.o: main.c main.h track.c track.h $(CC) $(CFLAGS) $(INCLUDES) $(MACROS) -c main.c packet.o: packet.c packet.h $(CC) $(CFLAGS) $(INCLUDES) $(MACROS) -c packet.c print.o: print.c print.h $(CC) $(CFLAGS) $(INCLUDES) $(MACROS) -c print.c utils.o: utils.c utils.h $(CC) $(CFLAGS) $(INCLUDES) $(MACROS) -c utils.c track.o: track.c track.h $(CC) $(CFLAGS) $(INCLUDES) $(MACROS) -c track.c serial.o: serial.c serial.h $(CC) $(CFLAGS) $(INCLUDES) $(MACROS) -c serial.c clean: rm -f $(PROJECT_NAME) $(OBJECTS) cls: clear
No comments:
Post a Comment