Home | History | Annotate | Download | only in include
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 // ----------------------------------------------------------------------
     19 //
     20 // This Software is an original work of authorship of PacketVideo Corporation.
     21 // Portions of the Software were developed in collaboration with NTT  DoCoMo,
     22 // Inc. or were derived from the public domain or materials licensed from
     23 // third parties.  Title and ownership, including all intellectual property
     24 // rights in and to the Software shall remain with PacketVideo Corporation
     25 // and NTT DoCoMo, Inc.
     26 //
     27 // -----------------------------------------------------------------------
     28 /************************************************************************/
     29 /*  file name       : semsd.h                                           */
     30 /*  file contents   : Master Slave Determination Signalling Entity      */
     31 /*                  :                                 Management Header */
     32 /*  draw            : '96.11.11                                         */
     33 /*----------------------------------------------------------------------*/
     34 /*  amendment       :                                                   */
     35 /*                          Copyright (C) 1996 NTT DoCoMo               */
     36 /************************************************************************/
     37 #ifndef _SEMSD_
     38 #define _SEMSD_
     39 
     40 #include "oscl_base.h"
     41 #include "oscl_rand.h"
     42 #include "oscl_tickcount.h"
     43 #include "oscl_timer.h"
     44 #include "sebase.h"
     45 #include "h245def.h"
     46 #include "h245inf.h"
     47 #include "semsgque.h"
     48 
     49 #define TWO_24 (1<<24)
     50 #define TWO_23 (1<<23)
     51 #define MSD_MAX_RETRIES 100
     52 
     53 enum MSDStatus { MSD_INDETERMINATE = 0, MSD_MASTER = 1, MSD_SLAVE = 2 };
     54 enum MSDErrCode
     55 {
     56     MSD_ERROR_CODE_A = 0, // no response from remove MSD
     57     MSD_ERROR_CODE_B = 1, // remote MSD see no response from local MSD
     58     MSD_ERROR_CODE_C = 2, // inappropriate message
     59     MSD_ERROR_CODE_D = 3, // inappropriate message
     60     MSD_ERROR_CODE_E = 4, // inconsistent field value
     61     MSD_ERROR_CODE_F = 5  // max number of retries reached
     62 };
     63 
     64 //////////////////////////////////////////////////////////////////////////
     65 //////////////////////////////////////////////////////////////////////////
     66 class MSDObserver
     67 {
     68     public:
     69         virtual ~MSDObserver() {}
     70         virtual void MSDDetermineConfirm(MSDStatus type) = 0;
     71         virtual void MSDDetermineIndication(MSDStatus type) = 0;
     72         virtual void MSDRejectIndication() = 0;
     73         virtual void MSDErrorIndication(MSDErrCode errCode) = 0;
     74 };
     75 
     76 //////////////////////////////////////////////////////////////////////////
     77 //////////////////////////////////////////////////////////////////////////
     78 class MSD : public SEBase, public OsclTimerObserver
     79 {
     80     private:
     81         enum MSDState { IDLE, OUTGOING_AWAITING_RESPONSE, INCOMING_AWAITING_RESPONSE }; // states
     82 
     83     public:
     84         MSD() :
     85                 Observer(NULL),
     86                 TerminalType(128),
     87                 State(IDLE),
     88                 Status(MSD_INDETERMINATE),
     89                 StatusDeterminationNumber(0),
     90                 RetryCnt(0)
     91         {
     92             // seed the random number generator
     93             RandGen.Seed(OsclTickCount::TickCount());
     94             // calcuate initial status determination number
     95             NewStatusDeterminationNumber();
     96         }
     97 
     98         virtual ~MSD() {}
     99 
    100         void Reset()
    101         {
    102             Print("Reset MSD\n");
    103             State = IDLE;
    104             Status = MSD_INDETERMINATE;
    105             RetryCnt = 0;
    106             // calcuate new status determination number
    107             NewStatusDeterminationNumber();
    108             ResetTimer();
    109         }
    110 
    111         void SetObserver(MSDObserver *observer)
    112         {
    113             Observer = observer;
    114         }
    115 
    116         void SetTerminalType(uint8 ttype)
    117         {
    118             TerminalType = ttype;
    119         }
    120 
    121         void DetermineRequest()
    122         {
    123             Print("Received MSD Determine Request\n");
    124             switch (GetState())
    125             {
    126                 case IDLE:
    127                     Idle();
    128                     break;
    129                 case OUTGOING_AWAITING_RESPONSE:
    130                 case INCOMING_AWAITING_RESPONSE:
    131                 default:
    132                     break;
    133             }
    134         }
    135 
    136         void Handler(PS_MasterSlaveDetermination msd)
    137         {
    138             Print("Received MSD\n");
    139             switch (GetState())
    140             {
    141                 case IDLE:
    142                     Idle(msd);
    143                     break;
    144                 case OUTGOING_AWAITING_RESPONSE:
    145                     OutgoingAwaitingResponse(msd);
    146                     break;
    147                 case INCOMING_AWAITING_RESPONSE:
    148                     IncomingAwaitingResponse(msd);
    149                     break;
    150                 default:
    151                     break;
    152             }
    153         }
    154 
    155         void Handler(PS_MasterSlaveDeterminationAck msda)
    156         {
    157             Print("Received MSDAck\n");
    158             switch (GetState())
    159             {
    160                 case IDLE:
    161                     break;
    162                 case OUTGOING_AWAITING_RESPONSE:
    163                     OutgoingAwaitingResponse(msda);
    164                     break;
    165                 case INCOMING_AWAITING_RESPONSE:
    166                     IncomingAwaitingResponse(msda);
    167                     break;
    168                 default:
    169                     break;
    170             }
    171         }
    172 
    173         void Handler(PS_MasterSlaveDeterminationReject msdr)
    174         {
    175             Print("Received MSDReject\n");
    176             switch (GetState())
    177             {
    178                 case IDLE:
    179                     break;
    180                 case OUTGOING_AWAITING_RESPONSE:
    181                     OutgoingAwaitingResponse(msdr);
    182                     break;
    183                 case INCOMING_AWAITING_RESPONSE:
    184                     IncomingAwaitingResponse(msdr);
    185                     break;
    186                 default:
    187                     break;
    188             }
    189         }
    190 
    191         void Handler(PS_MasterSlaveDeterminationRelease msdr)
    192         {
    193             Print("Received MSDRelease\n");
    194             switch (GetState())
    195             {
    196                 case IDLE:
    197                     break;
    198                 case OUTGOING_AWAITING_RESPONSE:
    199                     OutgoingAwaitingResponse(msdr);
    200                     break;
    201                 case INCOMING_AWAITING_RESPONSE:
    202                     IncomingAwaitingResponse(msdr);
    203                     break;
    204                 default:
    205                     break;
    206             }
    207         }
    208 
    209         void HandlerTimeout()
    210         {
    211             Print("Received MSD Timeout\n");
    212             switch (GetState())
    213             {
    214                 case IDLE:
    215                     break;
    216                 case OUTGOING_AWAITING_RESPONSE:
    217                     OutgoingAwaitingResponseTimeout();
    218                     break;
    219                 case INCOMING_AWAITING_RESPONSE:
    220                     IncomingAwaitingResponseTimeout();
    221                     break;
    222                 default:
    223                     break;
    224             }
    225         }
    226 
    227         void TimeoutOccurred(int32 timerID, int32 timeoutInfo)
    228         {
    229             Print("    MSD::TimeoutOccurred");
    230 
    231             OSCL_UNUSED_ARG(timerID);
    232             OSCL_UNUSED_ARG(timeoutInfo);
    233             HandlerTimeout();
    234         }
    235 
    236         MSDStatus GetStatus()
    237         {
    238             if (Status == MSD_INDETERMINATE) Print("    Status == INDETERMINATE\n");
    239             else if (Status == MSD_MASTER) Print("    Status == MASTER\n");
    240             else if (Status == MSD_SLAVE) Print("    Status == SLAVE\n");
    241 
    242             return Status;
    243         }
    244 
    245     private:
    246         MSD(const MSD&);
    247 
    248         void SetStatus(MSDStatus status)
    249         {
    250             Status = status;
    251 
    252             if (Status == MSD_INDETERMINATE) Print("    Status -> INDETERMINATE\n");
    253             else if (Status == MSD_MASTER) Print("    Status -> MASTER\n");
    254             else if (Status == MSD_SLAVE) Print("    Status -> SLAVE\n");
    255         }
    256 
    257         void SetState(MSDState state)
    258         {
    259             State = state;
    260 
    261             if (State == IDLE)  Print("    State -> IDLE\n");
    262             else if (State == OUTGOING_AWAITING_RESPONSE) Print("    State -> OUTGOING_AWAITING_RESPONSE\n");
    263             else if (State == INCOMING_AWAITING_RESPONSE) Print("    State -> INCOMING_AWAITING_RESPONSE\n");
    264         }
    265 
    266         MSDState GetState()
    267         {
    268             if (State == IDLE)  Print("    State == IDLE\n");
    269             else if (State == OUTGOING_AWAITING_RESPONSE) Print("    State == OUTGOING_AWAITING_RESPONSE\n");
    270             else if (State == INCOMING_AWAITING_RESPONSE) Print("    State == INCOMING_AWAITING_RESPONSE\n");
    271 
    272             return State;
    273         }
    274 
    275         // Handles Determine.Request when in IDLE state
    276         void Idle()
    277         {
    278             RetryCnt = 1;
    279             SetTimer();
    280             SetState(OUTGOING_AWAITING_RESPONSE);
    281             SendMSD();
    282         }
    283 
    284         void Idle(PS_MasterSlaveDetermination msd)
    285         {
    286             DetermineStatus(msd);
    287             if (GetStatus() == MSD_INDETERMINATE)
    288             {
    289                 SendMSDReject();
    290             }
    291             else
    292             {
    293                 SetTimer();
    294                 SetState(INCOMING_AWAITING_RESPONSE);
    295                 SendMSDAck();
    296                 if (Observer) Observer->MSDDetermineIndication(Status);
    297             }
    298         }
    299 
    300         void OutgoingAwaitingResponse(PS_MasterSlaveDeterminationAck msda)
    301         {
    302             ResetTimer();
    303             SetStatus(((msda->decision.index == 0) ? MSD_MASTER : MSD_SLAVE));
    304             SetState(IDLE);
    305             SendMSDAck();
    306             if (Observer) Observer->MSDDetermineConfirm(Status);
    307         }
    308 
    309         void OutgoingAwaitingResponse(PS_MasterSlaveDetermination msd)
    310         {
    311             ResetTimer();
    312             DetermineStatus(msd);
    313             if (GetStatus() == MSD_INDETERMINATE)
    314             {
    315                 if (RetryCnt >= MSD_MAX_RETRIES)
    316                 {
    317                     SetState(IDLE);
    318                     if (Observer)
    319                     {
    320                         Observer->MSDErrorIndication(MSD_ERROR_CODE_F);
    321                         Observer->MSDRejectIndication();
    322                     }
    323                 }
    324                 else
    325                 {
    326                     NewStatusDeterminationNumber();
    327                     RetryCnt++;
    328                     SetTimer();
    329                     SetState(OUTGOING_AWAITING_RESPONSE);
    330                     SendMSD();
    331                 }
    332             }
    333             else
    334             {
    335                 SetTimer();
    336                 SetState(INCOMING_AWAITING_RESPONSE);
    337                 SendMSDAck();
    338                 if (Observer) Observer->MSDDetermineIndication(Status);
    339             }
    340         }
    341 
    342         void OutgoingAwaitingResponse(PS_MasterSlaveDeterminationReject msdr)
    343         {
    344             OSCL_UNUSED_ARG(msdr);
    345             ResetTimer();
    346             if (RetryCnt >= MSD_MAX_RETRIES)
    347             {
    348                 SetState(IDLE);
    349                 if (Observer)
    350                 {
    351                     Observer->MSDErrorIndication(MSD_ERROR_CODE_F);
    352                     Observer->MSDRejectIndication();
    353                 }
    354             }
    355             else
    356             {
    357                 NewStatusDeterminationNumber();
    358                 RetryCnt++;
    359                 SetTimer();
    360                 SetState(OUTGOING_AWAITING_RESPONSE);
    361                 SendMSD();
    362             }
    363         }
    364 
    365         void OutgoingAwaitingResponse(PS_MasterSlaveDeterminationRelease msdr)
    366         {
    367             OSCL_UNUSED_ARG(msdr);
    368             ResetTimer();
    369             SetState(IDLE);
    370             if (Observer)
    371             {
    372                 Observer->MSDErrorIndication(MSD_ERROR_CODE_B);
    373                 Observer->MSDRejectIndication();
    374             }
    375         }
    376 
    377         void OutgoingAwaitingResponseTimeout()
    378         {
    379             SendMSDRelease();
    380             SetState(IDLE);
    381             if (Observer)
    382             {
    383                 Observer->MSDErrorIndication(MSD_ERROR_CODE_A);
    384                 Observer->MSDRejectIndication();
    385             }
    386         }
    387 
    388         void IncomingAwaitingResponse(PS_MasterSlaveDeterminationAck msda)
    389         {
    390             ResetTimer();
    391             if ((msda->decision.index == 0 && GetStatus() == MSD_MASTER) ||
    392                     (msda->decision.index == 1 && GetStatus() == MSD_SLAVE))
    393             {
    394                 SetState(IDLE);
    395                 if (Observer) Observer->MSDDetermineConfirm(Status);
    396             }
    397             else
    398             {
    399                 SetState(IDLE);
    400                 if (Observer)
    401                 {
    402                     Observer->MSDErrorIndication(MSD_ERROR_CODE_E);
    403                     Observer->MSDRejectIndication();
    404                 }
    405             }
    406         }
    407 
    408         void IncomingAwaitingResponse(PS_MasterSlaveDetermination msd)
    409         {
    410             OSCL_UNUSED_ARG(msd);
    411             ResetTimer();
    412             SetState(IDLE);
    413             if (Observer)
    414             {
    415                 Observer->MSDErrorIndication(MSD_ERROR_CODE_C);
    416                 Observer->MSDRejectIndication();
    417             }
    418         }
    419 
    420         void IncomingAwaitingResponse(PS_MasterSlaveDeterminationReject msdr)
    421         {
    422             OSCL_UNUSED_ARG(msdr);
    423             ResetTimer();
    424             SetState(IDLE);
    425             if (Observer)
    426             {
    427                 Observer->MSDErrorIndication(MSD_ERROR_CODE_D);
    428                 Observer->MSDRejectIndication();
    429             }
    430         }
    431 
    432         void IncomingAwaitingResponse(PS_MasterSlaveDeterminationRelease msdr)
    433         {
    434             OSCL_UNUSED_ARG(msdr);
    435             ResetTimer();
    436             SetState(IDLE);
    437             if (Observer)
    438             {
    439                 Observer->MSDErrorIndication(MSD_ERROR_CODE_B);
    440                 Observer->MSDRejectIndication();
    441             }
    442         }
    443 
    444         void IncomingAwaitingResponseTimeout()
    445         {
    446             SetState(IDLE);
    447             if (Observer)
    448             {
    449                 Observer->MSDErrorIndication(MSD_ERROR_CODE_A);
    450                 Observer->MSDRejectIndication();
    451             }
    452         }
    453 
    454         void DetermineStatus(PS_MasterSlaveDetermination msd)
    455         {
    456             Print("    My Terminal Type == %d, Incoming Terminal Type == %d\n", TerminalType, msd->terminalType);
    457             Print("    My Status Det Num == 0x%08x, Incoming Status Det Num == 0x%08x\n", StatusDeterminationNumber, msd->statusDeterminationNumber);
    458 
    459             if (TerminalType != msd->terminalType)
    460             {
    461                 SetStatus((TerminalType < msd->terminalType) ? MSD_SLAVE : MSD_MASTER);
    462             }
    463             else
    464             {
    465                 uint32 diff = (msd->statusDeterminationNumber - StatusDeterminationNumber) % TWO_24;
    466                 if (diff == 0 || diff == TWO_23) SetStatus(MSD_INDETERMINATE);
    467                 else SetStatus((diff < TWO_23) ? MSD_MASTER : MSD_SLAVE);
    468             }
    469         }
    470 
    471         void SendMSD()
    472         {
    473             Print("    Sending MSD - Terminal Type == %d, Status Det Num == 0x%08x\n", TerminalType, StatusDeterminationNumber);
    474             S_MasterSlaveDetermination masterSlaveDetermination ;
    475 
    476             masterSlaveDetermination.terminalType = TerminalType;
    477             masterSlaveDetermination.statusDeterminationNumber = StatusDeterminationNumber;
    478 
    479             MessageSend(H245_MSG_REQ, MSGTYP_MSD, (uint8*)&masterSlaveDetermination);
    480         }
    481 
    482         void SendMSDReject()
    483         {
    484             Print("    Sending MSDReject\n");
    485             S_MasterSlaveDeterminationReject masterSlaveDeterminationReject ;
    486 
    487             masterSlaveDeterminationReject.msdRejectCause.index = 0 ;
    488 
    489             MessageSend(H245_MSG_RPS, MSGTYP_MSD_RJT, (uint8*)&masterSlaveDeterminationReject) ;
    490         }
    491 
    492         void SendMSDAck()
    493         {
    494             Print("    Sending MSDAck\n");
    495             S_MasterSlaveDeterminationAck  masterSlaveDeterminationAck ;
    496 
    497             masterSlaveDeterminationAck.decision.index = (uint16)((Status == MSD_MASTER) ? 1 : 0);
    498 
    499             MessageSend(H245_MSG_RPS, MSGTYP_MSD_ACK, (uint8*)&masterSlaveDeterminationAck) ;
    500         }
    501 
    502         void SendMSDRelease()
    503         {
    504             Print("    Sending MSDRelease\n");
    505             S_MasterSlaveDeterminationRelease  masterSlaveDeterminationRelease ;
    506 
    507             MessageSend(H245_MSG_IDC, MSGTYP_MSD_RLS, (uint8*)&masterSlaveDeterminationRelease);
    508         }
    509 
    510         void NewStatusDeterminationNumber()
    511         {
    512             StatusDeterminationNumber = RandGen.Rand() & 0xFFFFFF; // 0xFFFFFF max allowed
    513             Print("    Status Det Number -> 0x%08x\n", StatusDeterminationNumber);
    514         }
    515 
    516         void SetTimer()
    517         {
    518             RequestTimer(106, 0, TimerDuration, this);
    519         }
    520         void ResetTimer()
    521         {
    522             CancelTimer(106);
    523         }
    524 
    525         MSDObserver *Observer;
    526         uint8 TerminalType;
    527         MSDState State;
    528         MSDStatus Status;
    529         uint32 StatusDeterminationNumber;
    530         uint8 RetryCnt;
    531         OsclRand RandGen;
    532 };
    533 
    534 #endif /* _SEMSD_ */
    535