• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~MSDObserver()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:
MSD()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 
~MSD()98         virtual ~MSD() {}
99 
Reset()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 
SetObserver(MSDObserver * observer)111         void SetObserver(MSDObserver *observer)
112         {
113             Observer = observer;
114         }
115 
SetTerminalType(uint8 ttype)116         void SetTerminalType(uint8 ttype)
117         {
118             TerminalType = ttype;
119         }
120 
DetermineRequest()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 
Handler(PS_MasterSlaveDetermination msd)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 
Handler(PS_MasterSlaveDeterminationAck msda)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 
Handler(PS_MasterSlaveDeterminationReject msdr)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 
Handler(PS_MasterSlaveDeterminationRelease msdr)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 
HandlerTimeout()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 
TimeoutOccurred(int32 timerID,int32 timeoutInfo)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 
GetStatus()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 
SetStatus(MSDStatus status)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 
SetState(MSDState state)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 
GetState()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
Idle()276         void Idle()
277         {
278             RetryCnt = 1;
279             SetTimer();
280             SetState(OUTGOING_AWAITING_RESPONSE);
281             SendMSD();
282         }
283 
Idle(PS_MasterSlaveDetermination msd)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 
OutgoingAwaitingResponse(PS_MasterSlaveDeterminationAck msda)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 
OutgoingAwaitingResponse(PS_MasterSlaveDetermination msd)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 
OutgoingAwaitingResponse(PS_MasterSlaveDeterminationReject msdr)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 
OutgoingAwaitingResponse(PS_MasterSlaveDeterminationRelease msdr)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 
OutgoingAwaitingResponseTimeout()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 
IncomingAwaitingResponse(PS_MasterSlaveDeterminationAck msda)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 
IncomingAwaitingResponse(PS_MasterSlaveDetermination msd)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 
IncomingAwaitingResponse(PS_MasterSlaveDeterminationReject msdr)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 
IncomingAwaitingResponse(PS_MasterSlaveDeterminationRelease msdr)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 
IncomingAwaitingResponseTimeout()444         void IncomingAwaitingResponseTimeout()
445         {
446             SetState(IDLE);
447             if (Observer)
448             {
449                 Observer->MSDErrorIndication(MSD_ERROR_CODE_A);
450                 Observer->MSDRejectIndication();
451             }
452         }
453 
DetermineStatus(PS_MasterSlaveDetermination msd)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 
SendMSD()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 
SendMSDReject()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 
SendMSDAck()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 
SendMSDRelease()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 
NewStatusDeterminationNumber()510         void NewStatusDeterminationNumber()
511         {
512             StatusDeterminationNumber = RandGen.Rand() & 0xFFFFFF; // 0xFFFFFF max allowed
513             Print("    Status Det Number -> 0x%08x\n", StatusDeterminationNumber);
514         }
515 
SetTimer()516         void SetTimer()
517         {
518             RequestTimer(106, 0, TimerDuration, this);
519         }
ResetTimer()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