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 #include "ace/OS.h"
00035 #include "pana_exceptions.h"
00036 #include "pana_session.h"
00037 #include "pana_memory_manager.h"
00038
00039 PANA_SessionAttribute::PANA_SessionAttribute()
00040 {
00041 m_LastPayload = NULL;
00042 Reset();
00043 }
00044
00045 PANA_SessionAttribute::~PANA_SessionAttribute()
00046 {
00047 Reset();
00048 }
00049
00050 void PANA_SessionAttribute::Reset()
00051 {
00052 if (m_LastPayload) {
00053 m_LastPayload->Release();
00054 }
00055
00056 while (! m_RxMessageQueue.empty()) {
00057 PANA_Message &msg = *(m_RxMessageQueue.front());
00058 m_RxMessageQueue.pop_front();
00059 delete &msg;
00060 }
00061
00062 m_PeerDeviceId.clear();
00063
00064 m_InitialPacTsec = 0;
00065 m_InitialPaaTsec = 0;
00066 m_LastTransmittedTsec = 0;
00067 m_LastReceivedRsec = 0;
00068 m_PeerPort = 0;
00069 m_LastPayload = NULL;
00070 m_SessionLifetime = 0;
00071 m_SeparateAuth = false;
00072 m_BindCount = 0;
00073 m_BindResult[0] = 0;
00074 m_BindResult[1] = 0;
00075 m_TerminationCause = PANA_TC_INVALID;
00076 }
00077
00078 void PANA_Session::ValidateMessage(PANA_Message &msg)
00079 {
00080
00081 PANA_DeviceId *ipId = msg.srcDevices().search(PANA_DeviceId::IPV4_ADDRESS);
00082 PANA_DeviceId *ipIdS = m_PeerDeviceId.search(PANA_DeviceId::IPV4_ADDRESS);
00083 if ((ipId && ipIdS) && (! (*ipId == *ipIdS))) {
00084 m_PeerDeviceId.replace(*ipId);
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #if __MAJOR_TBD__
00096 if (! ((msg.tseq() > m_LastReceivedTsec_) &&
00097 ((msg.rseq() >= (m_LastReceivedRsec_ + 1)) &&
00098 (msg.rseq() <= m_LastTransmittedTsec_)))) {
00099 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00100 "PANA session received msg with invalid seq number"));
00101 }
00102 #endif // __MAJOR_TBD__
00103
00104
00105
00106
00107
00108 if (m_SA.MSK().size() > 0) {
00109 ACE_DEBUG((LM_INFO, "(%P|%t) SA Present, validating MAC\n"));
00110 if (m_SA.ValidateMacValue(msg) == false) {
00111 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00112 "PANA session received msg with invalid MAC value"));
00113 }
00114 }
00115
00116
00117 if (m_SessionId.size() > 0) {
00118
00119 AAAAvpContainer *c_sessionId = msg.avpList().search("Session-Id");
00120 if (c_sessionId == NULL) {
00121 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00122 "PANA session received msg with no session ID"));
00123 }
00124 diameter_utf8string_t &id = (*c_sessionId)[0]->dataRef(Type2Type<diameter_utf8string_t>());
00125
00126 if (ACE_OS::memcmp(m_SessionId.data(), id.data(), id.size())) {
00127 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00128 "PANA session received invalid message, session id does not match"));
00129 }
00130 }
00131
00132
00133 if (m_PeerDeviceId.size() > 0) {
00134 AAAAvpContainer *c_deviceId = msg.avpList().search("Device-Id");
00135 if (c_deviceId) {
00136 PANA_TVData_t &deviceId = (*c_deviceId)[0]->dataRef(Type2Type<PANA_TVData_t>());
00137 PANA_DeviceId *knownId = m_PeerDeviceId.search(PANA_DeviceId::TYPE(deviceId.type));
00138 if (knownId) {
00139 if (ACE_OS::memcmp(deviceId.value.data(), knownId->id().data(), knownId->id().size())) {
00140 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00141 "Device ID AVP value does not match device id of known peer"));
00142 }
00143 }
00144 }
00145 }
00146
00147
00148 m_LastReceivedTsec = msg.tseq();
00149 m_LastReceivedRsec = msg.rseq();
00150 }
00151
00152 void PANA_Session::DestinationAddressFormatting(PANA_Message &msg,
00153 AAAMessageBlock *eapPayload)
00154 {
00155 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: No Tx address formatting present\n"));
00156 }
00157
00158 void PANA_Session::SendReAuthenticateRequest()
00159 {
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 ACE_DEBUG((LM_INFO, "(%P|%t) Sending re-auth request\n"));
00187
00188 if (m_SA.MSK().size() == 0) {
00189 throw (PANA_Exception(PANA_Exception::FAILED,
00190 "No MSK setup for this session"));
00191 }
00192
00193 AAAAvpContainerManager cm;
00194 AAAAvpContainerEntryManager em;
00195 PANA_Message *msg;
00196
00197 ACE_NEW_NORETURN(msg, PANA_Message);
00198 if (msg == NULL) {
00199 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00200 "Failed to allocate msg message"));
00201 }
00202
00203
00204 PANA_MsgHeader::Flags flg = { 1, 0, 0, 0 };
00205 msg->flags(flg);
00206 msg->type(PANA_MTYPE_REAUTH);
00207 msg->tseq(++ m_LastTransmittedTsec);
00208 msg->rseq(m_LastReceivedTsec);
00209
00210
00211 AAAAvpContainerEntry *e;
00212 AAAAvpContainer *c_sessionId = cm.acquire("Session-Id");
00213 AAAAvpContainer *c_deviceId = cm.acquire("Device-Id");
00214
00215
00216 e = em.acquire(AAA_AVP_UTF8_STRING_TYPE);
00217 diameter_utf8string_t &sessionId = e->dataRef(Type2Type<diameter_utf8string_t>());
00218 c_sessionId->add(e);
00219
00220 e = em.acquire(AAA_AVPDataType(AAA_AVP_DEVICEID_TYPE));
00221 PANA_TVData_t &deviceId = e->dataRef(Type2Type<PANA_TVData_t>());
00222 c_deviceId->add(e);
00223
00224
00225 msg->avpList().add(c_sessionId);
00226 msg->avpList().add(c_deviceId);
00227
00228
00229 PANA_DeviceIdContainer srcDevices;
00230 m_TxChannel.GetLocalAddress(srcDevices);
00231 PANA_DeviceId *id = srcDevices.search(m_ReqDeviceId);
00232 if (id) {
00233 deviceId.type = id->type();
00234 deviceId.value.assign(id->id().data(), id->id().size());
00235 }
00236 else {
00237 throw (PANA_Exception(PANA_Exception::FAILED,
00238 "No MAC address given in the device list"));
00239 }
00240 sessionId.assign(m_SessionId.data(), m_SessionId.size());
00241
00242
00243 DestinationAddressFormatting(*msg);
00244 m_TxChannel.Send(*this, *msg);
00245
00246 PANA_RtQueueNullData data;
00247 if (m_RtQueue.Schedule(data)) {
00248 m_Timer.Schedule(PANA_TID_PRAR_RETRY, data.Timeout());
00249 }
00250
00251 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: Re-Auth-Request, tseq=%d, rseq=%d\n",
00252 msg->tseq(), msg->rseq()));
00253 }
00254
00255 void PANA_Session::RetryReAuthenticateRequest()
00256 {
00257 m_Timer.Cancel(PANA_TID_PRAR_RETRY);
00258
00259 PANA_RtQueueData *data = NULL;
00260 if (m_RtQueue.ReSchedule(data)) {
00261 SendReAuthenticateRequest();
00262 m_Timer.Schedule(PANA_TID_PRAR_RETRY, data->Timeout());
00263 }
00264 else {
00265 m_Timer.Schedule(PANA_TID_DISCONNECT, 0);
00266 }
00267 }
00268
00269 void PANA_Session::ReceiveReAuthenticateRequest()
00270 {
00271 PANA_Message &msg = *(m_RxMessageQueue.front());
00272 m_RxMessageQueue.pop_front();
00273
00274
00275 m_Timer.Cancel(PANA_TID_DISC_RETRY);
00276 m_RtQueue.ClearFront();
00277
00278
00279 m_Timer.Cancel(PANA_TID_PSA_RETRY);
00280 m_RtQueue.ClearFront();
00281
00282 AAAAvpContainer* c_deviceId = msg.avpList().search("Device-Id");
00283 if (c_deviceId) {
00284 PANA_TVData_t &deviceId = (*c_deviceId)[0]->dataRef(Type2Type<PANA_TVData_t>());
00285 PANA_DeviceId id(PANA_DeviceId::TYPE(deviceId.type), deviceId.value);
00286 PANA_DeviceId *knownId = m_PeerDeviceId.search(PANA_DeviceId::TYPE(deviceId.type));
00287 if (knownId && !(*knownId == id)) {
00288 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00289 "Device id type in re-auth request does not match known peer id"));
00290 }
00291 else if (! knownId) {
00292 m_PeerDeviceId.clone(id);
00293 m_ReqDeviceId = PANA_DeviceId::TYPE(deviceId.type);
00294 }
00295 }
00296
00297 ACE_DEBUG((LM_INFO, "(%P|%t) RECV: ReAuthenticate-Req, tseq=%d, rseq=%d\n",
00298 msg.tseq(), msg.rseq()));
00299
00300 SendReAuthenticateAnswer();
00301
00302 ReAuthenticate(PANA_REAUTH_PANA);
00303
00304 if (c_deviceId) {
00305 PANA_TVData_t &deviceId = (*c_deviceId)[0]->dataRef(Type2Type<PANA_TVData_t>());
00306 PANA_DeviceId id(PANA_DeviceId::TYPE(deviceId.type), deviceId.value);
00307 m_Event.AuthorizePeer(id, true);
00308 }
00309
00310 m_Timer.Schedule(PANA_TID_SESSION, m_SessionLifetime);
00311 delete &msg;
00312 }
00313
00314 void PANA_Session::SendReAuthenticateAnswer()
00315 {
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 ACE_DEBUG((LM_INFO, "(%P|%t) Sending re-auth answer\n"));
00344
00345 if (m_SA.MSK().size() == 0) {
00346 throw (PANA_Exception(PANA_Exception::FAILED,
00347 "No MSK setup for this session"));
00348 }
00349
00350 AAAAvpContainerManager cm;
00351 AAAAvpContainerEntryManager em;
00352 PANA_Message *msg;
00353
00354 ACE_NEW_NORETURN(msg, PANA_Message);
00355 if (msg == NULL) {
00356 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00357 "Failed to allocate msg message"));
00358 }
00359
00360
00361 PANA_MsgHeader::Flags flg = { 0, 0, 0, 0 };
00362 msg->flags(flg);
00363 msg->type(PANA_MTYPE_REAUTH);
00364 msg->tseq(++ m_LastTransmittedTsec);
00365 msg->rseq(m_LastReceivedTsec);
00366
00367
00368 AAAAvpContainerEntry *e;
00369 AAAAvpContainer *c_sessionId = cm.acquire("Session-Id");
00370 AAAAvpContainer *c_deviceId = cm.acquire("Device-Id");
00371
00372
00373 e = em.acquire(AAA_AVP_UTF8_STRING_TYPE);
00374 diameter_utf8string_t &sessionId = e->dataRef(Type2Type<diameter_utf8string_t>());
00375 c_sessionId->add(e);
00376
00377 e = em.acquire(AAA_AVPDataType(AAA_AVP_DEVICEID_TYPE));
00378 PANA_TVData_t &deviceId = e->dataRef(Type2Type<PANA_TVData_t>());
00379 c_deviceId->add(e);
00380
00381
00382 msg->avpList().add(c_sessionId);
00383 msg->avpList().add(c_deviceId);
00384
00385
00386 PANA_DeviceIdContainer srcDevices;
00387 m_TxChannel.GetLocalAddress(srcDevices);
00388 PANA_DeviceId *id = srcDevices.search(m_ReqDeviceId);
00389 if (id) {
00390 deviceId.type = id->type();
00391 deviceId.value.assign(id->id().data(), id->id().size());
00392 }
00393 else {
00394 throw (PANA_Exception(PANA_Exception::FAILED,
00395 "No MAC address given in the device list"));
00396 }
00397 sessionId.assign(m_SessionId.data(), m_SessionId.size());
00398
00399
00400 DestinationAddressFormatting(*msg);
00401 m_TxChannel.Send(*this, *msg);
00402
00403 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: Re-Auth-Answer, tseq=%d, rseq=%d\n",
00404 msg->tseq(), msg->rseq()));
00405 }
00406
00407 void PANA_Session::ReceiveReAuthenticateAnswer()
00408 {
00409 PANA_Message &msg = *(m_RxMessageQueue.front());
00410 m_RxMessageQueue.pop_front();
00411
00412 m_Timer.Cancel(PANA_TID_PRAR_RETRY);
00413 m_RtQueue.ClearFront();
00414
00415 AAAAvpContainer* c_deviceId = msg.avpList().search("Device-Id");
00416 if (c_deviceId) {
00417 PANA_TVData_t &deviceId = (*c_deviceId)[0]->dataRef(Type2Type<PANA_TVData_t>());
00418 if (m_ReqDeviceId != deviceId.type) {
00419 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00420 "Device id type in bind answer does not match request"));
00421 }
00422 PANA_DeviceId id(PANA_DeviceId::TYPE(deviceId.type), deviceId.value);
00423 PANA_DeviceId *knownId = m_PeerDeviceId.search(PANA_DeviceId::TYPE(deviceId.type));
00424 if (knownId && !(*knownId == id)) {
00425 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00426 "Device id type in re-auth answer does not match known peer id"));
00427 }
00428 else if (! knownId) {
00429 m_PeerDeviceId.clone(id);
00430 }
00431 }
00432
00433 ACE_DEBUG((LM_INFO, "(%P|%t) RECV: ReAuthenticate-Answer, tseq=%d, rseq=%d\n",
00434 msg.tseq(), msg.rseq()));
00435
00436 ReAuthenticate(PANA_REAUTH_PANA);
00437
00438 if (c_deviceId) {
00439 PANA_TVData_t &deviceId = (*c_deviceId)[0]->dataRef(Type2Type<PANA_TVData_t>());
00440 PANA_DeviceId id(PANA_DeviceId::TYPE(deviceId.type), deviceId.value);
00441 m_Event.AuthorizePeer(id, true);
00442 }
00443
00444 m_Timer.Schedule(PANA_TID_SESSION, m_SessionLifetime);
00445 delete &msg;
00446 }
00447
00448 void PANA_Session::SendTerminationRequest()
00449 {
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 ACE_DEBUG((LM_INFO, "(%P|%t) Sending termination request\n"));
00470
00471 AAAAvpContainerManager cm;
00472 AAAAvpContainerEntryManager em;
00473 PANA_Message *msg;
00474
00475 ACE_NEW_NORETURN(msg, PANA_Message);
00476 if (msg == NULL) {
00477 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00478 "Failed to allocate msg message"));
00479 }
00480
00481
00482 PANA_MsgHeader::Flags flg = { 1, 0, 0, 0 };
00483 msg->flags(flg);
00484 msg->type(PANA_MTYPE_TERM);
00485 msg->tseq(++ m_LastTransmittedTsec);
00486 msg->rseq(m_LastReceivedTsec);
00487
00488
00489 AAAAvpContainerEntry *e;
00490 AAAAvpContainer *c_sessionId = cm.acquire("Session-Id");
00491 AAAAvpContainer *c_termCause = cm.acquire("Termination-Cause");
00492
00493
00494 e = em.acquire(AAA_AVP_UTF8_STRING_TYPE);
00495 diameter_utf8string_t &sessionId = e->dataRef(Type2Type<diameter_utf8string_t>());
00496 c_sessionId->add(e);
00497
00498 e = em.acquire(AAA_AVP_UINTEGER32_TYPE);
00499 diameter_unsigned32_t &termCause = e->dataRef(Type2Type<diameter_unsigned32_t>());
00500 c_termCause->add(e);
00501
00502
00503 msg->avpList().add(c_sessionId);
00504 msg->avpList().add(c_termCause);
00505
00506
00507 sessionId.assign(m_SessionId.data(), m_SessionId.size());
00508 termCause = m_TerminationCause;
00509
00510
00511 DestinationAddressFormatting(*msg);
00512 m_TxChannel.Send(*this, *msg);
00513
00514 PANA_RtQueueNullData data;
00515 if (m_RtQueue.Schedule(data)) {
00516 m_Timer.Schedule(PANA_TID_PTR_RETRY, data.Timeout());
00517 }
00518
00519 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: Termination-Request, tseq=%d, rseq=%d\n",
00520 msg->tseq(), msg->rseq()));
00521 }
00522
00523 void PANA_Session::RetryTerminationRequest()
00524 {
00525 m_Timer.Cancel(PANA_TID_PTR_RETRY);
00526
00527 PANA_RtQueueData *data = NULL;
00528 if (m_RtQueue.ReSchedule(data)) {
00529 SendTerminationRequest();
00530 m_Timer.Schedule(PANA_TID_PTR_RETRY, data->Timeout());
00531 }
00532 else {
00533 m_Timer.Schedule(PANA_TID_DISCONNECT, 0);
00534 }
00535 }
00536
00537 void PANA_Session::ReceiveTerminationRequest()
00538 {
00539 PANA_Message &msg = *(m_RxMessageQueue.front());
00540 m_RxMessageQueue.pop_front();
00541
00542 ACE_DEBUG((LM_INFO, "(%P|%t) RECV: Termination-Req, tseq=%d, rseq=%d\n",
00543 msg.tseq(), msg.rseq()));
00544
00545 AAAAvpContainer* c_cause = msg.avpList().search("Termination-Cause");
00546 if (c_cause == NULL) {
00547 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00548 "PANA client received term msg with no term cause"));
00549 }
00550 diameter_unsigned32_t &cause = (*c_cause)[0]->dataRef(Type2Type<diameter_unsigned32_t>());
00551 SendTerminationAnswer();
00552 Disconnect(cause);
00553 delete &msg;
00554 }
00555
00556 void PANA_Session::SendTerminationAnswer()
00557 {
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 AAAAvpContainerManager cm;
00577 AAAAvpContainerEntryManager em;
00578 PANA_Message *msg;
00579
00580 ACE_NEW_NORETURN(msg, PANA_Message);
00581 if (msg == NULL) {
00582 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00583 "Failed to allocate msg message"));
00584 }
00585
00586
00587 PANA_MsgHeader::Flags flg = { 0, 0, 0, 0 };
00588 msg->flags(flg);
00589 msg->type(PANA_MTYPE_TERM);
00590 msg->tseq(++ m_LastTransmittedTsec);
00591 msg->rseq(m_LastReceivedTsec);
00592
00593
00594 AAAAvpContainerEntry *e;
00595 AAAAvpContainer *c_sessionId = cm.acquire("Session-Id");
00596
00597
00598 e = em.acquire(AAA_AVP_UTF8_STRING_TYPE);
00599 diameter_utf8string_t &sessionId = e->dataRef(Type2Type<diameter_utf8string_t>());
00600 c_sessionId->add(e);
00601
00602
00603 msg->avpList().add(c_sessionId);
00604
00605
00606 sessionId.assign(m_SessionId.data(), m_SessionId.size());
00607
00608
00609 DestinationAddressFormatting(*msg);
00610 m_TxChannel.Send(*this, *msg);
00611
00612 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: Termination-Answer, tseq=%d, rseq=%d\n",
00613 msg->tseq(), msg->rseq()));
00614 }
00615
00616 void PANA_Session::ReceiveTerminationAnswer()
00617 {
00618 PANA_Message &msg = *(m_RxMessageQueue.front());
00619 m_RxMessageQueue.pop_front();
00620
00621 m_Timer.Cancel(PANA_TID_PTR_RETRY);
00622 m_RtQueue.ClearFront();
00623
00624 ACE_DEBUG((LM_INFO, "(%P|%t) RECV: Termination-Answer, tseq=%d, rseq=%d\n",
00625 msg.tseq(), msg.rseq()));
00626
00627 Disconnect(m_TerminationCause);
00628 delete &msg;
00629 }
00630
00631 void PANA_Session::ReAuthenticate(PANA_REAUTH cause)
00632 {
00633 ACE_DEBUG((LM_INFO, "(%P|%t) EVENT: Re-Authentication, cause=%d\n", cause));
00634 m_Timer.Cancel(PANA_TID_SESSION);
00635 m_Event.ReAuthentication(cause);
00636 }
00637
00638 void PANA_Session::Disconnect(ACE_UINT32 cause)
00639 {
00640 ACE_DEBUG((LM_INFO, "(%P|%t) EVENT: Disconnect, cause=%d\n", cause));
00641
00642
00643 m_Timer.Cancel(PANA_TID_PRAR_RETRY);
00644 m_RtQueue.ClearFront();
00645
00646
00647 m_Timer.Cancel(PANA_TID_PTR_RETRY);
00648 m_RtQueue.ClearFront();
00649
00650
00651 m_Timer.Cancel(PANA_TID_PBR_RETRY);
00652 m_RtQueue.ClearFront();
00653
00654
00655 m_Timer.Cancel(PANA_TID_DISCONNECT);
00656 m_Timer.Cancel(PANA_TID_SESSION);
00657
00658
00659 m_Event.Disconnect(cause);
00660 }
00661
00662 PANA_BIND_RESULT PANA_Session::BindResult(int rcode)
00663 {
00664 if (m_SeparateAuth) {
00665 if (m_BindCount < PANA_BIND_COUNT_MAX) {
00666 m_BindCount ++;
00667 m_BindResult[m_BindCount - 1] = rcode;
00668 }
00669 }
00670 else {
00671 m_BindResult[0] = rcode;
00672 }
00673 return BindResult();
00674 }
00675
00676 PANA_BIND_RESULT PANA_Session::BindResult()
00677 {
00678 PANA_BIND_RESULT br = PANA_BIND_FAILED;
00679 if (m_SeparateAuth) {
00680 if (m_BindCount < PANA_BIND_COUNT_MAX) {
00681 return (PANA_BIND_INTERIM);
00682 }
00683 else {
00684 for (unsigned int i = 0; i < m_BindCount; i ++) {
00685 if (PANA_RCODE_SUCCESS(m_BindResult[i])) {
00686 br = (i == 0) ? PANA_BIND_SUCCESS_INITIAL :
00687 PANA_BIND_SUCCESS_FINAL;
00688 break;
00689 }
00690 }
00691 }
00692 }
00693 else {
00694 br = PANA_RCODE_SUCCESS(m_BindResult[0]) ?
00695 PANA_BIND_SUCCESS_FINAL :
00696 PANA_BIND_FAILED;
00697 }
00698 return (br);
00699 }
00700
00701 void PANA_Session::BindResultReset()
00702 {
00703 m_BindCount = 0;
00704 for (int i = 0; i < PANA_BIND_COUNT_MAX; i++) {
00705 m_BindResult[i] = PANA_BIND_INVALID;
00706 }
00707 }
00708
00709 void PANA_Session::SendErrorMessage(ACE_UINT32 rcode, AAAAvpContainer *failedAvp)
00710 {
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 AAAAvpContainerManager cm;
00733 AAAAvpContainerEntryManager em;
00734 PANA_Message *msg;
00735
00736 ACE_NEW_NORETURN(msg, PANA_Message);
00737 if (msg == NULL) {
00738 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00739 "Failed to allocate msg message"));
00740 }
00741
00742
00743 PANA_MsgHeader::Flags flg = { 0, 0, 0, 0 };
00744 msg->flags(flg);
00745 msg->type(PANA_MTYPE_ERROR);
00746 msg->tseq(++ m_LastTransmittedTsec);
00747 msg->rseq(m_LastReceivedTsec);
00748
00749
00750 AAAAvpContainerEntry *e;
00751 AAAAvpContainer *c_sessionId = cm.acquire("Session-Id");
00752 AAAAvpContainer *c_resultCode = cm.acquire("Result-Code");
00753 AAAAvpContainer *c_failedAvp = cm.acquire("Failed-AVP");
00754
00755
00756 e = em.acquire(AAA_AVP_UTF8_STRING_TYPE);
00757 diameter_utf8string_t &sessionId = e->dataRef(Type2Type<diameter_utf8string_t>());
00758 c_sessionId->add(e);
00759
00760 e = em.acquire(AAA_AVP_UINTEGER32_TYPE);
00761 diameter_unsigned32_t &resultCode = e->dataRef(Type2Type<diameter_unsigned32_t>());
00762 c_resultCode->add(e);
00763
00764 e = em.acquire(AAA_AVP_GROUPED_TYPE);
00765 diameter_grouped_t &grpfailedAvp = e->dataRef(Type2Type<diameter_grouped_t>());
00766 c_failedAvp->add(e);
00767
00768
00769 msg->avpList().add(c_sessionId);
00770 msg->avpList().add(c_resultCode);
00771 msg->avpList().add(c_failedAvp);
00772
00773
00774 sessionId.assign(m_SessionId.data(), m_SessionId.size());
00775 resultCode = rcode;
00776 grpfailedAvp.add(failedAvp);
00777
00778
00779 DestinationAddressFormatting(*msg);
00780 m_TxChannel.Send(*this, *msg);
00781
00782 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: Error-Message, tseq=%d, rseq=%d\n",
00783 msg->tseq(), msg->rseq()));
00784 }
00785
00786 void PANA_Session::ReceiveErrorMessage(PANA_Message &msg)
00787 {
00788 ACE_DEBUG((LM_INFO, "(%P|%t) RECV: Error-Message, tseq=%d, rseq=%d\n",
00789 msg.tseq(), msg.rseq()));
00790
00791 AAAAvpContainer* c_rcode = msg.avpList().search("Result-Code");
00792 if (c_rcode == NULL) {
00793 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00794 "PANA client received error msg with no result code"));
00795 }
00796 diameter_unsigned32_t &rcode = (*c_rcode)[0]->dataRef(Type2Type<diameter_unsigned32_t>());
00797 m_Event.Error(rcode);
00798 }
00799
00800 void PANA_Session::Reset()
00801 {
00802 PANA_SessionAttribute::Reset();
00803 m_InStatefulDiscovery = false;
00804 m_RtQueue.Clear();
00805 }
00806