project

Fork of X_NUCLEO_IDB0XA1 by ST

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 "bluenrg_gatt_server.h"
00025 #include "bluenrg_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, FALSE) < 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 == UUID_TYPE_16){
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, FALSE) < 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 == UUID_TYPE_16){
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, FALSE) < 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 == UUID_TYPE_16){
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, FALSE) < 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_PAYLOAD_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 == UUID_TYPE_16){
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_PAYLOAD_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, FALSE) < 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_PAYLOAD_SIZE];
00325   uint8_t indx = 0;
00326     
00327   if ((charValueLen+6) > HCI_MAX_PAYLOAD_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, FALSE) < 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, FALSE) < 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, FALSE) < 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, FALSE) < 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, FALSE) < 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, FALSE) < 0)
00473     return BLE_STATUS_TIMEOUT;
00474 
00475   return status;
00476 }
00477   
00478 tBleStatus aci_att_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   att_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_ATT_FIND_INFO_REQ;
00491   rq.cparam = &cp;
00492   rq.clen = ATT_FIND_INFO_REQ_CP_SIZE;
00493   rq.rparam = &status;
00494   rq.rlen = 1;
00495 
00496   if (hci_send_req(&rq, FALSE) < 0)
00497     return BLE_STATUS_TIMEOUT;
00498 
00499   return status;
00500 }
00501 
00502 tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
00503                                           uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val)
00504 {
00505   struct hci_request rq;
00506   uint8_t status;
00507   att_find_by_type_value_req_cp cp;
00508   
00509   if(attr_val_len > sizeof(cp.attr_val))
00510     return BLE_STATUS_INVALID_PARAMS;
00511 
00512   cp.conn_handle = htobs(conn_handle);
00513   cp.start_handle = htobs(start_handle);
00514   cp.end_handle = htobs(end_handle);
00515   Osal_MemCpy(cp.uuid, uuid, 2);
00516   cp.attr_val_len = attr_val_len;
00517   Osal_MemCpy(cp.attr_val, attr_val, attr_val_len);
00518 
00519   Osal_MemSet(&rq, 0, sizeof(rq));
00520   rq.ogf = OGF_VENDOR_CMD;
00521   rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ;
00522   rq.cparam = &cp;
00523   rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len;
00524   rq.rparam = &status;
00525   rq.rlen = 1;
00526 
00527   if (hci_send_req(&rq, FALSE) < 0)
00528     return BLE_STATUS_TIMEOUT;
00529 
00530   return status;
00531 }
00532 
00533 tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
00534                                     uint8_t  uuid_type, uint8_t* uuid)
00535 {
00536   struct hci_request rq;
00537   uint8_t status;
00538   att_read_by_type_req_cp cp;
00539   uint8_t uuid_len;
00540   
00541   if(uuid_type == UUID_TYPE_16){
00542     uuid_len = 2;
00543   }
00544   else{
00545     uuid_len = 16;
00546   }
00547 
00548   cp.conn_handle = htobs(conn_handle);
00549   cp.start_handle = htobs(start_handle);
00550   cp.end_handle = htobs(end_handle);
00551   cp.uuid_type = uuid_type;
00552   Osal_MemCpy(cp.uuid, uuid, uuid_len);
00553 
00554   Osal_MemSet(&rq, 0, sizeof(rq));
00555   rq.ogf = OGF_VENDOR_CMD;
00556   rq.ocf = OCF_ATT_READ_BY_TYPE_REQ;
00557   rq.cparam = &cp;
00558   rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len;
00559   rq.rparam = &status;
00560   rq.rlen = 1;
00561 
00562   if (hci_send_req(&rq, FALSE) < 0)
00563     return BLE_STATUS_TIMEOUT;
00564 
00565   return status;
00566 }
00567 
00568 tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
00569                                     uint8_t  uuid_type, uint8_t* uuid)
00570 {
00571   struct hci_request rq;
00572   uint8_t status;
00573   att_read_by_group_type_req_cp cp;
00574   uint8_t uuid_len;
00575   
00576   if(uuid_type == UUID_TYPE_16){
00577     uuid_len = 2;
00578   }
00579   else{
00580     uuid_len = 16;
00581   }
00582 
00583   cp.conn_handle = htobs(conn_handle);
00584   cp.start_handle = htobs(start_handle);
00585   cp.end_handle = htobs(end_handle);
00586   cp.uuid_type = uuid_type;
00587   Osal_MemCpy(cp.uuid, uuid, uuid_len);
00588 
00589   Osal_MemSet(&rq, 0, sizeof(rq));
00590   rq.ogf = OGF_VENDOR_CMD;
00591   rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ;
00592   rq.cparam = &cp;
00593   rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len;
00594   rq.rparam = &status;
00595   rq.rlen = 1;
00596 
00597   if (hci_send_req(&rq, FALSE) < 0)
00598     return BLE_STATUS_TIMEOUT;
00599 
00600   return status;
00601 }
00602 
00603 tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset,
00604                                     uint8_t  attr_val_len, uint8_t* attr_val)
00605 {
00606   struct hci_request rq;
00607   uint8_t status;
00608   att_prepare_write_req_cp cp;
00609   
00610   if(attr_val_len > sizeof(cp.attr_val))
00611     return BLE_STATUS_INVALID_PARAMS;
00612 
00613   cp.conn_handle = htobs(conn_handle);
00614   cp.attr_handle = htobs(attr_handle);
00615   cp.value_offset = htobs(value_offset);
00616   cp.attr_val_len = attr_val_len;
00617   Osal_MemCpy(cp.attr_val, attr_val, attr_val_len);
00618 
00619   Osal_MemSet(&rq, 0, sizeof(rq));
00620   rq.ogf = OGF_VENDOR_CMD;
00621   rq.ocf = OCF_ATT_PREPARE_WRITE_REQ;
00622   rq.cparam = &cp;
00623   rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len;
00624   rq.rparam = &status;
00625   rq.rlen = 1;
00626 
00627   if (hci_send_req(&rq, FALSE) < 0)
00628     return BLE_STATUS_TIMEOUT;
00629 
00630   return status;
00631 }
00632 
00633 tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute)
00634 {
00635   struct hci_request rq;
00636   uint8_t status;
00637   att_execute_write_req_cp cp;
00638 
00639   cp.conn_handle = htobs(conn_handle);
00640   cp.execute = execute;
00641 
00642   Osal_MemSet(&rq, 0, sizeof(rq));
00643   rq.ogf = OGF_VENDOR_CMD;
00644   rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ;
00645   rq.cparam = &cp;
00646   rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE;
00647   rq.rparam = &status;
00648   rq.rlen = 1;
00649 
00650   if (hci_send_req(&rq, FALSE) < 0)
00651     return BLE_STATUS_TIMEOUT;
00652 
00653   return status;
00654 }
00655 
00656 tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle)
00657 {
00658   struct hci_request rq;
00659   uint8_t status;
00660   gatt_disc_all_prim_services_cp cp;
00661 
00662   cp.conn_handle = htobs(conn_handle);
00663 
00664   Osal_MemSet(&rq, 0, sizeof(rq));
00665   rq.ogf = OGF_VENDOR_CMD;
00666   rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES;
00667   rq.cparam = &cp;
00668   rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE;
00669   rq.event = EVT_CMD_STATUS;
00670   rq.rparam = &status;
00671   rq.rlen = 1;
00672 
00673   if (hci_send_req(&rq, FALSE) < 0)
00674     return BLE_STATUS_TIMEOUT;
00675 
00676   return status;
00677 }
00678 
00679 tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid)
00680 {
00681   struct hci_request rq;
00682   uint8_t status;
00683   gatt_disc_prim_service_by_uuid_cp cp;
00684   uint8_t uuid_len;
00685   
00686   if(uuid_type == UUID_TYPE_16){
00687     uuid_len = 2;
00688   }
00689   else{
00690     uuid_len = 16;
00691   }
00692 
00693   cp.conn_handle = htobs(conn_handle);
00694   cp.uuid_type = uuid_type;
00695   Osal_MemCpy(cp.uuid, uuid, uuid_len);
00696 
00697   Osal_MemSet(&rq, 0, sizeof(rq));
00698   rq.ogf = OGF_VENDOR_CMD;
00699   rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID;
00700   rq.cparam = &cp;
00701   rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len;
00702   rq.event = EVT_CMD_STATUS;
00703   rq.rparam = &status;
00704   rq.rlen = 1;
00705 
00706   if (hci_send_req(&rq, FALSE) < 0)
00707     return BLE_STATUS_TIMEOUT;
00708 
00709   return status;
00710 }
00711 
00712 tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, 
00713                        uint16_t end_service_handle)
00714 {
00715   struct hci_request rq;
00716   uint8_t status;
00717   gatt_find_included_services_cp cp;
00718 
00719   cp.conn_handle = htobs(conn_handle);
00720   cp.start_handle = htobs(start_service_handle);
00721   cp.end_handle = htobs(end_service_handle);
00722 
00723   Osal_MemSet(&rq, 0, sizeof(rq));
00724   rq.ogf = OGF_VENDOR_CMD;
00725   rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES;
00726   rq.cparam = &cp;
00727   rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE;
00728   rq.event = EVT_CMD_STATUS;
00729   rq.rparam = &status;
00730   rq.rlen = 1;
00731 
00732   if (hci_send_req(&rq, FALSE) < 0)
00733     return BLE_STATUS_TIMEOUT;
00734 
00735   return status;
00736 }
00737 
00738 tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, 
00739                         uint16_t end_attr_handle)
00740 {
00741   struct hci_request rq;
00742   uint8_t status;
00743   gatt_disc_all_charac_of_serv_cp cp;
00744 
00745   cp.conn_handle = htobs(conn_handle);
00746   cp.start_attr_handle = htobs(start_attr_handle);
00747   cp.end_attr_handle = htobs(end_attr_handle);
00748 
00749   Osal_MemSet(&rq, 0, sizeof(rq));
00750   rq.ogf = OGF_VENDOR_CMD;
00751   rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV;
00752   rq.cparam = &cp;
00753   rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE;
00754   rq.event = EVT_CMD_STATUS;
00755   rq.rparam = &status;
00756   rq.rlen = 1;
00757 
00758   if (hci_send_req(&rq, FALSE) < 0)
00759     return BLE_STATUS_TIMEOUT;
00760 
00761   return status;
00762 }
00763 
00764 tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle,
00765                                      uint16_t end_handle, uint8_t charUuidType,
00766                                                      const uint8_t* charUuid)
00767 {
00768   struct hci_request rq;
00769   uint8_t status;
00770   
00771   uint8_t buffer[23];
00772   uint8_t uuid_len;
00773   uint8_t indx = 0;
00774     
00775   conn_handle = htobs(conn_handle);
00776   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00777   indx += 2;
00778     
00779   start_handle = htobs(start_handle);
00780   Osal_MemCpy(buffer + indx, &start_handle, 2);
00781   indx += 2;
00782   
00783   end_handle = htobs(end_handle);
00784   Osal_MemCpy(buffer + indx, &end_handle, 2);
00785   indx += 2;
00786   
00787   buffer[indx] = charUuidType;
00788   indx++;
00789     
00790   if(charUuidType == 0x01){
00791     uuid_len = 2;
00792   }
00793   else {
00794     uuid_len = 16;
00795   }        
00796   Osal_MemCpy(buffer + indx, charUuid, uuid_len);
00797   indx +=  uuid_len;
00798 
00799   Osal_MemSet(&rq, 0, sizeof(rq));
00800   rq.ogf = OGF_VENDOR_CMD;
00801   rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID;
00802   rq.cparam = (void *)buffer;
00803   rq.clen = indx;
00804   rq.event = EVT_CMD_STATUS;
00805   rq.rparam = &status;
00806   rq.rlen = 1;
00807 
00808   if (hci_send_req(&rq, FALSE) < 0)
00809     return BLE_STATUS_TIMEOUT;
00810 
00811   return status;
00812 }
00813 
00814 tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, 
00815                         uint16_t char_end_handle)
00816 {
00817   struct hci_request rq;
00818   uint8_t status;
00819   gatt_disc_all_charac_descriptors_cp cp;
00820 
00821   cp.conn_handle = htobs(conn_handle);
00822   cp.char_val_handle = htobs(char_val_handle);
00823   cp.char_end_handle = htobs(char_end_handle);
00824 
00825   Osal_MemSet(&rq, 0, sizeof(rq));
00826   rq.ogf = OGF_VENDOR_CMD;
00827   rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS;
00828   rq.cparam = &cp;
00829   rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE;
00830   rq.event = EVT_CMD_STATUS;
00831   rq.rparam = &status;
00832   rq.rlen = 1;
00833 
00834   if (hci_send_req(&rq, FALSE) < 0)
00835     return BLE_STATUS_TIMEOUT;
00836 
00837   return status;
00838 }
00839 
00840 tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
00841 {
00842   struct hci_request rq;
00843   uint8_t status;
00844   gatt_read_charac_val_cp cp;
00845 
00846   cp.conn_handle = htobs(conn_handle);
00847   cp.attr_handle = htobs(attr_handle);
00848 
00849   Osal_MemSet(&rq, 0, sizeof(rq));
00850   rq.ogf = OGF_VENDOR_CMD;
00851   rq.ocf = OCF_GATT_READ_CHARAC_VAL;
00852   rq.cparam = &cp;
00853   rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE;
00854   rq.event = EVT_CMD_STATUS;
00855   rq.rparam = &status;
00856   rq.rlen = 1;
00857 
00858   if (hci_send_req(&rq, FALSE) < 0)
00859     return BLE_STATUS_TIMEOUT;
00860   
00861   return status;
00862 }
00863 
00864 tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
00865                                     uint8_t  uuid_type, uint8_t* uuid)
00866 {
00867   struct hci_request rq;
00868   uint8_t status;
00869   gatt_read_using_charac_uuid_cp cp;
00870   uint8_t uuid_len;
00871   
00872   if(uuid_type == UUID_TYPE_16){
00873     uuid_len = 2;
00874   }
00875   else{
00876     uuid_len = 16;
00877   }
00878 
00879   cp.conn_handle = htobs(conn_handle);
00880   cp.start_handle = htobs(start_handle);
00881   cp.end_handle = htobs(end_handle);
00882   cp.uuid_type = uuid_type;
00883   Osal_MemCpy(cp.uuid, uuid, uuid_len);
00884 
00885   Osal_MemSet(&rq, 0, sizeof(rq));
00886   rq.ogf = OGF_VENDOR_CMD;
00887   rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID;
00888   rq.cparam = &cp;
00889   rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len;
00890   rq.rparam = &status;
00891   rq.rlen = 1;
00892 
00893   if (hci_send_req(&rq, FALSE) < 0)
00894     return BLE_STATUS_TIMEOUT;
00895 
00896   return status;
00897 }
00898 
00899 tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, 
00900                      uint16_t val_offset)
00901 {
00902   struct hci_request rq;
00903   uint8_t status;
00904   gatt_read_long_charac_val_cp cp;
00905 
00906   cp.conn_handle = htobs(conn_handle);
00907   cp.attr_handle = htobs(attr_handle);
00908   cp.val_offset = htobs(val_offset);
00909 
00910   Osal_MemSet(&rq, 0, sizeof(rq));
00911   rq.ogf = OGF_VENDOR_CMD;
00912   rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL;
00913   rq.cparam = &cp;
00914   rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE;
00915   rq.event = EVT_CMD_STATUS;
00916   rq.rparam = &status;
00917   rq.rlen = 1;
00918 
00919   if (hci_send_req(&rq, FALSE) < 0)
00920     return BLE_STATUS_TIMEOUT;
00921 
00922   return status;
00923 }
00924 
00925 tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, 
00926                                              uint8_t* set_of_handles)
00927 {
00928   struct hci_request rq;
00929   uint8_t status;
00930   gatt_read_multiple_charac_val_cp cp;
00931   
00932   if(num_handles*2 > sizeof(cp.set_of_handles))
00933     return BLE_STATUS_INVALID_PARAMS;
00934 
00935   cp.conn_handle = htobs(conn_handle);
00936   cp.num_handles = htobs(num_handles);
00937   Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles);
00938 
00939   Osal_MemSet(&rq, 0, sizeof(rq));
00940   rq.ogf = OGF_VENDOR_CMD;
00941   rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL;
00942   rq.cparam = &cp;
00943   rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles;
00944   rq.event = EVT_CMD_STATUS;
00945   rq.rparam = &status;
00946   rq.rlen = 1;
00947 
00948   if (hci_send_req(&rq, FALSE) < 0)
00949     return BLE_STATUS_TIMEOUT;
00950 
00951   return status;
00952 }
00953 
00954 
00955 
00956 tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, 
00957                        uint8_t value_len, uint8_t *attr_value)
00958 {
00959   struct hci_request rq;
00960   uint8_t status;
00961   uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
00962   uint8_t indx = 0;
00963     
00964   if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE)
00965     return BLE_STATUS_INVALID_PARAMS;
00966 
00967   conn_handle = htobs(conn_handle);
00968   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00969   indx += 2;
00970     
00971   attr_handle = htobs(attr_handle);
00972   Osal_MemCpy(buffer + indx, &attr_handle, 2);
00973   indx += 2;
00974 
00975   buffer[indx] = value_len;
00976   indx++;
00977         
00978   Osal_MemCpy(buffer + indx, attr_value, value_len);
00979   indx +=  value_len;
00980 
00981   Osal_MemSet(&rq, 0, sizeof(rq));
00982   rq.ogf = OGF_VENDOR_CMD;
00983   rq.ocf = OCF_GATT_WRITE_CHAR_VALUE;
00984   rq.cparam = (void *)buffer;
00985   rq.clen = indx;
00986   rq.event = EVT_CMD_STATUS;
00987   rq.rparam = &status;
00988   rq.rlen = 1;
00989 
00990   if (hci_send_req(&rq, FALSE) < 0)
00991     return BLE_STATUS_TIMEOUT;
00992 
00993   return status;
00994 }
00995 
00996 tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle,
00997                                           uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val)
00998 {
00999   struct hci_request rq;
01000   uint8_t status;
01001   gatt_write_long_charac_val_cp cp;
01002   
01003   if(val_len > sizeof(cp.attr_val))
01004     return BLE_STATUS_INVALID_PARAMS;
01005 
01006   cp.conn_handle = htobs(conn_handle);
01007   cp.attr_handle = htobs(attr_handle);
01008   cp.val_offset = htobs(val_offset);
01009   cp.val_len = val_len;
01010   Osal_MemCpy(cp.attr_val, attr_val, val_len);
01011 
01012   Osal_MemSet(&rq, 0, sizeof(rq));
01013   rq.ogf = OGF_VENDOR_CMD;
01014   rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL;
01015   rq.cparam = &cp;
01016   rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len;
01017   rq.event = EVT_CMD_STATUS;
01018   rq.rparam = &status;
01019   rq.rlen = 1;
01020 
01021   if (hci_send_req(&rq, FALSE) < 0)
01022     return BLE_STATUS_TIMEOUT;
01023 
01024   return status;
01025 }
01026 
01027 tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle,
01028                                           uint16_t val_offset, uint8_t val_len, uint8_t* attr_val)
01029 {
01030   struct hci_request rq;
01031   uint8_t status;
01032   gatt_write_charac_reliable_cp cp;
01033   
01034   if(val_len > sizeof(cp.attr_val))
01035     return BLE_STATUS_INVALID_PARAMS;
01036 
01037   cp.conn_handle = htobs(conn_handle);
01038   cp.attr_handle = htobs(attr_handle);
01039   cp.val_offset = htobs(val_offset);
01040   cp.val_len = val_len;
01041   Osal_MemCpy(cp.attr_val, attr_val, val_len);
01042 
01043   Osal_MemSet(&rq, 0, sizeof(rq));
01044   rq.ogf = OGF_VENDOR_CMD;
01045   rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE;
01046   rq.cparam = &cp;
01047   rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len;
01048   rq.event = EVT_CMD_STATUS;
01049   rq.rparam = &status;
01050   rq.rlen = 1;
01051 
01052   if (hci_send_req(&rq, FALSE) < 0)
01053     return BLE_STATUS_TIMEOUT;
01054 
01055   return status;
01056 }
01057 
01058 tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
01059                                           uint16_t val_offset, uint8_t val_len, uint8_t* attr_val)
01060 {
01061   struct hci_request rq;
01062   uint8_t status;
01063   gatt_write_charac_reliable_cp cp;
01064   
01065   if(val_len > sizeof(cp.attr_val))
01066     return BLE_STATUS_INVALID_PARAMS;
01067 
01068   cp.conn_handle = htobs(conn_handle);
01069   cp.attr_handle = htobs(attr_handle);
01070   cp.val_offset = htobs(val_offset);
01071   cp.val_len = val_len;
01072   Osal_MemCpy(cp.attr_val, attr_val, val_len);
01073 
01074   Osal_MemSet(&rq, 0, sizeof(rq));
01075   rq.ogf = OGF_VENDOR_CMD;
01076   rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC;
01077   rq.cparam = &cp;
01078   rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len;
01079   rq.event = EVT_CMD_STATUS;
01080   rq.rparam = &status;
01081   rq.rlen = 1;
01082 
01083   if (hci_send_req(&rq, FALSE) < 0)
01084     return BLE_STATUS_TIMEOUT;
01085 
01086   return status;
01087 }
01088 
01089 tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
01090                                           uint16_t val_offset)
01091 {
01092   struct hci_request rq;
01093   uint8_t status;
01094   gatt_read_long_charac_desc_cp cp;
01095 
01096   cp.conn_handle = htobs(conn_handle);
01097   cp.attr_handle = htobs(attr_handle);
01098   cp.val_offset = htobs(val_offset);
01099 
01100   Osal_MemSet(&rq, 0, sizeof(rq));
01101   rq.ogf = OGF_VENDOR_CMD;
01102   rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC;
01103   rq.cparam = &cp;
01104   rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE;
01105   rq.event = EVT_CMD_STATUS;
01106   rq.rparam = &status;
01107   rq.rlen = 1;
01108 
01109   if (hci_send_req(&rq, FALSE) < 0)
01110     return BLE_STATUS_TIMEOUT;
01111 
01112   return status;
01113 }
01114 
01115 tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, 
01116                        uint8_t value_len, uint8_t *attr_value)
01117 {
01118   struct hci_request rq;
01119   uint8_t status;
01120   uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
01121   uint8_t indx = 0;
01122     
01123   if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE)
01124     return BLE_STATUS_INVALID_PARAMS;
01125 
01126   conn_handle = htobs(conn_handle);
01127   Osal_MemCpy(buffer + indx, &conn_handle, 2);
01128   indx += 2;
01129     
01130   attr_handle = htobs(attr_handle);
01131   Osal_MemCpy(buffer + indx, &attr_handle, 2);
01132   indx += 2;
01133 
01134   buffer[indx] = value_len;
01135   indx++;
01136         
01137   Osal_MemCpy(buffer + indx, attr_value, value_len);
01138   indx +=  value_len;
01139 
01140   Osal_MemSet(&rq, 0, sizeof(rq));
01141   rq.ogf = OGF_VENDOR_CMD;
01142   rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR;
01143   rq.cparam = (void *)buffer;
01144   rq.clen = indx;
01145   rq.event = EVT_CMD_STATUS; 
01146   rq.rparam = &status;
01147   rq.rlen = 1;
01148 
01149   if (hci_send_req(&rq, FALSE) < 0)
01150     return BLE_STATUS_TIMEOUT;
01151 
01152   return status;
01153 }
01154 
01155 tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle)
01156 {
01157   struct hci_request rq;
01158   uint8_t status;
01159   gatt_read_long_charac_desc_cp cp;
01160 
01161   cp.conn_handle = htobs(conn_handle);
01162   cp.attr_handle = htobs(attr_handle);
01163 
01164   Osal_MemSet(&rq, 0, sizeof(rq));
01165   rq.ogf = OGF_VENDOR_CMD;
01166   rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR;
01167   rq.cparam = &cp;
01168   rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE;
01169   rq.event = EVT_CMD_STATUS;
01170   rq.rparam = &status;
01171   rq.rlen = 1;
01172 
01173   if (hci_send_req(&rq, FALSE) < 0)
01174     return BLE_STATUS_TIMEOUT;
01175 
01176   return status;
01177 }
01178 
01179 tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle,
01180                                               uint8_t val_len, const uint8_t* attr_val)
01181 {
01182   struct hci_request rq;
01183   uint8_t status;
01184   gatt_write_without_resp_cp cp;
01185   
01186   if(val_len > sizeof(cp.attr_val))
01187     return BLE_STATUS_INVALID_PARAMS;
01188 
01189   cp.conn_handle = htobs(conn_handle);
01190   cp.attr_handle = htobs(attr_handle);
01191   cp.val_len = val_len;
01192   Osal_MemCpy(cp.attr_val, attr_val, val_len);
01193 
01194   Osal_MemSet(&rq, 0, sizeof(rq));
01195   rq.ogf = OGF_VENDOR_CMD;
01196   rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE;
01197   rq.cparam = &cp;
01198   rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; 
01199   rq.rparam = &status;
01200   rq.rlen = 1;
01201 
01202   if (hci_send_req(&rq, FALSE) < 0)
01203     return BLE_STATUS_TIMEOUT;
01204 
01205   return status;
01206 }
01207 
01208 tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle,
01209                                               uint8_t val_len, uint8_t* attr_val)
01210 {
01211   struct hci_request rq;
01212   uint8_t status;
01213   gatt_signed_write_without_resp_cp cp;
01214   
01215   if(val_len > sizeof(cp.attr_val))
01216     return BLE_STATUS_INVALID_PARAMS;
01217 
01218   cp.conn_handle = htobs(conn_handle);
01219   cp.attr_handle = htobs(attr_handle);
01220   cp.val_len = val_len;
01221   Osal_MemCpy(cp.attr_val, attr_val, val_len);
01222 
01223   Osal_MemSet(&rq, 0, sizeof(rq));
01224   rq.ogf = OGF_VENDOR_CMD;
01225   rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE;
01226   rq.cparam = &cp;
01227   rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len;
01228   rq.rparam = &status;
01229   rq.rlen = 1;
01230 
01231   if (hci_send_req(&rq, FALSE) < 0)
01232     return BLE_STATUS_TIMEOUT;
01233 
01234   return status;
01235 }
01236 
01237 tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle)
01238 {
01239   struct hci_request rq;
01240   uint8_t status;
01241   gatt_confirm_indication_cp cp;
01242 
01243   cp.conn_handle = htobs(conn_handle);
01244   
01245   Osal_MemSet(&rq, 0, sizeof(rq));
01246   rq.ogf = OGF_VENDOR_CMD;
01247   rq.ocf = OCF_GATT_CONFIRM_INDICATION;
01248   rq.cparam = &cp;
01249   rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE;
01250   rq.rparam = &status;
01251   rq.rlen = 1;
01252 
01253   if (hci_send_req(&rq, FALSE) < 0)
01254     return BLE_STATUS_TIMEOUT;
01255   
01256   return status;
01257 }
01258 
01259 tBleStatus aci_gatt_write_response(uint16_t conn_handle,
01260                                    uint16_t attr_handle,
01261                                    uint8_t write_status,
01262                                    uint8_t err_code,
01263                                    uint8_t att_val_len,
01264                                    uint8_t *att_val)
01265 {
01266   struct hci_request rq;
01267   uint8_t status;
01268   uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
01269   uint8_t indx = 0;
01270   
01271   if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE)
01272     return BLE_STATUS_INVALID_PARAMS;
01273 
01274   conn_handle = htobs(conn_handle);  
01275   Osal_MemCpy(buffer + indx, &conn_handle, 2);
01276   indx += 2;
01277     
01278   attr_handle = htobs(attr_handle);
01279   Osal_MemCpy(buffer + indx, &attr_handle, 2);
01280   indx += 2;
01281     
01282   buffer[indx] = write_status;
01283   indx += 1;
01284     
01285   buffer[indx] = err_code;
01286   indx += 1;
01287     
01288   buffer[indx] = att_val_len;
01289   indx += 1;
01290     
01291   Osal_MemCpy(buffer + indx, att_val, att_val_len);
01292   indx += att_val_len;
01293 
01294   Osal_MemSet(&rq, 0, sizeof(rq));
01295   rq.ogf = OGF_VENDOR_CMD;
01296   rq.ocf = OCF_GATT_WRITE_RESPONSE;
01297   rq.cparam = (void *)buffer;
01298   rq.clen = indx;
01299   rq.rparam = &status;
01300   rq.rlen = 1;
01301 
01302   if (hci_send_req(&rq, FALSE) < 0)
01303     return BLE_STATUS_TIMEOUT;
01304 
01305   if (status) {
01306     return status;
01307   }
01308 
01309   return 0;
01310 }
01311 
01312 tBleStatus aci_gatt_allow_read(uint16_t conn_handle)
01313 {
01314     struct hci_request rq;
01315     gatt_allow_read_cp cp;
01316     uint8_t status;
01317     
01318     cp.conn_handle = htobs(conn_handle);
01319 
01320     Osal_MemSet(&rq, 0, sizeof(rq));
01321     rq.ogf = OGF_VENDOR_CMD;
01322     rq.ocf = OCF_GATT_ALLOW_READ;
01323     rq.cparam = &cp;
01324     rq.clen = GATT_ALLOW_READ_CP_SIZE;
01325     rq.rparam = &status;
01326     rq.rlen = 1;
01327 
01328     if (hci_send_req(&rq, FALSE) < 0)
01329       return BLE_STATUS_TIMEOUT;
01330 
01331     return status;
01332 }
01333 
01334 tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle,
01335                                             uint8_t security_permission)
01336 {
01337     struct hci_request rq;
01338     gatt_set_security_permission_cp cp;
01339     uint8_t status;
01340     
01341     cp.service_handle = htobs(service_handle);
01342     cp.attr_handle = htobs(attr_handle);
01343     cp.security_permission = security_permission;
01344 
01345     Osal_MemSet(&rq, 0, sizeof(rq));
01346     rq.ogf = OGF_VENDOR_CMD;
01347     rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION;
01348     rq.cparam = &cp;
01349     rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE;
01350     rq.rparam = &status;
01351     rq.rlen = 1;
01352 
01353     if (hci_send_req(&rq, FALSE) < 0)
01354       return BLE_STATUS_TIMEOUT;
01355 
01356     return status;
01357 }
01358 
01359 tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, 
01360                    uint16_t charHandle,
01361                    uint16_t charDescHandle,
01362                    uint16_t charDescValOffset,
01363                    uint8_t charDescValueLen,   
01364                    const uint8_t *charDescValue)
01365 {
01366   struct hci_request rq;
01367   uint8_t status;
01368   uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
01369   uint8_t indx = 0;
01370     
01371   if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE)
01372     return BLE_STATUS_INVALID_PARAMS;
01373 
01374   servHandle = htobs(servHandle);
01375   Osal_MemCpy(buffer + indx, &servHandle, 2);
01376   indx += 2;
01377     
01378   charHandle = htobs(charHandle);
01379   Osal_MemCpy(buffer + indx, &charHandle, 2);
01380   indx += 2;
01381     
01382   charDescHandle = htobs(charDescHandle);
01383   Osal_MemCpy(buffer + indx, &charDescHandle, 2);
01384   indx += 2;
01385     
01386   Osal_MemCpy(buffer + indx, &charDescValOffset, 2);
01387   indx += 2;
01388     
01389   buffer[indx] = charDescValueLen;
01390   indx++;
01391         
01392   Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen);
01393   indx +=  charDescValueLen;
01394 
01395   Osal_MemSet(&rq, 0, sizeof(rq));
01396   rq.ogf = OGF_VENDOR_CMD;
01397   rq.ocf = OCF_GATT_SET_DESC_VAL;
01398   rq.cparam = (void *)buffer;
01399   rq.clen = indx;
01400   rq.rparam = &status;
01401   rq.rlen = 1;
01402 
01403   if (hci_send_req(&rq, FALSE) < 0)
01404     return BLE_STATUS_TIMEOUT;
01405 
01406   return status;
01407 }
01408 
01409 tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data)
01410 {
01411   struct hci_request rq;
01412   gatt_read_handle_val_cp cp;
01413   gatt_read_handle_val_rp rp;
01414  
01415   if(data_len > sizeof(rp.value))
01416     return BLE_STATUS_INVALID_PARAMS;
01417 
01418   cp.attr_handle = htobs(attr_handle);
01419 
01420   Osal_MemSet(&rq, 0, sizeof(rq));
01421   rq.ogf = OGF_VENDOR_CMD;
01422   rq.ocf = OCF_GATT_READ_HANDLE_VALUE;
01423   rq.cparam = &cp;
01424   rq.clen = sizeof(cp);
01425   rq.rparam = &rp;
01426   rq.rlen = sizeof(rp);
01427 
01428   if (hci_send_req(&rq, FALSE) < 0)
01429     return BLE_STATUS_TIMEOUT;
01430   
01431   if(rp.status)
01432     return rp.status;
01433 
01434   *data_len_out_p = btohs(rp.value_len);
01435 
01436   Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p));
01437 
01438   return 0;
01439 }
01440 
01441 tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data)
01442 {
01443   struct hci_request rq;
01444   gatt_read_handle_val_offset_cp cp;
01445   gatt_read_handle_val_offset_rp rp;
01446   
01447   if(data_len > sizeof(rp.value))
01448     return BLE_STATUS_INVALID_PARAMS;
01449 
01450   cp.attr_handle = htobs(attr_handle);
01451   cp.offset = offset;
01452 
01453   Osal_MemSet(&rq, 0, sizeof(rq));
01454   rq.ogf = OGF_VENDOR_CMD;
01455   rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET;
01456   rq.cparam = &cp;
01457   rq.clen = sizeof(cp);
01458   rq.rparam = &rp;
01459   rq.rlen = sizeof(rp);
01460 
01461   if (hci_send_req(&rq, FALSE) < 0)
01462     return BLE_STATUS_TIMEOUT;
01463   
01464   if(rp.status)
01465     return rp.status;
01466 
01467   *data_len_out_p = rp.value_len;
01468 
01469   Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p));
01470 
01471   return 0; 
01472 }