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