/* -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */

/* By Pablo Martin and Paula Ballester,
 * Strathclyde University, Glasgow.
 * June, 2003.
*/

/* Copyright (c) 2003 Strathclyde University of Glasgow, Scotland.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code and binary code must contain
 * the above copyright notice, this list of conditions and the following
 * disclaimer.
 *
 * 2. All advertising materials mentioning features or use of this software
 * must display the following acknowledgement:
 * This product includes software developed at Strathclyde University of
 * Glasgow, Scotland.
 *
 * 3. The name of the University may not be used to endorse or promote
 * products derived from this software without specific prior written
 * permission.
 * STRATHCLYDE UNIVERSITY OF GLASGOW, MAKES NO REPRESENTATIONS
 * CONCERNING EITHER THE MERCHANTABILITY OF THIS SOFTWARE OR THE
 * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE.  The software
 * is provided "as is" without express or implied warranty of any kind.
*/

#ifndef ns_phy_umts_nodeb_h
#define ns_phy_umts_nodeb_h
#include "marshall.h"
#include "phy-umts.h"
#include <delay.h>
#include <connector.h>
#include <packet.h>
#include <random.h>
#include <arp.h>
#include "phy-umts.h"
#include "mac-umts-nodeb.h"
#include "phy-timers.h"


struct ue_info{
	int paging_group;
	double bytes_slot;
	int in_seq_;
	int count;
      // For Interference Model
  	unsigned long ul_ErrorRate;	// 1 / BLER per frequence
  	double lastRate;			// last rate arrived for this UE
  	double Prx;				// Power received from this UE
	int ul_freq;			// freq used for this UE
	int nSamples;			// samples taken for interference calculation
	double IntPower;			// total power received from this UE
						// for interference calculation
};


/* Umts Phy layer. */
class PhyUmtsNodeb : public LinkDelay {

  friend class PagingTimer;
  friend class DownSlotUmtsTimer;
  friend class AichSlotUmtsTimer;
  friend class TxPktNodebTimer;
  friend class RxPktNodebTimer;
  friend class BlerNodebTimer;

public:
  PhyUmtsNodeb();

  Phy *netif_;            // network interface
  int nodeb_address_;
  void recv(Packet *p, Handler *h);

  // Timer handlers
  void PagingHandler(Event *e);
  void downslotHandler(Event *e);
  void aichslotHandler(Event *e);
  void recvHandler(Event *e);
  void sendHandler(Event *e);
  void blerHandler(Event *e);

  // Store the byte capacity per slot
  void slot_bytes(int pdest, double bytes);
  void remove_ue(int addr);

  nsaddr_t ip_nodeb_;
  inline double& tti() { return tti_;}

 protected:

  LL* ll_;		// ll
  Mac* mac_;

  NsObject* downtarget_;		// for outgoing packet
  NsObject* uptarget_;		// for incoming packet

  PacketQueue* paging_temp_; //temporary storage for a PCH pkt while waiting

  int wait_;		// wait to tx the next paging

  // user defined variables
  static int max_num_ms_;      // user defined max num of MS in cell
  static int max_num_freq_;    // num of frequencies to be permitted inthe cell

  int ue_id[MAX_NUM_UE];	// is a conversion matrix for internal addressing.
  					// The position in the array is the internal address,
					// and the content is MAC address.

  ue_info ue_info_[MAX_NUM_UE];	// information related to ue's


  wcdma_control w_control;	// control parameters for wcdma coding
  int sig_ue_[MAX_NUM_UE];	// signature used for each ue
  double tti_;

  dpcch_contr d_control[MAX_NUM_UE];	// control parameters for DPDCH multiplexing
  static int verbose_;   // to include a verbose output ..

  PacketQueue* aichtoTx_;	// packets to tx in the current slot
  PacketQueue* pkttoTx_;	// packets to tx in the current slot
  PacketQueue* pchtoTx_;	// packets to tx in the current slot
  PacketQueue* data_temp_[MAX_NUM_UE];	// packet received in the current slot from MAC
  Packet * pch_recv_;		// PCH packet received in Physical layer

  // dpdch packets in a slot
  Packet * rx_dpdch[MAX_NUM_UE][MAX_NUM_DPDCH];

  int paging_dest_;	// address of the ue target for paging procedure
  int tx_rate;


  // Interference Model
  double Ioth[MAX_NUM_FREQ];			// Interference power receceived from other NodeB
  int noIoth[MAX_NUM_FREQ];			// Number of samples of Ioth
  int addr[MAX_NUM_UE];				// for passing results to MAC
  unsigned long error[MAX_NUM_UE];		// for passing results to MAC


  BlerTable* BTable;
  Event intr_;
  Event intr1_;
  Event intr;
  Event intrb;

  int down_slot_;

 private:
  int command(int argc, const char*const* argv);

  void radioSwitch(int i);

  // Packet Transmission Functions.

  void recv_from_phy(Packet* p, Handler *h);
  void tx_aich(Packet* p);
  void tx_pich(Packet* p);
  void tx_pch(Packet* p);
  void dl_mux(Packet* p);
  void ul_demux(Packet* p);
  void mk_dpxch(void);
  void decode(int id);
  void send_msg(Packet* p, int scram_c, int sf, int k);
  void send_to_rrc(Packet* p);
  int packet_for_me(Packet* p);
  void mk_pccpch(void);
  void mk_sch(void);
//  int scrambling_allot(void);
  int n_rx_dpdch(int id);
  void tx_to_ue(Packet* p);
  void ue_registry(Packet* p);
  int look_for(int phyaddr);
  void tx_fach(Packet* p);
  void c_coding(Packet* p);
  void c_decoding(Packet* p);


  // to calculate tx time for a packet
  double TX_Time(Packet *p);

  static double start_time_; // The start time for whole WCDMA scheduling.
  static double slot_time_;  // The duration of each WCDMA slot
  static double aich_slot_time_;  // The duration of each AICH slot

  // indicates whether the radio is active or not. Each MS has a seperate radio
  int radio_active_;

  // Timers
  PagingTimer pPaging_;
  DownSlotUmtsTimer pDownSlot_;
  AichSlotUmtsTimer pAichSlot_;
  TxPktNodebTimer pTxPkt_;
  RxPktNodebTimer pRxPkt_;
  BlerNodebTimer pBler_;

  NsObject*	logtarget_;

};

#endif /* __phy_Umts_h__ */
