// 秒寻科技
// 基站模块主控子模块。基站模块核心功能包括计算最强幅度，实施信号同步，计算基站ID和跟踪基站ID。
// 基站模块向外输出一组定位基站
// zt
// 2023-03-12

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

// 定义在本模块使用的全局变量
BTS_AMPL_MIRROR_DATA_T gBts_astBtsAmplMirrorDataList[PUB_SYS_CARRIER_NUM] = {0}; // 基站幅度镜像数据队列
BTS_MAX_AMPL_DATA_T gBts_astBtsMaxAmplDataList[PUB_SYS_CARRIER_NUM] = {0};       // 基站最大幅度数据队列
int32 *gBts_pstInstallBtsList = NULL;                                            // 本地基站组

// 导出全局变量
extern PUB_SYS_STATUS_T gg_stSysStatus;
extern PUB_CURRENT_LCT_RESULT_T gg_stCurrentLctCoord;
extern uint32 gg_dwFrameNo;

// 模块初始化
void bts_main_init()
{
    memset(gBts_astBtsAmplMirrorDataList, 0, sizeof(BTS_AMPL_MIRROR_DATA_T) * PUB_SYS_CARRIER_NUM);
    for (uint8 i = 0; i < PUB_SYS_CARRIER_NUM; i++)
    {
        gBts_astBtsAmplMirrorDataList[i].byFreqIndex = i;
    }
    memset(gBts_astBtsMaxAmplDataList, 0, sizeof(BTS_MAX_AMPL_DATA_T) * PUB_SYS_CARRIER_NUM);

    // 申请一片内存，供JS模块写入数据
    gBts_pstInstallBtsList = malloc(sizeof(BTS_INSTALL_BTS_LIST_T));
    memset(gBts_pstInstallBtsList, 0, sizeof(BTS_INSTALL_BTS_LIST_T));

    // 基站ID模块初始化
    // bts_id_init();

    // TODO组织测试基站数据
    if (PUB_DEBUG_ENABLE)
    {
        bts_main_gen_test_bts();
    }
}

// 模块反初始化
void bts_main_deinit()
{
    free(gBts_pstInstallBtsList);
    gBts_pstInstallBtsList = NULL;
}

// 查询安装基站队列
int32 *bts_main_get_install_bts_list()
{
    return (int32 *)gBts_pstInstallBtsList;
}

// 基站模块主控函数，负责输出定位基站队列，需要分三种情况处理，即开机阶段、大楼或楼层切换阶段和同楼层移动
// pstLocationDataList:各频点定位数据队列
// pstNearbyBtsList:附近安装基站队列
// pstLctBtsList:一组定位基站（返回参数）
void bts_main(PUB_LOCATION_DATA_T *pstLocationDataList, ROUTE_NEARBY_BTS_LIST *pstNearbyBtsList, PUB_LCT_BTS_LIST_T *pstLctBtsList)
{
    uint8 byRemainder = 0;
    PUB_LCT_BTS_LIST_T stLctBtsList = {0};

    // 镜像定位数据
    // bts_mirror_main(pstLocationDataList, gBts_astBtsAmplMirrorDataList);

    // 基站幅度计算，并对幅度进行倒排序(幅度最强站的为主站，其余的为从站)
    bts_ampl_main(pstLocationDataList, gBts_astBtsAmplMirrorDataList, gBts_astBtsMaxAmplDataList);

    // 各基站进行同步(调整定位数据队列的各种消费索引)，包括时隙同步和比特同步
    bts_sync_main(pstLocationDataList, gBts_astBtsAmplMirrorDataList, gBts_astBtsMaxAmplDataList);

    // 系统处于基站捕获阶段
    if (!gg_stSysStatus.byBtsCaptureFlag)
    {
        if (gg_dwFrameNo > 1)
        {
            // 基于蓝牙基站组织定位基站队列
            byRemainder = (gg_dwFrameNo - 1) % PUB_SYS_SLOT_NUM;
            if (gg_stSysStatus.bySyncFlag && byRemainder == 0)
            {
                // 定位基站队列复位
                memset(pstLctBtsList, 0, sizeof(PUB_LCT_BTS_LIST_T));

                // 蓝牙周边基站数据有效期
                if (pstNearbyBtsList->byValidFlag)
                {
                    // 基于蓝牙或wifi基站生成定位基站队列
                    bts_main_gen_lct_bts_list_by_blue_or_wifi(pstNearbyBtsList, pstLctBtsList);
                }

                // 根据定位基站队列更新定位数据队列
                bts_main_update_lct_data_list(pstLocationDataList, pstLctBtsList);
            }
        }
    }
    // 已捕获到主站
    else
    {
        // 当前帧需要重新计算定位基站队列(一个同步周期计算一次定位基站队列)
        byRemainder = (gg_dwFrameNo - 1) % BTS_SYNC_STABLE_SYNC_FRAMES;
        if (byRemainder == 0)
        {
            // 定位基站队列复位
            memset(pstLctBtsList, 0, sizeof(PUB_LCT_BTS_LIST_T));

            // 基于定位坐标计算定位基站队列
            bts_track_by_coord(gg_stCurrentLctCoord, pstLctBtsList);

            // 根据定位基站队列更新定位数据队列
            bts_main_update_lct_data_list(pstLocationDataList, pstLctBtsList);
        }
    }

    return;
}

// 根据定位基站组队列更新对应的定位数据队列
// pstLctBtsList:定位基站队列
// pstLctDataList:定位数据队列
void bts_main_update_lct_data_list(PUB_LOCATION_DATA_T *pstLctDataList, PUB_LCT_BTS_LIST_T *pstLctBtsList)
{
    uint8 byBtsNum = pstLctBtsList->byBtsNum; // 定位基站个数
    PUB_LCT_BTS_T stLctBts = {0};
    uint8 byFreqIndex = 0;

    // 重置定位数据中的基站ID和时隙
    for (uint8 i = 0; i < PUB_SYS_CARRIER_NUM; i++)
    {
        pstLctDataList[i].dwSetBtsId = 0;
        pstLctDataList[i].bySetSlot = PUB_SYS_SLOT_NUM;
        pstLctDataList[i].byLctBtsFlag = 0;
    }

    // 遍历定位基站组，更新定位数据队列中的基站ID和时隙
    for (uint8 j = 0; j < byBtsNum; j++)
    {
        stLctBts = pstLctBtsList->astLocationBts[j]; // 定位基站数据
        byFreqIndex = (uint8)stLctBts.dwFreqIndex;   // 定位基站频率索引

        pstLctDataList[byFreqIndex].dwSetBtsId = stLctBts.dwBtsId;      // 更新定位数据中的基站ID
        pstLctDataList[byFreqIndex].bySetSlot = (uint8)stLctBts.dwSlot; // 更新定位数据中的时隙
        pstLctDataList[byFreqIndex].byLctBtsFlag = 1;
    }

    return;
}

// 根据基站最强幅度队列更新主站标识符
// pstLctBtsList:定位基站队列
// pstBtsMaxAmplDataList:基站最强幅度数据队列
void bts_main_update_main_bts_flag_by_max_ampl(PUB_LCT_BTS_LIST_T *pstLctBtsList, BTS_MAX_AMPL_DATA_T *pstBtsMaxAmplDataList)
{
    BTS_MAX_AMPL_DATA_T stTmp = {0};
    PUB_LCT_BTS_T *pstBts = NULL;
    uint8 byFlag = 0;

    for (uint8 j = 0; j < PUB_SYS_CARRIER_NUM; j++)
    {
        stTmp = pstBtsMaxAmplDataList[j];
        for (uint8 i = 0; i < pstLctBtsList->byBtsNum; i++)
        {
            pstBts = &pstLctBtsList->astLocationBts[i];
            if ((uint8)pstBts->dwFreqIndex == stTmp.byFreqIndex)
            {
                pstBts->dwMainBtsFlag = 1; // 主站
                byFlag = 1;
                break;
            }
        }

        if (byFlag)
        {
            break;
        }
    }

    return;
}

// 基于蓝牙或者声波基站生成定位基站队列
void bts_main_gen_lct_bts_list_by_blue_or_wifi(ROUTE_NEARBY_BTS_LIST *pstNearbyBtsList, PUB_LCT_BTS_LIST_T *pstLctBtsList)
{
    BTS_INSTALL_BTS_T stNearbyBts = {0};
    uint8 byNearbyBtsNum = 0;

    PUB_LCT_BTS_T *pstLctBts = NULL;

    byNearbyBtsNum = (uint8)pstNearbyBtsList->byBtsNum;
    for (uint8 i = 0; i < byNearbyBtsNum; i++)
    {
        stNearbyBts = pstNearbyBtsList->astBtsList[i];
        pstLctBts = &pstLctBtsList->astLocationBts[i];

        memset(pstLctBts, 0, sizeof(PUB_LCT_BTS_T));
        pstLctBts->dwBuildId = stNearbyBts.dwBuildId;
        pstLctBts->dwLayerId = stNearbyBts.dwLayerId;

        pstLctBts->dwBtsId = stNearbyBts.dwBtsId;
        pstLctBts->dwFreqIndex = stNearbyBts.dwFreqIndex;
        pstLctBts->dwSlot = stNearbyBts.dwSlot;

        pstLctBts->dwLctType = stNearbyBts.dwLctType;
        pstLctBts->dwTwoBtsNum = stNearbyBts.dwTwoBtsNum;
        memcpy(pstLctBts->adwTwoBtsList, stNearbyBts.adwTwoBtsList, sizeof(uint32) * stNearbyBts.dwTwoBtsNum);

        pstLctBts->dwCoordX = stNearbyBts.dwCoordX;
        pstLctBts->dwCoordY = stNearbyBts.dwCoordY;
        pstLctBts->dwCoordZ = stNearbyBts.dwCoordZ;
    }
    pstLctBtsList->byBtsNum = byNearbyBtsNum;

    return;
}

// 检查定位基站的有效性
// pstLctDataList:定位数据队列
// pstLctBtsList:定位基站队列（返回参数）
void bts_main_check_lct_bts_valid(PUB_LOCATION_DATA_T *pstLctDataList, PUB_LCT_BTS_LIST_T *pstLctBtsList)
{
    PUB_LOCATION_DATA_T *pstLctData = NULL;
    PUB_LCT_BTS_T *pstLctBts = NULL;
    uint8 byLctBtsNum = pstLctBtsList->byBtsNum;
    uint8 byFreqIndex = 0;
    uint8 byCounter = 0;

    for (uint8 i = 0; i < byLctBtsNum; i++)
    {
        pstLctBts = &pstLctBtsList->astLocationBts[i]; // 定位基站
        byFreqIndex = (uint8)pstLctBts->dwFreqIndex;

        pstLctData = &pstLctDataList[byFreqIndex]; // 定位数据
        if (pstLctData->byBtsValidFlag)
        {
            memcpy(&pstLctBtsList->astLocationBts[byCounter], pstLctBts, sizeof(PUB_LCT_BTS_T));
            byCounter++;
        }
    }

    pstLctBtsList->byBtsNum = byCounter;

    return;
}

void bts_main_gen_test_bts()
{
    BTS_INSTALL_BTS_LIST_T *pstHead = (BTS_INSTALL_BTS_LIST_T *)gBts_pstInstallBtsList;
    // 1号基站
    pstHead->astLocalBtsList[0].dwBuildId = 1;
    pstHead->astLocalBtsList[0].dwLayerId = 15;
    pstHead->astLocalBtsList[0].dwBtsId = 10001;
    pstHead->astLocalBtsList[0].dwFreqIndex = 3;
    pstHead->astLocalBtsList[0].dwSlot = 0;
    pstHead->astLocalBtsList[0].dwLctType = 2;
    pstHead->astLocalBtsList[0].dwTwoBtsNum = 0;
    pstHead->astLocalBtsList[0].adwTwoBtsList[0] = 0;
    pstHead->astLocalBtsList[0].dwCoordX = 0;
    pstHead->astLocalBtsList[0].dwCoordY = 0;
    pstHead->astLocalBtsList[0].dwCoordZ = 300;

    // 2号基站
    pstHead->astLocalBtsList[1].dwBuildId = 1;
    pstHead->astLocalBtsList[1].dwLayerId = 15;
    pstHead->astLocalBtsList[1].dwBtsId = 10002;
    pstHead->astLocalBtsList[1].dwFreqIndex = 4;
    pstHead->astLocalBtsList[1].dwSlot = 1;
    pstHead->astLocalBtsList[1].dwLctType = 2;
    pstHead->astLocalBtsList[1].dwTwoBtsNum = 0;
    pstHead->astLocalBtsList[1].adwTwoBtsList[0] = 0;
    pstHead->astLocalBtsList[1].dwCoordX = 2500;
    pstHead->astLocalBtsList[1].dwCoordY = 0;
    pstHead->astLocalBtsList[1].dwCoordZ = 300;
    pstHead->astLocalBtsList[1].adwBluetoothMac[0] = 1; // 蓝牙mac0
    pstHead->astLocalBtsList[1].adwBluetoothMac[1] = 2; // 蓝牙mac1
    pstHead->astLocalBtsList[1].adwBluetoothMac[2] = 3; // 蓝牙mac2

    // 3号基站
    pstHead->astLocalBtsList[2].dwBuildId = 1;
    pstHead->astLocalBtsList[2].dwLayerId = 15;
    pstHead->astLocalBtsList[2].dwBtsId = 10003;
    pstHead->astLocalBtsList[2].dwFreqIndex = 5;
    pstHead->astLocalBtsList[2].dwSlot = 2;
    pstHead->astLocalBtsList[2].dwLctType = 2;
    pstHead->astLocalBtsList[2].dwTwoBtsNum = 0;
    pstHead->astLocalBtsList[2].adwTwoBtsList[0] = 10002;
    pstHead->astLocalBtsList[2].dwCoordX = 5000;
    pstHead->astLocalBtsList[2].dwCoordY = 0;
    pstHead->astLocalBtsList[2].dwCoordZ = 300;

    // 4号基站
    pstHead->astLocalBtsList[3].dwBuildId = 1;
    pstHead->astLocalBtsList[3].dwLayerId = 15;
    pstHead->astLocalBtsList[3].dwBtsId = 10004;
    pstHead->astLocalBtsList[3].dwFreqIndex = 6;
    pstHead->astLocalBtsList[3].dwSlot = 3;
    pstHead->astLocalBtsList[3].dwCoordX = 5000;
    pstHead->astLocalBtsList[3].dwCoordY = 2500;
    pstHead->astLocalBtsList[3].dwCoordZ = 300;
    pstHead->astLocalBtsList[3].dwLctType = 2;
    pstHead->astLocalBtsList[3].dwTwoBtsNum = 0;
    pstHead->astLocalBtsList[3].adwTwoBtsList[0] = 10003;

    // 5号基站
    pstHead->astLocalBtsList[4].dwBuildId = 1;
    pstHead->astLocalBtsList[4].dwLayerId = 15;
    pstHead->astLocalBtsList[4].dwBtsId = 10005;
    pstHead->astLocalBtsList[4].dwFreqIndex = 7;
    pstHead->astLocalBtsList[4].dwSlot = 0;
    pstHead->astLocalBtsList[4].dwCoordX = 2500;
    pstHead->astLocalBtsList[4].dwCoordY = 2500;
    pstHead->astLocalBtsList[4].dwCoordZ = 300;
    pstHead->astLocalBtsList[4].dwLctType = 2;
    pstHead->astLocalBtsList[4].dwTwoBtsNum = 0;
    pstHead->astLocalBtsList[4].adwTwoBtsList[0] = 10003;

    // 6号基站
    pstHead->astLocalBtsList[5].dwBuildId = 1;
    pstHead->astLocalBtsList[5].dwLayerId = 15;
    pstHead->astLocalBtsList[5].dwBtsId = 10006;
    pstHead->astLocalBtsList[5].dwFreqIndex = 2;
    pstHead->astLocalBtsList[5].dwSlot = 1;
    pstHead->astLocalBtsList[5].dwCoordX = 0;
    pstHead->astLocalBtsList[5].dwCoordY = 2500;
    pstHead->astLocalBtsList[5].dwCoordZ = 300;
    pstHead->astLocalBtsList[5].dwLctType = 2;
    pstHead->astLocalBtsList[5].dwTwoBtsNum = 0;
    pstHead->astLocalBtsList[5].adwTwoBtsList[0] = 10003;

    pstHead->dwBtsNum = 6;
}

// 显示安装基站
void bts_main_show_install_bts()
{
    BTS_INSTALL_BTS_LIST_T *pstInstallBtsList = (BTS_INSTALL_BTS_LIST_T *)gBts_pstInstallBtsList;
    BTS_INSTALL_BTS_T stInstallBts = {0};

    // 打印基站数量
    printf("bts num is :%d\n", pstInstallBtsList->dwBtsNum);

    // 打印基站数据
    for (uint32 i = 0; i < pstInstallBtsList->dwBtsNum; i++)
    {
        memset(&stInstallBts, 0, sizeof(BTS_INSTALL_BTS_T));
        stInstallBts = pstInstallBtsList->astLocalBtsList[i];

        printf("bts index :%d\n", (i + 1));

        printf("build id :%d\n", stInstallBts.dwBuildId);
        printf("layer id :%d\n", stInstallBts.dwLayerId);

        printf("bts id :%d\n", stInstallBts.dwBtsId);
        printf("freq id :%d\n", stInstallBts.dwFreqIndex);
        printf("slot id :%d\n", stInstallBts.dwSlot);

        printf("coord x :%d\n", stInstallBts.dwCoordX);
        printf("coord y :%d\n", stInstallBts.dwCoordY);
        printf("coord z :%d\n", stInstallBts.dwCoordZ);

        printf("lct type :%d\n", stInstallBts.dwLctType);
        printf("two bts num :%d\n", stInstallBts.dwTwoBtsNum);
        printf("two bts id : ");
        for (uint8 j = 0; j < stInstallBts.dwTwoBtsNum; j++)
        {
            printf("%d", stInstallBts.adwTwoBtsList[j]);
        }
        printf("\n");

        // 打印蓝牙mac
        printf("ble mac : ");
        for (uint8 j = 0; j < 12; j++)
        {
            printf("%d ", stInstallBts.adwBluetoothMac[j]);
        }
        printf("\n");

        // 打印wifi mac
        printf("wifi mac : ");
        for (uint8 j = 0; j < 12; j++)
        {
            printf("%d ", stInstallBts.adwWifiMac[j]);
        }
        printf("\n");
    }
}