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 "pana_client.h"
00035 #include "pana_device_id.h"
00036 #include "pana_serial_num.h"
00037 #include "pana_config_manager.h"
00038
00039 void PANA_Client::SendDiscover()
00040 {
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 AAAAvpContainerManager cm;
00074 AAAAvpContainerEntryManager em;
00075 PANA_Message *msg;
00076
00077 ACE_NEW_NORETURN(msg, PANA_Message);
00078 if (msg == NULL) {
00079 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00080 "Failed to allocate msg message"));
00081 }
00082
00083
00084 PANA_MsgHeader::Flags flg = { 0, 0, 0, 0 };
00085 msg->flags(flg);
00086 msg->type(PANA_MTYPE_DISCOVER);
00087 msg->tseq(0);
00088 msg->rseq(0);
00089
00090
00091 AAAAvpContainerEntry *e;
00092 AAAAvpContainer *c_deviceId = cm.acquire("Device-Id");
00093
00094
00095 e = em.acquire(AAA_AVPDataType(AAA_AVP_DEVICEID_TYPE));
00096 PANA_TVData_t &deviceId = e->dataRef(Type2Type<PANA_TVData_t>());
00097 c_deviceId->add(e);
00098
00099
00100 msg->avpList().add(c_deviceId);
00101
00102
00103 if (m_SessionId.size() > 0) {
00104 AAAAvpContainer *c_sessionId = cm.acquire("Session-Id");
00105
00106
00107 e = em.acquire(AAA_AVP_UTF8_STRING_TYPE);
00108 diameter_utf8string_t &sid = e->dataRef(Type2Type<diameter_utf8string_t>());
00109 c_sessionId->add(e);
00110
00111 msg->avpList().add(c_sessionId);
00112 sid.assign(m_SessionId.data(), m_SessionId.size());
00113
00114
00115 msg->tseq(++ m_LastTransmittedTsec);
00116 msg->rseq(m_LastReceivedTsec);
00117
00118
00119 ReAuthenticate(PANA_REAUTH_EAP);
00120 }
00121
00122
00123 PANA_DeviceIdContainer srcDevices;
00124 m_TxChannel.GetLocalAddress(srcDevices);
00125
00126
00127 PANA_DeviceId *id = srcDevices.search(PANA_DeviceId::LL_ADDRESS);
00128 if (id == NULL) {
00129 id = srcDevices.search(PANA_DeviceId::IPV4_ADDRESS);
00130 }
00131
00132 if (id) {
00133 deviceId.type = id->type();
00134 deviceId.value.assign(id->id().data(), id->id().size());
00135 }
00136 else {
00137 throw (PANA_Exception(PANA_Exception::FAILED,
00138 "No device ID available"));
00139 }
00140
00141 DestinationAddressFormatting(*msg);
00142 m_TxChannel.Send(*this, *msg);
00143
00144 PANA_RtQueueNullData data;
00145 if (m_RtQueue.Schedule(data)) {
00146 m_Timer.Schedule(PANA_TID_DISC_RETRY, data.Timeout());
00147 }
00148
00149 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: Discover, tseq=%d, rseq=%d\n",
00150 msg->tseq(), msg->rseq()));
00151 }
00152
00153 void PANA_Client::RetryDiscover()
00154 {
00155 m_Timer.Cancel(PANA_TID_DISC_RETRY);
00156
00157 PANA_RtQueueData *data = NULL;
00158 if (m_RtQueue.ReSchedule(data)) {
00159 SendDiscover();
00160 m_Timer.Schedule(PANA_TID_DISC_RETRY, data->Timeout());
00161 }
00162 else {
00163 m_Timer.Schedule(PANA_TID_DISCONNECT, 0);
00164 }
00165 }
00166
00167 void PANA_Client::ReceiveStartRequest()
00168 {
00169 PANA_Message &msg = *(m_RxMessageQueue.front());
00170 m_RxMessageQueue.pop_front();
00171
00172 ACE_DEBUG((LM_INFO, "(%P|%t) RECV: Start Req, S-flag %d, tseq=%d, rseq=%d\n",
00173 msg.flags().separate, msg.tseq(), msg.rseq()));
00174
00175
00176 m_Timer.Cancel(PANA_TID_DISC_RETRY);
00177 m_RtQueue.ClearFront();
00178
00179
00180 AAAAvpContainer* c_napInfo = msg.avpList().search("NAP-Information");
00181 if (c_napInfo) {
00182 diameter_grouped_t &nap = (*c_napInfo)[0]->dataRef
00183 (Type2Type<diameter_grouped_t>());
00184 PANA_ProviderInfoTool infoTool;
00185 infoTool.Extract(nap, m_PreferedNAP);
00186
00187 ACE_DEBUG((LM_INFO, "(%P|%t) NAP information received: [%d] %s\n",
00188 m_PreferedNAP.id_, m_PreferedNAP.name_.data()));
00189 }
00190
00191
00192 AAAAvpContainer* c_ispInfo = msg.avpList().search("ISP-Information");
00193 if (c_ispInfo) {
00194 m_IspSelected = IspSelection(c_ispInfo);
00195 }
00196
00197
00198 m_InitialPaaTsec = msg.tseq();
00199 m_InitialPacTsec = PANA_SerialNumber::generateIsn(msg.tseq());
00200 m_LastTransmittedTsec = m_InitialPacTsec;
00201 m_LastReceivedTsec = msg.tseq();
00202 m_LastReceivedRsec = msg.rseq();
00203 m_PeerPort = msg.srcPort();
00204 m_PeerDeviceId.clone(msg.srcDevices());
00205 m_ReqDeviceId = PANA_DeviceId::IPV4_ADDRESS;
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 bool localSFlag = PANA_CONFIG_CLIENT().s_flag_ ? true : false;
00233 m_SeparateAuth = (msg.flags().separate) ? localSFlag : false;
00234
00235
00236
00237
00238 static_cast<PANA_ClientEventInterface&>(m_Event).EapStart();
00239
00240
00241
00242
00243
00244
00245
00246
00247 AAAAvpContainer *c_cookie = msg.avpList().search("Cookie");
00248 AAAAvpContainer* c_eapPayload = msg.avpList().search("EAP-Payload");
00249 if (c_cookie) {
00250 m_Cookie = (*c_cookie)[0]->dataRef
00251 (Type2Type<diameter_octetstring_t>());
00252 if (c_eapPayload) {
00253 throw (PANA_Exception(PANA_Exception::FAILED,
00254 "Both cookie and EAP AVP present in PSR"));
00255 }
00256 SendStartAnswer(NULL);
00257 }
00258 else if (c_eapPayload) {
00259 diameter_octetstring_t &eapPayload = (*c_eapPayload)[0]->
00260 dataRef(Type2Type<diameter_octetstring_t>());
00261
00262 m_InStatefulDiscovery = true;
00263
00264 AAAMessageBlock *block = AAAMessageBlock::Acquire
00265 ((char*)eapPayload.data(), eapPayload.size());
00266 static_cast<PANA_ClientEventInterface&>(m_Event).EapRequest
00267 (block, PANA_PINFO_NONE);
00268 block->Release();
00269 }
00270 else {
00271 SendStartAnswer(NULL);
00272 }
00273 }
00274
00275 void PANA_Client::SendStartAnswer(AAAMessageBlock *response)
00276 {
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 AAAAvpContainerManager cm;
00309 AAAAvpContainerEntryManager em;
00310 PANA_Message *msg;
00311
00312 ACE_NEW_NORETURN(msg, PANA_Message);
00313 if (msg == NULL) {
00314 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00315 "Failed to allocate start answer message"));
00316 }
00317
00318
00319 PANA_MsgHeader::Flags flg = { 0, 0, 0, 0 };
00320 msg->flags(flg);
00321 msg->type(PANA_MTYPE_START);
00322 msg->tseq(m_InitialPacTsec);
00323 msg->rseq(m_LastReceivedTsec);
00324 msg->flags().separate = m_SeparateAuth;
00325
00326
00327 AAAAvpContainerEntry *e;
00328 if (response == NULL) {
00329
00330 AAAAvpContainer *c_cookie = cm.acquire("Cookie");
00331 e = em.acquire(AAA_AVPDataType(AAA_AVP_STRING_TYPE));
00332 diameter_octetstring_t &dest_cookie = e->dataRef(Type2Type<diameter_octetstring_t>());
00333 c_cookie->add(e);
00334
00335
00336 msg->avpList().add(c_cookie);
00337
00338
00339 dest_cookie.assign(m_Cookie.data(), m_Cookie.size());
00340 }
00341 else {
00342
00343 AAAAvpContainer *c_eapPayload = cm.acquire("EAP-Payload");
00344 e = em.acquire(AAA_AVP_STRING_TYPE);
00345 diameter_octetstring_t &eapPayload = e->dataRef(Type2Type<diameter_octetstring_t>());
00346 c_eapPayload->add(e);
00347
00348
00349 msg->avpList().add(c_eapPayload);
00350
00351
00352 eapPayload.assign(response->base(), response->size());
00353
00354
00355 m_InStatefulDiscovery = false;
00356 }
00357
00358
00359 if (m_IspSelected) {
00360
00361 ACE_DEBUG((LM_INFO, "(%P|%t) Selected ISP: [id=%d] %s\n",
00362 m_PreferedISP.id_, m_PreferedISP.name_.data()));
00363
00364 AAAAvpContainer *c_ispInfo = cm.acquire("ISP-Information");
00365 e = em.acquire(AAA_AVP_GROUPED_TYPE);
00366 diameter_grouped_t &ispInfo = e->dataRef(Type2Type<diameter_grouped_t>());
00367 c_ispInfo->add(e);
00368
00369
00370 msg->avpList().add(c_ispInfo);
00371 PANA_ProviderInfoTool infoTool;
00372 infoTool.Add(ispInfo, m_PreferedISP);
00373 }
00374
00375
00376 if (PANA_CONFIG_GENERAL().mobility_) {
00377
00378 AAAAvpContainerEntry *e;
00379 AAAAvpContainer *c_sessionId = cm.acquire("Session-Id");
00380
00381
00382 e = em.acquire(AAA_AVP_UTF8_STRING_TYPE);
00383 diameter_utf8string_t &sid = e->dataRef(Type2Type<diameter_utf8string_t>());
00384 c_sessionId->add(e);
00385
00386 msg->avpList().add(c_sessionId);
00387 sid.assign(m_SessionId.data(), m_SessionId.size());
00388 }
00389
00390 DestinationAddressFormatting(*msg);
00391 m_TxChannel.Send(*this, *msg);
00392
00393 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: Start-Answer, tseq=%d, rseq=%d\n",
00394 msg->tseq(), msg->rseq()));
00395
00396 PANA_RtQueueMsgBlockData data(response);
00397 if (m_RtQueue.Schedule(data)) {
00398 m_Timer.Schedule(PANA_TID_PSA_RETRY, data.Timeout());
00399 }
00400 }
00401
00402 void PANA_Client::RetryStartAnswer()
00403 {
00404 m_Timer.Cancel(PANA_TID_PSA_RETRY);
00405
00406 PANA_RtQueueData *data = NULL;
00407 if (m_RtQueue.ReSchedule(data)) {
00408 SendStartAnswer(static_cast<PANA_RtQueueMsgBlockData*>(data)->MsgBlock());
00409 m_Timer.Schedule(PANA_TID_PSA_RETRY, data->Timeout());
00410 }
00411 else {
00412 m_Timer.Schedule(PANA_TID_DISCONNECT, 0);
00413 }
00414 }
00415
00416 void PANA_Client::ReceiveEapRequest()
00417 {
00418 PANA_Message &msg = *(m_RxMessageQueue.front());
00419 m_RxMessageQueue.pop_front();
00420
00421 ACE_DEBUG((LM_INFO, "(%P|%t) RECV: EAP-Request, S-flag %d, tseq=%d, rseq=%d\n",
00422 msg.flags().separate, msg.tseq(), msg.rseq()));
00423
00424
00425 m_Timer.Cancel(PANA_TID_DISC_RETRY);
00426 m_RtQueue.ClearFront();
00427
00428
00429 m_Timer.Cancel(PANA_TID_PSA_RETRY);
00430 m_RtQueue.ClearFront();
00431
00432 if (m_SessionId.size() == 0) {
00433
00434 AAAAvpContainer *c_sessionId = msg.avpList().search("Session-Id");
00435 diameter_utf8string_t &id = (*c_sessionId)[0]->dataRef(Type2Type<diameter_utf8string_t>());
00436 m_SessionId.assign(id.data(), id.size());
00437 }
00438
00439
00440 AAAAvpContainer* c_eapPayload = msg.avpList().search("EAP-Payload");
00441 diameter_octetstring_t &eapPayload = (*c_eapPayload)[0]->dataRef(Type2Type<diameter_octetstring_t>());
00442
00443
00444 AAAMessageBlock *block = AAAMessageBlock::Acquire((char*)eapPayload.data(),
00445 eapPayload.size());
00446
00447 AAAAvpContainer *c_pInfo;
00448 diameter_grouped_t *pList = NULL;
00449 PANA_PINFO type = PANA_PINFO_NONE;
00450
00451
00452 if ((c_pInfo = msg.avpList().search("NAP-Information"))) {
00453 pList = (*c_pInfo)[0]->dataPtr(Type2Type<diameter_grouped_t>());
00454 type = PANA_PINFO_NAP;
00455 }
00456 else if ((c_pInfo = msg.avpList().search("ISP-Information"))) {
00457 pList = (*c_pInfo)[0]->dataPtr(Type2Type<diameter_grouped_t>());
00458 type = PANA_PINFO_ISP;
00459 }
00460
00461
00462 if (pList) {
00463 PANA_CfgProviderInfo pInfo;
00464 PANA_ProviderInfoTool infoTool;
00465 infoTool.Extract(*pList, pInfo);
00466 static_cast<PANA_ClientEventInterface&>(m_Event).EapRequest(block, type, &pInfo);
00467 }
00468 else {
00469 static_cast<PANA_ClientEventInterface&>(m_Event).EapRequest(block, type);
00470 }
00471 block->Release();
00472 delete &msg;
00473 }
00474
00475 void PANA_Client::ReceiveEapReAuthRequest()
00476 {
00477 PANA_Message &msg = *(m_RxMessageQueue.front());
00478 m_RxMessageQueue.pop_front();
00479
00480 ACE_DEBUG((LM_INFO, "(%P|%t) RECV: EAP-ReAuth-Request, S-flag %d, tseq=%d, rseq=%d\n",
00481 msg.flags().separate, msg.tseq(), msg.rseq()));
00482
00483
00484 ReAuthenticate(PANA_REAUTH_EAP);
00485
00486
00487 AAAAvpContainer* c_eapPayload = msg.avpList().search("EAP-Payload");
00488 diameter_octetstring_t &eapPayload = (*c_eapPayload)[0]->dataRef(Type2Type<diameter_octetstring_t>());
00489
00490
00491 AAAMessageBlock *block = AAAMessageBlock::Acquire((char*)eapPayload.data(),
00492 eapPayload.size());
00493
00494 static_cast<PANA_ClientEventInterface&>(m_Event).EapRequest(block, PANA_PINFO_NONE);
00495 block->Release();
00496 delete &msg;
00497 }
00498
00499 void PANA_Client::SendEapResponse(AAAMessageBlock *response)
00500 {
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 AAAAvpContainerManager cm;
00529 AAAAvpContainerEntryManager em;
00530 PANA_Message *msg;
00531
00532 ACE_NEW_NORETURN(msg, PANA_Message);
00533 if (msg == NULL) {
00534 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00535 "Failed to allocate msg message"));
00536 }
00537
00538
00539 PANA_MsgHeader::Flags flg = { 0, 0, 0, 0 };
00540 msg->flags(flg);
00541 msg->type(PANA_MTYPE_AUTH);
00542 msg->tseq(++ m_LastTransmittedTsec);
00543 msg->rseq(m_LastReceivedTsec);
00544
00545
00546 AAAAvpContainerEntry *e;
00547 AAAAvpContainer *c_sessionId = cm.acquire("Session-Id");
00548 AAAAvpContainer *c_eapPayload = cm.acquire("EAP-Payload");
00549
00550
00551 e = em.acquire(AAA_AVP_UTF8_STRING_TYPE);
00552 diameter_utf8string_t &sessionId = e->dataRef(Type2Type<diameter_utf8string_t>());
00553 c_sessionId->add(e);
00554
00555 e = em.acquire(AAA_AVP_STRING_TYPE);
00556 diameter_octetstring_t &eapPayload = e->dataRef(Type2Type<diameter_octetstring_t>());
00557 c_eapPayload->add(e);
00558
00559
00560 msg->avpList().add(c_sessionId);
00561 msg->avpList().add(c_eapPayload);
00562
00563
00564
00565
00566
00567
00568
00569
00570 sessionId.assign(m_SessionId.data(), m_SessionId.size());
00571 eapPayload.assign(response->base(), response->size());
00572
00573 DestinationAddressFormatting(*msg, response);
00574 m_TxChannel.Send(*this, *msg);
00575
00576 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: EAP-Response, tseq=%d, rseq=%d\n",
00577 msg->tseq(), msg->rseq()));
00578 }
00579
00580 void PANA_Client::ReceiveBindRequest()
00581 {
00582 PANA_Message &msg = *(m_RxMessageQueue.front());
00583 m_RxMessageQueue.pop_front();
00584
00585
00586 m_Timer.Cancel(PANA_TID_DISC_RETRY);
00587 m_RtQueue.ClearFront();
00588
00589
00590 m_Timer.Cancel(PANA_TID_PSA_RETRY);
00591 m_RtQueue.ClearFront();
00592
00593 if (BindResult() == PANA_BIND_SUCCESS_FINAL) {
00594 AAAAvpContainer* c_sessionLifetime = msg.avpList().search
00595 ("Session-Lifetime");
00596 if (c_sessionLifetime) {
00597 diameter_unsigned32_t &sessLifetime = (*c_sessionLifetime)
00598 [0]->dataRef(Type2Type<diameter_unsigned32_t>());
00599 m_SessionLifetime = sessLifetime;
00600 m_Timer.Schedule(PANA_TID_SESSION, sessLifetime);
00601 }
00602 }
00603
00604
00605 AAAAvpContainer* c_eapPayload = msg.avpList().search("EAP-Payload");
00606 if (c_eapPayload == NULL) {
00607 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00608 "PANA client received bind msg with no EAP payload"));
00609 }
00610 diameter_octetstring_t &eapPayload = (*c_eapPayload)[0]->dataRef(
00611 Type2Type<diameter_octetstring_t>());
00612
00613 AAAMessageBlock *block = AAAMessageBlock::Acquire((char*)eapPayload.data(),
00614 eapPayload.size());
00615
00616 AAAAvpContainer* c_rcode = msg.avpList().search("Result-Code");
00617 if (c_rcode == NULL) {
00618 throw (PANA_Exception(PANA_Exception::INVALID_MESSAGE,
00619 "PANA client received bind msg with no result code"));
00620 }
00621 diameter_unsigned32_t &rcode = (*c_rcode)[0]->dataRef(Type2Type<diameter_unsigned32_t>());
00622
00623 diameter_unsigned32_t pcap = PANA_PCAP_UNKNOWN;
00624 AAAAvpContainer* c_pcap = msg.avpList().search("Protection-Capability");
00625 if (c_pcap) {
00626 pcap = (*c_pcap)[0]->dataRef(Type2Type<diameter_unsigned32_t>());
00627 }
00628
00629 AAAAvpContainer* c_keyId = msg.avpList().search("Key-Id");
00630 if (c_keyId) {
00631 diameter_integer32_t &id = (*c_keyId)[0]->dataRef
00632 (Type2Type<diameter_integer32_t>());
00633 if (m_SA.KeyId() != id) {
00634 m_SA.KeyId(id);
00635 m_RegenerateKey = true;
00636 }
00637 }
00638
00639 PANA_DeviceIdContainer epId;
00640 AAAAvpContainer* c_epId = msg.avpList().search("EP-Device-Id");
00641 if (c_epId) {
00642 for (unsigned int i=0; i<c_epId->size(); i++) {
00643 PANA_TVData_t &deviceId = (*c_epId)[i]->dataRef(Type2Type<PANA_TVData_t>());
00644 PANA_DeviceId newId(PANA_DeviceId::TYPE(deviceId.type));
00645 std::string &value = const_cast<std::string&>(newId.id());
00646 value.assign(deviceId.value.data(), deviceId.value.size());
00647 epId.clone(newId);
00648 }
00649 }
00650
00651 AAAAvpContainer* c_deviceId = msg.avpList().search("Device-Id");
00652 if (c_deviceId) {
00653 PANA_TVData_t &deviceId = (*c_deviceId)[0]->dataRef(Type2Type<PANA_TVData_t>());
00654 m_ReqDeviceId = PANA_DeviceId::TYPE(deviceId.type);
00655 }
00656
00657 ACE_DEBUG((LM_INFO, "(%P|%t) RECV: Bind-Request, tseq=%d, rseq=%d\n",
00658 msg.tseq(), msg.rseq()));
00659
00660 static_cast<PANA_ClientEventInterface&>(m_Event).EapRequest
00661 (block, rcode, pcap, epId);
00662 block->Release();
00663
00664 if (BindResult() == PANA_BIND_FAILED) {
00665
00666
00667 SendBindAnswer();
00668 PANA_Session::Disconnect(PANA_TC_ADMINISTRATIVE);
00669 }
00670 delete &msg;
00671 }
00672
00673 void PANA_Client::SendBindAnswer()
00674 {
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 AAAAvpContainerManager cm;
00704 AAAAvpContainerEntryManager em;
00705 PANA_Message *msg;
00706
00707 ACE_NEW_NORETURN(msg, PANA_Message);
00708 if (msg == NULL) {
00709 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00710 "Failed to allocate msg message"));
00711 }
00712
00713
00714 PANA_MsgHeader::Flags flg = { 0, 0, 0, 0 };
00715 msg->flags(flg);
00716 msg->type(PANA_MTYPE_BIND);
00717 msg->tseq(++ m_LastTransmittedTsec);
00718 msg->rseq(m_LastReceivedTsec);
00719
00720
00721 AAAAvpContainerEntry *e;
00722 AAAAvpContainer *c_sessionId = cm.acquire("Session-Id");
00723 AAAAvpContainer *c_deviceId = cm.acquire("Device-Id");
00724
00725
00726 e = em.acquire(AAA_AVP_UTF8_STRING_TYPE);
00727 diameter_utf8string_t &sessionId = e->dataRef(Type2Type<diameter_utf8string_t>());
00728 c_sessionId->add(e);
00729
00730 e = em.acquire(AAA_AVPDataType(AAA_AVP_DEVICEID_TYPE));
00731 PANA_TVData_t &deviceId = e->dataRef(Type2Type<PANA_TVData_t>());
00732 c_deviceId->add(e);
00733
00734
00735 msg->avpList().add(c_sessionId);
00736 msg->avpList().add(c_deviceId);
00737
00738
00739 sessionId.assign(m_SessionId.data(), m_SessionId.size());
00740
00741
00742 PANA_DeviceIdContainer srcDevices;
00743 m_TxChannel.GetLocalAddress(srcDevices);
00744
00745
00746 PANA_DeviceId *id = srcDevices.search(m_ReqDeviceId);
00747 if (id == NULL) {
00748 throw (PANA_Exception(PANA_Exception::FAILED,
00749 "No IPV4/MAC address given in the peer device list"));
00750 }
00751 deviceId.type = id->type();
00752 deviceId.value.assign(id->id().data(), id->id().size());
00753
00754
00755 if (m_SA.MSK().length() > 0) {
00756
00757 AAAAvpContainer *c_keyId = cm.acquire("Key-Id");
00758
00759 e = em.acquire(AAA_AVP_INTEGER32_TYPE);
00760 diameter_integer32_t &keyId = e->dataRef(Type2Type<diameter_integer32_t>());
00761 c_keyId->add(e);
00762
00763 msg->avpList().add(c_keyId);
00764 keyId = m_SA.KeyId();
00765
00766 ACE_DEBUG((LM_INFO, "(%P|%t) key id=%d\n", id));
00767 }
00768
00769 DestinationAddressFormatting(*msg);
00770 m_TxChannel.Send(*this, *msg);
00771
00772 ACE_DEBUG((LM_INFO, "(%P|%t) SEND: Bind-Answer, tseq=%d, rseq=%d\n",
00773 msg->tseq(), msg->rseq()));
00774 }
00775
00776 void PANA_Client::DestinationAddressFormatting(PANA_Message &msg,
00777 AAAMessageBlock *eapPayload)
00778 {
00779
00780 if (eapPayload) {
00781 if (m_LastPayload) {
00782 m_LastPayload->Release();
00783 }
00784 m_LastPayload = AAAMessageBlock::Acquire(eapPayload);
00785 }
00786
00787 PANA_CfgClient &c = PANA_CONFIG_CLIENT();
00788
00789
00790 PANA_DeviceId *ipId, *hwId;
00791
00792
00793
00794
00795
00796
00797 ipId = m_PeerDeviceId.search(PANA_DeviceId::IPV4_ADDRESS);
00798 if (ipId) {
00799 msg.srcDevices().clone(*ipId);
00800 msg.srcPort(m_PeerPort);
00801 }
00802 else {
00803
00804 std::string *destIp;
00805
00806 if (c.paa_ip_address_.size() > 0) {
00807 destIp = &c.paa_ip_address_;
00808 msg.srcPort(PANA_CONFIG_CLIENT().paa_port_number_);
00809 }
00810 else if (c.paa_mcast_address_.size() > 0) {
00811 destIp = &c.paa_mcast_address_;
00812 msg.srcPort(PANA_CONFIG_CLIENT().paa_mcast_port_number_);
00813 }
00814 else {
00815 throw (PANA_Exception(PANA_Exception::FAILED,
00816 "Unable to configure a destination address"));
00817 }
00818
00819 char buf[64];
00820 ACE_OS::sprintf(buf, "%s:%d", destIp->data(), c.paa_port_number_);
00821 ACE_INET_Addr paaAddr(buf);
00822
00823 ACE_NEW_NORETURN(ipId, PANA_DeviceId(PANA_DeviceId::IPV4_ADDRESS));
00824
00825 if (ipId == NULL) {
00826 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00827 "Failed to allocate IP device id"));
00828 }
00829
00830 ACE_UINT32 ipAddr = paaAddr.get_ip_address();
00831 const_cast<std::string&>(ipId->id()).assign((char*)&ipAddr, sizeof(ACE_UINT32));
00832
00833 msg.srcDevices().push_back(ipId);
00834 }
00835
00836
00837
00838 hwId = m_PeerDeviceId.search(PANA_DeviceId::LL_ADDRESS);
00839 if (hwId) {
00840 msg.srcDevices().clone(*hwId);
00841 }
00842 }
00843
00844 bool PANA_Client::IspSelection(AAAAvpContainer* c_ispInfo)
00845 {
00846 ACE_DEBUG((LM_INFO, "(%P|%t) ISP information received [count=%d]\n", c_ispInfo->size()));
00847
00848 PANA_CfgProviderList ispList;
00849 PANA_CfgProviderList::iterator n;
00850 PANA_CfgProviderInfo *ispInfo, *ispChoice = NULL;
00851
00852 try {
00853
00854 for (unsigned int i = 0; i < c_ispInfo->size(); i ++) {
00855
00856 ACE_NEW_NORETURN(ispInfo, PANA_CfgProviderInfo);
00857 if (ispInfo) {
00858 PANA_ProviderInfoTool infoTool;
00859 diameter_grouped_t &isp = (*c_ispInfo)[i]->dataRef(Type2Type<diameter_grouped_t>());
00860 infoTool.Extract(isp, *ispInfo);
00861 ispList.push_back(ispInfo);
00862 }
00863 else {
00864 throw (PANA_Exception(PANA_Exception::NO_MEMORY,
00865 "Failed to allocate ISP structure"));
00866 }
00867 }
00868
00869 static_cast<PANA_ClientEventInterface&>(m_Event).ChooseISP(ispList, ispChoice);
00870 if (ispChoice) {
00871 throw(true);
00872 }
00873
00874
00875 if (PANA_CONFIG_CLIENT().isp_info_.name_.length() > 0) {
00876 for (n = ispList.begin(); n != ispList.end(); n++) {
00877 ispChoice = *n;
00878 if (PANA_CONFIG_CLIENT().isp_info_.name_ == ispChoice->name_) {
00879 throw (true);
00880 }
00881 }
00882 }
00883 throw (false);
00884 }
00885 catch (const PANA_Exception &c) {
00886 ACE_UNUSED_ARG(c);
00887 }
00888 catch (bool rc) {
00889 if (rc) {
00890 m_PreferedISP.name_ = ispChoice->name_;
00891 m_PreferedISP.id_ = ispChoice->id_;
00892
00893 ACE_DEBUG((LM_INFO, "(%P|%t) ISP information choosen: id=%d %s\n",
00894 m_PreferedISP.id_, m_PreferedISP.name_.data()));
00895 }
00896 n = ispList.begin();
00897 while (! ispList.empty()) {
00898 ispChoice = ispList.front();
00899 ispList.pop_front();
00900 delete ispChoice;
00901 }
00902 return (rc);
00903 }
00904
00905 return (false);
00906 }