void S1mmeSession::CtEncodeKqi(S1MMEKQI* kqi, S1APNode* p_node, uint8_t worker_id) { MsgCommonInfo& common = p_node->GetCommonInfo(); SPUserInfo& sp_user_info = p_node->GetUserInfo(); //获取 buf TlvEncoder* p_encoder_cur = g_p_encoder_[worker_id]; YdCDR_T* p_dst_data = (YdCDR_T*)malloc(sizeof(YdCDR_T)); if (p_dst_data == NULL) { return; } p_dst_data->not_associate = 0; if ((common.not_associate & 0x03) == 0x03) p_dst_data->not_associate = 1; p_encoder_cur->Set(p_dst_data->cdr_data,kMaxOneCdrBufLen); uint64_t imsi = sp_user_info->GetIMSI(); if(common.eci == 0) { common.eci = sp_user_info->GetEci(); } uint16_t tmp_enbid = common.tac;//>>8; //uint32_t tmp_enbid = (common.eci >> 8)&0xfffff; char xdrid_str[32]={0}; #ifdef OPEN_NEW_HUISU convert_xdrid_to_string(xdrid_str, kqi->xdrid, s_xdr_id_len); #else #ifdef OPENCTPR g4sigtran::pr::ProcBlock* p_blk = kqi->binary_block_in_xdr_.GetBlock(); p_blk->SerializeXid(xdrid_str, sizeof(xdrid_str)); #else uint64_t subcdrid = g_ct_xdr_id.GetXid(); //reverse subend; if(::is_open_reverse) { SetReverseSubend(p_node, subcdrid); } #ifdef ONE_THIRD_YUNNAN_MRO g_ct_xdr_id.Serialize((uint8_t*)xdrid_str, s_xdr_id_len, imsi); #else g_ct_xdr_id.Serialize((uint8_t*)xdrid_str, s_xdr_id_len); #endif #endif #endif struct timespec start_time = kqi->request_time_, end_time = kqi->response_time_; if (kqi->request_time_.tv_sec == 0) { if (!(kqi->response_time_.tv_sec == 0)) { start_time = kqi->response_time_; } else if (!(kqi->complete_time_.tv_sec == 0)) { start_time = kqi->complete_time_; } } 在S1mmeSession::CtEncodeKqi函数最后面加一个函数,来维护一组key、value的关系。 key:imsi value:imsi、imei、common.eci、common.tac、last_time 要求,imsi相同时,以最后一条记录的value内容为准进行保存。
时间: 2024-03-29 10:41:10 浏览: 70
可以使用一个 std::unordered_map 来维护这组 key-value 的关系,其中 key 为 imsi,value 为一个结构体,包含了 imsi、imei、common.eci、common.tac、last_time 等信息。每次调用 CtEncodeKqi 函数时,先从 unordered_map 中查找该 imsi 是否已经存在,如果存在则更新该 imsi 对应的 value 值,否则插入一个新的 key-value 对。最后需要注意,当 unordered_map 中的 value 被更新时,需要同时更新 last_time 值为当前时间。
相关问题
void S1mmeSession::CtOutputKqi(S1MMEKQI* kqi, S1APNode* p_node, uint8_t worker_id) { SPUserInfo& sp_user_info = p_node->GetUserInfo(); //先填充kqi中承载信息 for (uint8_t i=0; i<kqi->GetBearerNum(); i++) { KQIBearer* p_bearer = kqi->GetBearer(i); if (p_bearer == NULL) break; sp_user_info->FillKQIBearer(p_bearer->ebi, p_bearer); } //再执行该信令功能 switch (kqi->kqi_type_) { case kS1mmeProcTypeEPSBearerContextDeactivation: //删除释放的承载 sp_user_info->EraseEBI(kqi->GetBearer1()->ebi); break; case kS1mmeProcTypeERABRelease: case kS1mmeProcTypeERABReleaseIndication: //删除需要释放的承载 for (uint8_t i=0; i<kqi->GetBearerNum(); i++) { KQIBearer* p_bearer = kqi->GetBearer(i); if (p_bearer == NULL) break; sp_user_info->EraseEBI(p_bearer->ebi); } break; case kS1mmeProcTypePathSwitch: case kS1mmeProcTypeS1SwitchOut: case kS1mmeProcTypeS1SwitchIn: kqi->bearer_num_ = 0;//暂不输出切换相关的承载信息 //删除没有切换过来的承载 break; } if (!(kqi->kqi_type_ >= kS1mmeProcTypeAttach && kqi->kqi_type_ <= kS1mmeProcTypeMax)) { return; } // CtEncodeKqi(kqi, p_node, worker_id); update_test(p_node); return; }什么意思
这是一段 C++ 代码,其中定义了一个名为 S1mmeSession 的类,该类包含一个名为 CtOutputKqi 的成员函数。该函数的作用是根据传入的 S1MMEKQI 类型的参数 kqi,向 sp_user_info 对象中填充一些信息,然后根据 kqi 的类型执行不同的功能。具体来说,如果 kqi 的类型是 kS1mmeProcTypeEPSBearerContextDeactivation,则删除释放的承载;如果 kqi 的类型是 kS1mmeProcTypeERABRelease 或 kS1mmeProcTypeERABReleaseIndication,则删除需要释放的承载;如果 kqi 的类型是 kS1mmeProcTypePathSwitch、kS1mmeProcTypeS1SwitchOut 或 kS1mmeProcTypeS1SwitchIn,则删除没有切换过来的承载;如果 kqi 的类型不在 kS1mmeProcTypeAttach 和 kS1mmeProcTypeMax 之间,则直接返回。最后,该函数调用 CtEncodeKqi 函数对 kqi 进行编码,并且更新 test。
void S1mmeSession::CuOutputNode(S1APNode* p_node, uint8_t worker_id,bool timeout) { bool output_ue_release = true, out_put_pdn_connect = true; time_t last_kqi_sec = 0; for (std::vector<CuKqiInfo_T>::iterator it = p_node->cu_kqi_.begin(); it != p_node->cu_kqi_.end();) { CuOutputKqi(p_node, it->msg_type, it->ebi, last_kqi_sec, output_ue_release,worker_id); it = p_node->cu_kqi_.erase(it); } S1MMEKQI* kqi_main = p_node->FindKqi(kS1mmeProcTypeERABModification); if(kqi_main){ CuEncodeErabModification(kqi_main, p_node->GetCommonInfo(), p_node->GetUserInfo(), current_time_.tv_sec,worker_id); } kqi_main = p_node->FindKqi(kS1mmeProcTypeSecondaryRatDataUsage); if(kqi_main){ CuEncodeSecondaryRatDataUsageReport(kqi_main, p_node->GetCommonInfo(), p_node->GetUserInfo(), current_time_.tv_sec,worker_id); } kqi_main = p_node->FindKqi(kS1mmeProcTypeAttach); if (kqi_main && ((timeout && nas_default_encrypt_alg_) || (!timeout))) { S1MMEKQI* kqi_ue_release = p_node->FindKqi(kS1mmeProcTypeUEContextRelease); S1MMEKQI* kqi_pdn_connect = p_node->FindKqi(kS1mmeProcTypePdnConnect, 5); if (1) { for (uint8_t i=0; i<1; i++) { //KQIBearer* p_bearer = kqi_initial_context->GetBearer(i); //if (p_bearer == NULL) break; //p_node->GetUserInfo()->FillKQIBearer(p_bearer->ebi, p_bearer); } } CuEncodeAttach(kqi_main, p_node->GetCommonInfo(), p_node->GetUserInfo(), current_time_.tv_sec,worker_id,kqi_ue_release,kqi_pdn_connect); //output attach if (output_ue_release && kqi_ue_release && kqi_ue_release->complete_time_.tv_sec - kqi_main->complete_time_.tv_sec > 15) { //output UEContextRelease; CuEncodeUEContextRelease(kqi_ue_release,p_node->GetCommonInfo(),p_node->GetUserInfo(),current_time_.tv_sec,worker_id); output_ue_release = false; } out_put_pdn_connect = false; }什么意思
这段代码主要是将S1APNode的信息输出到CU(Control Unit)中。首先,它会遍历p_node->cu_kqi_中的每个CuKqiInfo_T对象,并调用CuOutputKqi()函数将KQI信息编码并输出到CU中。接着,它会查找S1MMEKQI对象,并调用CuEncodeErabModification()、CuEncodeSecondaryRatDataUsageReport()和CuEncodeAttach()函数将ERAB Modification、Secondary RAT Data Usage Report和Attach信息编码并输出到CU中。如果timeout为true且nas_default_encrypt_alg_不为空,还会调用CuEncodeUEContextRelease()函数将UE Context Release信息编码并输出到CU中。在输出Attach信息时,如果output_ue_release为true且kqi_ue_release不为空,且kqi_ue_release已完成的时间与kqi_main已完成的时间相差大于15秒,则会调用CuEncodeUEContextRelease()函数将UE Context Release信息编码并输出到CU中。最后,将out_put_pdn_connect设置为false。
阅读全文