Main Page | Class Hierarchy | Class List | File List | Class Members

common.cpp

00001 #include "common.h"
00002 #include <stdio.h>
00003 #include <iostream>
00004 #include <string.h>
00005 #include <time.h>
00006 #include <pthread.h>
00007 using namespace std;
00008 
00009 //================================================================
00010 // Packet Header class
00011 //
00012 PacketHdr::PacketHdr()
00013 { 
00014   length_ = 0;  
00015   info_ = new  unsigned char[MAX_HEADER_SIZE] ;
00016 }
00017 
00018 int PacketHdr::getIntegerInfo(int position)
00019 {
00020   int val;
00021   unsigned char *p = info_ +position;
00022   val = *(p++);
00023   val = val << 8 | *(p++);
00024   val = val << 8 | *(p++);
00025   val = val << 8 | *(p);
00026   
00027   return val;
00028 }
00029 
00030 short PacketHdr::getShortIntegerInfo(int position)
00031 {
00032   short val;
00033   unsigned char *p = info_ + position;
00034   val = *(p++);
00035   val = val << 8 | *(p++);
00036 
00037   return val;
00038 }
00039 
00040 void PacketHdr::setIntegerInfo(int a, int position)
00041 {
00042   unsigned char *p = info_ + position;
00043   *(p++) =  a >> 24;
00044   *(p++) = (a >> 16) & 0xFF;
00045   *(p++) = (a >> 8) & 0xFF;
00046   *(p++) =  a & 0xFF;
00047   length_ +=4;
00048 }
00049 
00050 void PacketHdr::setShortIntegerInfo(short b, int position)
00051 {
00052   unsigned char *p = info_ + position;
00053   *(p++) =  b >> 8;
00054   *(p++) =  b & 0xFF;
00055   length_+=2;
00056 }
00057 
00058 
00059 //=================================================================
00060 //  Packet Class
00061 
00062 Packet::Packet()
00063 {
00064   size_ = 0;
00065   length_ = DEFAULT_PAYLOAD_SIZE;
00066   payload_ = new char[DEFAULT_PAYLOAD_SIZE];
00067   header_ = new PacketHdr();
00068 }
00069 
00075 Packet::Packet(int buffer_length)
00076 {
00077   size_ = 0;
00078   length_ = buffer_length;
00079   payload_ = new char[buffer_length];
00080   header_ = new PacketHdr();
00081 }
00082 
00093 void Packet::setPayloadSize(int size)
00094 {
00095   size_ =  size;
00096   if (size > length_) {
00097     if (payload_ != NULL) delete [] payload_;
00098     length_ = (int)(1.5 * size);
00099     payload_ =  new char[length_];
00100   }
00101 }
00102 
00107 int Packet::fillPayload(int size, char *inputstream)
00108 {
00109   setPayloadSize(size);
00110   if (memcpy((char *)payload_, (char *)inputstream,  size) == NULL) {
00111     throw "Fill payload Failed";
00112   }
00113   return 0;
00114 }
00115 
00120 int Packet::makePacket( char *streambuf )
00121 {
00122   streambuf[0]= ( header_->getSize() ) & 0xff;
00123   streambuf[1]=  0x00;
00124   memcpy(streambuf+1, header_->accessInfo(), header_->getSize());
00125   memcpy(streambuf+1+header_->getSize(), payload_, size_);
00126   
00127   return 1+size_+ header_->getSize();
00128 }
00129 
00133 void Packet::extractHeader( char *streambuf )
00134 {
00135   char* p= streambuf; 
00136   int a  = *(p++);
00137   header_->setHeaderSize(a);
00138   memcpy( header_->accessInfo(), p ,a);   
00139 }
00140 
00141 
00142 // =========================================================================
00143 // Address Class
00144 
00145 Address::Address():port_(-1)
00146 {   
00147   hostname_[0] = '\0';  
00148   macaddr_[0] = '\0';
00149 }
00150 
00151 Address::Address(const char* hostname, short port)
00152 { 
00153    setPort(port); 
00154    setHostname(hostname);
00155 }
00156 
00163 void Address::setHWAddrFromColonFormat(const char* colonmac)
00164 {  
00165   char HexChar;
00166   //First verify the address
00167   int Count  = 0;
00168   int num_mac_char = 0;
00169   /* Two ASCII characters per byte of binary data */
00170   bool error_end = false;
00171   while (!error_end)
00172     { /* Scan string for first non-hex character.  Also stop scanning at end
00173          of string (HexChar == 0), or when out of six binary storage space */
00174       HexChar = (char)colonmac[Count++];
00175       if (HexChar == ':') continue;     
00176       if (HexChar > 0x39) HexChar = HexChar | 0x20;  /* Convert upper case to lower */
00177       if ( (HexChar == 0x00) || num_mac_char  >= (MAC_ADDR_LENGTH * 2) ||
00178            (!(((HexChar >= 0x30) && (HexChar <= 0x39))||  /* 0 - 9 */
00179              ((HexChar >= 0x61) && (HexChar <= 0x66))) ) ) /* a - f */ 
00180         {
00181           error_end = true;
00182         } else 
00183             num_mac_char++;
00184     }
00185   if (num_mac_char != MAC_ADDR_LENGTH * 2 )
00186     throw "Given Wrong MAC address Format.";
00187 
00188   // Conversion
00189   unsigned char HexValue = 0x00;
00190   Count = 0;
00191   num_mac_char = 0;
00192   int mac_byte_num = 0;
00193   while (mac_byte_num < MAC_ADDR_LENGTH )
00194     {
00195       HexChar = (char)colonmac[Count++];
00196       if (HexChar == ':') continue;
00197       num_mac_char++;  // locate a HEX character
00198       if (HexChar > 0x39)
00199         HexChar = HexChar | 0x20;  /* Convert upper case to lower */
00200       HexChar -= 0x30;
00201       if (HexChar > 0x09)  /* HexChar is "a" - "f" */
00202         HexChar -= 0x27;
00203       HexValue = (HexValue << 4) | HexChar;
00204       if (num_mac_char % 2  == 0 ) /* If we've converted two ASCII chars... */
00205         {
00206           macaddr_[mac_byte_num] = HexValue;
00207           HexValue = 0x0;
00208           mac_byte_num++;
00209         }
00210     }  
00211   return;   
00212 }
00213 
00214 
00218 char *Address::convertHWAddrToColonFormat()
00219 {
00220   char *colonformat =  new char[17];
00221   //printf("HW Address: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",u[0], u[1], u[2], u[3], u[4], u[5]);
00222   sprintf(colonformat,"%02X:%02X:%02X:%02X:%02X:%02X",
00223           macaddr_[0],macaddr_[1],macaddr_[2],macaddr_[3],macaddr_[4],macaddr_[5]);
00224   // cout << colonformat << endl;
00225   return colonformat;
00226 
00227 }
00228 
00232 void Address::setHWAddr(unsigned char* hwaddr)
00233 {
00234   memcpy(macaddr_, hwaddr , MAC_ADDR_LENGTH*sizeof(unsigned char));
00235 }
00236 
00241 bool Address::isSameMACAddr( Address *addr)
00242 {
00243   if ( memcmp(macaddr_, addr->getHWAddr(), MAC_ADDR_LENGTH*sizeof(unsigned char))  == 0 )
00244            return true;
00245   return false;
00246 
00247 }
00248 
00249 Address* Address::clone()
00250 {
00251   Address * ad =  new Address(hostname_, port_);
00252   ad->setHWAddr(macaddr_);
00253   return ad;
00254 }
00255 
00256 //===============================================================
00257 // Port Class
00258 
00263 Port::Port():sockfd_(0)
00264 {
00265 }
00266 
00267 void Port::setAddress(Address* addr)
00268 {
00269   setHostname(addr->getHostname());
00270   setPort(addr->getPort());
00271 }
00272 
00273 void Port::setRemoteAddress(Address* daddr)
00274 {
00275   setRemoteHostname(daddr->getHostname());
00276   setRemotePort(daddr->getPort());
00277 }
00278 
00287 struct sockaddr * Port::setSockAddress(Address *addr, struct sockaddr_in *address)
00288 {
00289   char *hostname;
00290   int port;
00291   unsigned int tmp;
00292   struct hostent *hp;
00293 
00294   hostname = addr->getHostname();
00295   port = addr->getPort();
00296 
00297   address->sin_family = AF_INET;
00298   address->sin_port   = htons((short)port);
00299       
00300   if (strcmp(hostname, "") == 0) {
00301     address->sin_addr.s_addr = htonl(INADDR_ANY);  
00302   } 
00303   else {
00304     //tmp = inet_addr(hostname);  // If an IP address is given
00305     tmp = inet_aton(hostname, &(address->sin_addr));
00306     //if(tmp != (unsigned long) INADDR_NONE){    
00307     //  address->sin_addr.s_addr = tmp;  
00308     //}
00309     if (tmp == 0) 
00310     {  // if a hostname is passed, call DNS
00311       if ((hp = gethostbyname(hostname)) == NULL) {
00312         herror("gethostbyname");
00313         throw "Error in Resolving hostname!" ;                           
00314       }
00315       memcpy((char *)&address->sin_addr, (char *)hp->h_addr, hp->h_length);
00316     }
00317   }
00318   return (sockaddr*)address;
00319 }
00320 
00325 void Port::decodeSockAddress(Address *addr, struct sockaddr_in *address)
00326 {
00327   addr->setHostname(inet_ntoa(address->sin_addr));
00328   addr->setPort(ntohs(address->sin_port));  
00329 }
00330 
00331 
00332 
00333 //==========================================================
00334 // Sending Port Class
00335 
00336 
00337 SendingPort::SendingPort(): Port(),bcastflag_(0),timer_(this)
00338 {
00339   setHostname("localhost"); 
00340   setPort(DEFAULT_SEND_PORT);  
00341   // setRemoteHostname("internal2");  
00342 }
00343 
00344 
00345 SendingPort::SendingPort(char *hostname, short port):Port(),bcastflag_(0),timer_(this)
00346 {
00347   setHostname(hostname);
00348   setPort(port);
00349   //setRemotePort(DEFAULT_RECV_PORT); 
00350 }
00351 
00365 void SendingPort::init()
00366 {
00367   //"0" shows the sockfd is uninitialized, -1 means error
00368   if (sockfd_ != 0) {
00369     cout << "socket has not been properly initialized!" << endl;
00370     return;
00371   }
00372   if ( myaddr_.isSet() == false) {
00373     setHostname("localhost");
00374     setPort(DEFAULT_SEND_PORT);
00375   }
00376   //check if itsaddr_ is set
00377   if ( itsaddr_.isSet() == false)
00378     throw "Destination address of a sending port is not set!";
00379 
00380   if ((sockfd_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00381     perror("socket");
00382     throw "Error while opening a UDP socket";
00383   }
00384   Address *emptyAddr = new Address("", myaddr_.getPort());
00385   struct sockaddr* addr = setSockAddress(emptyAddr, &mySockAddress_);
00386   if (  bind(sockfd_, addr, sizeof(struct sockaddr_in))  < 0 ){
00387     perror("bind");
00388     throw "Scoket Bind Error";
00389   }
00390    
00391   if (bcastflag_ == 1) 
00392     if (setsockopt(sockfd_,SOL_SOCKET,SO_BROADCAST,&bcastflag_,sizeof(bcastflag_)) == -1   )
00393          {
00394            perror("setsockopt");
00395            throw "Set broadcast option failed.";
00396          }; 
00397 
00398   //create sending buffer
00399   sendingbuf_ = new char[MTU_SIZE+1];
00400   return; 
00401 
00402 }
00403 
00409 void SendingPort::sendPacket(Packet* pkt)
00410 {  
00411    int pktlen = pkt->makePacket(sendingbuf_); 
00412    Address *dst = getRemoteAddr();
00413    int  length = sizeof(struct sockaddr_in); 
00414    struct sockaddr *dest = setSockAddress(dst, &dstSockAddress_);
00415    int len = sendto(sockfd_, sendingbuf_, pktlen, 0, dest, length); 
00416    if (len == -1) 
00417    { 
00418          perror("send");
00419          throw "Sending Error.";
00420    }
00421 }
00422 
00423 //====================================================================
00424 // Functions of ReceivingPort class
00429 ReceivingPort::ReceivingPort(): Port()
00430 {
00431   pkt_= new Packet(MAXBUFLENGTH);
00432 }
00433 
00448 void ReceivingPort::init()
00449 { 
00450   if (sockfd_ != 0) {
00451     return;
00452   }
00453   if ( myaddr_.isSet() == false) {
00454     setHostname("localhost");
00455     setPort(DEFAULT_RECV_PORT);
00456   }
00457   
00458   if ((sockfd_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00459     throw "Error while opening UDP socket of a receiver";
00460   }
00461   Address *emptyAddr = new Address("", myaddr_.getPort());
00462   struct sockaddr* addr = setSockAddress(emptyAddr, &mySockAddress_);
00463   if (  bind(sockfd_, addr, sizeof(struct sockaddr_in))  < 0 ){
00464     throw "Scoket Bind Error occured in an UDP receiver";
00465   }
00466   //cout << "binding to port: " << myaddr_.getPort() << "......" << endl;
00467   // needs a dummy buffer for storing packets
00468   tmpBuffer_ =  new char[MAXBUFLENGTH];
00469 }
00470 
00484 Packet* ReceivingPort::receivePacket()
00485 {
00486   struct sockaddr_in tmpSockAddr;
00487   int length = sizeof(struct sockaddr);
00488   int len = (int)recvfrom(sockfd_, tmpBuffer_, MAXBUFLENGTH, 0, (struct sockaddr*)&tmpSockAddr,(socklen_t *)&length); 
00489   if (len == -1) 
00490   {
00491            perror("recvfrom");
00492            return false;
00493   }         
00494   decodeSockAddress( &itsaddr_, &tmpSockAddr);
00495   pkt_->extractHeader(tmpBuffer_);
00496   //tmpBuffer_ pointer shall not be moved/shifted,it will reused by the receiving port.
00497   pkt_->fillPayload(len-1-pkt_->getHeaderSize(), tmpBuffer_+pkt_->getHeaderSize()+1 );
00498   return pkt_;
00499 }
00500  
00501 //===================================================================
00502 //    LossyReceivingPort class
00507 LossyReceivingPort::LossyReceivingPort(float lossyratio): ReceivingPort(), loss_ratio_(lossyratio),secdelay_(1)
00508 {
00509 }
00510 
00514 Packet* LossyReceivingPort::receivePacket()
00515 {   
00516   Packet *p = ReceivingPort::receivePacket();
00517   //simulate some delay
00518   sleep(secdelay_); //delay
00519   float  x;
00520   // Set evil seed (initial seed)
00521   srand( (unsigned)time( NULL ) );
00522   x = (double) rand()/RAND_MAX;
00523   //cout << x << endl;
00524   if ( x <= loss_ratio_) 
00525     return NULL;
00526   else
00527     return p;
00528 }
00529 
00530 
00531 //====================================================
00533 //===================================================
00534 
00535 TxTimer::TxTimer(SendingPort *txport)
00536 {
00537   port_ = txport;  
00538   tdelay_.tv_nsec = 0;
00539   tdelay_.tv_sec =  0; 
00540 }
00541 
00542 void *TxTimer::timerProc(void *arg) {
00543   TxTimer *th = (TxTimer *)arg;
00544   nanosleep(&(th->tdelay_), NULL);
00545   th->port_->timerHandler(); 
00546   return NULL;
00547 }
00548 
00549 void TxTimer::startTimer(float delay)
00550 {
00551   tdelay_.tv_nsec = (long int)((delay - (int)delay)*1e9);
00552   tdelay_.tv_sec =  (int)delay; 
00553   int error = pthread_create(&tid_, NULL, &timerProc, this );
00554   if (error) 
00555     throw "Timer thread creation failed...";
00556   
00557 }
00558 void TxTimer::stopTimer()
00559 {
00560   pthread_cancel(tid_);
00561 }

Generated on Fri Feb 17 17:55:49 2006 for Common_Classes_Projects_ECE544 by  doxygen 1.4.2