Filippo Casamassima / Nucleo_blueNRG

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bluenrg_gatt_aci.c Source File

bluenrg_gatt_aci.c

00001 /******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
00002 * File Name          : bluenrg_gatt_aci.c
00003 * Author             : AMS - AAS
00004 * Version            : V1.0.0
00005 * Date               : 26-Jun-2014
00006 * Description        : File with GATT commands for BlueNRG FW6.3.
00007 ********************************************************************************
00008 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00009 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
00010 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
00011 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
00012 * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
00013 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00014 *******************************************************************************/
00015 
00016 #include "hal_types.h"
00017 #include "osal.h"
00018 #include "ble_status.h"
00019 #include "hal.h"
00020 #include "osal.h"
00021 #include "hci_const.h"
00022 #include "bluenrg_aci_const.h"
00023 #include "bluenrg_gatt_aci.h"
00024 #include "gatt_server.h"
00025 #include "gap.h"
00026 
00027 #define MIN(a,b)            ((a) < (b) )? (a) : (b)
00028 #define MAX(a,b)            ((a) > (b) )? (a) : (b)
00029 
00030 
00031 tBleStatus aci_gatt_init(void)
00032 {
00033   struct hci_request rq;
00034   uint8_t status;
00035 
00036   Osal_MemSet(&rq, 0, sizeof(rq));
00037   rq.ogf = OGF_VENDOR_CMD;
00038   rq.ocf = OCF_GATT_INIT;
00039   rq.rparam = &status;
00040   rq.rlen = 1;
00041 
00042   if (hci_send_req(&rq) < 0)
00043     return BLE_STATUS_TIMEOUT;
00044 
00045   return status;
00046 }
00047 
00048 tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle)
00049 {
00050   struct hci_request rq;
00051   gatt_add_serv_rp resp;    
00052   uint8_t buffer[19];
00053   uint8_t uuid_len;
00054   uint8_t indx = 0;
00055     
00056   buffer[indx] = service_uuid_type;
00057   indx++;
00058     
00059   if(service_uuid_type == 0x01){
00060     uuid_len = 2;
00061   }
00062   else {
00063     uuid_len = 16;
00064   }        
00065   Osal_MemCpy(buffer + indx, service_uuid, uuid_len);
00066   indx +=  uuid_len;
00067     
00068   buffer[indx] = service_type;
00069   indx++;
00070     
00071   buffer[indx] = max_attr_records;
00072   indx++;
00073     
00074     
00075   Osal_MemSet(&resp, 0, sizeof(resp));
00076 
00077   Osal_MemSet(&rq, 0, sizeof(rq));
00078   rq.ogf = OGF_VENDOR_CMD;
00079   rq.ocf = OCF_GATT_ADD_SERV;
00080   rq.cparam = (void *)buffer;
00081   rq.clen = indx;
00082   rq.rparam = &resp;
00083   rq.rlen = GATT_ADD_SERV_RP_SIZE;
00084 
00085   if (hci_send_req(&rq) < 0)
00086     return BLE_STATUS_TIMEOUT;
00087 
00088   if (resp.status) {
00089     return resp.status;
00090   }
00091     
00092   *serviceHandle = btohs(resp.handle);
00093 
00094   return 0;
00095 }
00096 
00097 tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle,
00098                     uint16_t included_end_handle, uint8_t included_uuid_type,
00099                     const uint8_t* included_uuid, uint16_t *included_handle)
00100 {
00101   struct hci_request rq;
00102   gatt_include_serv_rp resp;    
00103   uint8_t buffer[23];
00104   uint8_t uuid_len;
00105   uint8_t indx = 0;
00106 
00107   service_handle = htobs(service_handle);
00108   Osal_MemCpy(buffer, &service_handle, 2);
00109   indx += 2;
00110     
00111   included_start_handle = htobs(included_start_handle);
00112   Osal_MemCpy(buffer+indx, &included_start_handle, 2);
00113   indx += 2;
00114 
00115   included_end_handle = htobs(included_end_handle);
00116   Osal_MemCpy(buffer+indx, &included_end_handle, 2);
00117   indx += 2;
00118 
00119   if(included_uuid_type == 0x01){
00120     uuid_len = 2;
00121   } else {
00122     uuid_len = 16;
00123   }        
00124 
00125   buffer[indx] = included_uuid_type;
00126   indx++;
00127 
00128   Osal_MemCpy(buffer + indx, included_uuid, uuid_len);
00129   indx += uuid_len;
00130     
00131   Osal_MemSet(&resp, 0, sizeof(resp));
00132 
00133   Osal_MemSet(&rq, 0, sizeof(rq));
00134   rq.ogf = OGF_VENDOR_CMD;
00135   rq.ocf = OCF_GATT_INCLUDE_SERV;
00136   rq.cparam = (void *)buffer;
00137   rq.clen = indx;
00138   rq.rparam = &resp;
00139   rq.rlen = GATT_INCLUDE_SERV_RP_SIZE;
00140 
00141   if (hci_send_req(&rq) < 0)
00142     return BLE_STATUS_TIMEOUT;
00143 
00144   if (resp.status) {
00145     return resp.status;
00146   }
00147     
00148   *included_handle = btohs(resp.handle);
00149 
00150   return 0;
00151 }
00152 
00153 tBleStatus aci_gatt_add_char(uint16_t serviceHandle,
00154                  uint8_t charUuidType,
00155                  const uint8_t* charUuid, 
00156                  uint8_t charValueLen, 
00157                  uint8_t charProperties,
00158                  uint8_t secPermissions,
00159                  uint8_t gattEvtMask,
00160                  uint8_t encryKeySize,
00161                  uint8_t isVariable,
00162                  uint16_t* charHandle)                     
00163 {
00164   struct hci_request rq;
00165   gatt_add_serv_rp resp;
00166   uint8_t buffer[25];
00167   uint8_t uuid_len;
00168   uint8_t indx = 0;
00169     
00170   serviceHandle = htobs(serviceHandle);
00171   Osal_MemCpy(buffer + indx, &serviceHandle, 2);
00172   indx += 2;
00173     
00174   buffer[indx] = charUuidType;
00175   indx++;
00176     
00177   if(charUuidType == 0x01){
00178     uuid_len = 2;
00179   }
00180   else {
00181     uuid_len = 16;
00182   }        
00183   Osal_MemCpy(buffer + indx, charUuid, uuid_len);
00184   indx +=  uuid_len;
00185     
00186   buffer[indx] = charValueLen;
00187   indx++;
00188     
00189   buffer[indx] = charProperties;
00190   indx++;
00191     
00192   buffer[indx] = secPermissions;
00193   indx++;
00194     
00195   buffer[indx] = gattEvtMask;
00196   indx++;
00197     
00198   buffer[indx] = encryKeySize;
00199   indx++;
00200     
00201   buffer[indx] = isVariable;
00202   indx++;
00203     
00204   Osal_MemSet(&resp, 0, sizeof(resp));
00205 
00206   Osal_MemSet(&rq, 0, sizeof(rq));
00207   rq.ogf = OGF_VENDOR_CMD;
00208   rq.ocf = OCF_GATT_ADD_CHAR;
00209   rq.cparam = (void *)buffer;
00210   rq.clen = indx;
00211   rq.rparam = &resp;
00212   rq.rlen = GATT_ADD_CHAR_RP_SIZE;
00213 
00214   if (hci_send_req(&rq) < 0)
00215     return BLE_STATUS_TIMEOUT;
00216 
00217   if (resp.status) {
00218     return resp.status;
00219   }
00220     
00221   *charHandle = btohs(resp.handle);
00222 
00223   return 0;
00224 }
00225 
00226 tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle,
00227                                   uint16_t charHandle,
00228                                   uint8_t descUuidType,
00229                                   const uint8_t* uuid, 
00230                                   uint8_t descValueMaxLen,
00231                                   uint8_t descValueLen,
00232                                   const void* descValue, 
00233                                   uint8_t secPermissions,
00234                                   uint8_t accPermissions,
00235                                   uint8_t gattEvtMask,
00236                                   uint8_t encryKeySize,
00237                                   uint8_t isVariable,
00238                                   uint16_t* descHandle)                     
00239 {
00240   struct hci_request rq;
00241   gatt_add_char_desc_rp resp;
00242   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00243   uint8_t uuid_len;
00244   uint8_t indx = 0;
00245     
00246   serviceHandle = htobs(serviceHandle);
00247   Osal_MemCpy(buffer + indx, &serviceHandle, 2);
00248   indx += 2;
00249     
00250   charHandle = htobs(charHandle);
00251   Osal_MemCpy(buffer + indx, &charHandle, 2);
00252   indx += 2;
00253     
00254   buffer[indx] = descUuidType;
00255   indx++;
00256     
00257   if(descUuidType == 0x01){
00258     uuid_len = 2;
00259   }
00260   else {
00261     uuid_len = 16;
00262   }        
00263   Osal_MemCpy(buffer + indx, uuid, uuid_len);
00264   indx +=  uuid_len;
00265     
00266   buffer[indx] = descValueMaxLen;
00267   indx++;
00268     
00269   buffer[indx] = descValueLen;
00270   indx++;
00271 
00272   if ((descValueLen+indx+5) > HCI_MAX_PACKET_SIZE)
00273     return BLE_STATUS_INVALID_PARAMS;
00274   
00275   Osal_MemCpy(buffer + indx, descValue, descValueLen);
00276   indx += descValueLen;
00277     
00278   buffer[indx] = secPermissions;
00279   indx++;
00280     
00281   buffer[indx] = accPermissions;
00282   indx++;
00283     
00284   buffer[indx] = gattEvtMask;
00285   indx++;
00286     
00287   buffer[indx] = encryKeySize;
00288   indx++;
00289     
00290   buffer[indx] = isVariable;
00291   indx++;
00292     
00293   Osal_MemSet(&resp, 0, sizeof(resp));
00294 
00295   Osal_MemSet(&rq, 0, sizeof(rq));
00296   rq.ogf = OGF_VENDOR_CMD;
00297   rq.ocf = OCF_GATT_ADD_CHAR_DESC;
00298   rq.cparam = (void *)buffer;
00299   rq.clen = indx;
00300   rq.rparam = &resp;
00301   rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE;
00302 
00303   if (hci_send_req(&rq) < 0)
00304     return BLE_STATUS_TIMEOUT;
00305 
00306   if (resp.status) {
00307     return resp.status;
00308   }
00309     
00310   *descHandle = btohs(resp.handle);
00311 
00312   return 0;
00313 }
00314 
00315 
00316 tBleStatus aci_gatt_update_char_value(uint16_t servHandle, 
00317                       uint16_t charHandle,
00318                       uint8_t charValOffset,
00319                       uint8_t charValueLen,   
00320                       const uint8_t *charValue)
00321 {
00322   struct hci_request rq;
00323   uint8_t status;
00324   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00325   uint8_t indx = 0;
00326     
00327   if ((charValueLen+6) > HCI_MAX_PACKET_SIZE)
00328     return BLE_STATUS_INVALID_PARAMS;
00329 
00330   servHandle = htobs(servHandle);
00331   Osal_MemCpy(buffer + indx, &servHandle, 2);
00332   indx += 2;
00333     
00334   charHandle = htobs(charHandle);
00335   Osal_MemCpy(buffer + indx, &charHandle, 2);
00336   indx += 2;
00337     
00338   buffer[indx] = charValOffset;
00339   indx++;
00340     
00341   buffer[indx] = charValueLen;
00342   indx++;
00343         
00344   Osal_MemCpy(buffer + indx, charValue, charValueLen);
00345   indx +=  charValueLen;
00346 
00347   Osal_MemSet(&rq, 0, sizeof(rq));
00348   rq.ogf = OGF_VENDOR_CMD;
00349   rq.ocf = OCF_GATT_UPD_CHAR_VAL;
00350   rq.cparam = (void *)buffer;
00351   rq.clen = indx;
00352   rq.rparam = &status;
00353   rq.rlen = 1;
00354 
00355   if (hci_send_req(&rq) < 0)
00356     return BLE_STATUS_TIMEOUT;
00357 
00358   if (status) {
00359     return status;
00360   }
00361 
00362   return 0;
00363 }
00364 
00365 tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle)
00366 {
00367   struct hci_request rq;
00368   uint8_t status;
00369   gatt_del_char_cp cp;
00370 
00371   cp.service_handle = htobs(servHandle);
00372   cp.char_handle = htobs(charHandle);
00373 
00374   Osal_MemSet(&rq, 0, sizeof(rq));
00375   rq.ogf = OGF_VENDOR_CMD;
00376   rq.ocf = OCF_GATT_DEL_CHAR;
00377   rq.cparam = &cp;
00378   rq.clen = GATT_DEL_CHAR_CP_SIZE;
00379   rq.rparam = &status;
00380   rq.rlen = 1;
00381 
00382   if (hci_send_req(&rq) < 0)
00383     return BLE_STATUS_TIMEOUT;
00384 
00385   return status;
00386 }
00387                                       
00388 tBleStatus aci_gatt_del_service(uint16_t servHandle)
00389 {
00390   struct hci_request rq;
00391   uint8_t status;
00392   gatt_del_serv_cp cp;
00393 
00394   cp.service_handle = htobs(servHandle);
00395 
00396   Osal_MemSet(&rq, 0, sizeof(rq));
00397   rq.ogf = OGF_VENDOR_CMD;
00398   rq.ocf = OCF_GATT_DEL_SERV;
00399   rq.cparam = &cp;
00400   rq.clen = GATT_DEL_SERV_CP_SIZE;
00401   rq.rparam = &status;
00402   rq.rlen = 1;
00403 
00404   if (hci_send_req(&rq) < 0)
00405     return BLE_STATUS_TIMEOUT;
00406 
00407   return status;
00408 }
00409 
00410 tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle)
00411 {
00412   struct hci_request rq;
00413   uint8_t status;
00414   gatt_del_inc_serv_cp cp;
00415 
00416   cp.service_handle = htobs(servHandle);
00417   cp.inc_serv_handle = htobs(includeServHandle);
00418 
00419   Osal_MemSet(&rq, 0, sizeof(rq));
00420   rq.ogf = OGF_VENDOR_CMD;
00421   rq.ocf = OCF_GATT_DEL_INC_SERV;
00422   rq.cparam = &cp;
00423   rq.clen = GATT_DEL_INC_SERV_CP_SIZE;
00424   rq.rparam = &status;
00425   rq.rlen = 1;
00426 
00427   if (hci_send_req(&rq) < 0)
00428     return BLE_STATUS_TIMEOUT;
00429 
00430   return status;
00431 }
00432 
00433 tBleStatus aci_gatt_set_event_mask(uint32_t event_mask)
00434 {
00435   struct hci_request rq;
00436   uint8_t status;
00437   gatt_set_evt_mask_cp cp;
00438 
00439   cp.evt_mask = htobs(event_mask);
00440 
00441   Osal_MemSet(&rq, 0, sizeof(rq));
00442   rq.ogf = OGF_VENDOR_CMD;
00443   rq.ocf = OCF_GATT_SET_EVT_MASK;
00444   rq.cparam = &cp;
00445   rq.clen = GATT_SET_EVT_MASK_CP_SIZE;
00446   rq.rparam = &status;
00447   rq.rlen = 1;
00448 
00449   if (hci_send_req(&rq) < 0)
00450     return BLE_STATUS_TIMEOUT;
00451 
00452   return status;
00453 }
00454   
00455 tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle)
00456 {
00457   struct hci_request rq;
00458   uint8_t status;
00459   gatt_exchange_config_cp cp;
00460 
00461   cp.conn_handle = htobs(conn_handle);
00462 
00463   Osal_MemSet(&rq, 0, sizeof(rq));
00464   rq.ogf = OGF_VENDOR_CMD;
00465   rq.ocf = OCF_GATT_EXCHANGE_CONFIG;
00466   rq.cparam = &cp;
00467   rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE;
00468   rq.event = EVT_CMD_STATUS; 
00469   rq.rparam = &status;
00470   rq.rlen = 1;
00471 
00472   if (hci_send_req(&rq) < 0)
00473     return BLE_STATUS_TIMEOUT;
00474 
00475   return status;
00476 }
00477   
00478 tBleStatus aci_gatt_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)
00479 {
00480   struct hci_request rq;
00481   uint8_t status;
00482   gatt_find_info_req_cp cp;
00483 
00484   cp.conn_handle = htobs(conn_handle);
00485   cp.start_handle = htobs(start_handle);
00486   cp.end_handle = htobs(end_handle);
00487 
00488   Osal_MemSet(&rq, 0, sizeof(rq));
00489   rq.ogf = OGF_VENDOR_CMD;
00490   rq.ocf = OCF_GATT_FIND_INFO_REQ;
00491   rq.cparam = &cp;
00492   rq.clen = GATT_GATT_FIND_INFO_REQ_CP_SIZE;
00493   rq.rparam = &status;
00494   rq.rlen = 1;
00495 
00496   if (hci_send_req(&rq) < 0)
00497     return BLE_STATUS_TIMEOUT;
00498 
00499   return status;
00500 }
00501 
00502 tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle)
00503 {
00504   struct hci_request rq;
00505   uint8_t status;
00506   gatt_disc_all_prim_services_cp cp;
00507 
00508   cp.conn_handle = htobs(conn_handle);
00509 
00510   Osal_MemSet(&rq, 0, sizeof(rq));
00511   rq.ogf = OGF_VENDOR_CMD;
00512   rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES;
00513   rq.cparam = &cp;
00514   rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE;
00515   rq.event = EVT_CMD_STATUS;
00516   rq.rparam = &status;
00517   rq.rlen = 1;
00518 
00519   if (hci_send_req(&rq) < 0)
00520     return BLE_STATUS_TIMEOUT;
00521 
00522   return status;
00523 }
00524 
00525 tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, 
00526                        uint16_t end_service_handle)
00527 {
00528   struct hci_request rq;
00529   uint8_t status;
00530   gatt_find_included_services_cp cp;
00531 
00532   cp.conn_handle = htobs(conn_handle);
00533   cp.start_handle = htobs(start_service_handle);
00534   cp.end_handle = htobs(end_service_handle);
00535 
00536   Osal_MemSet(&rq, 0, sizeof(rq));
00537   rq.ogf = OGF_VENDOR_CMD;
00538   rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES;
00539   rq.cparam = &cp;
00540   rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE;
00541   rq.event = EVT_CMD_STATUS;
00542   rq.rparam = &status;
00543   rq.rlen = 1;
00544 
00545   if (hci_send_req(&rq) < 0)
00546     return BLE_STATUS_TIMEOUT;
00547 
00548   return status;
00549 }
00550 
00551 tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, 
00552                         uint16_t end_attr_handle)
00553 {
00554   struct hci_request rq;
00555   uint8_t status;
00556   gatt_disc_all_charac_of_serv_cp cp;
00557 
00558   cp.conn_handle = htobs(conn_handle);
00559   cp.start_attr_handle = htobs(start_attr_handle);
00560   cp.end_attr_handle = htobs(end_attr_handle);
00561 
00562   Osal_MemSet(&rq, 0, sizeof(rq));
00563   rq.ogf = OGF_VENDOR_CMD;
00564   rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV;
00565   rq.cparam = &cp;
00566   rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE;
00567   rq.event = EVT_CMD_STATUS;
00568   rq.rparam = &status;
00569   rq.rlen = 1;
00570 
00571   if (hci_send_req(&rq) < 0)
00572     return BLE_STATUS_TIMEOUT;
00573 
00574   return status;
00575 }
00576 
00577 tBleStatus aci_gatt_discovery_characteristic_by_uuid(uint16_t conn_handle, uint16_t start_handle,
00578                                      uint16_t end_handle, uint8_t charUuidType,
00579                                                      const uint8_t* charUuid)
00580 {
00581   struct hci_request rq;
00582   uint8_t status;
00583   
00584   uint8_t buffer[23];
00585   uint8_t uuid_len;
00586   uint8_t indx = 0;
00587     
00588   conn_handle = htobs(conn_handle);
00589   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00590   indx += 2;
00591     
00592   start_handle = htobs(start_handle);
00593   Osal_MemCpy(buffer + indx, &start_handle, 2);
00594   indx += 2;
00595   
00596   end_handle = htobs(end_handle);
00597   Osal_MemCpy(buffer + indx, &end_handle, 2);
00598   indx += 2;
00599   
00600   buffer[indx] = charUuidType;
00601   indx++;
00602     
00603   if(charUuidType == 0x01){
00604     uuid_len = 2;
00605   }
00606   else {
00607     uuid_len = 16;
00608   }        
00609   Osal_MemCpy(buffer + indx, charUuid, uuid_len);
00610   indx +=  uuid_len;
00611 
00612   Osal_MemSet(&rq, 0, sizeof(rq));
00613   rq.ogf = OGF_VENDOR_CMD;
00614   rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID;
00615   rq.cparam = (void *)buffer;
00616   rq.clen = indx;
00617   rq.event = EVT_CMD_STATUS;
00618   rq.rparam = &status;
00619   rq.rlen = 1;
00620 
00621   if (hci_send_req(&rq) < 0)
00622     return BLE_STATUS_TIMEOUT;
00623 
00624   return status;
00625 }
00626 
00627 tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, 
00628                         uint16_t char_end_handle)
00629 {
00630   struct hci_request rq;
00631   uint8_t status;
00632   gatt_disc_all_charac_descriptors_cp cp;
00633 
00634   cp.conn_handle = htobs(conn_handle);
00635   cp.char_val_handle = htobs(char_val_handle);
00636   cp.char_end_handle = htobs(char_end_handle);
00637 
00638   Osal_MemSet(&rq, 0, sizeof(rq));
00639   rq.ogf = OGF_VENDOR_CMD;
00640   rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS;
00641   rq.cparam = &cp;
00642   rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE;
00643   rq.event = EVT_CMD_STATUS;
00644   rq.rparam = &status;
00645   rq.rlen = 1;
00646 
00647   if (hci_send_req(&rq) < 0)
00648     return BLE_STATUS_TIMEOUT;
00649 
00650   return status;
00651 }
00652 
00653 tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
00654 {
00655   struct hci_request rq;
00656   uint8_t status;
00657   gatt_read_charac_val_cp cp;
00658 
00659   cp.conn_handle = htobs(conn_handle);
00660   cp.attr_handle = htobs(attr_handle);
00661 
00662   Osal_MemSet(&rq, 0, sizeof(rq));
00663   rq.ogf = OGF_VENDOR_CMD;
00664   rq.ocf = OCF_GATT_READ_CHARAC_VAL;
00665   rq.cparam = &cp;
00666   rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE;
00667   rq.event = EVT_CMD_STATUS;
00668   rq.rparam = &status;
00669   rq.rlen = 1;
00670 
00671   if (hci_send_req(&rq) < 0)
00672     return BLE_STATUS_TIMEOUT;
00673   
00674   return status;
00675 }
00676 
00677 tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, 
00678                      uint16_t val_offset)
00679 {
00680   struct hci_request rq;
00681   uint8_t status;
00682   gatt_read_long_charac_val_cp cp;
00683 
00684   cp.conn_handle = htobs(conn_handle);
00685   cp.attr_handle = htobs(attr_handle);
00686   cp.val_offset = htobs(val_offset);
00687 
00688   Osal_MemSet(&rq, 0, sizeof(rq));
00689   rq.ogf = OGF_VENDOR_CMD;
00690   rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL;
00691   rq.cparam = &cp;
00692   rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE;
00693   rq.event = EVT_CMD_STATUS;
00694   rq.rparam = &status;
00695   rq.rlen = 1;
00696 
00697   if (hci_send_req(&rq) < 0)
00698     return BLE_STATUS_TIMEOUT;
00699 
00700   return status;
00701 }
00702 
00703 tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, 
00704                        uint8_t value_len, uint8_t *attr_value)
00705 {
00706   struct hci_request rq;
00707   uint8_t status;
00708   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00709   uint8_t indx = 0;
00710     
00711   if ((value_len+5) > HCI_MAX_PACKET_SIZE)
00712     return BLE_STATUS_INVALID_PARAMS;
00713 
00714   conn_handle = htobs(conn_handle);
00715   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00716   indx += 2;
00717     
00718   attr_handle = htobs(attr_handle);
00719   Osal_MemCpy(buffer + indx, &attr_handle, 2);
00720   indx += 2;
00721 
00722   buffer[indx] = value_len;
00723   indx++;
00724         
00725   Osal_MemCpy(buffer + indx, attr_value, value_len);
00726   indx +=  value_len;
00727 
00728   Osal_MemSet(&rq, 0, sizeof(rq));
00729   rq.ogf = OGF_VENDOR_CMD;
00730   rq.ocf = OCF_GATT_WRITE_CHAR_VALUE;
00731   rq.cparam = (void *)buffer;
00732   rq.clen = indx;
00733   rq.event = EVT_CMD_STATUS;
00734   rq.rparam = &status;
00735   rq.rlen = 1;
00736 
00737   if (hci_send_req(&rq) < 0)
00738     return BLE_STATUS_TIMEOUT;
00739 
00740   return status;
00741 }
00742 
00743 tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, 
00744                        uint8_t value_len, uint8_t *attr_value)
00745 {
00746   struct hci_request rq;
00747   uint8_t status;
00748   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00749   uint8_t indx = 0;
00750     
00751   if ((value_len+5) > HCI_MAX_PACKET_SIZE)
00752     return BLE_STATUS_INVALID_PARAMS;
00753 
00754   conn_handle = htobs(conn_handle);
00755   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00756   indx += 2;
00757     
00758   attr_handle = htobs(attr_handle);
00759   Osal_MemCpy(buffer + indx, &attr_handle, 2);
00760   indx += 2;
00761 
00762   buffer[indx] = value_len;
00763   indx++;
00764         
00765   Osal_MemCpy(buffer + indx, attr_value, value_len);
00766   indx +=  value_len;
00767 
00768   Osal_MemSet(&rq, 0, sizeof(rq));
00769   rq.ogf = OGF_VENDOR_CMD;
00770   rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR;
00771   rq.cparam = (void *)buffer;
00772   rq.clen = indx;
00773   rq.event = EVT_CMD_STATUS; 
00774   rq.rparam = &status;
00775   rq.rlen = 1;
00776 
00777   if (hci_send_req(&rq) < 0)
00778     return BLE_STATUS_TIMEOUT;
00779 
00780   return status;
00781 }
00782 
00783 tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, 
00784                        uint8_t value_len, uint8_t *attr_value)
00785 {
00786   struct hci_request rq;
00787   uint8_t status;
00788   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00789   uint8_t indx = 0;
00790     
00791   if ((value_len+5) > HCI_MAX_PACKET_SIZE)
00792     return BLE_STATUS_INVALID_PARAMS;
00793 
00794   conn_handle = htobs(conn_handle);
00795   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00796   indx += 2;
00797     
00798   attr_handle = htobs(attr_handle);
00799   Osal_MemCpy(buffer + indx, &attr_handle, 2);
00800   indx += 2;
00801 
00802   buffer[indx] = value_len;
00803   indx++;
00804         
00805   Osal_MemCpy(buffer + indx, attr_value, value_len);
00806   indx +=  value_len;
00807 
00808   Osal_MemSet(&rq, 0, sizeof(rq));
00809   rq.ogf = OGF_VENDOR_CMD;
00810   rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE;
00811   rq.cparam = (void *)buffer;
00812   rq.clen = indx;
00813   rq.rparam = &status;
00814   rq.rlen = 1;
00815 
00816   if (hci_send_req(&rq) < 0)
00817     return BLE_STATUS_TIMEOUT;
00818 
00819   return status;
00820 
00821 }
00822 
00823 tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle)
00824 {
00825   struct hci_request rq;
00826   uint8_t status;
00827   gatt_confirm_indication_cp cp;
00828 
00829   cp.conn_handle = htobs(conn_handle);
00830   
00831   Osal_MemSet(&rq, 0, sizeof(rq));
00832   rq.ogf = OGF_VENDOR_CMD;
00833   rq.ocf = OCF_GATT_CONFIRM_INDICATION;
00834   rq.cparam = &cp;
00835   rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE;
00836   rq.rparam = &status;
00837   rq.rlen = 1;
00838 
00839   if (hci_send_req(&rq) < 0)
00840     return BLE_STATUS_TIMEOUT;
00841   
00842   return status;
00843 }
00844 
00845 tBleStatus aci_gatt_write_response(uint16_t conn_handle,
00846                                    uint16_t attr_handle,
00847                                    uint8_t write_status,
00848                                    uint8_t err_code,
00849                                    uint8_t att_val_len,
00850                                    uint8_t *att_val)
00851 {
00852   struct hci_request rq;
00853   uint8_t status;
00854   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00855   uint8_t indx = 0;
00856   
00857   if ((att_val_len+7) > HCI_MAX_PACKET_SIZE)
00858     return BLE_STATUS_INVALID_PARAMS;
00859 
00860   conn_handle = htobs(conn_handle);  
00861   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00862   indx += 2;
00863     
00864   attr_handle = htobs(attr_handle);
00865   Osal_MemCpy(buffer + indx, &attr_handle, 2);
00866   indx += 2;
00867     
00868   buffer[indx] = write_status;
00869   indx += 1;
00870     
00871   buffer[indx] = err_code;
00872   indx += 1;
00873     
00874   buffer[indx] = att_val_len;
00875   indx += 1;
00876     
00877   Osal_MemCpy(buffer + indx, att_val, att_val_len);
00878   indx += att_val_len;
00879 
00880   Osal_MemSet(&rq, 0, sizeof(rq));
00881   rq.ogf = OGF_VENDOR_CMD;
00882   rq.ocf = OCF_GATT_WRITE_RESPONSE;
00883   rq.cparam = (void *)buffer;
00884   rq.clen = indx;
00885   rq.rparam = &status;
00886   rq.rlen = 1;
00887 
00888   if (hci_send_req(&rq) < 0)
00889     return BLE_STATUS_TIMEOUT;
00890 
00891   if (status) {
00892     return status;
00893   }
00894 
00895   return 0;
00896 }
00897 
00898 tBleStatus aci_gatt_allow_read(uint16_t conn_handle)
00899 {
00900     struct hci_request rq;
00901     gatt_allow_read_cp cp;
00902     uint8_t status;
00903     
00904     cp.conn_handle = htobs(conn_handle);
00905 
00906     Osal_MemSet(&rq, 0, sizeof(rq));
00907     rq.ogf = OGF_VENDOR_CMD;
00908     rq.ocf = OCF_GATT_ALLOW_READ;
00909     rq.cparam = &cp;
00910     rq.clen = GATT_ALLOW_READ_CP_SIZE;
00911     rq.rparam = &status;
00912     rq.rlen = 1;
00913 
00914     if (hci_send_req(&rq) < 0)
00915       return BLE_STATUS_TIMEOUT;
00916 
00917     return status;
00918 }
00919 
00920 tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, 
00921                    uint16_t charHandle,
00922                    uint16_t charDescHandle,
00923                    uint16_t charDescValOffset,
00924                    uint8_t charDescValueLen,   
00925                    const uint8_t *charDescValue)
00926 {
00927   struct hci_request rq;
00928   uint8_t status;
00929   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00930   uint8_t indx = 0;
00931     
00932   if ((charDescValueLen+9) > HCI_MAX_PACKET_SIZE)
00933     return BLE_STATUS_INVALID_PARAMS;
00934 
00935   servHandle = htobs(servHandle);
00936   Osal_MemCpy(buffer + indx, &servHandle, 2);
00937   indx += 2;
00938     
00939   charHandle = htobs(charHandle);
00940   Osal_MemCpy(buffer + indx, &charHandle, 2);
00941   indx += 2;
00942     
00943   charDescHandle = htobs(charDescHandle);
00944   Osal_MemCpy(buffer + indx, &charDescHandle, 2);
00945   indx += 2;
00946     
00947   Osal_MemCpy(buffer + indx, &charDescValOffset, 2);
00948   indx += 2;
00949     
00950   buffer[indx] = charDescValueLen;
00951   indx++;
00952         
00953   Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen);
00954   indx +=  charDescValueLen;
00955 
00956   Osal_MemSet(&rq, 0, sizeof(rq));
00957   rq.ogf = OGF_VENDOR_CMD;
00958   rq.ocf = OCF_GATT_SET_DESC_VAL;
00959   rq.cparam = (void *)buffer;
00960   rq.clen = indx;
00961   rq.rparam = &status;
00962   rq.rlen = 1;
00963 
00964   if (hci_send_req(&rq) < 0)
00965     return BLE_STATUS_TIMEOUT;
00966 
00967   return status;
00968 }
00969 
00970 tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data)
00971 {
00972   struct hci_request rq;
00973   gatt_read_handle_val_cp cp;
00974 
00975   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00976  
00977   if ((data_len+2) > HCI_MAX_PACKET_SIZE)
00978     return BLE_STATUS_INVALID_PARAMS;
00979 
00980   cp.attr_handle = htobs(attr_handle);
00981 
00982   Osal_MemSet(&rq, 0, sizeof(rq));
00983   rq.ogf = OGF_VENDOR_CMD;
00984   rq.ocf = OCF_GATT_READ_HANDLE_VALUE;
00985   rq.cparam = &cp;
00986   rq.clen = GATT_READ_HANDLE_VALUE_CP_SIZE;
00987   rq.rparam = buffer;
00988   rq.rlen = data_len+2;
00989 
00990   if (hci_send_req(&rq) < 0)
00991     return BLE_STATUS_TIMEOUT;
00992 
00993   *data_len_out_p = LE_TO_HOST_16(buffer+2);
00994 
00995   Osal_MemCpy(data, buffer + 2, MIN(data_len, *data_len_out_p));
00996 
00997   return buffer[0]; 
00998 }
00999