void SMSvcApplyWork::Func_Begin( Work *work )
{
    SMSvcApplyWork *svcapply_work  = (SMSvcApplyWork*)work;
    PSMContext *psm_context      = (PSMContext*)work->user_ptr_;

    unsigned int ret_code = RC_SUCCESS;
    do 
    {
        const char *apply_url = NULL;
        ByteStream apply_desc_buf;

		if ( svcapply_work->apply_type_ == TermSvcApplyWork::SelfSvcApply )
		{
			apply_url = svcapply_work->pkg_->svc_self_apply_desc_.apply_url_.c_str();
		}
		else
		{
			apply_url = svcapply_work->pkg_->svc_cross_apply_desc_.init_apply_url_.c_str();
		}

		string service_name = svcapply_work->GetServiceName(apply_url);
		psm_context->logger_.Trace("%s 开始处理业务申请请求, 获取协议头为:%s.", svcapply_work->log_header_, service_name.c_str());

		if ( !psm_context->business_apply_svr_->IsValidServieName(service_name) )
		{ 
			// 当收到的业务申请请求url的协议头为非SM支持的协议头时,需要将该业务申请直接转发给对应终端,通知终端业务切换;            
			svcapply_work->AddNotifySvcSwitchWork();

			psm_context->logger_.Trace("%s 添加终端业务切换通知工作任务成功,向SM发送成功应答。", svcapply_work->log_header_);

			svcapply_work->SendResponed(RC_SUCCESS);
			TermSvcApplyWork::Func_End(work);
			return;
		}

        if ( svcapply_work->apply_type_ == TermSvcApplyWork::SelfSvcApply )
        {
            if ( svcapply_work->pkg_->svc_self_apply_desc_.back_url_.empty() )
            {
                //提升
                shared_ptr<TermSession> session_info(svcapply_work->self_session_info_.lock());
                if (session_info) {
                    psm_context->logger_.Trace("%s 本屏业务申请的BackURL为空,补填为:%s", svcapply_work->log_header_, session_info->last_local_svc_url_.c_str());
                    svcapply_work->pkg_->svc_self_apply_desc_.back_url_ = session_info->last_local_svc_url_;
                } else {
                    //todo:: loggggggg...
                }
            }
            else
            {
                string service_name = svcapply_work->GetServiceName(svcapply_work->pkg_->svc_self_apply_desc_.back_url_.c_str());
                if ( !psm_context->business_apply_svr_->IsValidServieName(service_name) )
                {
                    //提升
                    shared_ptr<TermSession> session_info(svcapply_work->self_session_info_.lock());
                    if (session_info)
                        session_info->last_local_svc_url_ = svcapply_work->pkg_->svc_self_apply_desc_.back_url_;
                }
            }

            apply_url       = svcapply_work->pkg_->svc_self_apply_desc_.apply_url_.c_str();
            apply_desc_buf  = svcapply_work->pkg_->svc_self_apply_desc_.SerializeFull();
        }
        else
        {
            if ( svcapply_work->pkg_->svc_cross_apply_desc_.init_back_url_.empty() )
            {
                shared_ptr<TermSession> session_info(svcapply_work->self_session_info_.lock());
                if (session_info) {
                    psm_context->logger_.Trace("%s 开始处理业务申请请求, 终端业务申请发起方的BackURL为空,需要补为上个业务的URL...", svcapply_work->log_header_);
                    svcapply_work->pkg_->svc_cross_apply_desc_.init_back_url_ = session_info->last_local_svc_url_;
                } else {
                    //todo:: logggggggg...
                }
            }
            else
            {
                string service_name = svcapply_work->GetServiceName(svcapply_work->pkg_->svc_cross_apply_desc_.init_back_url_.c_str());
                if ( !psm_context->business_apply_svr_->IsValidServieName(service_name) )
                {
                    //提升
                    shared_ptr<TermSession> sp_session_info(svcapply_work->self_session_info_.lock());
                    if (sp_session_info)
                        sp_session_info->last_local_svc_url_ = svcapply_work->pkg_->svc_cross_apply_desc_.init_back_url_;
                }
            }

            if ( svcapply_work->pkg_->svc_cross_apply_desc_.show_back_url_.empty() )
            {
                shared_ptr<TermSession> session_info(svcapply_work->cross_session_info_.lock());
                if (session_info) {
                    psm_context->logger_.Trace("%s 开始处理业务申请请求, 终端业务申请呈现方的BackURL为空,需要补为上个业务的URL...", svcapply_work->log_header_);
                    svcapply_work->pkg_->svc_cross_apply_desc_.show_back_url_ = session_info->last_local_svc_url_;
                } else {
                    //todo:: loggggggg...
                }
            }
            else
            {
                string service_name = svcapply_work->GetServiceName(svcapply_work->pkg_->svc_cross_apply_desc_.show_back_url_.c_str());
                if ( !psm_context->business_apply_svr_->IsValidServieName(service_name) )
                {
                    //提升
                    shared_ptr<TermSession> sp_session_info(svcapply_work->cross_session_info_.lock());
                    if (sp_session_info)
                        sp_session_info->last_local_svc_url_ = svcapply_work->pkg_->svc_cross_apply_desc_.show_back_url_;
                }
            }

            apply_url       = svcapply_work->pkg_->svc_cross_apply_desc_.init_apply_url_.c_str();
            apply_desc_buf  = svcapply_work->pkg_->svc_cross_apply_desc_.SerializeFull();
        }

		/*
		psm_context->logger_.Trace("%s 检查BackURL,如果为空,则需要补填为上一个本地业务的URL...", svcapply_work->log_header_);

		if ( svcapply_work->apply_type_ == TermSvcApplyWork::SelfSvcApply )
		{
			if ( svcapply_work->pkg_->svc_self_apply_desc_.back_url_.empty() )
			{
				psm_context->logger_.Trace("%s 本屏业务申请的BackURL为空,补填为:%s", svcapply_work->log_header_, svcapply_work->self_session_info_->last_local_svc_url_.c_str());
				svcapply_work->pkg_->svc_self_apply_desc_.back_url_ = svcapply_work->self_session_info_->last_local_svc_url_;
			}
			else
			{
				string service_name = svcapply_work->GetServiceName(svcapply_work->pkg_->svc_self_apply_desc_.back_url_.c_str());
				if ( !psm_context->business_apply_svr_->IsValidServieName(service_name) )
				{
					svcapply_work->self_session_info_->last_local_svc_url_ = svcapply_work->pkg_->svc_self_apply_desc_.back_url_;
				}
			}

			apply_desc_buf  = svcapply_work->pkg_->svc_self_apply_desc_.SerializeFull();
		}
		else
		{
			if ( svcapply_work->pkg_->svc_cross_apply_desc_.init_back_url_.empty() )
			{
				psm_context->logger_.Trace("%s 开始处理业务申请请求, 终端业务申请发起方的BackURL为空,需要补为上个业务的URL...", svcapply_work->log_header_);
				svcapply_work->pkg_->svc_cross_apply_desc_.init_back_url_ = svcapply_work->self_session_info_->last_local_svc_url_;
			}
			else
			{
				string service_name = svcapply_work->GetServiceName(svcapply_work->pkg_->svc_cross_apply_desc_.init_back_url_.c_str());
				if ( !psm_context->business_apply_svr_->IsValidServieName(service_name) )
				{
					svcapply_work->self_session_info_->last_local_svc_url_ = svcapply_work->pkg_->svc_cross_apply_desc_.init_back_url_;
				}
			}

			if ( svcapply_work->pkg_->svc_cross_apply_desc_.show_back_url_.empty() )
			{
				psm_context->logger_.Trace("%s 开始处理业务申请请求, 终端业务申请呈现方的BackURL为空,需要补为上个业务的URL...", svcapply_work->log_header_);
				svcapply_work->pkg_->svc_cross_apply_desc_.show_back_url_ = svcapply_work->cross_session_info_->last_local_svc_url_;
			}
			else
			{
				string service_name = svcapply_work->GetServiceName(svcapply_work->pkg_->svc_cross_apply_desc_.show_back_url_.c_str());
				if ( !psm_context->business_apply_svr_->IsValidServieName(service_name) )
				{
					svcapply_work->cross_session_info_->last_local_svc_url_ = svcapply_work->pkg_->svc_cross_apply_desc_.show_back_url_;
				}
			}

			apply_desc_buf  = svcapply_work->pkg_->svc_cross_apply_desc_.SerializeFull();
		}
		*/

		svcapply_work->run_step_  = SMSvcApplyWork::SvcApply_Init_begin;
        svcapply_work->work_func_ = SMSvcApplyWork::Func_Inited;

        ret_code = svcapply_work->AddSendHttpRequestWork(service_name, apply_desc_buf);
        if ( ret_code != RC_SUCCESS )
        {
            break;
        }

        // 添加请求任务成功,等待回调Func_Inited即可
        return;
    } while ( 0 );

    // 参数错误,直接给终端应答
    psm_context->logger_.Warn("%s 处理业务申请请求失败,向终端发送失败应答。", svcapply_work->log_header_);

    svcapply_work->SendResponed(ret_code);

    SMSvcApplyWork::Func_End(work);
}
void SMSvcApplyWork::Func_Inited( Work *work )
{
    SMSvcApplyWork *svcapply_work  = (SMSvcApplyWork*)work;
    PSMContext *psm_context      = (PSMContext*)work->user_ptr_;

    svcapply_work->run_step_ = SMSvcApplyWork::SvcApply_Init_end;

    unsigned int ret_code = RC_SUCCESS;

    do 
    {
        //HTTP请求返回失败
        if ( svcapply_work->http_request_info_.request_result_ != HTTPAysnRequestInfo::OK )
        {
            psm_context->logger_.Warn("%s 处理业务申请请求, 接收SM应答失败。 ", svcapply_work->log_header_);

            ret_code = ST_RC_TERM_SVC_INIT_ERROR;
            break;
        }

        psm_context->logger_.Trace("%s 处理业务申请请求, 接收到SM的应答,content=%s ", 
                                    svcapply_work->log_header_, 
                                    (char*)svcapply_work->http_request_info_.responed_body_.GetBuffer());

        //解析描述符
        vector<PB_SvcURLDescriptor>   svc_url_desc_list;
        PB_KeyMapIndicateDescriptor   sm_keymaping_indicate_desc;

        ret_code = svcapply_work->ParseHttpResponse(svcapply_work->http_request_info_.responed_body_, svc_url_desc_list, sm_keymaping_indicate_desc);
        if ( ret_code != RC_SUCCESS )
        {
            psm_context->logger_.Warn("%s 处理业务申请请求, 解析接收到SM的应答,解析失败。", svcapply_work->log_header_);

            break;
        }

        PT_KeyMapIndicateDescriptor   term_keymaping_indicate_desc;
        term_keymaping_indicate_desc.dest_session_id_        = sm_keymaping_indicate_desc.session_id_;
        term_keymaping_indicate_desc.dest_sm_session_id_     = sm_keymaping_indicate_desc.dest_sm_session_id_;
        term_keymaping_indicate_desc.mapping_protocol_       = sm_keymaping_indicate_desc.mapping_protocol_;
        term_keymaping_indicate_desc.mapping_server_ip_      = sm_keymaping_indicate_desc.mapping_server_ip_;
        term_keymaping_indicate_desc.mapping_server_port_    = sm_keymaping_indicate_desc.mapping_server_port_;
        term_keymaping_indicate_desc.mapping_type_           = 1;
        term_keymaping_indicate_desc.valid_                  = sm_keymaping_indicate_desc.valid_;

        bool need_send_keymap_indicate = sm_keymaping_indicate_desc.valid_;
        for ( vector<PB_SvcURLDescriptor>::iterator iter = svc_url_desc_list.begin(); iter != svc_url_desc_list.end(); iter++ )
        {
            if ( iter->valid_ )
            {                
                weak_ptr<TermSession> wp_show_term_session = psm_context->busi_pool_->FindTermSessionById(iter->session_id_);
                shared_ptr<TermSession> show_term_session(wp_show_term_session.lock());
                if ( show_term_session != NULL )
                {
                    //更新backurl
                    if ( iter->back_url_.empty() )
                    {
                        iter->back_url_ = show_term_session->last_local_svc_url_;
                    }
                    else
                    {
                        string service_name = svcapply_work->GetServiceName(iter->back_url_.c_str());
                        if ( !psm_context->business_apply_svr_->IsValidServieName(service_name) )
                        {
                            //提升
                            shared_ptr<TermSession> session_info(svcapply_work->self_session_info_.lock());
                            if (session_info)
                                session_info->last_local_svc_url_ = iter->back_url_;
                        }
                    }

                    // 更新终端业务信息
                    show_term_session->UpdateSessionInfo(*iter);

                    // 通知呈现端业务切换
                    PtSvcSwitchRequest *svcswitch_request = new PtSvcSwitchRequest;
					svcswitch_request->svc_url_desc_.url_           = iter->url_;
					svcswitch_request->svc_url_desc_.back_url_      = iter->back_url_;
					svcswitch_request->svc_url_desc_.sm_session_id_ = iter->sm_session_id_;
					svcswitch_request->svc_url_desc_.valid_         = true;
                    //svcswitch_request->svc_url_desc_ = *iter;
                    if ( need_send_keymap_indicate && (sm_keymaping_indicate_desc.session_id_ == iter->session_id_) )
                    {                       
                        svcswitch_request->keymap_indicate_desc_ = term_keymaping_indicate_desc;
                        need_send_keymap_indicate                = false;
                    }

					psm_context->logger_.Warn("%s 处理业务申请请求, 添加业务切换通知工作任务。 \n目标终端SID:" SFMT64U "", svcapply_work->log_header_);

                    psm_context->term_basic_func_svr_->AddSvcSwitchNotifyWork(show_term_session, svcswitch_request);
                }
            }
            else
            {
                ret_code = PT_RC_MSG_FORMAT_ERROR;
                break;
            }
        }

        // 按键映射指示需要单独发送
        if ( need_send_keymap_indicate )
        {
            weak_ptr<TermSession> wp_show_term_session = psm_context->busi_pool_->FindTermSessionById(term_keymaping_indicate_desc.dest_session_id_);
            shared_ptr<TermSession> show_term_session(wp_show_term_session.lock());
            if ( show_term_session != NULL )
            {
                // 通知控制端业务切换
                PtSvcSwitchRequest *svcswitch_request = new PtSvcSwitchRequest;
                svcswitch_request->keymap_indicate_desc_ = term_keymaping_indicate_desc;

                psm_context->term_basic_func_svr_->AddSvcSwitchNotifyWork(show_term_session, svcswitch_request);
            }
        }
    } while ( 0 );

    // 参数错误,直接给终端应答
    svcapply_work->SendResponed(ret_code);

    SMSvcApplyWork::Func_End(work);   
}
void V800export::export_sessions(QList<QString> sessions, unsigned char mode)
{
    QSettings settings;
    QString default_dir = settings.value(tr("default_dir")).toString();

    for(int sessions_iter = 0; sessions_iter < sessions.length(); sessions_iter++)
    {
        QStringList filters;
        filters << QString(tr("%1_*")).arg(sessions[sessions_iter]);

        QDir filter_dir(default_dir);
        filter_dir.setNameFilters(filters);
        filter_dir.setFilter(QDir::Dirs);

        int multi_sessions_iter;
        QStringList multi_sessions = filter_dir.entryList();
        for(multi_sessions_iter = 0; multi_sessions_iter < multi_sessions.length(); multi_sessions_iter++)
        {
            if(!make_bipolar_names(multi_sessions[multi_sessions_iter]))
            {
                emit export_session_error(sessions[sessions_iter], RENAME_ERROR);
                continue;
            }

            QString session_info(QString(tr("%1/%2/v2-users-0000000-training-sessions-%3")).arg(default_dir).arg(multi_sessions[multi_sessions_iter]).arg(multi_sessions[multi_sessions_iter]));
            polar::v2::TrainingSession parser(session_info);

            qDebug("Parser: %s", session_info.toUtf8().constData());

            parser.setTcxOption(polar::v2::TrainingSession::ForceTcxUTC, true);

            if(!parser.parse())
                emit export_session_error(sessions[sessions_iter], PARSE_ERROR);

            if(mode & TCX_EXPORT)
            {
                QString tcx(QString(tr("%1/%2.tcx")).arg(default_dir).arg(multi_sessions[multi_sessions_iter]));
                if(!parser.writeTCX(tcx))
                    emit export_session_error(sessions[sessions_iter], TCX_ERROR);
            }

            if(mode & HRM_EXPORT)
            {
                QString hrm(QString(tr("%1/%2")).arg(default_dir).arg(multi_sessions[multi_sessions_iter]));
                QStringList hrm_out = parser.writeHRM(hrm);
                if(hrm_out.length() < 1)
                    emit export_session_error(sessions[sessions_iter], HRM_ERROR);
            }

            if(mode & GPX_EXPORT)
            {
                QString gpx(QString(tr("%1/%2.gpx")).arg(default_dir).arg(multi_sessions[multi_sessions_iter]));
                if(!parser.writeGPX(gpx))
                    emit export_session_error(sessions[sessions_iter], GPX_ERROR);
            }

            QDir(QString(tr("%1/%2")).arg(default_dir).arg(multi_sessions[multi_sessions_iter])).removeRecursively();
        }

        emit export_session_done(sessions_iter, sessions.length());
    }

    emit export_sessions_done();
}