#include "netdev_lmb26.h"

#include "sr_osal.h"
#include "sr_log.h"
#include "sr_uart.h"
#include "at.h"

//私有头文件
#include "nb/svc/svc_nb_core.h"


#define LMB26_UART_ID       SR_UART2
#define NET_SERVER_IP       "2000000126.nb.ctwing.cn"
#define NET_SERVER_PORT     5683
#define AT_CLIENT_BUF_SIZE  720



static SR_NETDEV_T gs_lmb26Netdev; // 网卡设备对象

static AT_DEVICE_T lmb26; // AT设备对象实例

#ifdef LMB26_USE_DEVOM_OPS

static SR_NETDEV_OM_OPS_T  servOps =
{
	// .get_imei = _Lmb26GetImei,
	// .get_imsi = _Lmb26GetImsi,
	// .get_iccid = _Lmb26GetIccid,
	// .get_cfun = _Lmb26GetCfun,
	// .set_cfun = _Lmb26SetCfun,
	// .get_cell_info = _Lmb26GetCellInfo, 
	// .get_signal_streng = _Lmb26GetSignalStreng,
	// .get_net_reg_sta = _Lmb26GetNetRegSta,
	// .check_sim_ready    = _Lmb26CheckSimReady,
	// .get_netlink_sta = _Lmb26GetNetlinkSta,
	// .get_pdp_sta     = _Lmb26GetPdpSta,
	.net_switch = _Lmb26NetSwitch,
};

#endif

#ifdef LMB26_USE_CTW_OPS

static SR_NETDEV_CTW_OPS_T  ctwOps =
{
	.ctw_connect = _Lmb26CtwConnect,
    .ctw_send = _Lmb26CtwSend
	
};

#endif


extern void Nb_Coap_Sendok_Proc(void);


//+CTM2M通知处理函数
static void _UrcCtm2mFunc(struct at_client *client, char *data, srSize_t size)
{
	AT_DEVICE_T *atDev = SR_CONTAINER_OF(client, AT_DEVICE_T, atClient);
	char opt[12] = {0};
	uint8_t statusCode = 0xFF;
	SR_LOG(DEBUG, "[URC] %*s", size, data);
	if (sscanf(data, "+CTM2M: %12[^,], %hhu", opt, &statusCode) == 2)
	{
		// SR_LOG(DEBUG,"[URC] sscanf +CTM2M: opt(%s) code(%d)",opt,statusCode);
		if (strcmp(opt, "obsrv") == 0)
		{
			if (statusCode == 0)
			{
				SR_LOG(DEBUG,"NB net init ok!");
				atDev->flags |= LMB26_FLAG_CWT_REGOK_MASK;

				//Svc_Nb_Core_Set_Cur_State(E_NB_RUN);
			}
		}
		else if (strcmp(opt, "send") == 0)
		{

			if (statusCode == 0)
			{
				//Nb_Coap_Sendok_Proc();
				atDev->flags |= LMB26_FLAG_CWT_SENDOK_MASK;
				SR_LOG(DEBUG, "send success,flag(0x%x)",atDev->flags);
				
			}
		}
	}
	else
	{
		SR_LOG_NOTICE("[URC] sscanf +CTM2M fail");
	}
}


//下行接收数据处理函数
static void _UrcRecvFunc(struct at_client *client,  char *data, srSize_t dLen)
{ 
    //数据示例：+CTM2MRECV: 6173646667	
	AT_DEVICE_T *atDev = SR_CONTAINER_OF(client, AT_DEVICE_T, atClient);
	SR_NETDEV_T *netdev = atDev->netdev;
	CtwEvtCb eventCb = (CtwEvtCb)netdev->ctwEvtCb;
	//SR_LOG_DEBUG("recv:");
	//SR_LOG_DEBUG("%*s", dLen, data);

	//调用事件回调
	if(eventCb) eventCb(CTW_EVT_RECV,(uint8_t *)(data+12),dLen-12,netdev->ctwEvtArgs);
}

//+CEREG通知处理函数
static void _UrcCeregFunc(struct at_client *client,  char *data, srSize_t size)
{ 
	uint8_t status=0;
	NetdevEvtCb eventCb = (NetdevEvtCb)gs_lmb26Netdev.netEvtCb;

	SR_LOG_DEBUG("recv:");
	SR_LOG_DEBUG("%*s", size, data);   //  +CEREG: 0

	if (sscanf(data, "+CEREG: %hhu\r", &status) == 1)
	{
		//调用网卡运维事件回调
		if(eventCb) eventCb(gs_lmb26Netdev.netEvtArgs,SR_NET_EVT_REGSTA,0,status);
	}
	
}



//URC列表：是模组主动通知的信息，提供其处理函数
static const struct at_urc urc_table[] =
{
    {"+CTM2M:", "\r\n", _UrcCtm2mFunc},
    {"+CTM2MRECV:", "\r\n", _UrcRecvFunc},
	{"+CEREG:", "\r\n", _UrcCeregFunc},
};



//注册网络设备
static int _BspNetdevRegLmb26(void)
{
	int result=0;
		
	gs_lmb26Netdev.name = LMB26_NETDEV_NAME;  

#ifdef LMB26_USE_DEVOM_OPS
	gs_lmb26Netdev.devomOps = &servOps; //运维功能API
#endif

#ifdef LMB26_USE_CTW_OPS
	gs_lmb26Netdev.ctwOps = &ctwOps;   //CTWING功能API
#endif

	gs_lmb26Netdev.wifiOps = SR_NULL;  //无

	//网卡设备与AT_DEVICE互相关联
	lmb26.netdev = &gs_lmb26Netdev; 
	gs_lmb26Netdev.atDev = &lmb26;   
		
	result = SR_NetdevRegister(&gs_lmb26Netdev);
		
	return result;
}
SR_INIT_BSP_EXPORT(_BspNetdevRegLmb26,SR_PRIORITY_1);





//网络设备软件初始化
static int _BspNetdevInitLmb26(void)
{
	// 1、AT Client初始化
	SR_UART_CFG_T config = SR_UART_CFG_DEFAULT; // 初始默认配置
	config.baudrate = SR_UART_BAUD_9600;
	config.dataBits = SR_UART_DATA_BIT_8;
	config.parity = SR_UART_PARITY_NONE;
	config.stopBits = SR_UART_STOP_BIT_1;
	config.rxBufsz = AT_CLIENT_BUF_SIZE;
	at_client_init(&lmb26.atClient, LMB26_UART_ID, &config, AT_CLIENT_BUF_SIZE);

	// 2、设置URC通知列表，当收到模组主动发送URC时，会调用相应的处理函数
	at_obj_set_urc_table(&lmb26.atClient, urc_table, sizeof(urc_table) / sizeof(urc_table[0]));


	//3、创建响应结构体，设置最大支持响应数据长度为 512 字节，响应数据行数无限制，超时时间为 5 秒 
	lmb26.resp = at_create_resp(512, 0, SR_OsMsToTick(5000));
	if (lmb26.resp == SR_NULL)
	{
		SR_LOG(ERR, "No memory for response structure!");
		return -1;
	}

#if 0
    //4、创建网络任务线程

	osThreadId_t thd;
	osThreadAttr_t thdAttr = {0};
	thdAttr.name = "nbTask",			  // 线程名称
	thdAttr.stack_size = 128,			  // 线程栈大小
	thdAttr.priority = osPriorityNormal1, // 线程优先级

	thd = osThreadNew(_NbNetTask, &lmb26, &thdAttr);
	SR_LOG(INFO, "[NB] net task create %s",(thd == SR_NULL)?"fail":"ok");
 #endif 

  	return 0;
}
SR_INIT_BSP_EXPORT(_BspNetdevInitLmb26,SR_PRIORITY_0);


