stm32f103与esp8266通信 |
您所在的位置:网站首页 › esp8266rst › stm32f103与esp8266通信 |
UART.h文件 /************************************************************************UART.h****************************/ #ifndef _USART2_H_ #define _USART2_H_ #include "stm32f10x.h" #include "stdio.h" extern u8 flag; typedef struct { unsigned char RxBuff[256]; unsigned char TxBuff[256]; unsigned short FlagLen; unsigned char RecFlag; }USART2_InitStructure; extern USART2_InitStructure Usart2; void Usart2_Init(u32 bound); void SendUsart2Data(u8 *data); void SendUsart2Package(u8 *data,u16 len); void Usart2_Send_byte(u8 data); void ffff(void); #endif /**********************************************************UART.C*****************************************/ #include "USART2.h" #include "stdio.h" #include "esp8266.h" #include "stdbool.h" #include "stdio.h" #include "USART1.h" #include "string.h" #include "motor.h" #include "paj7620u2.h" #include "oled.h" #include "exti.h" #include "led.h" #include "rtc.h" #include "gettime.h" #define WIFI_USART USART2 USART2_InitStructure Usart2; /*********************************** 函数名称:void USAR_Init(u32 bound) 函数功能:串口1的初始化 入口参数:u32 bound (自己设定 一般为115200 9600) 出口参数:无 返回值: 无 说明:四要数(开启串口时钟 gpio口时钟 波特率寄存器 控制寄存器以及设置GPIO口相应的模式) ************************************/ void Usart2_Init(u32 bound) { USART_InitTypeDef USART_InitStruct; //定义串口类型结构体变量 GPIO_InitTypeDef GPIO_InitStruct; //定义GPIO类型结构体变量 NVIC_InitTypeDef NVIC_InitStruct; //定义中断向量控制器的变量 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 开启串口1时钟 开启A口时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 开启串口1时钟 开启A口时钟 //PA3 发送引脚 RX GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3; //引脚9设置 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化GPIOA // PA2 接收引脚 TX GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; //引脚9设置 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //输出速率50M GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化GPIOA USART_InitStruct.USART_BaudRate = bound;//设置波特率 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能 USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //全双工模式(发送使能 接收使能) USART_InitStruct.USART_Parity = USART_Parity_No; //奇偶失能(无校验) USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位一个 USART_InitStruct.USART_WordLength = USART_WordLength_8b; //8位数据 USART_Init(USART2, &USART_InitStruct); //初始化串口1 USART_Cmd(USART2, ENABLE); // 串口1使能 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能串口接收中断 USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); //空闲中断 使能 NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn; //通道选择(USART1 全局中断) NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //设置抢占优先级(范围0~3) NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; //设置响应优先级(范围0~3) NVIC_Init(&NVIC_InitStruct); //初始化 } void USART2_IRQHandler(void) { if (USART_GetITStatus(USART2, USART_IT_RXNE)) //如果是接收中断 { if (Usart2.FlagLen >= 256) Usart2.FlagLen = 0; Usart2.RxBuff[Usart2.FlagLen++] = USART_ReceiveData(USART2); //把收到的数据存起来 } else if (USART_GetITStatus(USART2, USART_IT_IDLE)) //如果是空闲中断 { Usart2.RxBuff[Usart2.FlagLen] = '\0'; //添加空字符 Usart2.FlagLen |= 0x8000; //最高位置1 Usart2.RecFlag = true; USART_ReceiveData(USART2); //读取DR,相当于清空SR的RXNE和IDLE位 } } void SendUsart2Data(u8 *data) //发送数据,末尾才有‘\0’ { while (*data != '\0') { while (!USART_GetFlagStatus(WIFI_USART, USART_FLAG_TC)); USART_SendData(WIFI_USART, *data++); } } void SendUsart2Package(u8 *data, u16 len) //发送数据包,中间包含‘\0’,所以需要依赖长度进行发送 { while (len--) { while (!USART_GetFlagStatus(WIFI_USART, USART_FLAG_TC)); USART_SendData(WIFI_USART, *data++); } } void Usart2_Send_byte(u8 data) { while (!USART_GetFlagStatus(USART2, USART_FLAG_TXE)); USART_SendData(USART2, data); } /************************************************esp8266.c*************************************************/ #include "esp8266.h" #include #include #include "delay.h" //#include "systick.h" #include "USART1.h" #include "hmacsha1.h" #include "led.h" #include "USART2.h" #include #include "DHT11.h" //#include "rgb.h" //#include "lcd.h" #include "paj7620u2.h" #include "oled.h" static unsigned char ConnectFlag = false;//true:已连接,false:未连接 static unsigned char mqtt_message[256]; //打包数据缓冲区 static unsigned char ssid[MESSAGE_MAX/2] = {SSID}, pwsd[MESSAGE_MAX/2] = {PWSD}; static void CalculateSha1(unsigned char *password); static void mstrcat(char *s1, const char *s2); static unsigned short CRC16_Compute(unsigned char *buffer, unsigned short len); /********************************************************************************************************* * 函 数 名 : Esp12_PublishMessage * 功能说明 : 上报数据 * 形 参 : StructMessage:自行强转指针类型即可上报任意类型的数据 * 返 回 值 : 无 * 备 注 : MQTT固件内部自带15S心跳,所以不需要间隔上报数据也可以保持长连接 *********************************************************************************************************/ void Esp12_PublishMessage(void *StructMessage) { /*一次上报的数据包不能大于缓冲区的大小,字段多时应分段上报,否则......*/ memset(mqtt_message, 0, sizeof(mqtt_message)); sprintf((char *)mqtt_message, "AT+MQTTPUB=0,\"%s\",\"{\\\"method\\\":\\\"thing.service.property.set\\\"\\,\\\"id\\\":\\\"2012934115\\\"\\,\ \\\"params\\\":{\\\"temperature\\\":%0.2f}\\,\\\"version\\\":\\\"1.0.0\\\"}\",1,0\r\n", PublishMessageTopPost, 25.5 ); SendUsart2Data(mqtt_message); } /********************************************************************************************************* * 函 数 名 : Esp12_Connect //标记 主要是这个函数 发送流程 * 功能说明 : esp12连接云服务器 * 形 参 : 无 * 返 回 值 : 无 * 备 注 : 10ms的刷新间隔 *********************************************************************************************************/ void Esp12_Connect(void) { unsigned char PassWord[50] = {0}; unsigned char cnt = 5; Restoration: printf("\r\nStart connecting to the server!\r\n"); while(!Esp12SendCmd("AT\r\n", "OK", 500)); //检测器件是否存在 Delay_Ms(200); while(!Esp12SendCmd("AT+CWMODE=1\r\n", "OK", 500) && cnt--); //设置为站点模式 Delay_Ms(200); memset(WifiUsart.RxBuff, 0, sizeof(WifiUsart.RxBuff)); // /*调好后可以注释掉这段 while(!Esp12SendCmd("ATE1\r\n", "OK", 500) && cnt--); //关闭指令回显 Delay_Ms(200); memset(WifiUsart.RxBuff, 0, sizeof(WifiUsart.RxBuff)); // */ if(!Esp12SendCmd("AT+CIFSR\r\n", "192", 500)) //如果已经连接网络,将不再重新连接 { if( (ssid[0]!=0 || pwsd[0]!=0)) //如果已经存有账号密码,先尝试连接 { // printf("--%s %s--\r\n", ssid, pwsd); memset(mqtt_message, 0, sizeof(mqtt_message)); memset(WifiUsart.RxBuff, 0, sizeof(WifiUsart.RxBuff)); sprintf((char *)mqtt_message, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, pwsd); // printf("%s\r\n", mqtt_message); SendUsart2Data((unsigned char *)mqtt_message); //连接目标AP while(strstr((char *)WifiUsart.RxBuff,"OK") == NULL) { Delay_Ms(100); if(++cnt >= 100) { printf("\r\nWarning: Failed to connect to WIFI. WiFi module will be reset!\r\n"); Esp12SendCmd("AT+RST\r\n","OK",100); for(cnt=0; cnt printf("\r\nWarning: Failed to configure MQTT user information. WiFi module will be reset!\r\n"); Esp12SendCmd("AT+RST\r\n","OK",100); for(cnt=0; cnt printf("\r\nWarning: Failed to configure MQTT clientid information. WiFi module will be reset!\r\n"); Esp12SendCmd("AT+RST\r\n","OK",100); for(cnt=0; cnt printf("\r\nWarning: Failed to configure MQTT clientid information. WiFi module will be reset!\r\n"); Esp12SendCmd("AT+RST\r\n","OK",100); for(cnt=0; cnt unsigned char temp[3] = {0}; unsigned char cnt = 0; hmac_sha1((unsigned char *)DeviceSecret,32,(unsigned char *)Encryption,46,mqtt_message); memset(temp, 0, sizeof(temp)); for(cnt=0;cnt return ConnectFlag; } void Esp12_Set_ConnectionStatus(unsigned char value) { ConnectFlag = value; } /********************************************************************************************************* * 函 数 名 : Esp12SendCmd * 功能说明 : 向esp12模组发送指令并等待希望的应答 * 形 参 : cmd:发送的命令,ack:希望的应答,waittime:等待应答的时间(ms) * 返 回 值 : 1没有得到希望的应答,0得到了希望的应答 * 备 注 : 无 *********************************************************************************************************/ //发送指令函数 unsigned char Esp12SendCmd(char *cmd, char *ack, unsigned short waittime) { WifiUsart.FlagLen = 0; //标示位、长度清零 waittime /= 10; //超时时间 SendUsart2Data((unsigned char *)cmd); //发送命令 while(--waittime) //等待串口接收完毕或超时退出 { if(WifiUsart.RecFlag == true) { // printf("wifi\r\n"); if(strstr((char *)WifiUsart.RxBuff, (char *)ack)) { WifiUsart.FlagLen = 0; WifiUsart.RecFlag = false; //printf("%s\r\n", WifiUsart.RxBuff); break; } WifiUsart.FlagLen = 0; WifiUsart.RecFlag = false; printf("%s\r\n", WifiUsart.RxBuff); } Delay_Ms(10); } if(waittime) return 1; return 0; } /* ************************************************************************************** *函数名: void MQTT_Send(void) *功能说明: 上传温湿度数据至阿里云 *形参: 无 *返回值: 无 ***************************************************************************************/ void MQTT_Send(float Temp,float Humi) { // float buff[3]; // buff[0] = HT.Tem; // buff[1] = HT.Hum; // Sht20_GetTemAndHumValue(&HT); memset(Usart2.TxBuff, 0, sizeof(Usart2.TxBuff)); sprintf((char *)Usart2.TxBuff, "AT+MQTTPUB=0,\"%s\",\"{\\\"method\\\":\\\"thing.service.property.set\\\"\\,\\\"id\\\":\\\"2012934115\\\"\\,\ \\\"params\\\":{\\\"temperature\\\":%0.2f\\,\\\"Humidity\\\":%0.2f}\\,\\\"version\\\":\\\"1.0.0\\\"}\",1,0\r\n", PublishMessageTopPost, Temp, Humi // buff[0], // buff[1] ); while(!Esp12SendCmd((char *)Usart2.TxBuff,"OK",2000)) { printf("正在发布消息!\r\n"); Delay_Ms(1000); } memset(Usart2.RxBuff,0,256); Delay_Ms(100); printf("发布消息成功!\r\n"); } void MQTT_Send_zhuangtai(u8 Door_status,u8 chuang,u8 deng) { // float buff[3]; // buff[0] = HT.Tem; // buff[1] = HT.Hum; // Sht20_GetTemAndHumValue(&HT); memset(Usart2.TxBuff, 0, sizeof(Usart2.TxBuff)); sprintf((char *)Usart2.TxBuff, "AT+MQTTPUB=0,\"%s\",\"{\\\"method\\\":\\\"thing.service.property.set\\\"\\,\\\"id\\\":\\\"2012934115\\\"\\,\ \\\"params\\\":{\\\"mendezhuangtai\\\":%d\\,\\\"chuangdezhuangtai\\\":%d\\,\\\"LightStatus\\\":%d}\\,\\\"version\\\":\\\"1.0.0\\\"}\",1,0\r\n", PublishMessageTopPost, Door_status, Window_status, Led_status // buff[0], // buff[1] ); while(!Esp12SendCmd((char *)Usart2.TxBuff,"OK",2000)) { printf("正在发布消息!\r\n"); Delay_Ms(1000); } memset(Usart2.RxBuff,0,256); Delay_Ms(100); printf("发布消息成功!\r\n"); } void MQTT_Send_naozhong(int xiaoshi,int fenzhong,int miaozhong) { // float buff[3]; // buff[0] = HT.Tem; // buff[1] = HT.Hum; // Sht20_GetTemAndHumValue(&HT); memset(Usart2.TxBuff, 0, sizeof(Usart2.TxBuff)); sprintf((char *)Usart2.TxBuff, "AT+MQTTPUB=0,\"%s\",\"{\\\"method\\\":\\\"thing.service.property.set\\\"\\,\\\"id\\\":\\\"2012934115\\\"\\,\ \\\"params\\\":{\\\"naozhongxiaoshi\\\":%d\\,\\\"naozhongfenzhong\\\":%d\\,\\\"naozhongmiao\\\":%d}\\,\\\"version\\\":\\\"1.0.0\\\"}\",1,0\r\n", PublishMessageTopPost, CLC.ALACLK_H, CLC.ALACLK_M, CLC.ALACLK_S // buff[0], // buff[1] ); while(!Esp12SendCmd((char *)Usart2.TxBuff,"OK",2000)) { printf("正在发布消息!\r\n"); Delay_Ms(1000); } memset(Usart2.RxBuff,0,256); Delay_Ms(100); printf("发布消息成功!\r\n"); } /******************************************************* *函数名:CRC16_Compute *功 能:校验计算 *参 数:需要校验的数据指针,需要校验的数据长度 *返 回:校验码 *备 注:无 ********************************************************/ static unsigned short CRC16_Compute(unsigned char *buffer, unsigned short len) { extern const unsigned short crc16_list[256];//校验表声明 unsigned short crc_code = 0xFFFF;//校验码初值 unsigned int i = 0; //CRC校验表索引值 while (len--) { i = (crc_code&0xff) ^ ((*buffer) & 0xff); //计算CRC crc_code = ((crc_code>>8) & 0xff) ^ crc16_list[i]; buffer++; } return crc_code ; //返回校验码 (高字节+低字节) } /*crc校验表*/ const unsigned short crc16_list[256] = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 }; /****************************************esp8266,h*********************************************************/ #ifndef __ESP8266_H #define __ESP8266_H #include "io_bit.h" #include "USART2.h" #include "DHT11.h" /***************************************************************************/ /**********************用户需要修改的,其他不要动***************************/ #define SSID "LENOVO 4539" //热点名称 #define PWSD "00+V4f24" //热点密码 #define MODE "TCP" //连接方式 #define IP "203.107.45.14" //服务器IP或域名,203.107.45.14 深圳 #define PORT 1883 //连接端口号,MQTT默认1883 #define WifiUsart Usart2 //与esp8266通信的串口的数据结构体 #if 0 //目前的两个产品信息(测试用例,请勿使用) #define DeviceName "FEN1" #define ProductKey "a1w5hhwMrXh" #define DeviceSecret "374fe27f993c261eaabaa9c72e4e10c4" #else #define DeviceName "SSSB" //设备名称 #define ProductKey "a1vfhhJz42E" //产品密匙 #define DeviceSecret "75393fc919308c8e8c0911f8cd7f0065" //设备密匙 //#define DeviceName "LED1" //设备名称 //#define ProductKey "a1hpYBrWoxL" //产品密匙 //#define DeviceSecret "21521b2c423fd802a6f04caa09fd7e2c" //设备密匙 #endif /***************************************************************************/ /***************************************************************************/ #define SYS "/sys/" #define LINK "/" #define TOP "/thing/event/property/" #define POST "post" #define ESET "set" #define PublishMessageTopPost (SYS ProductKey LINK DeviceName TOP POST) #define PublishMessageTopSet (SYS ProductKey LINK DeviceName TOP ESET) #define Client "clientId123deviceName" #define productKey "productKey" #define Encryption (Client DeviceName productKey ProductKey) #define AND "&" #define ClientId "123|securemode=3\\,signmethod=hmacsha1|" //客户端ID #define UserName (DeviceName AND ProductKey) //用户名 //#define PassWord "20C185291C1767917341AF3960B15A17D86CB653" //密码(由代码自动生成) void Esp12_Connect(void); void Esp12_TaskHandle(void); void Esp12_PublishMessage(void *StructMessage); void Esp12_ConfigNetWork(void); unsigned char Esp12_Get_ConnectionStatus(void); void Esp12_Set_ConnectionStatus(unsigned char value); void RevampState(char *cmd, unsigned char sta, unsigned char bef, unsigned char nex, unsigned char ack, unsigned short to, unsigned short inte); unsigned char CheckFlashOrBuffer(unsigned char *ssid, unsigned char *pwsd, char mode); unsigned char Esp12SendCmd(char *cmd, char *ack, unsigned short waittime); //void MQTT_Send(SHT_TypeDef HT); void MQTT_Send(float Temp,float Humi); void MQTT_Send_zhuangtai(u8 Door_status,u8 chuang,u8 deng); void MQTT_Send_naozhong(int xiaoshi,int fenzhong,int miaozhong); extern unsigned char ConnectFlag; #define WIFI_DEGBUG 0 #define CONFIG_NET 3 #define WAIT_CONFIG 4 #define MESSAGE_MAX 50 //账号密码总长 #define DATA_FLASH_BASE 0x08003C00 //存放wifi账号密码的地址 #define UNIQUE_ID_ADDRESS 0x1FFFF7AC //STM32唯一ID地址 #endif /****************************************************hmacsha1.c*******************************************/ #include "hmacsha1.h" /*****************************/ /**** Function Prototypes ****/ /*****************************/ unsigned long int ft (int t, unsigned long int x, unsigned long int y, unsigned long int z); int get_testcase (int test_case, unsigned char *plaintext, unsigned char *key, int *key_length_ptr); void sha1 (unsigned char *message, int message_length, unsigned char *digest); /****************************************/ /* sha1() */ /* Performs the NIST SHA-1 algorithm */ /****************************************/ unsigned long int ft(int t, unsigned long int x, unsigned long int y, unsigned long int z) { unsigned long int a = 0, b = 0, c = 0; if (t < 20) { a = x & y; b = (~x) & z; c = a ^ b; } else if (t < 40) { c = x ^ y ^ z; } else if (t < 60) { a = x & y; b = a ^ (x & z); c = b ^ (y & z); } else if (t < 80) { c = (x ^ y) ^ z; } return c; } unsigned long int k(int t) { unsigned long int c = 0; if (t < 20) c = 0x5a827999; else if (t < 40) c = 0x6ed9eba1; else if (t < 60) c = 0x8f1bbcdc; else if (t < 80) c = 0xca62c1d6; return c; } unsigned long int rotr(int bits, unsigned long int a) { unsigned long int c = 0, d = 0, e = 0, f = 0, g = 0; c = (0x0001 > bits; f = (a & c) unsigned char i = 0; unsigned char num_blocks = 0; unsigned char block_remainder = 0; unsigned char padded_length = 0; unsigned char t = 0; unsigned short int l = 0; unsigned long int h[5] = {0}; unsigned long int *pw = NULL; unsigned long int temp = 0; unsigned long int a = 0, b = 0, c = 0, d = 0, e = 0; /* Calculate the number of 512 bit blocks */ padded_length = message_length + 8; /* Add length for l */ padded_length = padded_length + 1; /* Add the 0x01 bit postfix */ l = message_length * 8; num_blocks = padded_length / 64; block_remainder = padded_length % 64; if (block_remainder > 0) num_blocks++; padded_length = padded_length + (64 - block_remainder); /* clear the padding field */ for (i = message_length; i < (num_blocks * 64); i++) message[i] = 0x00; /* insert b1 padding bit */ message[message_length] = 0x80; /* Insert l */ message[(num_blocks * 64) - 1] = (unsigned char) ( l & 0xff); message[(num_blocks * 64) - 2] = (unsigned char) ((l >> 8) & 0xff); message[(num_blocks * 64) - 3] = (unsigned char) ((l >> 16) & 0xff); message[(num_blocks * 64) - 4] = (unsigned char) ((l >> 24) & 0xff); /* Set initial hash state */ h[0] = 0x67452301; h[1] = 0xefcdab89; h[2] = 0x98badcfe; h[3] = 0x10325476; h[4] = 0xc3d2e1f0; pw = (unsigned long int *)malloc(80 * 4); for (i = 0; i < num_blocks; i++) { /* Prepare the message schedule */ for (t=0; t < 80; t++) { if (t < 16) { pw[t] = (256 * 256 * 256) * message[(i * 64) + (t * 4)]; pw[t] += (256 * 256) * message[(i * 64) + (t * 4) + 1]; pw[t] += (256) * message[(i * 64 )+ (t * 4) + 2]; pw[t] += message[(i * 64) + (t * 4) + 3]; } else if (t < 80) { pw[t] = rotl(1,(pw[t - 3] ^ pw[t - 8] ^ pw[t - 14] ^ pw[t - 16])); } } /* Initialize the five working variables */ a = h[0]; b = h[1]; c = h[2]; d = h[3]; e = h[4]; /* iterate a-e 80 times */ for (t = 0; t < 80; t++) { temp = (rotl(5, a) + ft(t, b, c, d)) & 0xffffffff; temp = (temp + e) & 0xffffffff; temp = (temp + k(t)) & 0xffffffff; temp = (temp + pw[t]) & 0xffffffff; e = d; d = c; c = rotl(30, b); b = a; a = temp; } /* compute the ith intermediate hash value */ h[0] = (a + h[0]) & 0xffffffff; h[1] = (b + h[1]) & 0xffffffff; h[2] = (c + h[2]) & 0xffffffff; h[3] = (d + h[3]) & 0xffffffff; h[4] = (e + h[4]) & 0xffffffff; } free(pw); pw = NULL; digest[3] = (unsigned char) ( h[0] & 0xff); digest[2] = (unsigned char) ((h[0] >> 8) & 0xff); digest[1] = (unsigned char) ((h[0] >> 16) & 0xff); digest[0] = (unsigned char) ((h[0] >> 24) & 0xff); digest[7] = (unsigned char) ( h[1] & 0xff); digest[6] = (unsigned char) ((h[1] >> 8) & 0xff); digest[5] = (unsigned char) ((h[1] >> 16) & 0xff); digest[4] = (unsigned char) ((h[1] >> 24) & 0xff); digest[11] = (unsigned char) ( h[2] & 0xff); digest[10] = (unsigned char) ((h[2] >> 8) & 0xff); digest[9] = (unsigned char) ((h[2] >> 16) & 0xff); digest[8] = (unsigned char) ((h[2] >> 24) & 0xff); digest[15] = (unsigned char) ( h[3] & 0xff); digest[14] = (unsigned char) ((h[3] >> 8) & 0xff); digest[13] = (unsigned char) ((h[3] >> 16) & 0xff); digest[12] = (unsigned char) ((h[3] >> 24) & 0xff); digest[19] = (unsigned char) ( h[4] & 0xff); digest[18] = (unsigned char) ((h[4] >> 8) & 0xff); digest[17] = (unsigned char) ((h[4] >> 16) & 0xff); digest[16] = (unsigned char) ((h[4] >> 24) & 0xff); } /******************************************************/ /* hmac-sha1() */ /* Performs the hmac-sha1 keyed secure hash algorithm */ /******************************************************/ void hmac_sha1(unsigned char *key, int key_length, unsigned char *data, int data_length, unsigned char *digest) { unsigned char b = 64; /* blocksize */ unsigned char ipad = 0x36; unsigned char opad = 0x5c; unsigned char k0[64] = {0}; unsigned char k0xorIpad[64] = {0}; unsigned char step7data[64] = {0}; unsigned char i = 0; unsigned char step8data[64+20] = {0}; unsigned char step5data[64+64] = {0}; for (i = 0; i < 64; i++) k0[i] = 0x00; if (key_length != b) /* Step 1 */ { /* Step 2 */ if (key_length > b) { sha1(key, key_length, digest); for (i = 0; i < 20; i++) k0[i] = digest[i]; } else if (key_length < b) /* Step 3 */ { for (i = 0; i < key_length; i++) k0[i] = key[i]; } } else { for (i = 0; i < b; i++) k0[i] = key[i]; } /* Step 4 */ for (i = 0; i < 64; i++) k0xorIpad[i] = k0[i] ^ ipad; /* Step 5 */ for (i = 0; i < 64; i++) step5data[i] = k0xorIpad[i]; for (i = 0; i < data_length; i++) step5data[i + 64] = data[i]; /* Step 6 */ sha1(step5data, data_length+b, digest); /* Step 7 */ for (i = 0; i < 64; i++) step7data[i] = k0[i] ^ opad; /* Step 8 */ for (i = 0; i < 64; i++) step8data[i] = step7data[i]; for (i = 0;i < 20; i++) step8data[i + 64] = digest[i]; /* Step 9 */ sha1(step8data, b + 20, digest); } /*************************************************hmacsha1.h******************************************/ #ifndef __hmacsha1_h #define __hmacsha1_h #include #include void hmac_sha1(unsigned char *key, int key_length, unsigned char *data, int data_length, unsigned char *digest); #endif |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |