00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <ptlib.h>
00040 #include <h323.h>
00041
00042 #ifdef H323_H224
00043
00044 #ifdef __GNUC__
00045 #pragma implementation "h224.h"
00046 #pragma implementation "h224handler.h"
00047 #endif
00048
00049 #ifdef _MSC_VER
00050 #pragma warning(disable : 4244)
00051 #endif
00052
00053 #include <h224.h>
00054 #include <h224handler.h>
00055 #include <h323con.h>
00056 #include <h245.h>
00057
00058
00059 H224_Frame::H224_Frame(PINDEX size)
00060 : Q922_Frame(H224_HEADER_SIZE + size)
00061 {
00062 SetHighPriority(FALSE);
00063
00064 SetControlFieldOctet(0x03);
00065
00066 BYTE *data = GetInformationFieldPtr();
00067
00068
00069 data[0] = 0;
00070 data[1] = 0;
00071 data[2] = 0;
00072 data[3] = 0;
00073
00074
00075 data[4] = 0;
00076
00077
00078 data[5] = 0;
00079 }
00080
00081 H224_Frame::~H224_Frame()
00082 {
00083 }
00084
00085 void H224_Frame::SetHighPriority(BOOL flag)
00086 {
00087 SetHighOrderAddressOctet(0x00);
00088
00089 if(flag) {
00090 SetLowOrderAddressOctet(0x71);
00091 } else {
00092 SetLowOrderAddressOctet(0x061);
00093 }
00094 }
00095
00096 WORD H224_Frame::GetDestinationTerminalAddress() const
00097 {
00098 BYTE *data = GetInformationFieldPtr();
00099 return (WORD)((data[0] << 8) | data[1]);
00100 }
00101
00102 void H224_Frame::SetDestinationTerminalAddress(WORD address)
00103 {
00104 BYTE *data = GetInformationFieldPtr();
00105 data[0] = (BYTE)(address >> 8);
00106 data[1] = (BYTE) address;
00107 }
00108
00109 WORD H224_Frame::GetSourceTerminalAddress() const
00110 {
00111 BYTE *data = GetInformationFieldPtr();
00112 return (WORD)((data[2] << 8) | data[3]);
00113 }
00114
00115 void H224_Frame::SetSourceTerminalAddress(WORD address)
00116 {
00117 BYTE *data = GetInformationFieldPtr();
00118 data[2] = (BYTE)(address >> 8);
00119 data[3] = (BYTE) address;
00120 }
00121
00122 BYTE H224_Frame::GetClientID() const
00123 {
00124 BYTE *data = GetInformationFieldPtr();
00125
00126 return data[4] & 0x7f;
00127 }
00128
00129 void H224_Frame::SetClientID(BYTE clientID)
00130 {
00131
00132
00133 PAssert(clientID <= 0x01, "Invalid client ID");
00134
00135 BYTE *data = GetInformationFieldPtr();
00136
00137 data[4] = clientID;
00138 }
00139
00140 BOOL H224_Frame::GetBS() const
00141 {
00142 BYTE *data = GetInformationFieldPtr();
00143
00144 return (data[5] & 0x80) != 0;
00145 }
00146
00147 void H224_Frame::SetBS(BOOL flag)
00148 {
00149 BYTE *data = GetInformationFieldPtr();
00150
00151 if(flag) {
00152 data[5] |= 0x80;
00153 } else {
00154 data[5] &= 0x7f;
00155 }
00156 }
00157
00158 BOOL H224_Frame::GetES() const
00159 {
00160 BYTE *data = GetInformationFieldPtr();
00161
00162 return (data[5] & 0x40) != 0;
00163 }
00164
00165 void H224_Frame::SetES(BOOL flag)
00166 {
00167 BYTE *data = GetInformationFieldPtr();
00168
00169 if(flag) {
00170 data[5] |= 0x40;
00171 } else {
00172 data[5] &= 0xbf;
00173 }
00174 }
00175
00176 BOOL H224_Frame::GetC1() const
00177 {
00178 BYTE *data = GetInformationFieldPtr();
00179
00180 return (data[5] & 0x20) != 0;
00181 }
00182
00183 void H224_Frame::SetC1(BOOL flag)
00184 {
00185 BYTE *data = GetInformationFieldPtr();
00186
00187 if(flag) {
00188 data[5] |= 0x20;
00189 } else {
00190 data[5] &= 0xdf;
00191 }
00192 }
00193
00194 BOOL H224_Frame::GetC0() const
00195 {
00196 BYTE *data = GetInformationFieldPtr();
00197
00198 return (data[5] & 0x10) != 0;
00199 }
00200
00201 void H224_Frame::SetC0(BOOL flag)
00202 {
00203 BYTE *data = GetInformationFieldPtr();
00204
00205 if(flag) {
00206 data[5] |= 0x10;
00207 } else {
00208 data[5] &= 0xef;
00209 }
00210 }
00211
00212 BYTE H224_Frame::GetSegmentNumber() const
00213 {
00214 BYTE *data = GetInformationFieldPtr();
00215
00216 return (data[5] & 0x0f);
00217 }
00218
00219 void H224_Frame::SetSegmentNumber(BYTE segmentNumber)
00220 {
00221 BYTE *data = GetInformationFieldPtr();
00222
00223 data[5] &= 0xf0;
00224 data[5] |= (segmentNumber & 0x0f);
00225 }
00226
00227 BOOL H224_Frame::Decode(const BYTE *data,
00228 PINDEX size)
00229 {
00230 BOOL result = Q922_Frame::Decode(data, size);
00231
00232 if(result == FALSE) {
00233 return FALSE;
00234 }
00235
00236
00237 BYTE highOrderAddressOctet = GetHighOrderAddressOctet();
00238 BYTE lowOrderAddressOctet = GetLowOrderAddressOctet();
00239 BYTE controlFieldOctet = GetControlFieldOctet();
00240
00241 if((highOrderAddressOctet != 0x00) ||
00242 (!(lowOrderAddressOctet == 0x61 || lowOrderAddressOctet == 0x71)) ||
00243 (controlFieldOctet != 0x03) ||
00244 (GetClientID() > 0x02))
00245 {
00246 return FALSE;
00247 }
00248
00249 return TRUE;
00250 }
00251
00253
00254 OpalH224Handler::OpalH224Handler(H323Connection & connection,
00255 unsigned sessionID)
00256 : transmitMutex()
00257 {
00258
00259
00260 RTP_Session *session;
00261 H245_TransportAddress addr;
00262 connection.GetControlChannel().SetUpTransportPDU(addr, H323Transport::UseLocalTSAP);
00263 session = connection.UseSession(sessionID,addr,H323Channel::IsBidirectional);
00264
00265 h281Handler = connection.CreateH281ProtocolHandler(*this);
00266 receiverThread = NULL;
00267
00268 }
00269
00270 OpalH224Handler::~OpalH224Handler()
00271 {
00272 delete h281Handler;
00273 }
00274
00275 void OpalH224Handler::StartTransmit()
00276 {
00277 PWaitAndSignal m(transmitMutex);
00278
00279 if(canTransmit == TRUE) {
00280 return;
00281 }
00282
00283 canTransmit = TRUE;
00284
00285 transmitFrame = new RTP_DataFrame(300);
00286
00287
00288 transmitFrame->SetPayloadType((RTP_DataFrame::PayloadTypes)100);
00289 transmitBitIndex = 7;
00290 transmitStartTime = new PTime();
00291
00292 SendClientList();
00293 SendExtraCapabilities();
00294 }
00295
00296 void OpalH224Handler::StopTransmit()
00297 {
00298 PWaitAndSignal m(transmitMutex);
00299
00300 delete transmitStartTime;
00301 transmitStartTime = NULL;
00302
00303 canTransmit = FALSE;
00304 }
00305
00306 void OpalH224Handler::StartReceive()
00307 {
00308 if(receiverThread != NULL) {
00309 PTRACE(5, "H.224 handler is already receiving");
00310 return;
00311 }
00312
00313 receiverThread = CreateH224ReceiverThread();
00314 receiverThread->Resume();
00315 }
00316
00317 void OpalH224Handler::StopReceive()
00318 {
00319 if(receiverThread != NULL) {
00320 receiverThread->Close();
00321 }
00322 }
00323
00324 BOOL OpalH224Handler::SendClientList()
00325 {
00326 PWaitAndSignal m(transmitMutex);
00327
00328 if(canTransmit == FALSE) {
00329 return FALSE;
00330 }
00331
00332 H224_Frame h224Frame = H224_Frame(4);
00333 h224Frame.SetHighPriority(TRUE);
00334 h224Frame.SetDestinationTerminalAddress(H224_BROADCAST);
00335 h224Frame.SetSourceTerminalAddress(H224_BROADCAST);
00336
00337
00338 h224Frame.SetClientID(0x00);
00339
00340
00341 h224Frame.SetBS(TRUE);
00342 h224Frame.SetES(TRUE);
00343 h224Frame.SetC1(FALSE);
00344 h224Frame.SetC0(FALSE);
00345 h224Frame.SetSegmentNumber(0);
00346
00347 BYTE *ptr = h224Frame.GetClientDataPtr();
00348
00349 ptr[0] = 0x01;
00350 ptr[1] = 0x00;
00351 ptr[2] = 0x01;
00352 ptr[3] = (0x80 | H281_CLIENT_ID);
00353
00354 TransmitFrame(h224Frame);
00355
00356 return TRUE;
00357 }
00358
00359 BOOL OpalH224Handler::SendExtraCapabilities()
00360 {
00361 PWaitAndSignal m(transmitMutex);
00362
00363 if(canTransmit == FALSE) {
00364 return FALSE;
00365 }
00366
00367 h281Handler->SendExtraCapabilities();
00368
00369 return TRUE;
00370 }
00371
00372 BOOL OpalH224Handler::SendClientListCommand()
00373 {
00374 PWaitAndSignal m(transmitMutex);
00375
00376 if(canTransmit == FALSE) {
00377 return FALSE;
00378 }
00379
00380 H224_Frame h224Frame = H224_Frame(2);
00381 h224Frame.SetHighPriority(TRUE);
00382 h224Frame.SetDestinationTerminalAddress(H224_BROADCAST);
00383 h224Frame.SetSourceTerminalAddress(H224_BROADCAST);
00384
00385
00386 h224Frame.SetClientID(0x00);
00387
00388
00389 h224Frame.SetBS(TRUE);
00390 h224Frame.SetES(TRUE);
00391 h224Frame.SetC1(FALSE);
00392 h224Frame.SetC0(FALSE);
00393 h224Frame.SetSegmentNumber(0);
00394
00395 BYTE *ptr = h224Frame.GetClientDataPtr();
00396
00397 ptr[0] = 0x01;
00398 ptr[1] = 0xff;
00399
00400 TransmitFrame(h224Frame);
00401
00402 return TRUE;
00403 }
00404
00405 BOOL OpalH224Handler::SendExtraCapabilitiesCommand(BYTE clientID)
00406 {
00407 PWaitAndSignal m(transmitMutex);
00408
00409 if(canTransmit == FALSE) {
00410 return FALSE;
00411 }
00412
00413 if(clientID != H281_CLIENT_ID) {
00414 return FALSE;
00415 }
00416
00417 H224_Frame h224Frame = H224_Frame(4);
00418 h224Frame.SetHighPriority(TRUE);
00419 h224Frame.SetDestinationTerminalAddress(H224_BROADCAST);
00420 h224Frame.SetSourceTerminalAddress(H224_BROADCAST);
00421
00422
00423 h224Frame.SetClientID(0x00);
00424
00425
00426 h224Frame.SetBS(TRUE);
00427 h224Frame.SetES(TRUE);
00428 h224Frame.SetC1(FALSE);
00429 h224Frame.SetC0(FALSE);
00430 h224Frame.SetSegmentNumber(0);
00431
00432 BYTE *ptr = h224Frame.GetClientDataPtr();
00433
00434 ptr[0] = 0x01;
00435 ptr[1] = 0xFF;
00436 ptr[2] = (0x80 | clientID);
00437
00438 TransmitFrame(h224Frame);
00439
00440 return TRUE;
00441 }
00442
00443 BOOL OpalH224Handler::SendExtraCapabilitiesMessage(BYTE clientID,
00444 BYTE *data, PINDEX length)
00445 {
00446 PWaitAndSignal m(transmitMutex);
00447
00448
00449 if(clientID != H281_CLIENT_ID) {
00450
00451 return FALSE;
00452 }
00453
00454 if(canTransmit == FALSE) {
00455 return FALSE;
00456 }
00457
00458 H224_Frame h224Frame = H224_Frame(length+3);
00459 h224Frame.SetHighPriority(TRUE);
00460 h224Frame.SetDestinationTerminalAddress(H224_BROADCAST);
00461 h224Frame.SetSourceTerminalAddress(H224_BROADCAST);
00462
00463
00464 h224Frame.SetClientID(0x00);
00465
00466
00467 h224Frame.SetBS(TRUE);
00468 h224Frame.SetES(TRUE);
00469 h224Frame.SetC1(FALSE);
00470 h224Frame.SetC0(FALSE);
00471 h224Frame.SetSegmentNumber(0);
00472
00473 BYTE *ptr = h224Frame.GetClientDataPtr();
00474
00475 ptr[0] = 0x02;
00476 ptr[1] = 0x00;
00477 ptr[2] = (0x80 | clientID);
00478
00479 memcpy(ptr+3, data, length);
00480
00481 TransmitFrame(h224Frame);
00482
00483 return TRUE;
00484 }
00485
00486 BOOL OpalH224Handler::TransmitClientFrame(BYTE clientID, H224_Frame & frame)
00487 {
00488 PWaitAndSignal m(transmitMutex);
00489
00490
00491 if(clientID != H281_CLIENT_ID) {
00492 return FALSE;
00493 }
00494
00495 frame.SetClientID(clientID);
00496
00497 TransmitFrame(frame);
00498
00499 return TRUE;
00500 }
00501
00502 BOOL OpalH224Handler::OnReceivedFrame(H224_Frame & frame)
00503 {
00504 if(frame.GetDestinationTerminalAddress() != H224_BROADCAST) {
00505
00506 PTRACE(3, "Received H.224 frame with non-broadcast address");
00507 return TRUE;
00508 }
00509 BYTE clientID = frame.GetClientID();
00510
00511 if(clientID == 0x00) {
00512 return OnReceivedCMEMessage(frame);
00513 }
00514
00515 if(clientID == H281_CLIENT_ID) {
00516 h281Handler->OnReceivedMessage((const H281_Frame &)frame);
00517 }
00518
00519 return TRUE;
00520 }
00521
00522 BOOL OpalH224Handler::OnReceivedCMEMessage(H224_Frame & frame)
00523 {
00524 BYTE *data = frame.GetClientDataPtr();
00525
00526 if(data[0] == 0x01) {
00527
00528 if(data[1] == 0x00) {
00529 return OnReceivedClientList(frame);
00530
00531 } else if(data[1] == 0xff) {
00532 return OnReceivedClientListCommand();
00533 }
00534
00535 } else if(data[0] == 0x02) {
00536
00537 if(data[1] == 0x00) {
00538 return OnReceivedExtraCapabilities(frame);
00539
00540 } else if(data[1] == 0xff) {
00541 return OnReceivedExtraCapabilitiesCommand();
00542 }
00543 }
00544
00545
00546 return TRUE;
00547 }
00548
00549 BOOL OpalH224Handler::OnReceivedClientList(H224_Frame & frame)
00550 {
00551 BYTE *data = frame.GetClientDataPtr();
00552
00553 BYTE numberOfClients = data[2];
00554
00555 PINDEX i = 3;
00556
00557 BOOL remoteHasH281 = FALSE;
00558
00559 while(numberOfClients > 0) {
00560
00561 BYTE clientID = (data[i] & 0x7f);
00562
00563 if(clientID == H281_CLIENT_ID) {
00564 remoteHasH281 = TRUE;
00565 i++;
00566 } else if(clientID == 0x7e) {
00567 i += 2;
00568 } else if(clientID == 0x7f) {
00569 i += 6;
00570 } else {
00571 i++;
00572 }
00573 numberOfClients--;
00574 }
00575
00576 h281Handler->SetRemoteHasH281(remoteHasH281);
00577
00578 return TRUE;
00579 }
00580
00581 BOOL OpalH224Handler::OnReceivedClientListCommand()
00582 {
00583 SendClientList();
00584 return TRUE;
00585 }
00586
00587 BOOL OpalH224Handler::OnReceivedExtraCapabilities(H224_Frame & frame)
00588 {
00589 BYTE *data = frame.GetClientDataPtr();
00590
00591 BYTE clientID = (data[2] & 0x7f);
00592
00593 if(clientID == H281_CLIENT_ID) {
00594 PINDEX size = frame.GetClientDataSize() - 3;
00595 h281Handler->OnReceivedExtraCapabilities((data + 3), size);
00596 }
00597
00598 return TRUE;
00599 }
00600
00601 BOOL OpalH224Handler::OnReceivedExtraCapabilitiesCommand()
00602 {
00603 SendExtraCapabilities();
00604 return TRUE;
00605 }
00606
00607 OpalH224ReceiverThread * OpalH224Handler::CreateH224ReceiverThread()
00608 {
00609 return new OpalH224ReceiverThread(this, *session);
00610 }
00611
00612 void OpalH224Handler::TransmitFrame(H224_Frame & frame)
00613 {
00614 PINDEX size = frame.GetEncodedSize();
00615
00616 if(!frame.Encode(transmitFrame->GetPayloadPtr(), size, transmitBitIndex)) {
00617 PTRACE(3, "Failed to encode H.224 frame");
00618 return;
00619 }
00620
00621
00622 PTime currentTime = PTime();
00623 PTimeInterval timePassed = currentTime - *transmitStartTime;
00624 transmitFrame->SetTimestamp((DWORD)timePassed.GetMilliSeconds() * 8);
00625
00626 transmitFrame->SetPayloadSize(size);
00627 transmitFrame->SetMarker(TRUE);
00628
00629 if(!session->WriteData(*transmitFrame)) {
00630 PTRACE(3, "Failed to write encoded H.224 frame");
00631 }
00632 }
00633
00635
00636 OpalH224ReceiverThread::OpalH224ReceiverThread(OpalH224Handler *theH224Handler, RTP_Session & session)
00637 : PThread(10000, NoAutoDeleteThread, HighestPriority, "H.224 Receiver Thread"),
00638 rtpSession(session)
00639 {
00640 h224Handler = theH224Handler;
00641 timestamp = 0;
00642 terminate = FALSE;
00643 }
00644
00645 OpalH224ReceiverThread::~OpalH224ReceiverThread()
00646 {
00647 }
00648
00649 void OpalH224ReceiverThread::Main()
00650 {
00651 RTP_DataFrame packet = RTP_DataFrame(300);
00652 H224_Frame h224Frame = H224_Frame();
00653
00654 for (;;) {
00655
00656 inUse.Wait();
00657
00658 if(!rtpSession.ReadBufferedData(timestamp, packet)) {
00659 inUse.Signal();
00660 return;
00661 }
00662
00663 timestamp = packet.GetTimestamp();
00664
00665 if(h224Frame.Decode(packet.GetPayloadPtr(), packet.GetPayloadSize())) {
00666 BOOL result = h224Handler->OnReceivedFrame(h224Frame);
00667
00668 if(result == FALSE) {
00669
00670 return;
00671 }
00672 } else {
00673 PTRACE(3, "Decoding of H.224 frame failed");
00674 }
00675
00676 inUse.Signal();
00677
00678 if(terminate == TRUE) {
00679 return;
00680 }
00681 }
00682 }
00683
00684 void OpalH224ReceiverThread::Close()
00685 {
00686 rtpSession.Close(TRUE);
00687
00688 inUse.Wait();
00689
00690 terminate = TRUE;
00691
00692 inUse.Signal();
00693
00694 PAssert(WaitForTermination(10000), "H224 receiver thread not terminated");
00695 }
00696
00697 #endif // H323_H224