source: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/ble_shield2.1/nRF8001.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 27.4 KB
Line 
1/*
2 * TOPPERS BASE PLATFORM MIDDLEWARE
3 *
4 * Copyright (C) 2017-2018 by TOPPERS PROJECT
5 * Educational Working Group.
6 *
7 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12 * スコード中に含まれていること.
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16 * の無保証規定を掲載すること.
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19 * と.
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23 * 報告すること.
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28 * 免責すること.
29 *
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34 * の責任を負わない.
35 *
36 * @(#) $Id$
37 */
38
39/*
40The MIT License (MIT)
41
42Copyright (c) 2014 Sandeep Mistry
43
44Permission is hereby granted, free of charge, to any person obtaining a copy
45of this software and associated documentation files (the "Software"), to deal
46in the Software without restriction, including without limitation the rights
47to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
48copies of the Software, and to permit persons to whom the Software is
49furnished to do so, subject to the following conditions:
50
51The above copyright notice and this permission notice shall be included in all
52copies or substantial portions of the Software.
53
54THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
60SOFTWARE.
61*/
62
63#include <utility/lib_aci.h>
64#include <utility/aci_setup.h>
65#include "BLECentral.h"
66#include "BLECharacteristic.h"
67#include "BLEPeripheral.h"
68
69
70#define ADVERTISING_INTERVAL 0x050
71
72struct setupMsgData {
73 uint8_t length;
74 uint8_t cmd;
75 uint8_t type;
76 uint8_t offset;
77 uint8_t data[28];
78};
79
80/*
81 * nRF8001セットアップデータ
82 */
83static hal_aci_data_t baseSetupMsgs[NB_BASE_SETUP_MESSAGES] PROGMEM = {
84 {0x00,
85 {0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xfe,},
86 },
87 {0x00,
88 {0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x06,0x00,0x06,
89 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
90 },
91 {0x00,
92 {0x1f,0x06,0x10,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
93 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x90,0x00,0xff,},
94 },
95 {0x00,
96 {0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
97 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x00,},
98 },
99 {0x00,
100 {0x05,0x06,0x10,0x54,0x00,0x02,},
101 },
102 {0x00,
103 {0x19,0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
104 0x00,0x00,0x00,0x00,0x00,0x00,},
105 },
106 {0x00,
107 {0x19,0x06,0x70,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
108 0x00,0x00,0x00,0x00,0x00,0x00,},
109 },
110};
111
112static struct pipeInfo _pinfovalue[MAX_ATTRIBUTE];
113
114/*
115 * CRC16計算
116 */
117static uint16_t
118crc_16_ccitt(uint16_t crc, uint8_t * data_in, uint16_t data_len)
119{
120 uint16_t i;
121
122 for(i = 0 ; i < data_len ; i++){
123 crc = (unsigned char)(crc >> 8) | (crc << 8);
124 crc ^= data_in[i];
125 crc ^= (unsigned char)(crc & 0xff) >> 4;
126 crc ^= (crc << 8) << 4;
127 crc ^= ((crc & 0xff) << 4) << 1;
128 }
129 return crc;
130}
131
132/*
133 * nRF8001開始
134 */
135void
136nRF8001_begin(nRF8001* pnRF8001, const uint8_t *advertisementData, uint8_t advertisementDataLength, const uint8_t *scanData,
137 uint8_t scanDataLength, BLEAttribute** attributes, uint8_t numAttributes)
138{
139 hal_aci_data_t setupMsg;
140 struct setupMsgData *setupMsgData;
141 uint8_t numPipedCharacteristics = 0;
142 uint8_t pipeSetupMsgOffet = 0;
143 uint8_t gattSetupMsgOffset = 0;
144 uint16_t handle = 1;
145 uint8_t pipe = 1;
146 uint8_t numPiped = 0;
147 ER ercd;
148 int i;
149
150 for(i = 0 ; i < numAttributes ; i++){
151 BLEAttribute* attribute = attributes[i];
152
153 if(attribute->_type == BLETypeCharacteristic){
154 BLECharacteristic *pcharc = (BLECharacteristic *)attribute;
155
156 if(pcharc->_properties){
157 numPipedCharacteristics++;
158 }
159 }
160 }
161
162 pnRF8001->_pipeInfo = _pinfovalue;
163
164#if DEBUG == 0
165 lib_aci_init(&pnRF8001->_aciState, false);
166#else
167 lib_aci_init(&pnRF8001->_aciState, true);
168#endif
169
170 nRF8001_waitForSetupMode(pnRF8001);
171
172 setupMsgData = (struct setupMsgData*)setupMsg.buffer;
173 setupMsg.status_byte = 0;
174
175 for (i = 0; i < NB_BASE_SETUP_MESSAGES; i++) {
176 int setupMsgSize = pgm_read_byte_near(&baseSetupMsgs[i].buffer[0]) + 2;
177
178 memcpy(&setupMsg, &baseSetupMsgs[i], setupMsgSize);
179 if(i == 1){
180 setupMsgData->data[6] = numPipedCharacteristics;
181 setupMsgData->data[8] = numPipedCharacteristics;
182 }
183 else if(i == 2 && advertisementData && advertisementDataLength){
184 setupMsgData->data[22] = 0x40;
185 }
186 else if(i == 3 && scanData && scanDataLength){
187 setupMsgData->data[12] = 0x40;
188 }
189 else if(i == 5 && advertisementData && advertisementDataLength){
190 memcpy(setupMsgData->data, advertisementData, advertisementDataLength);
191 }
192 else if(i == 6 && scanData && scanDataLength){
193 memcpy(setupMsgData->data, scanData, scanDataLength);
194 }
195
196 ercd = nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
197 if(ercd != E_OK)
198 i--;
199 }
200
201 // GATT
202 for(i = 0 ; i < numAttributes ; i++){
203 BLEAttribute* attribute = attributes[i];
204 BLEUuid* puuid = &attribute->_uuid;
205
206 if(attribute->_type == BLETypeService){
207 setupMsgData->length = 12 + puuid->_length;
208 setupMsgData->cmd = ACI_CMD_SETUP;
209 setupMsgData->type = 0x20;
210 setupMsgData->offset = gattSetupMsgOffset;
211
212 setupMsgData->data[0] = 0x04;
213 setupMsgData->data[1] = 0x04;
214 setupMsgData->data[2] = puuid->_length;
215 setupMsgData->data[3] = puuid->_length;
216 setupMsgData->data[4] = (handle >> 8) & 0xff;
217 setupMsgData->data[5] = handle & 0xff;
218 handle++;
219
220 setupMsgData->data[6] = (attribute->_type >> 8) & 0xff;
221 setupMsgData->data[7] = attribute->_type & 0xff;
222 setupMsgData->data[8] = ACI_STORE_LOCAL;
223 memcpy(&setupMsgData->data[9], puuid->_data, puuid->_length);
224 gattSetupMsgOffset += 9 + puuid->_length;
225
226 nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
227 }
228 else if(attribute->_type == BLETypeCharacteristic){
229 BLECharacteristic *pcharc = (BLECharacteristic *)attribute;
230 struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[numPiped];
231
232 memset(pipeInfo, 0, sizeof(struct pipeInfo));
233 pipeInfo->pcharc = pcharc;
234 if(pcharc->_properties){
235 numPiped++;
236 pipeInfo->startPipe = pipe;
237 if(pcharc->_properties & BLENotify){
238 pipeInfo->txPipe = pipe;
239 pipe++;
240 }
241
242 if(pcharc->_properties & BLEIndicate){
243 pipeInfo->txAckPipe = pipe;
244 pipe++;
245 }
246 if(pcharc->_properties & BLEWriteWithoutResponse){
247 pipeInfo->rxPipe = pipe;
248 pipe++;
249 }
250 if(pcharc->_properties & BLEWrite){
251 pipeInfo->rxAckPipe = pipe;
252 pipe++;
253 }
254 if(pcharc->_properties & BLERead){
255 pipeInfo->setPipe = pipe;
256 pipe++;
257 }
258 }
259
260 setupMsgData->length = 15 + puuid->_length;
261 setupMsgData->cmd = ACI_CMD_SETUP;
262 setupMsgData->type = 0x20;
263 setupMsgData->offset = gattSetupMsgOffset;
264
265 setupMsgData->data[0] = 0x04;
266 setupMsgData->data[1] = 0x04;
267 setupMsgData->data[2] = 3 + puuid->_length;
268 setupMsgData->data[3] = 3 + puuid->_length;
269
270 setupMsgData->data[4] = (handle >> 8) & 0xff;
271 setupMsgData->data[5] = handle & 0xff;
272 handle++;
273
274 setupMsgData->data[6] = (pcharc->_attr._type >> 8) & 0xff;
275 setupMsgData->data[7] = pcharc->_attr._type & 0xff;
276 setupMsgData->data[8] = ACI_STORE_LOCAL;
277 setupMsgData->data[9] = pcharc->_properties;
278 setupMsgData->data[10] = handle & 0xff;
279 setupMsgData->data[11] = (handle >> 8) & 0xff;
280 pipeInfo->valueHandle = handle;
281 handle++;
282
283 memcpy(&setupMsgData->data[12], puuid->_data, puuid->_length);
284
285 gattSetupMsgOffset += 12 + puuid->_length;
286
287 nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
288
289 setupMsgData->length = 12 + pcharc->_valueSize;
290 setupMsgData->cmd = ACI_CMD_SETUP;
291 setupMsgData->type = 0x20;
292 setupMsgData->offset = gattSetupMsgOffset;
293
294 setupMsgData->data[0] = 0x04;
295 setupMsgData->data[1] = 0x00;
296 if(pcharc->_fixedLength)
297 setupMsgData->data[0] |= 0x02;
298
299 if(pcharc->_properties & BLERead)
300 setupMsgData->data[1] |= 0x04;
301 if(pcharc->_properties & (BLEWrite | BLEWriteWithoutResponse)){
302 setupMsgData->data[0] |= 0x40;
303 setupMsgData->data[1] |= 0x10;
304 }
305 if(pcharc->_properties & BLENotify)
306 setupMsgData->data[0] |= 0x10;
307 if(pcharc->_properties & BLEIndicate)
308 setupMsgData->data[0] |= 0x20;
309 setupMsgData->data[2] = pcharc->_valueSize;
310 if(pcharc->_fixedLength)
311 setupMsgData->data[2]++;
312 setupMsgData->data[3] = pcharc->_valueLength;
313 setupMsgData->data[4] = (pipeInfo->valueHandle >> 8) & 0xff;
314 setupMsgData->data[5] = pipeInfo->valueHandle & 0xff;
315 setupMsgData->data[6] = 0x00;
316 setupMsgData->data[7] = 0x00;
317 setupMsgData->data[8] = 0x02;
318 memset(&setupMsgData->data[9], 0x00, pcharc->_valueSize);
319 memcpy(&setupMsgData->data[9], pcharc->_value, pcharc->_valueLength);
320
321 gattSetupMsgOffset += 9 + pcharc->_valueSize;
322
323 nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
324
325 if(pcharc->_properties & (BLENotify | BLEIndicate)){
326 setupMsgData->length = 14;
327 setupMsgData->cmd = ACI_CMD_SETUP;
328 setupMsgData->type = 0x20;
329 setupMsgData->offset = gattSetupMsgOffset;
330
331 setupMsgData->data[0] = 0x46;
332 setupMsgData->data[1] = 0x14;
333 setupMsgData->data[2] = 0x03;
334 setupMsgData->data[3] = 0x02;
335 setupMsgData->data[4] = (handle >> 8) & 0xff;
336 setupMsgData->data[5] = handle & 0xff;
337 pipeInfo->configHandle = handle;
338 handle++;
339
340 setupMsgData->data[6] = 0x29;
341 setupMsgData->data[7] = 0x02;
342 setupMsgData->data[8] = ACI_STORE_LOCAL;
343 setupMsgData->data[9] = 0x00;
344 setupMsgData->data[10] = 0x00;
345
346 gattSetupMsgOffset += 11;
347
348 nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
349 }
350 }
351 else if(attribute->_type == BLETypeDescriptor){
352 BLEDescriptor* descriptor = (BLEDescriptor *)attribute;
353
354 setupMsgData->length = 12 + descriptor->_valueSize;
355 setupMsgData->cmd = ACI_CMD_SETUP;
356 setupMsgData->type = 0x20;
357 setupMsgData->offset = gattSetupMsgOffset;
358
359 setupMsgData->data[0] = 0x04;
360 setupMsgData->data[1] = 0x04;
361 setupMsgData->data[2] = descriptor->_valueSize;
362 setupMsgData->data[3] = descriptor->_valueLength;
363 setupMsgData->data[4] = (handle >> 8) & 0xff;
364 setupMsgData->data[5] = handle & 0xff;
365 handle++;
366
367 setupMsgData->data[6] = puuid->_data[1];
368 setupMsgData->data[7] = puuid->_data[0];
369 setupMsgData->data[8] = ACI_STORE_LOCAL;
370 memcpy(&setupMsgData->data[9], descriptor->_value, descriptor->_valueLength);
371
372 gattSetupMsgOffset += 9 + descriptor->_valueSize;
373
374 nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
375 }
376 }
377 pnRF8001->_numPipeInfo = numPiped;
378
379 // terminator
380 setupMsgData->length = 4;
381 setupMsgData->cmd = ACI_CMD_SETUP;
382 setupMsgData->type = 0x20;
383 setupMsgData->offset = gattSetupMsgOffset;
384
385 setupMsgData->data[0] = 0x00;
386
387 gattSetupMsgOffset += 6;
388
389 nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
390
391 // pipes
392 for(i = 0 ; i < numPiped ; i++){
393 struct pipeInfo pipeInfo = pnRF8001->_pipeInfo[i];
394
395 setupMsgData->length = 13;
396 setupMsgData->cmd = ACI_CMD_SETUP;
397 setupMsgData->type = 0x40;
398 setupMsgData->offset = pipeSetupMsgOffet;
399
400 setupMsgData->data[0] = 0x00;
401 setupMsgData->data[1] = 0x00;
402 setupMsgData->data[2] = pipeInfo.startPipe;
403 setupMsgData->data[3] = 0x00;
404 setupMsgData->data[4] = 0x00;
405 setupMsgData->data[5] = 0x04;
406 setupMsgData->data[6] = (pipeInfo.valueHandle >> 8) & 0xff;
407 setupMsgData->data[7] = pipeInfo.valueHandle & 0xff;
408 setupMsgData->data[8] = (pipeInfo.configHandle >> 8) & 0xff;
409 setupMsgData->data[9] = pipeInfo.configHandle & 0xff;
410
411 if(pipeInfo.pcharc->_properties & BLEIndicate)
412 setupMsgData->data[4] |= 0x04; // TX Ack
413 if(pipeInfo.pcharc->_properties & BLENotify)
414 setupMsgData->data[4] |= 0x02; // TX
415 if(pipeInfo.pcharc->_properties & BLEWriteWithoutResponse)
416 setupMsgData->data[4] |= 0x08; // RX Ack
417 if(pipeInfo.pcharc->_properties & BLEWrite)
418 setupMsgData->data[4] |= 0x10; // RX Ack
419 if(pipeInfo.pcharc->_properties & BLERead)
420 setupMsgData->data[4] |= 0x80; // Set
421
422 pipeSetupMsgOffet += 10;
423
424 nRF8001_sendSetupMessage(pnRF8001, &setupMsg);
425 }
426 nRF8001_sendCrc(pnRF8001);
427}
428
429/*
430 * nRF8001参照
431 */
432bool_t
433nRF8001_poll(nRF8001* pnRF8001)
434{
435 if(lib_aci_event_get(&pnRF8001->_aciState, &pnRF8001->_aciData)){
436 aci_evt_t* aciEvt = &pnRF8001->_aciData.evt;
437 int i;
438#ifdef NRF_8001_DEBUG
439 uint32_t tmp1, tmp2;
440 uint32_t tmp3, tmp4;
441
442 syslog_3(LOG_NOTICE, " nRF8001_poll [%02x][%02x][%08x]", aciEvt->evt_opcode, aciEvt->params.device_started.device_mode, aciEvt);
443#endif
444 switch(aciEvt->evt_opcode){
445 /*
446 * スタートイベント(リセット後)
447 */
448 case ACI_EVT_DEVICE_STARTED: {
449 pnRF8001->_aciState.data_credit_total = aciEvt->params.device_started.credit_available;
450 switch(aciEvt->params.device_started.device_mode) {
451 case ACI_DEVICE_SETUP:
452 /*
453 * DEVICEセットアップ
454 */
455#ifdef NRF_8001_DEBUG
456 syslog_0(LOG_NOTICE, "Evt Device Started: Setup");
457#endif
458 break;
459
460 case ACI_DEVICE_STANDBY:
461 /*
462 * DEVICEスタンバイ
463 */
464#ifdef NRF_8001_DEBUG
465 syslog_0(LOG_NOTICE, "Evt Device Started: Standby");
466#endif
467 if(aciEvt->params.device_started.hw_error){
468 dly_tsk(20); /* ハードウェアエラー */
469 }
470 else{
471 lib_aci_connect(0/* in seconds : 0 means forever */, ADVERTISING_INTERVAL);
472#ifdef NRF_8001_DEBUG
473 syslog_0(LOG_NOTICE, "Advertising started");
474#endif
475 }
476 break;
477 default:
478 break;
479 }
480 }
481 break; /* ここまで、DEVICEスタート状態 */
482
483 case ACI_EVT_CMD_RSP:
484 //If an ACI command response event comes with an error -> stop
485 if(ACI_STATUS_SUCCESS != aciEvt->params.cmd_rsp.cmd_status){
486 //ACI ReadDynamicData and ACI WriteDynamicData will have status codes of
487 //TRANSACTION_CONTINUE and TRANSACTION_COMPLETE
488 //all other ACI commands will have status code of ACI_STATUS_SCUCCESS for a successful command
489#ifdef NRF_8001_DEBUG
490 syslog_2(LOG_NOTICE, "ACI Command [%02x] Evt Cmd respone: Status [%02x]",
491 aciEvt->params.cmd_rsp.cmd_opcode,
492 aciEvt->params.cmd_rsp.cmd_status);
493#endif
494 }
495 else{
496 switch (aciEvt->params.cmd_rsp.cmd_opcode) {
497 case ACI_CMD_GET_DEVICE_VERSION:
498 syslog_2(LOG_NOTICE, "VERSION configuration_id[%04x] aci_ver[%02x]",
499 aciEvt->params.cmd_rsp.params.get_device_version.configuration_id,
500 aciEvt->params.cmd_rsp.params.get_device_version.aci_version);
501 syslog_3(LOG_NOTICE, " setup_format[%02x] setup[%08x] setp_status[%02x]",
502 aciEvt->params.cmd_rsp.params.get_device_version.setup_format,
503 aciEvt->params.cmd_rsp.params.get_device_version.setup_id,
504 aciEvt->params.cmd_rsp.params.get_device_version.setup_status);
505 break;
506
507 case ACI_CMD_GET_DEVICE_ADDRESS: {
508#ifdef NRF_8001_DEBUG
509 syslog_4(LOG_NOTICE, "nRF8001_poll ACI_CMD_GET_DEVICE_ADDRESS type(%d) [%02x][%02x][%02x]",
510 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_type,
511 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[5],
512 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[4],
513 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[3]);
514 syslog_3(LOG_NOTICE, "nRF8001_poll [%02x][%02x][%02x]",
515 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[2],
516 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[1],
517 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[0]);
518#endif
519 if(pnRF8001->nRF8001AddressReceived){
520 pnRF8001->nRF8001AddressReceived(pnRF8001, aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own);
521 }
522 break;
523 }
524
525 case ACI_CMD_GET_BATTERY_LEVEL: {
526 float batteryLevel = aciEvt->params.cmd_rsp.params.get_battery_level.battery_level * 0.00352;
527 if(pnRF8001->nRF8001BatteryLevelReceived){
528 pnRF8001->nRF8001BatteryLevelReceived(pnRF8001, batteryLevel);
529 }
530 break;
531 }
532
533 case ACI_CMD_GET_TEMPERATURE: {
534 float temperature = aciEvt->params.cmd_rsp.params.get_temperature.temperature_value / 4.0;
535 if(pnRF8001->nRF8001TemperatureReceived){
536 pnRF8001->nRF8001TemperatureReceived(pnRF8001, temperature);
537 }
538 break;
539 }
540 default:
541 break;
542 }
543 }
544 break;
545
546 case ACI_EVT_CONNECTED:
547
548#ifdef NRF_8001_DEBUG
549 syslog_3(LOG_NOTICE, "Evt Connected [%02x][%02x][%02x]",
550 aciEvt->params.connected.dev_addr[5],
551 aciEvt->params.connected.dev_addr[4],
552 aciEvt->params.connected.dev_addr[3]):
553 syslog_3(LOG_NOTICE, " [%02x][%02x][%02x]",
554 aciEvt->params.connected.dev_addr[2],
555 aciEvt->params.connected.dev_addr[1],
556 aciEvt->params.connected.dev_addr[0]);
557#endif
558 if(pnRF8001->nRF8001Connected){
559 pnRF8001->nRF8001Connected(pnRF8001, aciEvt->params.connected.dev_addr);
560 }
561 pnRF8001->_aciState.data_credit_available = pnRF8001->_aciState.data_credit_total;
562 break;
563
564 case ACI_EVT_PIPE_STATUS:
565#ifdef NRF_8001_DEBUG
566 memcpy(&tmp1, &aciEvt->params.pipe_status.pipes_open_bitmap[0], 4);
567 memcpy(&tmp2, &aciEvt->params.pipe_status.pipes_open_bitmap[4], 4);
568 memcpy(&tmp3, &aciEvt->params.pipe_status.pipes_closed_bitmap[0], 4);
569 memcpy(&tmp4, &aciEvt->params.pipe_status.pipes_closed_bitmap[4], 4);
570 syslog_4(LOG_NOTICE, "Evt Pipe Status [%04x%04x][%04x%04x]", tmp1, tmp2, tmp3, tmp4);
571#endif
572 for(i = 0 ; i < pnRF8001->_numPipeInfo ; i++){
573 struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[i];
574
575 if(pipeInfo->txPipe){
576 pipeInfo->txPipeOpen = lib_aci_is_pipe_available(&pnRF8001->_aciState, pipeInfo->txPipe);
577 }
578 if(pipeInfo->txAckPipe){
579 pipeInfo->txAckPipeOpen = lib_aci_is_pipe_available(&pnRF8001->_aciState, pipeInfo->txAckPipe);
580 }
581
582 bool subscribed = (pipeInfo->txPipeOpen || pipeInfo->txAckPipeOpen);
583
584 if(pipeInfo->pcharc->_subscribed != subscribed){
585 if(pnRF8001->nRF8001CharacteristicSubscribedChanged){
586 pnRF8001->nRF8001CharacteristicSubscribedChanged(pnRF8001, pipeInfo->pcharc, subscribed);
587 }
588 }
589 }
590 break;
591
592 case ACI_EVT_TIMING:
593 break;
594
595 case ACI_EVT_DISCONNECTED:
596#ifdef NRF_8001_DEBUG
597 syslog_0(LOG_NOTICE, "Evt Disconnected/Advertising timed out");
598#endif
599 // all characteristics unsubscribed on disconnect
600 for(i = 0 ; i < pnRF8001->_numPipeInfo ; i++){
601 struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[i];
602
603 if(pipeInfo->pcharc->_subscribed){
604 if(pnRF8001->nRF8001CharacteristicSubscribedChanged){
605 pnRF8001->nRF8001CharacteristicSubscribedChanged(pnRF8001, pipeInfo->pcharc, false);
606 }
607 }
608 }
609 if(pnRF8001->nRF8001Disconnected){
610 pnRF8001->nRF8001Disconnected(pnRF8001);
611 }
612
613 lib_aci_connect(0/* in seconds : 0 means forever */, ADVERTISING_INTERVAL);
614#ifdef NRF_8001_DEBUG
615 syslog_0(LOG_NOTICE, "Advertising started.");
616#endif
617 break;
618
619 case ACI_EVT_DATA_RECEIVED: {
620 uint8_t dataLen = aciEvt->len - 2;
621 uint8_t pipe = aciEvt->params.data_received.rx_data.pipe_number;
622#ifdef NRF_8001_DEBUG
623 syslog_1(LOG_NOTICE, "Data Received, pipe = %d", aciEvt->params.data_received.rx_data.pipe_number);
624
625 for(int i = 0 ; i < dataLen ; i++){
626 syslog_2(LOG_NOTICE, "%d:%02x", i, aciEvt->params.data_received.rx_data.aci_data[i]);
627 }
628#endif
629 for(i = 0 ; i < pnRF8001->_numPipeInfo ; i++){
630 struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[i];
631
632 if(pipeInfo->rxAckPipe == pipe || pipeInfo->rxPipe == pipe){
633 if(pipeInfo->rxAckPipe == pipe){
634 lib_aci_send_ack(&pnRF8001->_aciState, pipeInfo->rxAckPipe);
635 }
636 if(pnRF8001->nRF8001CharacteristicValueChanged){
637 pnRF8001->nRF8001CharacteristicValueChanged(pnRF8001, pipeInfo->pcharc, aciEvt->params.data_received.rx_data.aci_data, dataLen);
638 }
639 break;
640 }
641 }
642 }
643 break;
644
645 case ACI_EVT_DATA_CREDIT:
646 pnRF8001->_aciState.data_credit_available = pnRF8001->_aciState.data_credit_available + aciEvt->params.data_credit.credit;
647 break;
648
649 case ACI_EVT_PIPE_ERROR:
650 //See the appendix in the nRF8001 Product Specication for details on the error codes
651#ifdef NRF_8001_DEBUG
652 syslog_2(LOG_ERROR, "ACI Evt Pipe Error: Pipe #:%d, Pipe Error Code: 0x%x",
653 aciEvt->params.pipe_error.pipe_number,
654 aciEvt->params.pipe_error.error_code);
655#endif
656 //Increment the credit available as the data packet was not sent.
657 //The pipe error also represents the Attribute protocol Error Response sent from the peer and that should not be counted
658 //for the credit.
659 if(ACI_STATUS_ERROR_PEER_ATT_ERROR != aciEvt->params.pipe_error.error_code){
660 pnRF8001->_aciState.data_credit_available++;
661 }
662 break;
663
664 case ACI_EVT_HW_ERROR:
665#ifdef NRF_8001_DEBUG
666 syslog_1(LOG_ERROR, "HW error: %d", aciEvt->params.hw_error.line_num);
667
668 for(uint8_t counter = 0; counter <= (aciEvt->len - 3); counter++) {
669 syslog_1(LOG_ERROR, "[%s]", aciEvt->params.hw_error.file_name[counter]);
670 }
671#endif
672 lib_aci_connect(0/* in seconds, 0 means forever */, ADVERTISING_INTERVAL);
673#ifdef NRF_8001_DEBUG
674 syslog_0(LOG_ERROR, "Advertising started.");
675#endif
676 break;
677 default:
678 break;
679 }
680 return true;
681 }
682 else
683 return false;
684}
685
686/*
687 * nRF8001キャラクティクス値更新
688 */
689bool_t
690nRF8001_updateCharacteristicValue(nRF8001* pnRF8001, BLECharacteristic *pcharc)
691{
692 bool_t success = true;
693 int i;
694
695 for(i = 0 ; i < pnRF8001->_numPipeInfo ; i++){
696 struct pipeInfo* pipeInfo = &pnRF8001->_pipeInfo[i];
697
698 if(pipeInfo->pcharc == pcharc){
699 if(pipeInfo->setPipe){
700 success &= lib_aci_set_local_data(&pnRF8001->_aciState, pipeInfo->setPipe, (uint8_t*)pcharc->_value, pcharc->_valueLength);
701 }
702 if(pipeInfo->txPipe && pipeInfo->txPipeOpen){
703 if(pcharc->canNotifyCharacteristic(pnRF8001, pcharc)){
704 pnRF8001->_aciState.data_credit_available--;
705 success &= lib_aci_send_data(pipeInfo->txPipe, (uint8_t*)pcharc->_value, pcharc->_valueLength);
706 }
707 else{
708 success = false;
709 }
710 }
711
712 if(pipeInfo->txAckPipe && pipeInfo->txAckPipeOpen){
713 if(pcharc->canIndicateCharacteristic(pnRF8001, pcharc)){
714 pnRF8001->_aciState.data_credit_available--;
715 success &= lib_aci_send_data(pipeInfo->txAckPipe, (uint8_t*)pcharc->_value, pcharc->_valueLength);
716 }
717 else{
718 success = false;
719 }
720 }
721 break;
722 }
723 }
724 return success;
725}
726
727/*
728 * nRF8001 NOTIFYキャラクティクス可能判定
729 */
730bool_t
731nRF8001_canNotifyCharacteristic(nRF8001* pnRF8001, BLECharacteristic *pcharc) {
732 return (lib_aci_get_nb_available_credits(&pnRF8001->_aciState) > 0);
733}
734
735/*
736 * nRF8001 INDICATEキャラクティクス可能判定
737 */
738bool_t
739nRF8001_canIndicateCharacteristic(nRF8001* pnRF8001, BLECharacteristic *pcharc) {
740 return (lib_aci_get_nb_available_credits(&pnRF8001->_aciState) > 0);
741}
742
743/*
744 * nRF8001切断
745 */
746void
747nRF8001_disconnect(nRF8001* pnRF8001)
748{
749 lib_aci_disconnect(&pnRF8001->_aciState, ACI_REASON_TERMINATE);
750}
751
752/*
753 * nRF8001アドレス要求
754 */
755void
756nRF8001_requestAddress(void)
757{
758 lib_aci_get_address();
759}
760
761/*
762 * nRF8001温度要求
763 */
764void
765nRF8001_requestTemperature(void)
766{
767 lib_aci_get_temperature();
768}
769
770/*
771 * nRF8001バッテリレベル要求
772 */
773void
774nRF8001_requestBatteryLevel(void)
775{
776 lib_aci_get_battery_level();
777}
778
779/*
780 * nRF8001セットアップモード待ち
781 */
782void
783nRF8001_waitForSetupMode(nRF8001* pnRF8001)
784{
785 bool_t setupMode = false;
786
787 while(!setupMode){
788 if(lib_aci_event_get(&pnRF8001->_aciState, &pnRF8001->_aciData)){
789 aci_evt_t* aciEvt = &pnRF8001->_aciData.evt;
790
791 switch(aciEvt->evt_opcode){
792 case ACI_EVT_DEVICE_STARTED: {
793 switch(aciEvt->params.device_started.device_mode) {
794 case ACI_DEVICE_SETUP:
795 /**
796 When the device is in the setup mode
797 */
798#ifdef NRF_8001_DEBUG
799 syslog_0(LOG_NOTICE, "Evt Device Started: Setup");
800#endif
801 setupMode = true;
802 break;
803 default:
804 break;
805 }
806 break;
807 }
808 default:
809 break;
810 }
811 }
812 else{
813 dly_tsk(1);
814 }
815 }
816}
817
818/*
819 * nRF8001セットアップメッセージ送信
820 */
821ER
822nRF8001_sendSetupMessage(nRF8001* pnRF8001, hal_aci_data_t* data)
823{
824 bool_t setupMsgSent = false;
825 int i = 0;
826
827 pnRF8001->_crcSeed = crc_16_ccitt(pnRF8001->_crcSeed, data->buffer, data->buffer[0] + 1);
828 hal_aci_tl_send(data);
829
830 while(!setupMsgSent){
831 if(lib_aci_event_get(&pnRF8001->_aciState, &pnRF8001->_aciData)){
832 aci_evt_t* aciEvt = &pnRF8001->_aciData.evt;
833
834 if(aciEvt->evt_opcode == ACI_EVT_CMD_RSP && aciEvt->params.cmd_rsp.cmd_status == ACI_STATUS_TRANSACTION_CONTINUE){
835#ifdef NRF_8001_DEBUG
836 syslog_2(LOG_NOTICE, "Evt Cmd Rsp: Transaction Continue evt[%02x] sts[%02x]", aciEvt->evt_opcode, aciEvt->params.cmd_rsp.cmd_status);
837#endif
838 setupMsgSent = true;
839 break;
840 }
841 }
842 else{
843 dly_tsk(1);
844 i++;
845 }
846 if(i > 500)
847 return E_TMOUT;
848 }
849 return E_OK;
850}
851
852/*
853 * nRF8001 CRC送信
854 */
855void
856nRF8001_sendCrc(nRF8001* pnRF8001)
857{
858 bool_t setupMsgSent = false;
859 hal_aci_data_t data;
860 data.status_byte = 0;
861
862 data.buffer[0] = 3 + 3;
863 data.buffer[1] = ACI_CMD_SETUP;
864 data.buffer[2] = 0xf0;
865 data.buffer[3] = 0x00;
866 data.buffer[4] = 0x03;
867 pnRF8001->_crcSeed = crc_16_ccitt(pnRF8001->_crcSeed, data.buffer, data.buffer[0] - 1);
868 data.buffer[5] = (pnRF8001->_crcSeed >> 8) & 0xff;
869 data.buffer[6] = pnRF8001->_crcSeed & 0xff;
870
871 hal_aci_tl_send(&data);
872
873 while(!setupMsgSent){
874 if(lib_aci_event_get(&pnRF8001->_aciState, &pnRF8001->_aciData)){
875 aci_evt_t* aciEvt = &pnRF8001->_aciData.evt;
876
877 switch(aciEvt->evt_opcode){
878 case ACI_EVT_CMD_RSP: {
879 switch(aciEvt->params.cmd_rsp.cmd_status) {
880 case ACI_STATUS_TRANSACTION_COMPLETE:
881#ifdef NRF_8001_DEBUG
882 syslog_0(LOG_NOTICE, "Evt Cmd Rsp: Transaction Complete");
883#endif
884 setupMsgSent = true;
885 break;
886 default:
887 break;
888 }
889 }
890 break;
891 default:
892 break;
893 }
894 }
895 else{
896 dly_tsk(1);
897 }
898 }
899}
900
Note: See TracBrowser for help on using the repository browser.