Newer
Older
BIRMM-GT200N / NB-IOT.c
#include "string.h"
#include "NB-IOT.h"
#include "rtc.h"
#include "string.h"
#include "gprs.h"

#include <errno.h>
#include "gsdk_api.h"
#include "gsdk_sdk.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include "gsdk_ril.h"
#include "lwip/sockets.h"
#include "lwip/ip.h"

#define DEBUG_LOG(fmt,...) printf("[LOGD]:Function:%s,Line:%d,"fmt,__func__,__LINE__,##__VA_ARGS__);
#define WARN_LOG(fmt,...) printf("[LOGW]:"fmt,##__VA_ARGS__);

#define MAX_IP_BYTE 20
#define MAX_HEX_SIZE 1024
#define MAX_REGISTER_SIZE 1024
#define LIFETIME 6000
#define IMEI_SIZE 32
#define IMSI_SIZE 32
#define ICCID_SIZE 32

extern struct    DeviceSet  DeviceConfig;
extern struct    Config_RegPara  ConfigData;//定义的下发配置参数,HEX格式,方便在系统进入休眠模式之前写入BKP寄存器
uint8_t   handle_func_Flag; //handle_func函数注册标志FLAG,只能注册一次

uint8_t    	ESOC_Num=0;    //连接套接字
char    IMEI_Code[32] = {0};  //有效15位结束位0
char    ICCID_Code[32] = {0}; //有效20位结束位0

uint8_t mtu_flag;
uint8_t SIMCard_Type;

static char recv_buf[MAX_REGISTER_SIZE] = {0};
static fd_set readfds;
static fd_set writefds;
static fd_set errorfds;
static int maxfd;
static int socket_id = -1;
static struct timeval tv;
static int error_code;

uint16_t PTU_flag;

uint8_t signalValue[6] = {0};

extern uint8_t        PD2_Flag;

/*information that come from iot appear will execute this function*/
static int handle_func(const char *s, const char *extra, int len, void *data)
{
	(void)extra;
	(void)len;
	WARN_LOG("infomation come from iot is %s\r\n", s);
	if (strlen(s) > (MAX_REGISTER_SIZE - 1))
	{
		WARN_LOG("the information is too large ,please change the size of recv_buf\r\n");
	}
	else
	{
		strncpy(data, s, MAX_REGISTER_SIZE);
	}
	PTU_flag = Receive_Data_Analysis((char *)s);
	return GSDK_AT_UNSOLICITED_HANDLED;
}

void str_to_hex(char *out, const char *in, int len)
{
	int i;
	for (i = 0; i < len; i++)
	{
		sprintf(out + (i * 2), "%02x", in[i]);
	}
}

/*******************************************************************************
* Function Name  : XX
* Description    : XX
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Code_Read_NB(void)
{
	gsdk_status_t status = GSDK_ERROR;
	char imsi_buf[IMSI_SIZE]         = {0};

	printf("\r\n*********NB Start!***********\r\n");

	/*Get NB module IMEI number*/
	status = gsdk_ril_get_imei(IMEI_Code, IMEI_SIZE);
	if (GSDK_ERROR == status)
	{
		DEBUG_LOG("Get imei number cmd failed\r\n");
	}

	WARN_LOG("Get imei number success,imei:%s\r\n", IMEI_Code + 7);
	
//	vTaskDelay(500);
	/*Get NB module ICCID number*/
	status = gsdk_ril_get_iccid(ICCID_Code, ICCID_SIZE);
	if (GSDK_ERROR == status)
	{
		DEBUG_LOG("Get iccid number cmd failed\r\n");
	}
	WARN_LOG("Get iccid number success,iccid:%s\r\n", ICCID_Code);
	
//	vTaskDelay(500);
	/*Get NB module IMSI number*/
	status = gsdk_ril_get_imsi(imsi_buf, IMSI_SIZE);
	if (GSDK_ERROR == status)
	{
		DEBUG_LOG("Get imsi number cmd failed\r\n");
	}
	WARN_LOG("Get imsi number success,imsi:%s\r\n", imsi_buf);

	mtu_flag = (*(imsi_buf + 3) - 48) * 10 + (*(imsi_buf + 4) - 48);

	if((mtu_flag == 11)||(mtu_flag == 3)||(mtu_flag == 5))
	{
		printf("\r\n ===========电信NB卡===========!!\r\n");
		SIMCard_Type = 1;
	}
	else if((mtu_flag == 1) || (mtu_flag == 6) || (mtu_flag == 9) || (mtu_flag == 0) || (mtu_flag == 2) || (mtu_flag == 4) || (mtu_flag == 7) || (mtu_flag == 8) || (mtu_flag == 13))
	{
		printf("\r\n ===========移动或者联通NB卡===========!!\r\n");
		SIMCard_Type = 0;
	}
	else
	{
		printf("\r\n ===========SIM卡异常===========!!\r\n");
		SIMCard_Type = 2;
	}
}

/*******************************************************************************
* Function Name  : XX
* Description    : XX
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Module_ME3616_menginfo_Check(void)
{	
	gsdk_status_t status             = GSDK_ERROR;
	cell_info_t cell_info;
	status = gsdk_ril_get_cell_info(&cell_info);
	if(status == GSDK_SUCCESS)
	{
		printf("\r\n MU m_pci:%d \r\n", cell_info.m_sc.m_pci); //测试使用
		printf("\r\n MU m_rsrp:%d \r\n", cell_info.m_sc.m_rsrp); //测试使用
		printf("\r\n MU m_snr:%d \r\n", cell_info.m_sc.m_snr); //测试使用
		signalValue[0] = (cell_info.m_sc.m_pci) >> 8; //数据上传时的NB主小区物理小区PCI号高字节
		signalValue[1] =  cell_info.m_sc.m_pci; //数据上传时的NB主小区物理小区PCI号低字节		
		signalValue[2] = (cell_info.m_sc.m_rsrp) >> 8; //数据上传时的NB主小区RSRP值高字节
		signalValue[3] =  cell_info.m_sc.m_rsrp; //数据上传时的NB主小区RSRP值低字节
		signalValue[4] = (cell_info.m_sc.m_snr) >> 8; //数据上传时的NB主小区lart SNR值高字节
		signalValue[5] =  cell_info.m_sc.m_snr; //数据上传时的NB主小区lart SNR值低字节	
	}
}

/*******************************************************************************
* Function Name  : XX
* Description    : XX
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
uint16_t SendMessage_NB_T(uint8_t* Psend, unsigned short iSize)
{
	gsdk_status_t status             = GSDK_ERROR;
	PTU_flag = 0;
	int lifetime                     = LIFETIME;
//	char hex_user_data[MAX_HEX_SIZE] = {"001aa320001341201901092003092004860103ef88a380890a345f18"};
	int count                        = 0;
	char srv_ip[MAX_IP_BYTE]         = IPNET_T;
    int srv_port                     = PORTNUM_T;
	int i;
	uint16_t k;
	char SendArry[300] ={'\0'};

	snprintf(SendArry,sizeof(SendArry),"00%.2x",iSize); 	
	for(i=0;i<iSize;i++)
	{
		k = strlen(SendArry);	
		snprintf(SendArry+k,sizeof(SendArry),"%.2x",*(Psend+i));  
	}
	printf("size:%d---SendArry:%s\r\n",strlen(SendArry),SendArry);

	if(handle_func_Flag == 0)
	{
		/*add function for handle unsolicited information relate to "+M2MCLIRECV:"*/
		unsolicited_handler_t handler;
		handler.prefix = "+M2MCLIRECV:";
		handler.func = handle_func;
		handler.user_data = recv_buf;
		status = gsdk_at_register_unsolicited_handler(&handler);
		handle_func_Flag = 1;		
		if (status != GSDK_SUCCESS)
		{
			DEBUG_LOG("some error hanppened in handle2,status is %d\r\n", status);
			goto _fail;
		}
	}

	/*set link iot*/
	status = gsdk_ril_set_link_iot(IMEI_Code + 7, srv_ip, srv_port, lifetime);
	if (status == GSDK_ERROR)
	{
		DEBUG_LOG("set link cmd is failed\r\n");
		goto _fail;
	}
	else if (status == GSDK_ERROR_UNINITIALIZED)
	{
		DEBUG_LOG("not register success,please do delete operation and set link again\r\n");
		goto _fail;
	}
	else if (status == GSDK_ERROR_UNSUPPORTED)
	{
		DEBUG_LOG("this maybe device not register previously,or signal is bad\r\n");
		goto _fail;
	}
	else if (status != GSDK_SUCCESS)
	{
		DEBUG_LOG("unknown error happen in set link iot\r\n");
		goto _fail;
	}
	else
	{
		WARN_LOG("set link iot success\r\n");
	}

	/*send update information to iot*/
	status = gsdk_ril_update_to_iot();
	if (status == GSDK_ERROR)
	{
		DEBUG_LOG("update iot cmd is failed\r\n");
//		goto _fail;
	}
	else if (status != GSDK_SUCCESS)
	{
		DEBUG_LOG("unknown error happen in update iot\r\n");
//		goto _fail;
	}
	else
	{
		WARN_LOG("update iot cmd is success\r\n");
	}

	/*send data to iot*/
	status = gsdk_ril_send_data_to_iot(SendArry);
	if (status == GSDK_ERROR)
	{
		DEBUG_LOG("send data to iot cmd is failed\r\n");
//		goto _fail;
	}
	else if (status != GSDK_SUCCESS)
	{
		DEBUG_LOG("unknown error happen in send data to iot\r\n");
//		goto _fail;
	}
	else
	{
		WARN_LOG("send data iot cmd is success\r\n");
	}

	/*wait for data from iot*/
	count = 0;
	while (1)
	{
		if (count > 40)
		{
			DEBUG_LOG("wait for receive information timeout\r\n");
//			goto _fail;
			break;
		}
		if (0 == strncmp(recv_buf, "+M2MCLIRECV:", 12))
		{
			WARN_LOG("send data to iot is success\r\n");
			break;
		}
		vTaskDelay(500 / portTICK_PERIOD_MS);
		count++;
		printf("\r\n send data count is : %d \r\n", count);
	}
		printf("\r\n send data final count is : %d \r\n", count);

	/*delete link with iot*/
	status = gsdk_ril_del_link_iot();
	if (status == GSDK_ERROR)
	{
		DEBUG_LOG("delete link iot cmd failed\r\n");
		goto _fail;
	}
	else if (status == GSDK_ERROR_TIMEOUT)
	{
		DEBUG_LOG("wait for information timeout,maybe signal bad\r\n");
		goto _fail;
	}
	else if (status != GSDK_SUCCESS)
	{
		DEBUG_LOG("unknown error happen in delete link iot\r\n");
		goto _fail;
	}
	else
	{
		WARN_LOG("delete iot is succcess\r\n");
	}
	
	return PTU_flag;

_fail:
	/*delete link with iot*/
	status = gsdk_ril_del_link_iot();
	if (status == GSDK_ERROR)
	{
		DEBUG_LOG("delete link iot cmd failed\r\n");
	}
	else if (status == GSDK_ERROR_TIMEOUT)
	{
		DEBUG_LOG("wait for information timeout,maybe signal bad\r\n");
	}
	else if (status != GSDK_SUCCESS)
	{
		DEBUG_LOG("unknown error happen in delete link iot\r\n");
	}
	else
	{
		WARN_LOG("delete iot is succcess\r\n");
	}
	return 0;
}

int ip_wait_func()
{
	int count = 0;
	gsdk_status_t status;
	char ip_buf[64] = {0};

	while(1)
	{
		if(count > 20)
		{
			OEM_LOGE("wait for IP timeout\r\n");
			return -1;
		}
		memset(ip_buf, 0, 64);
		status = gsdk_ril_get_local_ipaddr(ip_buf, 64);
		if(status == 1)
		{
			OEM_LOGI("get ip success!\r\n");
			break;
		}
		OEM_LOGE("get ip failed!\r\n");
		vTaskDelay(500);
		count++;
	}
	OEM_LOGI("ip registered\r\n");
	return 0;
}

int gsdk_ril_init_func(void)
{
	gsdk_status_t status;
	status = gsdk_ril_init();
	if (status != GSDK_SUCCESS)
	{
		OEM_LOGE("gsdk ril init fail\r\n");
		return -1;
	}
	OEM_LOGI("gsdk ril init OK\r\n");
	return 0;
}

int init_func()
{
	if(gsdk_ril_init_func() != 0) goto init_fail;

	OEM_LOGI("***************************************************\r\n");
	OEM_LOGI("*                                                  \r\n");
	OEM_LOGI("*                        tcp demo                  \r\n");
	OEM_LOGI("*                                                  \r\n");
	OEM_LOGI("***************************************************\r\n");

	OEM_LOGI("init_func end!\r\n");
	return 0;
init_fail:
	OEM_LOGE("init_func error!\r\n");
	return -1;
}

int create_socket_instance()
{
	socket_id=socket(AF_INET, SOCK_STREAM, 0);
	if(socket_id < 0)
	{
		OEM_LOGE("socket create fail!\r\n");
		return -1;
	}
	OEM_LOGI("socket create success, socket id is : %d\r\n", socket_id);
	return 0;
}

int connect_tcp_server()
{
	struct sockaddr_in remaddr;
	const char *server = DeviceConfig.ServerIP;
	int server_port = DeviceConfig.ServerPort;
	
	if(PD2_Flag > 0) //如果传三码或者主IP上传失败,将IP地址和端口号设置为203所平台
	{
		server = IPNET_203;
		server_port = PORTNUM_203;
		printf("\n\r*--------------连接备份服务器!---------------*\r\n");
	}

	/* get tcp server address and port */
	memset((char *) &remaddr, 0, sizeof(remaddr));
	remaddr.sin_family = AF_INET;
	remaddr.sin_port = htons(server_port);
	if (inet_aton(server, &remaddr.sin_addr)==0)
	{
		OEM_LOGE( "inet_aton func fail!\r\n");
		return -1;
	}
	if(0 > connect(socket_id, (struct sockaddr*)&remaddr, sizeof(remaddr)))
	{
		OEM_LOGE("connect tcp server fail!\r\n");
		perror("error code");
		OEM_LOGE("connect tcp server error, error number = %d\r\n", errno);

		return -1;
	}
	OEM_LOGI("connect tcp server success.\r\n");
	return 0;
}

int tcp_send_demo(char* buf, unsigned short iSize)
{
	int len, ret;

	FD_ZERO(&writefds);
	FD_ZERO(&errorfds);
	FD_SET(socket_id, &writefds);
	FD_SET(socket_id, &errorfds);
	maxfd = socket_id + 1;
	tv.tv_sec = 5;
	tv.tv_usec = 0;

	OEM_LOGI("tcp_send_demo start\r\n");
	/* monitor writefds and errorfds of socket */
	ret = select(maxfd, NULL, &writefds, &errorfds, &tv);
	if((ret > 0) && FD_ISSET(socket_id, &errorfds))
	{
		if(getsockopt(socket_id, SOL_SOCKET, SO_ERROR, &error_code, &len) == 0)
		{
			/* please refer to the arch.h of error_code's definition */
			OEM_LOGE("get error_code success : %d\r\n", error_code);
		}
	}
	if((ret > 0) && FD_ISSET(socket_id, &writefds))
	{
		if (send(socket_id, buf, iSize, 0) <= 0)
		{
			OEM_LOGE("tcp send fail\r\n");
			return -1;
		}
		else
		{
			OEM_LOGI("tcp send success, send data is : %s\r\n", buf);
		}
	}
	if(ret == 0)
	{
		OEM_LOGE("select timeout.\r\n");
		return -1;
	}
	else if(ret < 0)
	{
		perror("error code");
		OEM_LOGE("select error, error number = %d\r\n", errno);
		return -1;
	}
	return 0;
}

int tcp_receive_demo()
{
	int len,ret;
//    char recv_buf[500] = {0};
	int recvlen = 0;

	FD_ZERO(&readfds);
	FD_ZERO(&errorfds);
	FD_SET(socket_id, &readfds);
	FD_SET(socket_id, &errorfds);
	tv.tv_sec = 5;
	tv.tv_usec = 0;

	OEM_LOGI("tcp_receive_demo start\r\n");
	/* monitor readfds and errorfds of socket */
	ret = select(maxfd, &readfds, NULL, &errorfds, &tv);
	if((ret > 0) && FD_ISSET(socket_id, &errorfds))
	{
		if(getsockopt(socket_id, SOL_SOCKET, SO_ERROR, &error_code, &len) == 0)
		{
			/* please refer to the arch.h of error_code's definition */
			OEM_LOGE("get error_code success : %d\r\n", error_code);
		}
	}
	if((ret > 0) && FD_ISSET(socket_id, &readfds))
	{
		recvlen = recv(socket_id, recv_buf, 500, 0);
		if(recvlen <= 0)
		{
			OEM_LOGE("tcp receive error\r\n");
			return -1;
		}
		else
		{
			OEM_LOGI("tcp receive success, receive data is : %s\r\n", recv_buf);
			PTU_flag = Receive_Data_Analysis(recv_buf);
		}
	}
	if(ret == 0)
	{
		OEM_LOGE("select timeout.\r\n");
		return -1;
	}
	else if(ret < 0)
	{
		perror("error code");
		OEM_LOGE("select error, error number = %d\r\n", errno);
		return -1;
	}

	return 0;
}

/*******************************************************************************
* Function Name  : XX
* Description    : XX
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
uint16_t SendMessage_NB_MU(uint8_t* Psend, unsigned short iSize)
{
	PTU_flag = 0;

	/* system init */
//	if(init_func() != 0) goto end;

	/* wait for register network */
	if(ip_wait_func() != 0) goto end;

	/* create tcp socket instance */
	if(create_socket_instance() != 0) goto end;

	vTaskDelay(1 * 1000 / portTICK_PERIOD_MS);

	/* connect tcp server */
	if(connect_tcp_server() != 0) goto end;

	/* send data to tcp server */
	if(tcp_send_demo((char*)Psend, iSize) != 0) goto end;

	/* receive data from tcp server */
	if(tcp_receive_demo() != 0) goto end;

	/* close socket */
	if(socket_id >= 0)
	{
		OEM_LOGI("tcp send and receive finish, close socket now.\r\n");
		close(socket_id);
	}

	OEM_LOGI("tcp demo finish!\r\n");
	return PTU_flag;

end:

	OEM_LOGE("tcp demo abnormal exit!\r\n");
	if(socket_id >= 0)
	{
		OEM_LOGI("tcp demo error, close socket now.\r\n");
		close(socket_id);
	}

	return -1;
}