打印
[应用方案]

free同学的开发日记-微信蓝牙协议栈移植与应用

[复制链接]
2034|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 gaoyang9992006 于 2016-2-24 15:12 编辑

1、微信的基本架构(节选自微信官方协议文档)

厂商服务器和外设,由厂商开发完成。
微信会提供服务器的接口以对接厂商的服务器,会提供手机的接口(如本文规定的蓝牙协议)以对接厂商的外设。
主要功能该协议打通了设备和厂商服务器之间的数据链路,也就是支持将设备上的数据发送到厂商的服务器上,也支持将厂商的数据发送到设备。
厂商的数据对于微信来说,是黑盒,微信不对设备数据做分析。

该协议也打通了设备和微信服务器之间的数据链路。
设备和微信服务器之间的数据格式由微信规定,例如登录,新消息通知等。

2、微信蓝牙一般是基于串口的,所以只跟串口底层相关,也就是只需要将串口发送和接收两个函数填充到协议栈对外接口函数就行了。
先把微信SDK包加载在我们自己的项目中,如下我的项目添加到了interactive目录,4个c文件和4个h文件。
整个移植过程我们只需要改动proto.c文件里边5个接口函数。

3、微信传输的数据包结构

4、先把串口准备好,我的都在这个是uart.c文件中,以前的代码写的狗屎一般,看思路就行了。
#include "uart.h"
#include "uart_config.h"

enum BLE_TRAN_FSM
{
    bMagicNumber = 0,
    bVer,
    nLenghth_hi,
    nLenghth_low,
    bdata,
};  

unsigned char recv_from_ble_buf[60]= {0};
unsigned char m_frame_buffer[256]={0};   

unsigned char rxbuf[256]={0};
unsigned char rx_idx=0;
unsigned short uart0_rx_len;
unsigned short uart0_rx_cnt=0;
unsigned short uart0_buf_num=0;
static unsigned char uart0_tran_state = 0;
unsigned char uart0_tran_complt = 0;

void UART0_Init(void)
{   
}

void uart0_putchar(unsigned char dat)
{
}

unsigned char uart0_getchar(void)
{
    return 0;
}

unsigned char UART0_Put_N_Byte (unsigned char* data_buf,unsigned char data_len)
{
    unsigned char i;     
    //BT_EN_OFF;   
    for (i = 0; i < data_len; i++)
    {
        uart0_putchar(data_buf[i]);
    }   
    //BT_EN_ON;
    return data_len;
}

//拷贝串口缓冲区数据
unsigned char  UART0_Get_Buf(unsigned char* data_buf)
{
    unsigned char i;
    if(uart0_tran_complt)      
    {        
        uart0_buf_num = uart0_rx_len;
        for(i=0;i<uart0_rx_len;i++)
        {
            *data_buf ++ = rxbuf[i];
        }
        uart0_tran_complt = 0;
        uart0_rx_len = 0;               
    }
    else
    {
        uart0_buf_num = 0;
    }
    return uart0_buf_num;
}

void UART0_ISR(void)
{        
    rxbuf[rx_idx]=uart0_getchar(); //串口接收是从数据寄存器你读取数据,这个为了脱离平台限制,
                                   //添加了一个uart0_getchar()的空函数      
    rx_idx+=1;   
    switch(uart0_tran_state)
    {
        case bMagicNumber:
        if(MAGIC_NUMBER_ID == rxbuf[0])
        {            
            uart0_tran_state = bVer;
        }
        else
        {
            uart0_tran_state = bMagicNumber; rx_idx=0;
        }
        break;
        case bVer:
        if(DEVEICE_VERSION_ID == rxbuf[1])
        {
            uart0_tran_state = nLenghth_hi;
            //uart0_putstring("uart0_tran_state : bVer \r\n");
            //预留用一个定时器来做超时检测
            //uart0_timeout = 20;                     
        }
        else
        {
            uart0_tran_state = bMagicNumber; rx_idx=0;
        }
        break;
        
        case nLenghth_hi:                  
        uart0_tran_state = nLenghth_low;        
        break;  
        
        case nLenghth_low:      
        uart0_rx_len = (unsigned short) ((rxbuf[2]<<8)|rxbuf[3]);
        uart0_tran_state = bdata;
        break;
        
        case bdata:      
        if(rx_idx == uart0_rx_len)
        {              
            uart0_tran_complt = 1;
            uart0_tran_state = bMagicNumber;
            rx_idx=0;            
        }
        
        //串口超时之后再添加  
        //if(uart0_timeout)
        //{
        //    for(iRev=0;iRev<20;iRev++) {rxbuf[]=0;rx_idx=0;}         
        //}               
        break;
        
        default:
        uart0_tran_state = bMagicNumber; rx_idx=0;        
        break;
    }           
}
5、将proto.c文件里边
    void Auth(unsigned char *pBuf , unsigned short  int Length);
        void Unpack_Auth_Response(unsigned char *buf , unsigned short  int Length );
        void Unpack_Init_Response(unsigned char *buf , unsigned short  int Length );
        void SendDataToManuf(unsigned char *buf , unsigned short  int Length);
        void Unpack_SendDataToManufacturerSvrResponse(unsigned char *buf , unsigned short  int Length );
5个函数中的串口发送函数换成我们自己的。

6、我们接收厂商服务器的数据都在
void Unpack_ManufacturerSvrSendDataPush(unsigned char *buf , unsigned short  int Length )
函数你解析.



7、连接过程



沙发
gaoyang9992006|  楼主 | 2016-2-24 15:07 | 只看该作者
free同学最近在做开发笔记,写的很不错,我征求了意见,将抽空转载过来。以便大家跟free学习他的成功经验。
打赏我的话,我会把钱钱分给他的。:lol

使用特权

评论回复
板凳
yiyigirl2014| | 2016-2-24 15:10 | 只看该作者
楼主这个是不是不分什么单片机都是可以用的?

使用特权

评论回复
地板
gaoyang9992006|  楼主 | 2016-2-24 15:11 | 只看该作者
yiyigirl2014 发表于 2016-2-24 15:10
楼主这个是不是不分什么单片机都是可以用的?

是的,都是可以的。不谈什么单片机。

使用特权

评论回复
5
xyz549040622| | 2016-2-24 15:26 | 只看该作者
讲的有点简单。灰哥貌似发过一个详细的帖子的。

使用特权

评论回复
6
643757107| | 2016-2-24 19:44 | 只看该作者
该协议也打通了设备和微信服务器之间的数据链路。
神奇啊。虽然不长不过我都看懂了。

使用特权

评论回复
7
598330983| | 2016-2-24 21:27 | 只看该作者
微信蓝牙一般是基于串口的,所以只跟串口底层相关,也就是只需要将串口发送和接收两个函数填充到协议栈对外接口函数就行了。
嗯,我看好多的WIFI都是用的串口的模块。

使用特权

评论回复
8
dentsgot| | 2016-2-24 22:27 | 只看该作者
说的是微信可以在用户之间通过蓝牙传输?

使用特权

评论回复
9
Harvard| | 2016-2-25 11:27 | 只看该作者
mark一下 看看

使用特权

评论回复
10
yiyigirl2014| | 2016-2-25 20:50 | 只看该作者
原来可以通过本地的蓝牙方式进行直接通信,以前总觉得微信只能通过公共网络传输。

使用特权

评论回复
11
dongnanxibei| | 2016-2-25 22:08 | 只看该作者
厂商和微信提供了设备和接口,那么我们只需要对这些接口操作就行了,避免了复杂的协议,已经存储交换。

使用特权

评论回复
12
Jessicakjdsl| | 2016-2-26 08:59 | 只看该作者
感觉现在微信做的越来越强大了啊,以后估计能接入硬件了

使用特权

评论回复
13
wahahaheihei| | 2016-2-26 20:47 | 只看该作者
现在好多的物联网都接入了微信。另外我发现微信有的功能QQ有,而QQ功能更强大,为何大家都喜欢微信呢,我就好奇怪。

使用特权

评论回复
14
Bermanrep| | 2016-2-26 21:31 | 只看该作者
这个外围的硬件用的是什么啊

使用特权

评论回复
15
大苏牙| | 2016-2-28 22:53 | 只看该作者
楼主能否具体讲解一下微信蓝牙的定义呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

1971

主题

15987

帖子

210

粉丝