Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sensor_service.c
00001 /** 00002 ****************************************************************************** 00003 * @file sensor_service.c 00004 * @author MCD Application Team 00005 * @version V1.0.0 00006 * @date 04-July-2014 00007 * @brief Add a sample service using a vendor specific profile. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> 00012 * 00013 * Redistribution and use in source and binary forms, with or without modification, 00014 * are permitted provided that the following conditions are met: 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 2. Redistributions in binary form must reproduce the above copyright notice, 00018 * this list of conditions and the following disclaimer in the documentation 00019 * and/or other materials provided with the distribution. 00020 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00021 * may be used to endorse or promote products derived from this software 00022 * without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00028 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00029 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 ****************************************************************************** 00036 */ 00037 #include "sensor_service.h " 00038 00039 /* Private variables ---------------------------------------------------------*/ 00040 volatile int connected = FALSE; 00041 volatile uint8_t set_connectable = 1; 00042 volatile uint16_t connection_handle = 0; 00043 volatile uint8_t notification_enabled = FALSE; 00044 volatile AxesRaw_t axes_data = {0, 0, 0}; 00045 uint16_t sampleServHandle, TXCharHandle, RXCharHandle; 00046 uint16_t accServHandle, freeFallCharHandle, accCharHandle; 00047 uint16_t envSensServHandle, tempCharHandle, pressCharHandle, humidityCharHandle; 00048 00049 #define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ 00050 do {\ 00051 uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ 00052 uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ 00053 uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ 00054 uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ 00055 }while(0) 00056 00057 #define COPY_ACC_SERVICE_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0x02,0x36,0x6e,0x80, 0xcf,0x3a, 0x11,0xe1, 0x9a,0xb4, 0x00,0x02,0xa5,0xd5,0xc5,0x1b) 00058 #define COPY_FREE_FALL_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0xe2,0x3e,0x78,0xa0, 0xcf,0x4a, 0x11,0xe1, 0x8f,0xfc, 0x00,0x02,0xa5,0xd5,0xc5,0x1b) 00059 #define COPY_ACC_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0x34,0x0a,0x1b,0x80, 0xcf,0x4b, 0x11,0xe1, 0xac,0x36, 0x00,0x02,0xa5,0xd5,0xc5,0x1b) 00060 00061 #define COPY_ENV_SENS_SERVICE_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0x42,0x82,0x1a,0x40, 0xe4,0x77, 0x11,0xe2, 0x82,0xd0, 0x00,0x02,0xa5,0xd5,0xc5,0x1b) 00062 #define COPY_TEMP_CHAR_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0xa3,0x2e,0x55,0x20, 0xe4,0x77, 0x11,0xe2, 0xa9,0xe3, 0x00,0x02,0xa5,0xd5,0xc5,0x1b) 00063 #define COPY_PRESS_CHAR_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0xcd,0x20,0xc4,0x80, 0xe4,0x8b, 0x11,0xe2, 0x84,0x0b, 0x00,0x02,0xa5,0xd5,0xc5,0x1b) 00064 #define COPY_HUMIDITY_CHAR_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0x01,0xc5,0x0b,0x60, 0xe4,0x8c, 0x11,0xe2, 0xa0,0x73, 0x00,0x02,0xa5,0xd5,0xc5,0x1b) 00065 00066 /* Store Value into a buffer in Little Endian Format */ 00067 #define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ 00068 ((buf)[1] = (uint8_t) (val>>8) ) ) 00069 00070 /** 00071 * @brief Add an accelerometer service using a vendor specific profile. 00072 * 00073 * @param None 00074 * @retval tBleStatus Status 00075 */ 00076 tBleStatus Add_Acc_Service(void) 00077 { 00078 tBleStatus ret; 00079 00080 uint8_t uuid[16]; 00081 00082 COPY_ACC_SERVICE_UUID(uuid); 00083 ret = aci_gatt_add_serv(UUID_TYPE_128, uuid, PRIMARY_SERVICE, 7, 00084 &accServHandle); 00085 if (ret != BLE_STATUS_SUCCESS) goto fail; 00086 00087 COPY_FREE_FALL_UUID(uuid); 00088 ret = aci_gatt_add_char(accServHandle, UUID_TYPE_128, uuid, 1, 00089 CHAR_PROP_NOTIFY, ATTR_PERMISSION_NONE, 0, 00090 16, 0, &freeFallCharHandle); 00091 if (ret != BLE_STATUS_SUCCESS) goto fail; 00092 00093 COPY_ACC_UUID(uuid); 00094 ret = aci_gatt_add_char(accServHandle, UUID_TYPE_128, uuid, 6, 00095 CHAR_PROP_NOTIFY|CHAR_PROP_READ, 00096 ATTR_PERMISSION_NONE, 00097 GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP, 00098 16, 0, &accCharHandle); 00099 if (ret != BLE_STATUS_SUCCESS) goto fail; 00100 00101 PRINTF("Service ACC added. Handle 0x%04X, Free fall Charac handle: 0x%04X, Acc Charac handle: 0x%04X\n",accServHandle, freeFallCharHandle, accCharHandle); 00102 return BLE_STATUS_SUCCESS; 00103 00104 fail: 00105 PRINTF("Error while adding ACC service.\n"); 00106 return BLE_STATUS_ERROR ; 00107 00108 } 00109 00110 /** 00111 * @brief Send a notification for a Free Fall detection. 00112 * 00113 * @param None 00114 * @retval tBleStatus Status 00115 */ 00116 tBleStatus Free_Fall_Notify(void) 00117 { 00118 uint8_t val; 00119 tBleStatus ret; 00120 00121 val = 0x01; 00122 ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, 00123 &val); 00124 00125 if (ret != BLE_STATUS_SUCCESS){ 00126 PRINTF("Error while updating ACC characteristic.\n") ; 00127 return BLE_STATUS_ERROR ; 00128 } 00129 return BLE_STATUS_SUCCESS; 00130 } 00131 00132 /** 00133 * @brief Update acceleration characteristic value. 00134 * 00135 * @param Structure containing acceleration value in mg 00136 * @retval Status 00137 */ 00138 tBleStatus Acc_Update(AxesRaw_t *data) 00139 { 00140 tBleStatus ret; 00141 uint8_t buff[6]; 00142 00143 STORE_LE_16(buff,data->AXIS_X); 00144 STORE_LE_16(buff+2,data->AXIS_Y); 00145 STORE_LE_16(buff+4,data->AXIS_Z); 00146 00147 ret = aci_gatt_update_char_value(accServHandle, accCharHandle, 0, 6, buff); 00148 00149 if (ret != BLE_STATUS_SUCCESS){ 00150 PRINTF("Error while updating ACC characteristic.\n") ; 00151 return BLE_STATUS_ERROR ; 00152 } 00153 return BLE_STATUS_SUCCESS; 00154 } 00155 00156 /** 00157 * @brief Add the Environmental Sensor service. 00158 * 00159 * @param None 00160 * @retval Status 00161 */ 00162 tBleStatus Add_Environmental_Sensor_Service(void) 00163 { 00164 tBleStatus ret; 00165 uint8_t uuid[16]; 00166 uint16_t uuid16; 00167 charactFormat charFormat; 00168 uint16_t descHandle; 00169 00170 COPY_ENV_SENS_SERVICE_UUID(uuid); 00171 ret = aci_gatt_add_serv(UUID_TYPE_128, uuid, PRIMARY_SERVICE, 10, 00172 &envSensServHandle); 00173 if (ret != BLE_STATUS_SUCCESS) goto fail; 00174 00175 /* Temperature Characteristic */ 00176 COPY_TEMP_CHAR_UUID(uuid); 00177 ret = aci_gatt_add_char(envSensServHandle, UUID_TYPE_128, uuid, 2, 00178 CHAR_PROP_READ, ATTR_PERMISSION_NONE, 00179 GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP, 00180 16, 0, &tempCharHandle); 00181 if (ret != BLE_STATUS_SUCCESS) goto fail; 00182 00183 charFormat.format = FORMAT_SINT16; 00184 charFormat.exp = -1; 00185 charFormat.unit = UNIT_TEMP_CELSIUS; 00186 charFormat.name_space = 0; 00187 charFormat.desc = 0; 00188 00189 uuid16 = CHAR_FORMAT_DESC_UUID; 00190 00191 ret = aci_gatt_add_char_desc(envSensServHandle, 00192 tempCharHandle, 00193 UUID_TYPE_16, 00194 (uint8_t *)&uuid16, 00195 7, 00196 7, 00197 (void *)&charFormat, 00198 ATTR_PERMISSION_NONE, 00199 ATTR_ACCESS_READ_ONLY, 00200 0, 00201 16, 00202 FALSE, 00203 &descHandle); 00204 if (ret != BLE_STATUS_SUCCESS) goto fail; 00205 00206 /* Pressure Characteristic */ 00207 if(1){ //FIXME 00208 COPY_PRESS_CHAR_UUID(uuid); 00209 ret = aci_gatt_add_char(envSensServHandle, UUID_TYPE_128, uuid, 3, 00210 CHAR_PROP_READ, ATTR_PERMISSION_NONE, 00211 GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP, 00212 16, 0, &pressCharHandle); 00213 if (ret != BLE_STATUS_SUCCESS) goto fail; 00214 00215 charFormat.format = FORMAT_SINT24; 00216 charFormat.exp = -5; 00217 charFormat.unit = UNIT_PRESSURE_BAR; 00218 charFormat.name_space = 0; 00219 charFormat.desc = 0; 00220 00221 uuid16 = CHAR_FORMAT_DESC_UUID; 00222 00223 ret = aci_gatt_add_char_desc(envSensServHandle, 00224 pressCharHandle, 00225 UUID_TYPE_16, 00226 (uint8_t *)&uuid16, 00227 7, 00228 7, 00229 (void *)&charFormat, 00230 ATTR_PERMISSION_NONE, 00231 ATTR_ACCESS_READ_ONLY, 00232 0, 00233 16, 00234 FALSE, 00235 &descHandle); 00236 if (ret != BLE_STATUS_SUCCESS) goto fail; 00237 } 00238 /* Humidity Characteristic */ 00239 if(1){ //FIXME 00240 COPY_HUMIDITY_CHAR_UUID(uuid); 00241 ret = aci_gatt_add_char(envSensServHandle, UUID_TYPE_128, uuid, 2, 00242 CHAR_PROP_READ, ATTR_PERMISSION_NONE, 00243 GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP, 00244 16, 0, &humidityCharHandle); 00245 if (ret != BLE_STATUS_SUCCESS) goto fail; 00246 00247 charFormat.format = FORMAT_UINT16; 00248 charFormat.exp = -1; 00249 charFormat.unit = UNIT_UNITLESS; 00250 charFormat.name_space = 0; 00251 charFormat.desc = 0; 00252 00253 uuid16 = CHAR_FORMAT_DESC_UUID; 00254 00255 ret = aci_gatt_add_char_desc(envSensServHandle, 00256 humidityCharHandle, 00257 UUID_TYPE_16, 00258 (uint8_t *)&uuid16, 00259 7, 00260 7, 00261 (void *)&charFormat, 00262 ATTR_PERMISSION_NONE, 00263 ATTR_ACCESS_READ_ONLY, 00264 0, 00265 16, 00266 FALSE, 00267 &descHandle); 00268 if (ret != BLE_STATUS_SUCCESS) goto fail; 00269 } 00270 PRINTF("Service ENV_SENS added. Handle 0x%04X, TEMP Charac handle: 0x%04X, PRESS Charac handle: 0x%04X, HUMID Charac handle: 0x%04X\n",envSensServHandle, tempCharHandle, pressCharHandle, humidityCharHandle); 00271 return BLE_STATUS_SUCCESS; 00272 00273 fail: 00274 PRINTF("Error while adding ENV_SENS service.\n"); 00275 return BLE_STATUS_ERROR ; 00276 00277 } 00278 00279 /** 00280 * @brief Update temperature characteristic value. 00281 * @param Temperature in tenths of degree 00282 * @retval Status 00283 */ 00284 tBleStatus Temp_Update(int16_t temp) 00285 { 00286 tBleStatus ret; 00287 00288 ret = aci_gatt_update_char_value(envSensServHandle, tempCharHandle, 0, 2, 00289 (uint8_t*)&temp); 00290 00291 if (ret != BLE_STATUS_SUCCESS){ 00292 PRINTF("Error while updating TEMP characteristic.\n") ; 00293 return BLE_STATUS_ERROR ; 00294 } 00295 return BLE_STATUS_SUCCESS; 00296 00297 } 00298 00299 /** 00300 * @brief Update pressure characteristic value. 00301 * @param int32_t Pressure in mbar 00302 * @retval tBleStatus Status 00303 */ 00304 tBleStatus Press_Update(int32_t press) 00305 { 00306 tBleStatus ret; 00307 00308 ret = aci_gatt_update_char_value(envSensServHandle, pressCharHandle, 0, 3, 00309 (uint8_t*)&press); 00310 00311 if (ret != BLE_STATUS_SUCCESS){ 00312 PRINTF("Error while updating TEMP characteristic.\n") ; 00313 return BLE_STATUS_ERROR ; 00314 } 00315 return BLE_STATUS_SUCCESS; 00316 00317 } 00318 00319 /** 00320 * @brief Update humidity characteristic value. 00321 * @param uint16_thumidity RH (Relative Humidity) in thenths of % 00322 * @retval tBleStatus Status 00323 */ 00324 tBleStatus Humidity_Update(uint16_t humidity) 00325 { 00326 tBleStatus ret; 00327 00328 ret = aci_gatt_update_char_value(envSensServHandle, humidityCharHandle, 0, 2, 00329 (uint8_t*)&humidity); 00330 00331 if (ret != BLE_STATUS_SUCCESS){ 00332 PRINTF("Error while updating TEMP characteristic.\n") ; 00333 return BLE_STATUS_ERROR ; 00334 } 00335 return BLE_STATUS_SUCCESS; 00336 00337 } 00338 00339 /** 00340 * @brief Puts the device in connectable mode. 00341 * If you want to specify a UUID list in the advertising data, those data can 00342 * be specified as a parameter in aci_gap_set_discoverable(). 00343 * For manufacture data, aci_gap_update_adv_data must be called. 00344 * @param None 00345 * @retval None 00346 */ 00347 /* Ex.: 00348 * 00349 * tBleStatus ret; 00350 * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; 00351 * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; 00352 * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; 00353 * 00354 * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, PUBLIC_ADDR, NO_WHITE_LIST_USE, 00355 * 8, local_name, 3, serviceUUIDList, 0, 0); 00356 * ret = aci_gap_update_adv_data(5, manuf_data); 00357 * 00358 */ 00359 void setConnectable(void) 00360 { 00361 tBleStatus ret; 00362 00363 const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; 00364 00365 /* disable scan response */ 00366 hci_le_set_scan_resp_data(0,NULL); 00367 PRINTF("General Discoverable Mode.\n"); 00368 00369 ret = aci_gap_set_discoverable(ADV_IND, 0, 0, PUBLIC_ADDR, NO_WHITE_LIST_USE, 00370 sizeof(local_name), local_name, 0, NULL, 0, 0); 00371 PRINTF("%d\n",ret); 00372 } 00373 00374 /** 00375 * @brief This function is called when there is a LE Connection Complete event. 00376 * @param uint8_t Address of peer device 00377 * @param uint16_t Connection handle 00378 * @retval None 00379 */ 00380 void GAP_ConnectionComplete_CB(uint8_t addr[6], uint16_t handle) 00381 { 00382 connected = TRUE; 00383 connection_handle = handle; 00384 00385 PRINTF("Connected to device:"); 00386 for(int i = 5; i > 0; i--){ 00387 PRINTF("%02X-", addr[i]); 00388 } 00389 PRINTF("%02X\n", addr[0]); 00390 } 00391 00392 /** 00393 * @brief This function is called when the peer device get disconnected. 00394 * @param None 00395 * @retval None 00396 */ 00397 void GAP_DisconnectionComplete_CB(void) 00398 { 00399 connected = FALSE; 00400 PRINTF("Disconnected\n"); 00401 /* Make the device connectable again. */ 00402 set_connectable = TRUE; 00403 notification_enabled = FALSE; 00404 } 00405 00406 /** 00407 * @brief Read request callback. 00408 * @param uint16_t Handle of the attribute 00409 * @retval None 00410 */ 00411 void Read_Request_CB(uint16_t handle) 00412 { 00413 //signed short refvalue; 00414 00415 if(handle == accCharHandle + 1){ 00416 Acc_Update((AxesRaw_t*)&axes_data); 00417 } 00418 else if(handle == tempCharHandle + 1){ 00419 int16_t data; 00420 data = 270 + ((uint64_t)rand()*15)/RAND_MAX; //sensor emulation 00421 Acc_Update((AxesRaw_t*)&axes_data); //FIXME: to overcome issue on Android App 00422 // If the user button is not pressed within 00423 // a short time after the connection, 00424 // a pop-up reports a "No valid characteristics found" error. 00425 Temp_Update(data); 00426 } 00427 else if(handle == pressCharHandle + 1){ 00428 int32_t data; 00429 struct timer t; 00430 Timer_Set(&t, CLOCK_SECOND/10); 00431 data = 100000 + ((uint64_t)rand()*1000)/RAND_MAX; 00432 Press_Update(data); 00433 } 00434 else if(handle == humidityCharHandle + 1){ 00435 uint16_t data; 00436 00437 data = 450 + ((uint64_t)rand()*100)/RAND_MAX; 00438 00439 Humidity_Update(data); 00440 } 00441 00442 //EXIT: 00443 if(connection_handle != 0) 00444 aci_gatt_allow_read(connection_handle); 00445 } 00446 00447 /** 00448 * @brief Callback processing the ACI events. 00449 * @note Inside this function each event must be identified and correctly 00450 * parsed. 00451 * @param void* Pointer to the ACI packet 00452 * @retval None 00453 */ 00454 void HCI_Event_CB(void *pckt) 00455 { 00456 hci_uart_pckt *hci_pckt = pckt; 00457 /* obtain event packet */ 00458 hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; 00459 00460 if(hci_pckt->type != HCI_EVENT_PKT) 00461 return; 00462 00463 switch(event_pckt->evt){ 00464 00465 case EVT_DISCONN_COMPLETE: 00466 { 00467 GAP_DisconnectionComplete_CB(); 00468 } 00469 break; 00470 00471 case EVT_LE_META_EVENT: 00472 { 00473 evt_le_meta_event *evt = (void *)event_pckt->data; 00474 00475 switch(evt->subevent){ 00476 case EVT_LE_CONN_COMPLETE: 00477 { 00478 evt_le_connection_complete *cc = (void *)evt->data; 00479 GAP_ConnectionComplete_CB(cc->peer_bdaddr, cc->handle); 00480 } 00481 break; 00482 } 00483 } 00484 break; 00485 00486 case EVT_VENDOR: 00487 { 00488 evt_blue_aci *blue_evt = (void*)event_pckt->data; 00489 switch(blue_evt->ecode){ 00490 00491 case EVT_BLUE_GATT_READ_PERMIT_REQ: 00492 { 00493 evt_gatt_read_permit_req *pr = (void*)blue_evt->data; 00494 Read_Request_CB(pr->attr_handle); 00495 } 00496 break; 00497 } 00498 } 00499 break; 00500 } 00501 } 00502 00503 /** 00504 * @} 00505 */ 00506 00507 /** 00508 * @} 00509 */ 00510 00511 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 00512
Generated on Tue Jul 12 2022 17:28:29 by
1.7.2