// 协议栈下行模块模块
// 秒寻科技
// zt 2024-11-12

package psdl

import (
	"bytes"
	"encoding/binary"
	"ipsomc/module/ps/ap"
	"ipsomc/module/ps/psmodel"
	"ipsomc/module/socket/socketsend"
)

type PsDl struct {
	apApi         ap.Ap
	socketSendApi socketsend.SocketSend
}

// 协议栈下行应答模块
func (obj *PsDl) PsDlResp(stHeadModel *psmodel.PS_HEAD_T, dataList []byte) error {
	//组织数据
	projectId := stHeadModel.StVpHead.ProjectID
	btsId := stHeadModel.StVpHead.DeviceID
	byVpFlag := psmodel.VP_RESP
	byMcpType := stHeadModel.StVpHead.McpType
	byMcpCmd := stHeadModel.StMcpHead.Comd
	byMcpResp := psmodel.MCP_RESP_SUCC
	dataFrame := obj.PsDlOrganizeDlFrame(projectId, btsId, uint8(byVpFlag), byMcpType, byMcpCmd, uint8(byMcpResp), dataList)

	//AP层数据处理
	apDataFrame, wLen, err := obj.apApi.ApDl(dataFrame, len(dataFrame))
	if err != nil {
		return err
	}

	//将数据发送至socket模块
	//if err := obj.socketSendApi.SendDataToBts(projectId, btsId, apDataFrame, uint16(wLen)); err != nil {
	if err := obj.socketSendApi.SendDataToBtsTcp(projectId, btsId, apDataFrame, uint16(wLen)); err != nil {
		return err
	}

	return nil
}

// 组织下行数据帧
// projectId:项目编号
// btsId:基站编号
// byVpFlag:VP层标识符
// byMcpType:MCP协议类型
// byMcpCmd:MCP命令
// dataList:载荷
// 返回值：AP层数据帧
func (obj *PsDl) PsDlOrganizeDlFrame(projectId int, btsId int, byVpFlag uint8, byMcpType uint8, byMcpCmd uint8, byMcpResp uint8, dataList []byte) []byte {
	var frameData bytes.Buffer
	var wCrc uint16 = 0

	//协议头
	binary.Write(&frameData, binary.LittleEndian, uint8(psmodel.PS_AP_END_FLAG))

	//VP层
	binary.Write(&frameData, binary.LittleEndian, int32(projectId)) //项目ID
	binary.Write(&frameData, binary.LittleEndian, uint8(128))       //通信包号
	binary.Write(&frameData, binary.LittleEndian, int32(btsId))     //基站ID
	binary.Write(&frameData, binary.LittleEndian, byVpFlag)         //VP层标识符
	binary.Write(&frameData, binary.LittleEndian, byMcpType)        //MCP协议

	//MCP层
	binary.Write(&frameData, binary.LittleEndian, byMcpCmd)  //MCP命令
	binary.Write(&frameData, binary.LittleEndian, byMcpResp) //MCP应答

	//数据
	binary.Write(&frameData, binary.LittleEndian, dataList)

	//添加CRC校验码
	tmpList := frameData.Bytes()
	wCrc = obj.apApi.ApGenCrc16(tmpList[1:], uint16(len(tmpList)-1), 0)
	binary.Write(&frameData, binary.LittleEndian, wCrc) //CRC校验码

	//协议尾
	binary.Write(&frameData, binary.LittleEndian, uint8(psmodel.PS_AP_END_FLAG))

	return frameData.Bytes()
}

// 把网管中心的数据发送给基站(命令)
func (obj *PsDl) PsDlSendOamDataToBts(projectId int, btsId int, byMcpType uint8, byMcpCmd uint8, payload []byte) error {
	//生成帧
	frameData := obj.PsDlOrganizeDlFrame(projectId, btsId, psmodel.VP_CMMD, byMcpType, byMcpCmd, psmodel.MCP_CMD, payload)

	//ap层处理
	apDataFrame, wLen, err := obj.apApi.ApDl(frameData, len(frameData))
	if err != nil {
		return err
	}

	//发送数据到基站
	//if err := obj.socketSendApi.SendDataToBts(projectId, btsId, apDataFrame, uint16(wLen)); err != nil {
	if err := obj.socketSendApi.SendDataToBtsTcp(projectId, btsId, apDataFrame, uint16(wLen)); err != nil {
		return err
	}

	return nil

}
