// 秒寻科技
// 主站ID二次检查
// zt
// 2023-03-23

#include "../../includes/includes.h"

// 导入全局变量
extern PUB_SYS_STATUS_T gg_stSysStatus;
extern PUB_LOCATION_DATA_T gg_astLocationDataList[PUB_SYS_CARRIER_NUM];

// 对判决主站ID进行二次校验，输出一组定位基站
// pstJudgementMainBtsList:判决主站队列
// pstLctBtsList:一组定位基站（返回参数）
void bts_idcheck_main(BTS_ID_JUDGEMENT_MAIN_BTS_T *pstJudgementMainBtsList, PUB_LCT_BTS_LIST_T *pstLctBtsList)
{
    BTS_ID_MAIN_BTS_T stJudgementBtsData = {0};       // 判决基站
    BTS_INSTALL_BTS_LIST_T *pstInstallBtsList = NULL; // 安装基站队列
    BTS_INSTALL_BTS_T stMainBtsData = {0};            // 主基站
    uint8 byCheckFlag = 0;

    // 判决主站数量不合法
    if (pstJudgementMainBtsList->byBtsNum < 1)
    {
        return;
    }

    // 获得安装基站队列
    pstInstallBtsList = (BTS_INSTALL_BTS_LIST_T *)bts_main_get_install_bts_list();

    // 校验判决基站（将判决站转换成安装站）
    for (uint8 i = 0; i < pstJudgementMainBtsList->byBtsNum; i++)
    {
        stJudgementBtsData = pstJudgementMainBtsList->astBtsList[i]; // 获得判决站

        // 遍历安装基站列表，找出与“判决站ID”相同的安装基站，并检验该基站周边的基站是否包含在判决站队列中
        for (uint16 j = 0; j < pstInstallBtsList->dwBtsNum; j++)
        {
            stMainBtsData = pstInstallBtsList->astLocalBtsList[j]; // 主基站

            // 判决基站ID与安装基站ID相同
            if (stJudgementBtsData.dwBtsId == stMainBtsData.dwBtsId && stJudgementBtsData.byFreqIndex == (uint8)stMainBtsData.dwFreqIndex)
            {
                // 校验“主基站”的周边基站是否有包含在判决基站列表中的，有则校验成功，无则校验失败
                byCheckFlag = bts_idcheck_check_nearby_bts(stMainBtsData, pstInstallBtsList, pstJudgementMainBtsList);
                if (byCheckFlag) // 校验成功
                {
                    break;
                }
            }
        }

        // 校验成功
        if (byCheckFlag)
        {
            break;
        }
    }

    // 组织定位基站组(查询主站周边的基站)
    if (byCheckFlag)
    {
        bts_idcheck_gen_location_bts(stJudgementBtsData.byShiftTimes, stMainBtsData, pstInstallBtsList, pstLctBtsList);
        if (pstLctBtsList->byBtsNum > 1) // 有2个基站
        {
            gg_stSysStatus.byShiftTimes = stJudgementBtsData.byShiftTimes; // 保存右移次数

            // 切换系统至跟踪阶段
            if (!gg_stSysStatus.byBtsCaptureFlag)
            {
                gg_stSysStatus.byBtsCaptureFlag = 1;
            }
        }
    }

    return;
}

// 校验周边基站。计算主站与从站间的距离是否满足要求，若满足则进一步判断从站是否在判决基站队列中，在则校验成功，不在则校验失败。
// stMainBtsData:主站
// pstInstallBtsList:安装基站列表（都为从站）
// pstJudgementMainBtsList:判决基站列表
// 返回值:1：校验成功，0：校验失败
uint8 bts_idcheck_check_nearby_bts(BTS_INSTALL_BTS_T stMainBtsData, BTS_INSTALL_BTS_LIST_T *pstInstallBtsList, BTS_ID_JUDGEMENT_MAIN_BTS_T *pstJudgementMainBtsList)
{
    BTS_INSTALL_BTS_T stSlaveBts; // 从站
    flt32 fDistance = 0.0;
    uint8 byCheckFlag = 0;

    for (uint16 i = 0; i < pstInstallBtsList->dwBtsNum; i++)
    {
        stSlaveBts = pstInstallBtsList->astLocalBtsList[i]; // 从站

        // 若两基站在同一栋楼，也在同楼层
        if ((stMainBtsData.dwBtsId != stSlaveBts.dwBtsId && stMainBtsData.dwFreqIndex != stSlaveBts.dwFreqIndex) && (stMainBtsData.dwBuildId == stSlaveBts.dwBuildId) && (stMainBtsData.dwLayerId == stSlaveBts.dwLayerId))
        {
            // 检查主站与从站间的距离
            fDistance = bts_idcheck_cal_pp_distance(stMainBtsData.dwCoordX, stMainBtsData.dwCoordY, stSlaveBts.dwCoordX, stSlaveBts.dwCoordY);
            if (fDistance <= PUB_BTS_VALID_DISTANCE) // 距离合法
            {
                // 进一步检查从站是否在判决基站列表中
                for (uint8 j = 0; j < pstJudgementMainBtsList->byBtsNum; j++)
                {
                    if (stSlaveBts.dwBtsId == pstJudgementMainBtsList->astBtsList[j].dwBtsId && (uint8)stSlaveBts.dwFreqIndex == pstJudgementMainBtsList->astBtsList[j].byFreqIndex)
                    {
                        byCheckFlag = 1;
                        break;
                    }
                }
            }
        }

        if (byCheckFlag)
        {
            break;
        }
    }

    return byCheckFlag;
}

// 计算两点之间的距离，坐标单位：厘米
flt32 bts_idcheck_cal_pp_distance(int32 x1, int32 y1, int32 x2, int32 y2)
{
    flt32 fDistance = 0.0;

    fDistance = (flt32)sqrt(((flt32)x1 / 100 - (flt32)x2 / 100) * ((flt32)x1 / 100 - (flt32)x2 / 100) + ((flt32)y1 / 100 - (flt32)y2 / 100) * ((flt32)y1 / 100 - (flt32)y2 / 100));
    return fDistance;
}

// 组织一组定位基
// byShiftTimes:基站ID右移次数
// stMainBtsData:主站
// pstInstallBtsList:安装基站队列
// pstLocationGroup:一组定位基站
void bts_idcheck_gen_location_bts(uint8 byShiftTimes, BTS_INSTALL_BTS_T stMainBtsData, BTS_INSTALL_BTS_LIST_T *pstInstallBtsList, PUB_LCT_BTS_LIST_T *pstLocationGroup)
{
    BTS_INSTALL_BTS_T stSlaveBts; // 从站
    flt32 fDistance = 0.0;        // 主站与从站间的距离，单位：米

    PUB_LCT_BTS_T stLocationBts = {0}; // 定位基站
    uint8 byCounter = 0;               // 定位基站个数

    // // 首先保存基准站
    // stLocationBts.dwMainBtsFlag = 1; // 主站
    // stLocationBts.dwBuildId = stMainBtsData.dwBuildId;
    // stLocationBts.dwLayerId = stMainBtsData.dwLayerId;
    // stLocationBts.dwBtsId = stMainBtsData.dwBtsId;
    // stLocationBts.dwFreqIndex = stMainBtsData.dwFreqIndex;
    // stLocationBts.dwSlot = stMainBtsData.dwSlot;
    // stLocationBts.dwCoordX = stMainBtsData.dwCoordX;
    // stLocationBts.dwCoordY = stMainBtsData.dwCoordY;
    // stLocationBts.dwCoordZ = stMainBtsData.dwCoordZ;
    // pstLocationGroup->astLocationBts[byCounter] = stLocationBts;
    // byCounter++;

    // 从安装基站队列中查找主站周边的从站
    for (uint16 i = 0; i < pstInstallBtsList->dwBtsNum; i++)
    {
        stSlaveBts = pstInstallBtsList->astLocalBtsList[i]; // 从站
        if (stMainBtsData.dwBuildId == stSlaveBts.dwBuildId && stMainBtsData.dwLayerId == stSlaveBts.dwLayerId)
        {
            // 检查主站与从站间的距离是否满足要求
            fDistance = bts_idcheck_cal_pp_distance(stMainBtsData.dwCoordX, stMainBtsData.dwCoordY, stSlaveBts.dwCoordX, stSlaveBts.dwCoordY);
            if (fDistance <= PUB_BTS_VALID_DISTANCE) // 距离合法
            {
                stLocationBts.dwMainBtsFlag = 2; // 从站
                stLocationBts.dwBuildId = stSlaveBts.dwBuildId;
                stLocationBts.dwLayerId = stSlaveBts.dwLayerId;
                stLocationBts.dwBtsId = stSlaveBts.dwBtsId;
                stLocationBts.dwFreqIndex = stSlaveBts.dwFreqIndex;
                stLocationBts.dwSlot = stSlaveBts.dwSlot;
                stLocationBts.dwCoordX = stSlaveBts.dwCoordX;
                stLocationBts.dwCoordY = stSlaveBts.dwCoordY;
                stLocationBts.dwCoordZ = stSlaveBts.dwCoordZ;
                pstLocationGroup->astLocationBts[byCounter] = stLocationBts;

                byCounter++;
                if (byCounter >= PUB_LCT_BTS_MAX_NUM)
                {
                    break;
                }
            }
        }
    }

    pstLocationGroup->byBtsNum = byCounter;

    return;
}
