projectuser
2019-07-08 827102212c4403e5c454b77bc44b40310f23fa34
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include "aliIotLink.h"
 
 
SHA256 sha256;
 
AliIotLink::AliIotLink(PubSubClient& client)
{
    _client = &client;    
}
void AliIotLink::begin()
{
  //randomSeed(analogRead(A0));   //获取IO随机值【非安全的伪随机】作为种子
  //delayMicroseconds(random(0,10000));   //延迟随机时间
  
  generateClientId();
  readUrl();
  readUser();
  readPasswd();
  _client->setServer(_URL.c_str(),_port); //写入服务器名称与端口号
  
}
 
 
void AliIotLink::begin(String __DeviceName,String __ProductKey,String __DeviceSecret)
{
    _Id = __DeviceName;
    _DeviceName = __DeviceName;
    _ProductKey = __ProductKey;
    _DeviceSecret = __DeviceSecret;
    //randomSeed(analogRead(A0));
    //delayMicroseconds(random(0,10000));
    generateClientId();
    readUrl();
    readUser();
    readPasswd();
    _client->setServer(_URL.c_str(),_port);  //写入服务器名称与端口号
}
 
void AliIotLink::writeUrl(String __ServerUrl)    // 设置登录网址
{
    //_ServerUrl = __ServerUrl;
}
//服务器端口设置
void AliIotLink::writePort(uint16_t __port)
{
    _port = __port;
}
//硬件设备名称
void AliIotLink::writeID(String __Id)
{
    _Id = __Id;
}
// 设置设备硬件标签名称【阿里云提供】
void AliIotLink::writeDeviceName(String __DeviceName)  
{
    _DeviceName = __DeviceName;
}
//【阿里云提供】
void AliIotLink::writeProductKey(String __ProductKey)
{
    _ProductKey = __ProductKey;
}
//【阿里云提供】
void AliIotLink::writeDeviceSecret(String __DeviceSecret)
{
    _DeviceSecret = __DeviceSecret;
}
 
void AliIotLink::generateClientId()
{
    //ID+参数+随机数+结尾符号
    randomSeed(micros());
    Times  =random(0, 65535);
    _ClientId = _Id + FPSTR(_ClientIdSuffix) + Times +"|";
}
 
//获取合成好的登录用的ClientId
String AliIotLink::readClientId()
{
    return _ClientId;
}
 
 
//合成访问网址
 String AliIotLink::readUrl()
 {
     _URL = _ProductKey + F(".") + FPSTR(_ServerUrl);
     return _URL;
 }
 
 //合成访问用户名
 String AliIotLink::readUser()
 {
     _Username = _DeviceName + "&" + _ProductKey ;
     return _Username;
 }
 
 
 //合成访问密码
 String AliIotLink::readPasswd()
 {
     String _Passwd =  "clientId" + _Id + "deviceName" + _DeviceName +"productKey"+_ProductKey + "timestamp" + Times;
     _PasswdHash = "";
     
     byte hashData[64];
     
     HMAC(_DeviceSecret.c_str(), 32, _Passwd.c_str(), _Passwd.length(), hashData);
 
     for (int i = 0; i < 32; i++)  //hash 固定长度
     {
        _PasswdHash = _PasswdHash + "0123456789ABCDEF"[hashData[i] >> 4];
         _PasswdHash = _PasswdHash + "0123456789ABCDEF"[hashData[i] & 0xf];
     }
 
     //
     return _PasswdHash;  
     //返回HASH密文
 }
 //===================mqtt部分=====================
 
 bool AliIotLink::connect()
 {
 
 
     return _client->connect(_ClientId.c_str(),_Username.c_str(),_PasswdHash.c_str());   //像服务器传递 ClientId,用户名,密码
 
     
 }
 
 //重连
 void AliIotLink::reconnect()
 {
 
   while(!_client->connected()) //检查网络网络是否不正常,断开的网络会锁定重试
   {
 
      if (connect())   //重连并判断是否成功
      {
 
          //成功
          for(byte a = 0;a<TopicNum;a++)
          {
              subscribe(TopicName[a].c_str());
          }
          
          //填写上线订阅,应该是个String数组传入循环订阅处理
      } 
    else 
        {
            //链接失败
 
           delay(5000);   //暂停5秒钟重试
        }
  }
 }
 
 
 //循环检测
 void AliIotLink::loop()
 {
   if (!_client->connected()) 
   {
    reconnect();
   }
    _client->loop();
}
 
 
int AliIotLink::state()    //错误消息返回
{
    return _client->state();
}
 
 
 
//回调函数
void AliIotLink::setCallback(MQTT_CALLBACK_SIGNATURE)
{
    _client->setCallback(callback);
    //SerialUSB.println(callback);
}
//监听Topic
void AliIotLink::subscribe(const char* topic)
{
    _client->subscribe(topic);
}
//推送消息
void AliIotLink::publish(const char* topic, const char* payload)
{
    _client->publish(topic,payload);
}
 
 
//登记topic
void AliIotLink::subTopic(String topic)
{
    TopicName[TopicNum] = topic;
    TopicNum++;
    if(TopicNum > MQTT_Topic_Quantity)
    {
        TopicNum = MQTT_Topic_Quantity;
    }
}
 
void AliIotLink::HMAC( char const *key, byte KeySize,  char const *data, byte dataSize, byte *hashData)
{
  uint8_t result[32];
  sha256.resetHMAC(key, KeySize);  //传入KEY,和key长度
  sha256.update(data, dataSize);// 传输 hash明文
  sha256.finalizeHMAC(key, KeySize, result, sizeof(result)); // 计算
  for (byte a = 0; a < sizeof(result); a++) //传出签名
  {
    *(hashData + a) = result[a];
  }
}