#include "stdlib.h"
#include "math.h"
#include <stm32f4xx.h> /* STM32F4xx Definitions */
#include "RTC_Time.h"
#include "test.h"
#include "comm.h"
#include "emqq.h"
#define PORT 1883
#define MAXDATASIZE 1024 //
//9fbw-0y61-2yte npam-dl8n-qfgo
extern __task void CommToServerRcvTask (void);
extern __task void CommToServerSendTask (void);
sequeue_t DataSequeue;
int Platformsock = 0;
int Platformconnect = 0;
u8 PlatformRcvPackFlag = 0;
static int ConnectFlag = OFF;
static int SubscriFlag = OFF;
const char *topic = "/public/TEST/windows";
uint16_t subscrimsg_id=1;
char packet_buffer[MAXDATASIZE]={0};
char send_buffer[MAXDATASIZE];
int keepalive = 30;
mqtt_broker_handle_t broker;
int init_socket(mqtt_broker_handle_t* broker)
{
int flag = 1;
keepalive = 60;
mqtt_set_alive(broker,keepalive);
return 0;
}
sequeue_t *Get_DataSequeue()
{
return &DataSequeue;
}
//将接受数据存储在队列中之前,在数据的头加上'#'、'#'、len三个字节数据,len为此数据的长度,默认长度小于1024,大于则舍弃
void CheckDataToBuff(u8 *ptr,u16 par)
{
u16 i;
if(MAXDATASIZE < par)
return;
if(leftspace(&DataSequeue) < (par+4)) //队列缓冲区空间不够时舍弃此消息
{
os_evt_set(CommRcv_evt, t_COMMRCV);
return;
}
enqueue(&DataSequeue,'#');
enqueue(&DataSequeue,'#');
enqueue(&DataSequeue,par);
for(i = 0; i < par; i++)
enqueue(&DataSequeue,ptr[i]);
os_evt_set(CommRcv_evt, t_COMMRCV);
}
u16 tcp_callback (u8 soc, u8 event, u8 *ptr, u16 par)
{
/* This function is called on TCP event */
switch (event)
{
case TCP_EVT_CONREQ:
/* Remote host is trying to connect to our TCP socket. */
/* 'ptr' points to Remote IP, 'par' holds the remote port. */
/* Return 1 to accept connection, or 0 to reject connection */
return (1);
case TCP_EVT_ABORT:
/* Connection was aborted */
break;
case TCP_EVT_CONNECT:
/* Socket is connected to remote peer. */
break;
case TCP_EVT_CLOSE:
/* Connection has been closed */
break;
case TCP_EVT_ACK:
/* Our sent data has been acknowledged by remote peer */
break;
case TCP_EVT_DATA:
/* TCP data frame has been received, 'ptr' points to data */
/* Data length is 'par' bytes */
//----------------------将有效数据保存到队列中
CheckDataToBuff(ptr, par);
//----------------------
break;
}
return (0);
}
static void tcp_send_data (unsigned char *sendbuf, int length)
{
int state = 0;
unsigned char *ptemp = NULL;
state = tcp_get_state (Platformsock);
switch (state)
{
case TCP_STATE_FREE:
case TCP_STATE_CLOSED:
/* Connection idle, send Connect Request. */
break;
case TCP_STATE_CONNECT:
/* OK, socket is ready to send data. */
if (tcp_check_send (Platformsock) == __TRUE)
{
ptemp = tcp_get_buf(length);
memcpy(ptemp, sendbuf, length);
tcp_send (Platformsock, ptemp, length);
}
break;
}
}
void PlatformSendInformation(unsigned char *sendbuf, int length)
{
if (Platformconnect)
{
tcp_send_data(sendbuf, length);
}
}
__task void CommToServerRcvTask ()
{
u16 i,j,k;
init_sequeue(&DataSequeue);
while(1)
{
os_evt_wait_and (CommRcv_evt,0xffff); //200ms
//接收到数据
if (1 == WIFITransMode)
{
// os_dly_wait(1000);
ServerComParse();
}
os_tsk_pass();
}
}
__task void CommToServerSendTask ()
{
U8 i,RcvLifeErrorCount=0;
mqtt_init(&broker,"zyf_test");
init_socket(&broker);
while(1)
{
#if 1
//0:心跳
if(SendToServerCount[0] > 15)
{//心跳命令 30秒
SendToServerCount[0]=0;
RcvLifeErrorCount++;
if(RcvLifeErrorCount > 3)
{
ConnectFlag = OFF;
SubscriFlag = OFF;
}
if(ConnectFlag == ON)
{//登录成功,发心跳命令
mqtt_ping();
}
}
//1:登录
if(SendToServerCount[1] > 10)
{//登录命令 5秒
SendToServerCount[1] = 0;
if(ServerLoginFlag == OFF)
{ //登录不成功,继续发登录命令
SendToServerCount[0] = 0;
RcvLifeErrorCount = 0;
mqtt_connect(&broker);
}
}
if(SendToServerCount[2] > 5)
{//订阅命令 5秒
SendToServerCount[2] = 0;
if( (ON == ConnectFlag) && (OFF == SubscriFlag) )
{
mqtt_subscribe(&broker,topic,&subscrimsg_id);
}
}
if(SendToServerCount[3] > 10)
{//订阅命令 5秒
SendToServerCount[3] = 0;
if( (ON == ConnectFlag) && (ON == SubscriFlag) )
{
mqtt_publish(&broker,topic,"110",0);
}
}
#endif
os_tsk_pass();
}
}
void ServerComParse(void)
{
u8 messagetype,topic_len;
u16 i,mesglen=0,msg_len=0;
uint8_t tmpbuf[MAXDATASIZE]={0};
char StrTem[50],msg_buf[255],topic_buf[255]={0};
for(i = 0; i < (MAXDATASIZE+2); i++)
{
if(TRUE == check_seqeue_empty(&DataSequeue))
return;
tmpbuf[i] = 0;
tmpbuf[i] = dequeue(&DataSequeue);
if(0 == i)
{
if('#' != tmpbuf[i])
{
os_evt_set(CommRcv_evt, t_COMMRCV);
os_dly_wait(1);
return;
}
}
if(1 == i)
{
if('#' != tmpbuf[i])
{
os_evt_set(CommRcv_evt, t_COMMRCV);
os_dly_wait(1);
return;
}
}
if(2 == i)
{
mesglen = tmpbuf[i];
}
if((mesglen+2) == i) //从队列中取出一帧数据
break;
}
memcpy(&packet_buffer[0],&tmpbuf[3],mesglen);
messagetype = MQTTParseMessageType(packet_buffer);
switch(messagetype)
{
case MQTT_MSG_CONNACK:
{
if(0x00 ==packet_buffer[3])
{
ConnectFlag = ON;
SendToServerCount[0] = 20;
// printf("CONNACK successed!\n");
sprintf(StrTem, "%s", "CONNACK successed!");
DispLcdStandStr(20,10,0x6f,StrTem,40);
SendToLcdDelay();
}
break;
}
case MQTT_MSG_SUBACK:
{
if(subscrimsg_id == mqtt_parse_msg_id((uint8_t *)packet_buffer))
{
SubscriFlag = ON;
// printf("-----subscribe successful!---------\n");
sprintf(StrTem, "%s", "-----subscribe successful!------");
DispLcdStandStr(20,10,0x6f,StrTem,40);
SendToLcdDelay();
}
break;
}
case MQTT_MSG_PUBLISH:
topic_len = mqtt_parse_pub_topic((uint8_t *)packet_buffer,(uint8_t *)&topic_buf);
msg_len = mqtt_parse_publish_msg((uint8_t *)packet_buffer,(uint8_t *)&msg_buf);
// printf("publish msg resv!topic_len=%d,topic=%s\n",topic_len,topic_buf);
// printf("msg_len=%d,msg=",topic_len);
// for(i = 0; i < msg_len; i++)
// {
// printf("%x",msg_buf[i]);
// }
sprintf(StrTem, "publish msg resv!topic_len=%d,topic=%s",topic_len,topic_buf);
DispLcdStandStr(20,10,0x6f,StrTem,40);
SendToLcdDelay();
sprintf(StrTem, "msg_len=%d,msg=%s",topic_len,topic_buf);
DispLcdStandStr(20,60,0x6f,StrTem,40);
SendToLcdDelay();
break;
case MQTT_MSG_PINGRESP:
RcvLifeErrorCount = 0;
break;
default:
break;
}
os_dly_wait(1);
os_evt_set(CommRcv_evt, t_COMMRCV);
}
//队列函数定义
void init_sequeue(sequeue_t * sq)
{
memset(&sq->data[0],0,MAXSIZE);
sq->front = 0;
sq->rear = 0;
}
//判断队列是否为空
u8 check_seqeue_empty(sequeue_t * sq)
{
if(sq->front == sq->rear)
return TRUE;
else
return FALSE;
}
//入队
u8 enqueue(sequeue_t *sq ,u8 val)
{
/* 判断队列是否满,数组的最后一个存数空间不用 */
if((sq->rear + 1)%MAXSIZE == sq->front)
return ERROR;
sq->data[sq->rear] = val;
sq->rear = (sq->rear+1) % MAXSIZE; //循环存储
return SUCCESS;
}
//出队
u8 dequeue(sequeue_t * sq)
{
u8 val = 0;
if( TRUE == check_seqeue_empty(sq))
return ERROR;
val = sq->data[sq->front] ;
sq->front = (sq->front+1) % MAXSIZE;
return val;
}
//剩余空间
u8 leftspace(sequeue_t * sq)
{
u16 val = 0;
if( sq->front < sq->rear)
val = MAXSIZE - (sq->rear - sq->front) -1;
else if(sq->front == sq->rear)
val = MAXSIZE - 1;
else
val = sq->front - sq->rear - 1;
return val;
}