added debugging
Fork of BLE_nRF8001 by
Embed:
(wiki syntax)
Show/hide line numbers
nRF8001.cpp
00001 00002 #include "BLEAttribute.h" 00003 #include "BLEService.h" 00004 #include "BLECharacteristic.h" 00005 #include "BLEDescriptor.h" 00006 #include "BLEUuid.h" 00007 00008 #include "nRF8001.h" 00009 00010 //#define NRF_8001_DEBUG 00011 00012 #define ADVERTISING_INTERVAL 0x050 00013 00014 struct setupMsgData { 00015 unsigned char length; 00016 unsigned char cmd; 00017 unsigned char type; 00018 unsigned char offset; 00019 unsigned char data[28]; 00020 }; 00021 00022 #define NB_BASE_SETUP_MESSAGES 7 00023 00024 /* Store the setup for the nRF8001 in the flash of the AVR to save on RAM */ 00025 static hal_aci_data_t baseSetupMsgs[NB_BASE_SETUP_MESSAGES] PROGMEM = {\ 00026 {0x00,\ 00027 {\ 00028 0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xfe,\ 00029 },\ 00030 },\ 00031 {0x00,\ 00032 {\ 00033 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x06,0x00,0x06,\ 00034 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 00035 },\ 00036 },\ 00037 {0x00,\ 00038 {\ 00039 0x1f,0x06,0x10,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 00040 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x90,0x00,0xff,\ 00041 },\ 00042 },\ 00043 {0x00,\ 00044 {\ 00045 0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 00046 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x00,\ 00047 },\ 00048 },\ 00049 {0x00,\ 00050 {\ 00051 0x05,0x06,0x10,0x54,0x00,0x02,\ 00052 },\ 00053 },\ 00054 {0x00,\ 00055 {\ 00056 0x19,0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 00057 0x00,0x00,0x00,0x00,0x00,0x00,\ 00058 },\ 00059 },\ 00060 {0x00,\ 00061 {\ 00062 0x19,0x06,0x70,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 00063 0x00,0x00,0x00,0x00,0x00,0x00,\ 00064 },\ 00065 },\ 00066 }; 00067 00068 void __ble_assert(const char *file, uint16_t line) 00069 { 00070 serial.printf("ERROR "); 00071 serial.printf(file); 00072 serial.printf(": "); 00073 serial.printf("%d\n",line); 00074 while(1); 00075 } 00076 00077 /** crc function to re-calulate the CRC after making changes to the setup data. 00078 */ 00079 uint16_t crc_16_ccitt(uint16_t crc, uint8_t * data_in, uint16_t data_len) { 00080 00081 uint16_t i; 00082 00083 for(i = 0; i < data_len; i++) 00084 { 00085 crc = (unsigned char)(crc >> 8) | (crc << 8); 00086 crc ^= data_in[i]; 00087 crc ^= (unsigned char)(crc & 0xff) >> 4; 00088 crc ^= (crc << 8) << 4; 00089 crc ^= ((crc & 0xff) << 4) << 1; 00090 } 00091 00092 return crc; 00093 } 00094 00095 nRF8001::nRF8001(DigitalInOut *req, DigitalInOut *rdy, DigitalInOut *rst) : 00096 _pipeInfo(NULL), 00097 _numPipeInfo(0), 00098 00099 _crcSeed(0xFFFF), 00100 00101 _eventListener(NULL) 00102 { 00103 this->_aciState.aci_pins.reqn_pin = req; 00104 this->_aciState.aci_pins.rdyn_pin = rdy; 00105 00106 if (rst == NULL) { 00107 this->_aciState.aci_pins.board_name = REDBEARLAB_SHIELD_V1_1; 00108 } 00109 else { 00110 this->_aciState.aci_pins.board_name = BOARD_DEFAULT; 00111 } 00112 00113 this->_aciState.aci_pins.reset_pin = rst; 00114 this->_aciState.aci_pins.active_pin = NULL; 00115 00116 this->_aciState.aci_pins.interface_is_interrupt = false; 00117 this->_aciState.aci_pins.interrupt_number = 1; 00118 } 00119 00120 nRF8001::~nRF8001() { 00121 if (this->_pipeInfo) { 00122 free(this->_pipeInfo); 00123 } 00124 } 00125 00126 00127 00128 void nRF8001::setEventListener(nRF8001EventListener* eventListener) { 00129 this->_eventListener = eventListener; 00130 } 00131 00132 void nRF8001::begin(const unsigned char* advertisementData, 00133 unsigned char advertisementDataLength, 00134 const unsigned char* scanData, 00135 unsigned char scanDataLength, 00136 BLEAttribute** attributes, 00137 unsigned char numAttributes) 00138 { 00139 unsigned char numPipedCharacteristics = 0; 00140 00141 for (int i = 0; i < numAttributes; i++) { 00142 BLEAttribute* attribute = attributes[i]; 00143 00144 if (attribute->type() == BLETypeCharacteristic) { 00145 BLECharacteristic* characteristic = (BLECharacteristic *)attribute; 00146 00147 if (characteristic->properties()) { 00148 numPipedCharacteristics++; 00149 } 00150 } 00151 } 00152 00153 this->_pipeInfo = (struct pipeInfo*)malloc(sizeof(struct pipeInfo) * numPipedCharacteristics); 00154 00155 lib_aci_init(&this->_aciState, false); 00156 00157 this->waitForSetupMode(); 00158 00159 hal_aci_data_t setupMsg; 00160 struct setupMsgData* setupMsgData = (struct setupMsgData*)setupMsg.buffer; 00161 00162 setupMsg.status_byte = 0; 00163 00164 for (int i = 0; i < NB_BASE_SETUP_MESSAGES; i++) { 00165 int setupMsgSize = pgm_read_byte_near(&baseSetupMsgs[i].buffer[0]) + 2; 00166 00167 memcpy_P(&setupMsg, &baseSetupMsgs[i], setupMsgSize); 00168 00169 if (i == 1) { 00170 setupMsgData->data[6] = numPipedCharacteristics; 00171 setupMsgData->data[8] = numPipedCharacteristics; 00172 } else if (i == 2 && advertisementData && advertisementDataLength) { 00173 setupMsgData->data[22] = 0x40; 00174 } else if (i == 3 && scanData && scanDataLength) { 00175 setupMsgData->data[12] = 0x40; 00176 } else if (i == 5 && advertisementData && advertisementDataLength) { 00177 memcpy(setupMsgData->data, advertisementData, advertisementDataLength); 00178 } else if (i == 6 && scanData && scanDataLength) { 00179 memcpy(setupMsgData->data, scanData, scanDataLength); 00180 } 00181 00182 this->sendSetupMessage(&setupMsg); 00183 } 00184 00185 // GATT 00186 unsigned char gattSetupMsgOffset = 0; 00187 unsigned short handle = 1; 00188 unsigned char pipe = 1; 00189 unsigned char numPiped = 0; 00190 00191 for (int i = 0; i < numAttributes; i++) { 00192 BLEAttribute* attribute = attributes[i]; 00193 BLEUuid uuid = BLEUuid(attribute->uuid()); 00194 00195 if (attribute->type() == BLETypeService) { 00196 BLEService* service = (BLEService *)attribute; 00197 00198 setupMsgData->length = 12 + uuid.length(); 00199 setupMsgData->cmd = ACI_CMD_SETUP; 00200 setupMsgData->type = 0x20; 00201 setupMsgData->offset = gattSetupMsgOffset; 00202 00203 setupMsgData->data[0] = 0x04; 00204 setupMsgData->data[1] = 0x04; 00205 setupMsgData->data[2] = uuid.length(); 00206 setupMsgData->data[3] = uuid.length(); 00207 00208 setupMsgData->data[4] = (handle >> 8) & 0xff; 00209 setupMsgData->data[5] = handle & 0xff; 00210 handle++; 00211 00212 setupMsgData->data[6] = (service->type() >> 8) & 0xff; 00213 setupMsgData->data[7] = service->type() & 0xff; 00214 00215 setupMsgData->data[8] = ACI_STORE_LOCAL; 00216 00217 memcpy(&setupMsgData->data[9], uuid.data(), uuid.length()); 00218 00219 gattSetupMsgOffset += 9 + uuid.length(); 00220 00221 this->sendSetupMessage(&setupMsg); 00222 } else if (attribute->type() == BLETypeCharacteristic) { 00223 BLECharacteristic* characteristic = (BLECharacteristic *)attribute; 00224 00225 struct pipeInfo* pipeInfo = &this->_pipeInfo[numPiped]; 00226 00227 memset(pipeInfo, 0, sizeof(struct pipeInfo)); 00228 00229 pipeInfo->characteristic = characteristic; 00230 00231 if (characteristic->properties()) { 00232 numPiped++; 00233 00234 pipeInfo->startPipe = pipe; 00235 00236 if (characteristic->properties() & BLENotify) { 00237 pipeInfo->txPipe = pipe; 00238 00239 pipe++; 00240 } 00241 00242 if (characteristic->properties() & BLEIndicate) { 00243 pipeInfo->txAckPipe = pipe; 00244 00245 pipe++; 00246 } 00247 00248 if (characteristic->properties() & BLEWriteWithoutResponse) { 00249 pipeInfo->rxPipe = pipe; 00250 00251 pipe++; 00252 } 00253 00254 if (characteristic->properties() & BLEWrite) { 00255 pipeInfo->rxAckPipe = pipe; 00256 00257 pipe++; 00258 } 00259 00260 if (characteristic->properties() & BLERead) { 00261 pipeInfo->setPipe = pipe; 00262 00263 pipe++; 00264 } 00265 } 00266 00267 setupMsgData->length = 15 + uuid.length(); 00268 setupMsgData->cmd = ACI_CMD_SETUP; 00269 setupMsgData->type = 0x20; 00270 setupMsgData->offset = gattSetupMsgOffset; 00271 00272 setupMsgData->data[0] = 0x04; 00273 setupMsgData->data[1] = 0x04; 00274 setupMsgData->data[2] = 3 + uuid.length(); 00275 setupMsgData->data[3] = 3 + uuid.length(); 00276 00277 setupMsgData->data[4] = (handle >> 8) & 0xff; 00278 setupMsgData->data[5] = handle & 0xff; 00279 handle++; 00280 00281 setupMsgData->data[6] = (characteristic->type() >> 8) & 0xff; 00282 setupMsgData->data[7] = characteristic->type() & 0xff; 00283 00284 setupMsgData->data[8] = ACI_STORE_LOCAL; 00285 setupMsgData->data[9] = characteristic->properties(); 00286 00287 setupMsgData->data[10] = handle & 0xff; 00288 setupMsgData->data[11] = (handle >> 8) & 0xff; 00289 pipeInfo->valueHandle = handle; 00290 handle++; 00291 00292 memcpy(&setupMsgData->data[12], uuid.data(), uuid.length()); 00293 00294 gattSetupMsgOffset += 12 + uuid.length(); 00295 00296 this->sendSetupMessage(&setupMsg); 00297 00298 setupMsgData->length = 12 + characteristic->valueSize(); 00299 setupMsgData->cmd = ACI_CMD_SETUP; 00300 setupMsgData->type = 0x20; 00301 setupMsgData->offset = gattSetupMsgOffset; 00302 00303 setupMsgData->data[0] = 0x04; 00304 setupMsgData->data[1] = 0x00; 00305 00306 if (characteristic->fixedLength()) { 00307 setupMsgData->data[0] |= 0x02; 00308 } 00309 00310 if (characteristic->properties() & BLERead) { 00311 setupMsgData->data[1] |= 0x04; 00312 } 00313 00314 if (characteristic->properties() & (BLEWrite | BLEWriteWithoutResponse)) { 00315 setupMsgData->data[0] |= 0x40; 00316 setupMsgData->data[1] |= 0x10; 00317 } 00318 00319 if (characteristic->properties() & BLENotify) { 00320 setupMsgData->data[0] |= 0x10; 00321 } 00322 00323 if (characteristic->properties() & BLEIndicate) { 00324 setupMsgData->data[0] |= 0x20; 00325 } 00326 00327 setupMsgData->data[2] = characteristic->valueSize(); 00328 if (characteristic->fixedLength()) { 00329 setupMsgData->data[2]++; 00330 } 00331 00332 setupMsgData->data[3] = characteristic->valueLength(); 00333 00334 setupMsgData->data[4] = (pipeInfo->valueHandle >> 8) & 0xff; 00335 setupMsgData->data[5] = pipeInfo->valueHandle & 0xff; 00336 00337 setupMsgData->data[6] = 0x00; 00338 setupMsgData->data[7] = 0x00; 00339 00340 setupMsgData->data[8] = 0x02; 00341 00342 memset(&setupMsgData->data[9], 0x00, characteristic->valueSize()); 00343 memcpy(&setupMsgData->data[9], characteristic->value(), characteristic->valueLength()); 00344 00345 gattSetupMsgOffset += 9 + characteristic->valueSize(); 00346 00347 this->sendSetupMessage(&setupMsg); 00348 00349 if (characteristic->properties() & (BLENotify | BLEIndicate)) { 00350 setupMsgData->length = 14; 00351 setupMsgData->cmd = ACI_CMD_SETUP; 00352 setupMsgData->type = 0x20; 00353 setupMsgData->offset = gattSetupMsgOffset; 00354 00355 setupMsgData->data[0] = 0x46; 00356 setupMsgData->data[1] = 0x14; 00357 00358 setupMsgData->data[2] = 0x03; 00359 setupMsgData->data[3] = 0x02; 00360 00361 setupMsgData->data[4] = (handle >> 8) & 0xff; 00362 setupMsgData->data[5] = handle & 0xff; 00363 pipeInfo->configHandle = handle; 00364 handle++; 00365 00366 setupMsgData->data[6] = 0x29; 00367 setupMsgData->data[7] = 0x02; 00368 00369 setupMsgData->data[8] = ACI_STORE_LOCAL; 00370 00371 setupMsgData->data[9] = 0x00; 00372 setupMsgData->data[10] = 0x00; 00373 00374 gattSetupMsgOffset += 11; 00375 00376 this->sendSetupMessage(&setupMsg); 00377 } 00378 } else if (attribute->type() == BLETypeDescriptor) { 00379 BLEDescriptor* descriptor = (BLEDescriptor *)attribute; 00380 00381 setupMsgData->length = 12 + descriptor->valueSize(); 00382 setupMsgData->cmd = ACI_CMD_SETUP; 00383 setupMsgData->type = 0x20; 00384 setupMsgData->offset = gattSetupMsgOffset; 00385 00386 setupMsgData->data[0] = 0x04; 00387 setupMsgData->data[1] = 0x04; 00388 00389 setupMsgData->data[2] = descriptor->valueSize(); 00390 setupMsgData->data[3] = descriptor->valueLength(); 00391 00392 setupMsgData->data[4] = (handle >> 8) & 0xff; 00393 setupMsgData->data[5] = handle & 0xff; 00394 handle++; 00395 00396 setupMsgData->data[6] = uuid.data()[1]; 00397 setupMsgData->data[7] = uuid.data()[0]; 00398 00399 setupMsgData->data[8] = ACI_STORE_LOCAL; 00400 00401 memcpy(&setupMsgData->data[9], descriptor->value(), descriptor->valueLength()); 00402 00403 gattSetupMsgOffset += 9 + descriptor->valueSize(); 00404 00405 this->sendSetupMessage(&setupMsg); 00406 } 00407 } 00408 00409 this->_numPipeInfo = numPiped; 00410 00411 // terminator 00412 setupMsgData->length = 4; 00413 setupMsgData->cmd = ACI_CMD_SETUP; 00414 setupMsgData->type = 0x20; 00415 setupMsgData->offset = gattSetupMsgOffset; 00416 00417 setupMsgData->data[0] = 0x00; 00418 00419 gattSetupMsgOffset += 6; 00420 00421 this->sendSetupMessage(&setupMsg); 00422 00423 // pipes 00424 unsigned char pipeSetupMsgOffet = 0; 00425 00426 for (int i = 0; i < numPiped; i++) { 00427 struct pipeInfo pipeInfo = this->_pipeInfo[i]; 00428 00429 setupMsgData->length = 13; 00430 setupMsgData->cmd = ACI_CMD_SETUP; 00431 setupMsgData->type = 0x40; 00432 setupMsgData->offset = pipeSetupMsgOffet; 00433 00434 setupMsgData->data[0] = 0x00; 00435 setupMsgData->data[1] = 0x00; 00436 00437 setupMsgData->data[2] = pipeInfo.startPipe; 00438 00439 setupMsgData->data[3] = 0x00; 00440 setupMsgData->data[4] = 0x00; 00441 00442 setupMsgData->data[5] = 0x04; 00443 00444 setupMsgData->data[6] = (pipeInfo.valueHandle >> 8) & 0xff; 00445 setupMsgData->data[7] = pipeInfo.valueHandle & 0xff; 00446 00447 setupMsgData->data[8] = (pipeInfo.configHandle >> 8) & 0xff; 00448 setupMsgData->data[9] = pipeInfo.configHandle & 0xff; 00449 00450 if (pipeInfo.characteristic->properties() & BLEIndicate) { 00451 setupMsgData->data[4] |= 0x04; // TX Ack 00452 } 00453 00454 if (pipeInfo.characteristic->properties() & BLENotify) { 00455 setupMsgData->data[4] |= 0x02; // TX 00456 } 00457 00458 if (pipeInfo.characteristic->properties() & BLEWriteWithoutResponse) { 00459 setupMsgData->data[4] |= 0x08; // RX Ack 00460 } 00461 00462 if (pipeInfo.characteristic->properties() & BLEWrite) { 00463 setupMsgData->data[4] |= 0x10; // RX Ack 00464 } 00465 00466 if (pipeInfo.characteristic->properties() & BLERead) { 00467 setupMsgData->data[4] |= 0x80; // Set 00468 } 00469 00470 pipeSetupMsgOffet += 10; 00471 00472 this->sendSetupMessage(&setupMsg); 00473 } 00474 00475 this->sendCrc(); 00476 } 00477 00478 void nRF8001::poll() { 00479 // We enter the if statement only when there is a ACI event available to be processed 00480 if (lib_aci_event_get(&this->_aciState, &this->_aciData)) { 00481 aci_evt_t* aciEvt; 00482 aciEvt = &this->_aciData.evt; 00483 00484 switch(aciEvt->evt_opcode) { 00485 /** 00486 As soon as you reset the nRF8001 you will get an ACI Device Started Event 00487 */ 00488 case ACI_EVT_DEVICE_STARTED: { 00489 this->_aciState.data_credit_total = aciEvt->params.device_started.credit_available; 00490 switch(aciEvt->params.device_started.device_mode) { 00491 case ACI_DEVICE_SETUP: 00492 /** 00493 When the device is in the setup mode 00494 */ 00495 #ifdef NRF_8001_DEBUG 00496 Serial.println(F("Evt Device Started: Setup")); 00497 #endif 00498 break; 00499 00500 case ACI_DEVICE_STANDBY: 00501 #ifdef NRF_8001_DEBUG 00502 Serial.println(F("Evt Device Started: Standby")); 00503 #endif 00504 //Looking for an iPhone by sending radio advertisements 00505 //When an iPhone connects to us we will get an ACI_EVT_CONNECTED event from the nRF8001 00506 if (aciEvt->params.device_started.hw_error) { 00507 delay(20); //Handle the HW error event correctly. 00508 } else { 00509 lib_aci_connect(0/* in seconds : 0 means forever */, ADVERTISING_INTERVAL); 00510 #ifdef NRF_8001_DEBUG 00511 Serial.println(F("Advertising started")); 00512 #endif 00513 } 00514 break; 00515 } 00516 } 00517 break; //ACI Device Started Event 00518 00519 case ACI_EVT_CMD_RSP: 00520 //If an ACI command response event comes with an error -> stop 00521 if (ACI_STATUS_SUCCESS != aciEvt->params.cmd_rsp.cmd_status) { 00522 //ACI ReadDynamicData and ACI WriteDynamicData will have status codes of 00523 //TRANSACTION_CONTINUE and TRANSACTION_COMPLETE 00524 //all other ACI commands will have status code of ACI_STATUS_SCUCCESS for a successful command 00525 #ifdef NRF_8001_DEBUG 00526 Serial.print(F("ACI Command ")); 00527 Serial.println(aciEvt->params.cmd_rsp.cmd_opcode, HEX); 00528 Serial.print(F("Evt Cmd respone: Status ")); 00529 Serial.println(aciEvt->params.cmd_rsp.cmd_status, HEX); 00530 #endif 00531 } else { 00532 switch (aciEvt->params.cmd_rsp.cmd_opcode) { 00533 case ACI_CMD_GET_DEVICE_VERSION: 00534 break; 00535 00536 case ACI_CMD_GET_DEVICE_ADDRESS: { 00537 #ifdef NRF_8001_DEBUG 00538 char address[18]; 00539 00540 sprintf(address, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", 00541 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[5], 00542 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[4], 00543 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[3], 00544 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[2], 00545 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[1], 00546 aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own[0]); 00547 Serial.print(F("Device address = ")); 00548 Serial.println(address); 00549 00550 Serial.print(F("Device address type = ")); 00551 Serial.println(aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_type, DEC); 00552 #endif 00553 if (this->_eventListener) { 00554 this->_eventListener->nRF8001AddressReceived(*this, aciEvt->params.cmd_rsp.params.get_device_address.bd_addr_own); 00555 } 00556 break; 00557 } 00558 00559 case ACI_CMD_GET_BATTERY_LEVEL: { 00560 float batteryLevel = aciEvt->params.cmd_rsp.params.get_battery_level.battery_level * 0.00352; 00561 #ifdef NRF_8001_DEBUG 00562 Serial.print(F("Battery level = ")); 00563 Serial.println(batteryLevel); 00564 #endif 00565 if (this->_eventListener) { 00566 this->_eventListener->nRF8001BatteryLevelReceived(*this, batteryLevel); 00567 } 00568 break; 00569 } 00570 00571 case ACI_CMD_GET_TEMPERATURE: { 00572 float temperature = aciEvt->params.cmd_rsp.params.get_temperature.temperature_value / 4.0; 00573 #ifdef NRF_8001_DEBUG 00574 Serial.print(F("Temperature = ")); 00575 Serial.println(temperature); 00576 #endif 00577 if (this->_eventListener) { 00578 this->_eventListener->nRF8001TemperatureReceived(*this, temperature); 00579 } 00580 break; 00581 } 00582 } 00583 } 00584 break; 00585 00586 case ACI_EVT_CONNECTED: 00587 00588 #ifdef NRF_8001_DEBUG 00589 char address[18]; 00590 sprintf(address, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", 00591 aciEvt->params.connected.dev_addr[5], 00592 aciEvt->params.connected.dev_addr[4], 00593 aciEvt->params.connected.dev_addr[3], 00594 aciEvt->params.connected.dev_addr[2], 00595 aciEvt->params.connected.dev_addr[1], 00596 aciEvt->params.connected.dev_addr[0]); 00597 Serial.print(F("Evt Connected ")); 00598 Serial.println(address); 00599 #endif 00600 if (this->_eventListener) { 00601 this->_eventListener->nRF8001Connected(*this, aciEvt->params.connected.dev_addr); 00602 } 00603 00604 this->_aciState.data_credit_available = this->_aciState.data_credit_total; 00605 break; 00606 00607 case ACI_EVT_PIPE_STATUS: 00608 #ifdef NRF_8001_DEBUG 00609 Serial.println(F("Evt Pipe Status ")); 00610 00611 uint64_t openPipes; 00612 uint64_t closedPipes; 00613 00614 memcpy(&openPipes, aciEvt->params.pipe_status.pipes_open_bitmap, sizeof(openPipes)); 00615 memcpy(&closedPipes, aciEvt->params.pipe_status.pipes_closed_bitmap, sizeof(closedPipes)); 00616 00617 Serial.println((unsigned long)openPipes, HEX); 00618 Serial.println((unsigned long)closedPipes, HEX); 00619 #endif 00620 00621 for (int i = 0; i < this->_numPipeInfo; i++) { 00622 struct pipeInfo* pipeInfo = &this->_pipeInfo[i]; 00623 00624 if (pipeInfo->txPipe) { 00625 pipeInfo->txPipeOpen = lib_aci_is_pipe_available(&this->_aciState, pipeInfo->txPipe); 00626 } 00627 00628 if (pipeInfo->txAckPipe) { 00629 pipeInfo->txAckPipeOpen = lib_aci_is_pipe_available(&this->_aciState, pipeInfo->txAckPipe); 00630 } 00631 00632 bool subscribed = (pipeInfo->txPipeOpen || pipeInfo->txAckPipeOpen); 00633 00634 if (pipeInfo->characteristic->subscribed() != subscribed) { 00635 if (this->_eventListener) { 00636 this->_eventListener->nRF8001CharacteristicSubscribedChanged(*this, *pipeInfo->characteristic, subscribed); 00637 } 00638 } 00639 } 00640 break; 00641 00642 case ACI_EVT_TIMING: 00643 break; 00644 00645 case ACI_EVT_DISCONNECTED: 00646 #ifdef NRF_8001_DEBUG 00647 Serial.println(F("Evt Disconnected/Advertising timed out")); 00648 #endif 00649 // all characteristics unsubscribed on disconnect 00650 for (int i = 0; i < this->_numPipeInfo; i++) { 00651 struct pipeInfo* pipeInfo = &this->_pipeInfo[i]; 00652 00653 if (pipeInfo->characteristic->subscribed()) { 00654 if (this->_eventListener) { 00655 this->_eventListener->nRF8001CharacteristicSubscribedChanged(*this, *pipeInfo->characteristic, false); 00656 } 00657 } 00658 } 00659 00660 if (this->_eventListener) { 00661 this->_eventListener->nRF8001Disconnected(*this); 00662 } 00663 00664 lib_aci_connect(0/* in seconds : 0 means forever */, ADVERTISING_INTERVAL); 00665 #ifdef NRF_8001_DEBUG 00666 Serial.println(F("Advertising started.")); 00667 #endif 00668 break; 00669 00670 case ACI_EVT_DATA_RECEIVED: { 00671 uint8_t dataLen = aciEvt->len - 2; 00672 uint8_t pipe = aciEvt->params.data_received.rx_data.pipe_number; 00673 #ifdef NRF_8001_DEBUG 00674 Serial.print(F("Data Received, pipe = ")); 00675 Serial.println(aciEvt->params.data_received.rx_data.pipe_number, DEC); 00676 00677 for (int i = 0; i < dataLen; i++) { 00678 if ((aciEvt->params.data_received.rx_data.aci_data[i] & 0xf0) == 00) { 00679 Serial.print("0"); 00680 } 00681 00682 Serial.print(aciEvt->params.data_received.rx_data.aci_data[i], HEX); 00683 Serial.print(F(" ")); 00684 } 00685 Serial.println(); 00686 #endif 00687 00688 for (int i = 0; i < this->_numPipeInfo; i++) { 00689 struct pipeInfo* pipeInfo = &this->_pipeInfo[i]; 00690 00691 if (pipeInfo->rxAckPipe == pipe || pipeInfo->rxPipe == pipe) { 00692 if (pipeInfo->rxAckPipe == pipe) { 00693 lib_aci_send_ack(&this->_aciState, pipeInfo->rxAckPipe); 00694 } 00695 00696 if (this->_eventListener) { 00697 this->_eventListener->nRF8001CharacteristicValueChanged(*this, *pipeInfo->characteristic, aciEvt->params.data_received.rx_data.aci_data, dataLen); 00698 } 00699 break; 00700 } 00701 } 00702 } 00703 break; 00704 00705 case ACI_EVT_DATA_CREDIT: 00706 this->_aciState.data_credit_available = this->_aciState.data_credit_available + aciEvt->params.data_credit.credit; 00707 break; 00708 00709 case ACI_EVT_PIPE_ERROR: 00710 //See the appendix in the nRF8001 Product Specication for details on the error codes 00711 #ifdef NRF_8001_DEBUG 00712 Serial.print(F("ACI Evt Pipe Error: Pipe #:")); 00713 Serial.print(aciEvt->params.pipe_error.pipe_number, DEC); 00714 Serial.print(F(" Pipe Error Code: 0x")); 00715 Serial.println(aciEvt->params.pipe_error.error_code, HEX); 00716 #endif 00717 00718 //Increment the credit available as the data packet was not sent. 00719 //The pipe error also represents the Attribute protocol Error Response sent from the peer and that should not be counted 00720 //for the credit. 00721 if (ACI_STATUS_ERROR_PEER_ATT_ERROR != aciEvt->params.pipe_error.error_code) { 00722 this->_aciState.data_credit_available++; 00723 } 00724 break; 00725 00726 case ACI_EVT_HW_ERROR: 00727 #ifdef NRF_8001_DEBUG 00728 Serial.print(F("HW error: ")); 00729 Serial.println(aciEvt->params.hw_error.line_num, DEC); 00730 00731 for(uint8_t counter = 0; counter <= (aciEvt->len - 3); counter++) { 00732 Serial.write(aciEvt->params.hw_error.file_name[counter]); //uint8_t file_name[20]; 00733 } 00734 Serial.println(); 00735 #endif 00736 lib_aci_connect(0/* in seconds, 0 means forever */, ADVERTISING_INTERVAL); 00737 #ifdef NRF_8001_DEBUG 00738 Serial.println(F("Advertising started.")); 00739 #endif 00740 break; 00741 } 00742 } else { 00743 //Serial.println(F("No ACI Events available")); 00744 // No event in the ACI Event queue and if there is no event in the ACI command queue the arduino can go to sleep 00745 // Arduino can go to sleep now 00746 // Wakeup from sleep from the RDYN line 00747 } 00748 } 00749 00750 bool nRF8001::updateCharacteristicValue(BLECharacteristic& characteristic) { 00751 bool success = true; 00752 00753 for (int i = 0; i < this->_numPipeInfo; i++) { 00754 struct pipeInfo* pipeInfo = &this->_pipeInfo[i]; 00755 00756 if (pipeInfo->characteristic == &characteristic) { 00757 if (pipeInfo->setPipe) { 00758 success &= lib_aci_set_local_data(&this->_aciState, pipeInfo->setPipe, (uint8_t*)characteristic.value(), characteristic.valueLength()); 00759 } 00760 00761 if (pipeInfo->txPipe && pipeInfo->txPipeOpen) { 00762 if (this->canNotifyCharacteristic(characteristic)) { 00763 this->_aciState.data_credit_available--; 00764 success &= lib_aci_send_data(pipeInfo->txPipe, (uint8_t*)characteristic.value(), characteristic.valueLength()); 00765 } else { 00766 success = false; 00767 } 00768 } 00769 00770 if (pipeInfo->txAckPipe && pipeInfo->txAckPipeOpen) { 00771 if (this->canIndicateCharacteristic(characteristic)) { 00772 this->_aciState.data_credit_available--; 00773 success &= lib_aci_send_data(pipeInfo->txAckPipe, (uint8_t*)characteristic.value(), characteristic.valueLength()); 00774 } else { 00775 success = false; 00776 } 00777 } 00778 00779 break; 00780 } 00781 } 00782 00783 return success; 00784 } 00785 00786 bool nRF8001::canNotifyCharacteristic(BLECharacteristic& characteristic) { 00787 return (lib_aci_get_nb_available_credits(&this->_aciState) > 0); 00788 } 00789 00790 bool nRF8001::canIndicateCharacteristic(BLECharacteristic& characteristic) { 00791 return (lib_aci_get_nb_available_credits(&this->_aciState) > 0); 00792 } 00793 00794 void nRF8001::disconnect() { 00795 lib_aci_disconnect(&this->_aciState, ACI_REASON_TERMINATE); 00796 } 00797 void nRF8001::requestAddress() { 00798 lib_aci_get_address(); 00799 } 00800 00801 void nRF8001::requestTemperature() { 00802 lib_aci_get_temperature(); 00803 } 00804 00805 void nRF8001::requestBatteryLevel() { 00806 lib_aci_get_battery_level(); 00807 } 00808 00809 void nRF8001::waitForSetupMode() 00810 { 00811 bool setupMode = false; 00812 00813 while (!setupMode) { 00814 if (lib_aci_event_get(&this->_aciState, &this->_aciData)) { 00815 aci_evt_t* aciEvt = &this->_aciData.evt; 00816 00817 switch(aciEvt->evt_opcode) { 00818 case ACI_EVT_DEVICE_STARTED: { 00819 switch(aciEvt->params.device_started.device_mode) { 00820 case ACI_DEVICE_SETUP: 00821 /** 00822 When the device is in the setup mode 00823 */ 00824 #ifdef NRF_8001_DEBUG 00825 Serial.println(F("Evt Device Started: Setup")); 00826 #endif 00827 setupMode = true; 00828 break; 00829 } 00830 } 00831 } 00832 } else { 00833 delay(1); 00834 } 00835 } 00836 } 00837 00838 void nRF8001::sendSetupMessage(hal_aci_data_t* data) 00839 { 00840 this->_crcSeed = crc_16_ccitt(this->_crcSeed, data->buffer, data->buffer[0] + 1); 00841 00842 #ifdef NRF_8001_DEBUG 00843 for (int j = 0; j < (data->buffer[0] + 1); j++) { 00844 if ((data->buffer[j] & 0xf0) == 00) { 00845 Serial.print("0"); 00846 } 00847 00848 Serial.print(data->buffer[j], HEX); 00849 Serial.print(" "); 00850 } 00851 Serial.println(); 00852 #endif 00853 00854 hal_aci_tl_send(data); 00855 00856 bool setupMsgSent = false; 00857 00858 while (!setupMsgSent) { 00859 if (lib_aci_event_get(&this->_aciState, &this->_aciData)) { 00860 aci_evt_t* aciEvt = &this->_aciData.evt; 00861 00862 switch(aciEvt->evt_opcode) { 00863 case ACI_EVT_CMD_RSP: { 00864 switch(aciEvt->params.cmd_rsp.cmd_status) { 00865 case ACI_STATUS_TRANSACTION_CONTINUE: 00866 #ifdef NRF_8001_DEBUG 00867 Serial.println(F("Evt Cmd Rsp: Transaction Continue")); 00868 #endif 00869 setupMsgSent = true; 00870 break; 00871 } 00872 } 00873 } 00874 } else { 00875 delay(1); 00876 } 00877 } 00878 } 00879 00880 void nRF8001::sendCrc() 00881 { 00882 hal_aci_data_t data; 00883 data.status_byte = 0; 00884 00885 data.buffer[0] = 3 + 3; 00886 data.buffer[1] = ACI_CMD_SETUP; 00887 data.buffer[2] = 0xf0; 00888 data.buffer[3] = 0x00; 00889 00890 data.buffer[4] = 0x03; 00891 00892 this->_crcSeed = crc_16_ccitt(this->_crcSeed, data.buffer, data.buffer[0] - 1); 00893 00894 data.buffer[5] = (this->_crcSeed >> 8) & 0xff; 00895 data.buffer[6] = this->_crcSeed & 0xff; 00896 00897 #ifdef NRF_8001_DEBUG 00898 for (int j = 0; j < (data.buffer[0] + 1); j++) { 00899 if ((data.buffer[j] & 0xf0) == 00) { 00900 Serial.print("0"); 00901 } 00902 00903 Serial.print(data.buffer[j], HEX); 00904 Serial.print(" "); 00905 } 00906 Serial.println(); 00907 #endif 00908 00909 hal_aci_tl_send(&data); 00910 00911 bool setupMsgSent = false; 00912 00913 while (!setupMsgSent) { 00914 if (lib_aci_event_get(&this->_aciState, &this->_aciData)) { 00915 aci_evt_t* aciEvt = &this->_aciData.evt; 00916 00917 switch(aciEvt->evt_opcode) { 00918 case ACI_EVT_CMD_RSP: { 00919 switch(aciEvt->params.cmd_rsp.cmd_status) { 00920 case ACI_STATUS_TRANSACTION_COMPLETE: 00921 #ifdef NRF_8001_DEBUG 00922 Serial.println(F("Evt Cmd Rsp: Transaction Complete")); 00923 #endif 00924 setupMsgSent = true; 00925 break; 00926 } 00927 } 00928 } 00929 } else { 00930 delay(1); 00931 } 00932 } 00933 }
Generated on Tue Jul 12 2022 15:15:46 by 1.7.2