blob: d397706518631feaf7cafd3b13ecd670313119a2 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
// ----------------------------------------------------------------------
//
// This Software is an original work of authorship of PacketVideo Corporation.
// Portions of the Software were developed in collaboration with NTT DoCoMo,
// Inc. or were derived from the public domain or materials licensed from
// third parties. Title and ownership, including all intellectual property
// rights in and to the Software shall remain with PacketVideo Corporation
// and NTT DoCoMo, Inc.
//
// -----------------------------------------------------------------------
/************************************************************************/
/* file name : selcblccmn.h */
/* file contents : Uni-Directional and Bi-Directional */
/* : Logical Channel Signalling Entity */
/* : Common Management Header */
/* draw : '96.11.11 */
/*----------------------------------------------------------------------*/
/* amendment : */
/* Copyright (C) 1996 NTT DoCoMo */
/************************************************************************/
#ifndef _LCENTRY_H_
#define _LCENTRY_H_
#include <stdio.h>
#include "oscl_vector.h"
#include "oscl_mem.h"
#include "oscl_base.h"
/************************************************************************/
/* Uni-Directional and Bi-Directional Logical Status Definition */
/************************************************************************/
#define LCBLC_OUTGOING_RLSED 0X00 /* Outgoing Released */
#define LCBLC_OUTGOING_AWTING_ETBMNT 0X10 /* Outgoing Awaiting Establishement */
#define LCBLC_OUTGOING_ETBED 0X20 /* Outgoing Established */
#define LCBLC_OUTGOING_AWTING_RLS 0X30 /* Outgoing Awaiting Release */
#define LCBLC_INCOMING_RLSED 0X01 /* Incoming Released */
#define LCBLC_INCOMING_AWTING_ETBMNT 0X11 /* Incoming Awaiting Establishment */
#define LCBLC_INCOMING_AWTING_CNFMTN 0X21 /* Incoming Awaiting Confirmation ( Bi-Directional Only ) */
#define LCBLC_INCOMING_ETBED 0X31 /* Incoming Established */
/************************************************************************/
/* Directional Information Definition */
/************************************************************************/
#define NO_DIRECTIONAL 0 /* No-Directional */
#define UNI_DIRECTIONAL 1 /* Uni-Directional */
#define BI_DIRECTIONAL 2 /* Bi-Directional */
/************************************************************************/
/* CLC Definition */
/************************************************************************/
#define CLS_OUTGOING_IDLE 0X00 /* Outgoing Idle */
#define CLS_OUTGOING_AWTING_RPS 0X10 /* Outgoing Awaiting Response */
#define CLS_INCOMING_IDLE 0X01 /* Incoming Idle */
#define CLS_INCOMING_AWTING_RPS 0X11 /* Incoming Awaiting Response */
/************************************************************************/
/* Class Definitions */
/************************************************************************/
typedef enum { LC_OUTGOING, LC_INCOMING } LCDirection_t;
class LCEntry
{
public:
LCEntry(uint32 lcn, LCDirection_t direction)
{
FwdLcn = lcn ;
RvsLcn = 0 ;
/********************************************************/
/* NOTE: OUTGOING with respect to LCBLC */
/********************************************************/
if (direction == LC_OUTGOING)
{
Status = LCBLC_OUTGOING_RLSED ;
ClcStatus = CLS_INCOMING_IDLE;
}
else
{
Status = LCBLC_INCOMING_RLSED ;
ClcStatus = CLS_OUTGOING_IDLE;
}
Directional = NO_DIRECTIONAL ;
TmrSqcNumber = 0 ;
ClcTmrSqcNumber = 0;
}
~LCEntry() {}
void Reset()
{
RvsLcn = 0 ;
if (Status & 0x01) //LC_INCOMING
{
Status = LCBLC_INCOMING_RLSED ;
ClcStatus = CLS_OUTGOING_IDLE;
}
else //LC_OUTGOING
{
Status = LCBLC_OUTGOING_RLSED ;
ClcStatus = CLS_INCOMING_IDLE;
}
Directional = NO_DIRECTIONAL ;
TmrSqcNumber = 0 ;
ClcTmrSqcNumber = 0;
}
uint32 FwdLcnRead()
{
return FwdLcn;
}
void FwdLcnWrite(uint32 fwdLcn)
{
FwdLcn = fwdLcn;
}
uint32 RvsLcnRead()
{
return RvsLcn;
}
void RvsLcnWrite(uint32 rvsLcn)
{
RvsLcn = rvsLcn;
}
uint8 StatusRead()
{
return Status;
}
void StatusWrite(uint8 status)
{
#ifdef PVANALYZER
StatusShow(status, Status);
#endif
Status = status;
// if LC is set to released state, then reset it's attributes so it can be used again
if (Status == LCBLC_OUTGOING_RLSED || Status == LCBLC_INCOMING_RLSED)
{
RvsLcn = 0;
Directional = NO_DIRECTIONAL ;
TmrSqcNumber = 0 ;
}
}
uint8 DirectionalRead()
{
return Directional;
}
void DirectionalWrite(uint8 directional)
{
Directional = directional;
}
void TmrSqcNumberClear()
{
TmrSqcNumber = 0;
}
int32 TmrSqcNumberRead()
{
return TmrSqcNumber;
}
int32 TmrSqcNumberInc()
{
return (++TmrSqcNumber);
}
uint8 ClcStatusRead()
{
return ClcStatus;
}
void ClcStatusWrite(uint8 status)
{
#ifdef PVANALYZER
ClcStatusShow(status, ClcStatus);
#endif
ClcStatus = status;
}
void ClcTmrSqcNumberClear()
{
ClcTmrSqcNumber = 0;
}
int32 ClcTmrSqcNumberRead()
{
return ClcTmrSqcNumber;
}
void ClcTmrSqcNumberInc()
{
ClcTmrSqcNumber++;
}
#ifdef PVANALYZER /* --------SE Analyzer Tool -------- */
#define ANALYZER_SE 0x0020 // (Assume tag is fixed)
void StatusShow(uint8 oldStatus, uint8 newStatus)
{
void Show245(uint16 tag, uint16 indent, char* inString);
char tempString[80];
Show245(ANALYZER_SE, 0, "LCSE/BLCSE State Transition:");
sprintf(tempString, " LogicalChannelNumber = %u", FwdLcn);
Show245(ANALYZER_SE, 0, tempString);
sprintf(tempString, " from--> %s", StateLabel(oldStatus));
Show245(ANALYZER_SE, 0, tempString);
sprintf(tempString, " to--> %s", StateLabel(newStatus));
Show245(ANALYZER_SE, 0, tempString);
Show245(ANALYZER_SE, 0, " ");
}
char* StateLabel(uint8 status)
{
switch (status)
{
case LCBLC_OUTGOING_RLSED:
return("Outgoing RELEASED");
break;
case LCBLC_OUTGOING_AWTING_ETBMNT:
return("Outgoing AWAITING ESTABLISHMENT");
break;
case LCBLC_OUTGOING_ETBED:
return("Outgoing ESTABLISHED");
break;
case LCBLC_OUTGOING_AWTING_RLS:
return("Outgoing AWAITING RELEASE");
break;
case LCBLC_INCOMING_RLSED:
return("Incoming RELEASED");
break;
case LCBLC_INCOMING_AWTING_ETBMNT:
return("Incoming AWAITING ESTABLISHMENT");
break;
case LCBLC_INCOMING_AWTING_CNFMTN:
return("Incoming AWAITING CONFIRMATION");
break;
case LCBLC_INCOMING_ETBED:
return("Incoming ESTABLISHED");
break;
default:
return("UNKNOWN STATE");
}
}
void ClcStatusShow(uint8 oldStatus, uint8 newStatus)
{
void Show245(uint16 tag, uint16 indent, char* inString);
char tempString[80];
Show245(ANALYZER_SE, 0, "CLCSE State Transition:");
sprintf(tempString, " LogicalChannelNumber = %u", FwdLcn);
Show245(ANALYZER_SE, 0, tempString);
sprintf(tempString, " from--> %s", ClcStateLabel(oldStatus));
Show245(ANALYZER_SE, 0, tempString);
sprintf(tempString, " to--> %s", ClcStateLabel(newStatus));
Show245(ANALYZER_SE, 0, tempString);
Show245(ANALYZER_SE, 0, " ");
}
char *ClcStateLabel(uint8 status)
{
switch (status)
{
case CLS_OUTGOING_IDLE:
return("Outgoing IDLE");
break;
case CLS_OUTGOING_AWTING_RPS:
return("Outgoing AWAITING RESPONSE");
break;
case CLS_INCOMING_IDLE:
return("Incoming IDLE");
break;
case CLS_INCOMING_AWTING_RPS:
return("Incoming AWAITING RESPONSE");
break;
default:
return("UNKNOWN STATE");
}
}
#endif /* --------------------------------- */
private:
LCEntry(const LCEntry&);
uint32 FwdLcn ;
uint32 RvsLcn ;
uint8 Directional ;
uint8 Status ;
int32 TmrSqcNumber ;
uint8 ClcStatus; /* Multiple CLCSEs (RAN) */
int32 ClcTmrSqcNumber; /* Multiple CLCSEs (RAN) */
};
class LCEntryList
{
public:
LCEntryList() : Direction(LC_OUTGOING) {}
LCEntryList(LCDirection_t direction) : Direction(direction) {}
~LCEntryList()
{
// delete all LCEntry's remaining
for (Oscl_Vector<LCEntry*, OsclMemAllocator>::iterator it = EntryList.begin(); it != EntryList.end(); it++) OSCL_DELETE((*it));
}
void Reset()
{
// reset all LCEntry's remaining
for (Oscl_Vector<LCEntry*, OsclMemAllocator>::iterator it = EntryList.begin(); it != EntryList.end(); it++)(*it)->Reset();
}
void SetDirection(LCDirection_t direction)
{
Direction = direction;
}
LCEntry* NewLCEntry(uint32 lcn)
{
// allocate a new LCEntry
LCEntry *lcentry = OSCL_NEW(LCEntry, (lcn, Direction));
OsclError::LeaveIfNull(lcentry);
// add it to the list
EntryList.push_back(lcentry);
return lcentry;
}
LCEntry* GetLCEntry(uint32 lcn)
{
lcn = (lcn & 0xFFFF);
// look for existing LCEntry
for (Oscl_Vector<LCEntry*, OsclMemAllocator>::iterator it = EntryList.begin(); it != EntryList.end(); it++)
{
if ((*it)->FwdLcnRead() == lcn)
{
return (*it);
}
}
return NULL;
}
void DeleteLCEntry(uint32 lcn)
{
for (Oscl_Vector<LCEntry*, OsclMemAllocator>::iterator it = EntryList.begin(); it != EntryList.end(); it++)
{
if ((*it)->FwdLcnRead() == lcn)
{
OSCL_DELETE((*it));
EntryList.erase(it);
return;
}
}
}
void DeleteLCEntry(LCEntry *lcentry)
{
for (Oscl_Vector<LCEntry*, OsclMemAllocator>::iterator it = EntryList.begin(); it != EntryList.end(); it++)
{
if ((*it) == lcentry)
{
OSCL_DELETE((*it));
EntryList.erase(it);
return;
}
}
}
private:
LCDirection_t Direction;
Oscl_Vector<LCEntry*, OsclMemAllocator> EntryList;
};
#endif /* _LCENTRY_H_ */