ble

Dependencies:   HC_SR04_Ultrasonic_Library Servo mbed

Fork of FIP_REV1 by Robotique FIP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bluenrg_hci.c Source File

bluenrg_hci.c

00001 /******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
00002 * File Name          : bluenrg_hci.c
00003 * Author             : AMS - HEA&RF BU
00004 * Version            : V1.0.0
00005 * Date               : 4-Oct-2013
00006 * Description        : File with HCI commands for BlueNRG FW6.0 and above.
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_internal.h"
00022 #include "bluenrg_hci_internal.h"
00023 #include "gatt_service.h"
00024 
00025 
00026 tBleStatus aci_gatt_init()
00027 {
00028     struct hci_request rq;
00029     tHalUint8 status;
00030 
00031     Osal_MemSet(&rq, 0, sizeof(rq));
00032     rq.ogf = OGF_VENDOR_CMD;
00033     rq.ocf = OCF_GATT_INIT;
00034     rq.rparam = &status;
00035     rq.rlen = 1;
00036 
00037     if (hci_send_req(&rq) < 0)
00038         return -1;
00039 
00040     if (status) {
00041         return status;
00042     }
00043 
00044     return 0;
00045 }
00046 
00047 tBleStatus aci_gap_init(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle)
00048 {
00049     struct hci_request rq;
00050     gap_init_cp cp;
00051     gap_init_rp resp;
00052 
00053     cp.role = role;
00054     
00055     Osal_MemSet(&resp, 0, sizeof(resp));
00056 
00057     Osal_MemSet(&rq, 0, sizeof(rq));
00058     rq.ogf = OGF_VENDOR_CMD;
00059     rq.ocf = OCF_GAP_INIT;
00060     rq.cparam = &cp;
00061     rq.clen = GAP_INIT_CP_SIZE;
00062     rq.rparam = &resp;
00063     rq.rlen = GAP_INIT_RP_SIZE;
00064 
00065     if (hci_send_req(&rq) < 0)
00066         return -1;
00067 
00068     if (resp.status) {
00069         return resp.status;
00070     }
00071     
00072     *service_handle = resp.service_handle;
00073     *dev_name_char_handle = resp.dev_name_char_handle;
00074     *appearance_char_handle = resp.appearance_char_handle;
00075 
00076     return 0;
00077 }
00078 
00079 tBleStatus aci_gap_set_non_discoverable(void)
00080 {
00081     struct hci_request rq;
00082     tHalUint8 status;
00083 
00084     Osal_MemSet(&rq, 0, sizeof(rq));
00085     rq.ogf = OGF_VENDOR_CMD;
00086     rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE;
00087     rq.rparam = &status;
00088     rq.rlen = 1;
00089 
00090     if (hci_send_req(&rq) < 0)
00091         return -1;
00092 
00093     return status;  
00094 }
00095 
00096 tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
00097                              uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
00098                              const char *LocalName, uint8_t ServiceUUIDLen, const uint8_t* ServiceUUIDList,
00099                              uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax)
00100 {
00101     struct hci_request rq;
00102     uint8_t status;    
00103     uint8_t buffer[HCI_MAX_PACKET_SIZE];
00104     uint8_t indx = 0;
00105     
00106     buffer[indx] = AdvType;
00107     indx++;
00108     
00109     Osal_MemCpy(buffer + indx, &AdvIntervMin, 2);
00110     indx +=  2;
00111     
00112     Osal_MemCpy(buffer + indx, &AdvIntervMax, 2);
00113     indx +=  2;
00114     
00115     buffer[indx] = OwnAddrType;
00116     indx++;
00117     
00118     buffer[indx] = AdvFilterPolicy;
00119     indx++;
00120     
00121     buffer[indx] = LocalNameLen;
00122     indx++;
00123     
00124     Osal_MemCpy(buffer + indx, LocalName, LocalNameLen);
00125     indx +=  LocalNameLen;
00126 
00127     buffer[indx] = ServiceUUIDLen;
00128     indx++;
00129     
00130     Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen);
00131     indx +=  ServiceUUIDLen;
00132 
00133     Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2);
00134     indx +=  2;
00135     
00136     Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2);
00137     indx +=  2;    
00138 
00139     Osal_MemSet(&rq, 0, sizeof(rq));
00140     rq.ogf = OGF_VENDOR_CMD;
00141     rq.ocf = OCF_GAP_SET_DISCOVERABLE;
00142     rq.cparam = (void *)buffer;
00143     rq.clen = indx;
00144     rq.rparam = &status;
00145     rq.rlen = 1;
00146 
00147     if (hci_send_req(&rq) < 0)
00148         return -1;
00149 
00150     if (status) {
00151         return status;
00152     }
00153 
00154     return 0;
00155 }
00156 
00157 tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData)
00158 {
00159     struct hci_request rq;
00160     uint8_t status;
00161     uint8_t buffer[HCI_MAX_PACKET_SIZE];
00162     uint8_t indx = 0;
00163     
00164     buffer[indx] = AdvLen;
00165     indx++;
00166     
00167     Osal_MemCpy(buffer + indx, AdvData, AdvLen);
00168     indx +=  AdvLen;
00169     
00170     Osal_MemSet(&rq, 0, sizeof(rq));
00171     rq.ogf = OGF_VENDOR_CMD;
00172     rq.ocf = OCF_GAP_UPDATE_ADV_DATA;
00173     rq.cparam = (void *)buffer;
00174     rq.clen = indx;
00175     rq.rparam = &status;
00176     rq.rlen = 1;
00177     
00178     if (hci_send_req(&rq) < 0)
00179         return -1;
00180     
00181     return status;
00182 }
00183 
00184 
00185 tBleStatus aci_gatt_add_serv(tHalUint8 service_uuid_type, const tHalUint8* service_uuid, tHalUint8 service_type, tHalUint8 max_attr_records, tHalUint16 *serviceHandle)
00186 {
00187     struct hci_request rq;
00188     gatt_add_serv_rp resp;    
00189     uint8_t buffer[HCI_MAX_PACKET_SIZE];
00190     uint8_t uuid_len;
00191     uint8_t indx = 0;
00192     
00193     buffer[indx] = service_uuid_type;
00194     indx++;
00195     
00196     if(service_uuid_type == 0x01){
00197         uuid_len = 2;
00198     }
00199     else {
00200         uuid_len = 16;
00201     }        
00202     Osal_MemCpy(buffer + indx, service_uuid, uuid_len);
00203     indx +=  uuid_len;
00204     
00205     buffer[indx] = service_type;
00206     indx++;
00207     
00208     buffer[indx] = max_attr_records;
00209     indx++;
00210     
00211     
00212     Osal_MemSet(&resp, 0, sizeof(resp));
00213 
00214     Osal_MemSet(&rq, 0, sizeof(rq));
00215     rq.ogf = OGF_VENDOR_CMD;
00216     rq.ocf = OCF_GATT_ADD_SERV;
00217     rq.cparam = (void *)buffer;
00218     rq.clen = indx;
00219     rq.rparam = &resp;
00220     rq.rlen = GATT_ADD_SERV_RP_SIZE;
00221 
00222     if (hci_send_req(&rq) < 0)
00223         return -1;
00224 
00225     if (resp.status) {
00226         return resp.status;
00227     }
00228     
00229     *serviceHandle = resp.handle;
00230 
00231     return 0;
00232 }
00233 
00234 tBleStatus aci_gatt_add_char(tHalUint16 serviceHandle,
00235                       tUuidType charUuidType,
00236                       const tHalUint8* charUuid, 
00237                       tHalUint16 charValueLen, 
00238                       tHalUint8 charProperties,
00239                       tAttrSecurityFlags secPermissions,
00240                       tGattServerEvent gattEvtMask,
00241                       tHalUint8 encryKeySize,
00242                       tHalUint8 isVariable,
00243                       tHalUint16* charHandle)
00244                       
00245                       
00246 {
00247     struct hci_request rq;
00248     gatt_add_serv_rp resp;
00249     uint8_t buffer[HCI_MAX_PACKET_SIZE];
00250     uint8_t uuid_len;
00251     uint8_t indx = 0;
00252     
00253     Osal_MemCpy(buffer + indx, &serviceHandle, 2);
00254     indx += 2;
00255     
00256     buffer[indx] = charUuidType;
00257     indx++;
00258     
00259     if(charUuidType == 0x01){
00260         uuid_len = 2;
00261     }
00262     else {
00263         uuid_len = 16;
00264     }        
00265     Osal_MemCpy(buffer + indx, charUuid, uuid_len);
00266     indx +=  uuid_len;
00267     
00268     buffer[indx] = charValueLen;
00269     indx++;
00270     
00271     buffer[indx] = charProperties;
00272     indx++;
00273     
00274     buffer[indx] = secPermissions;
00275     indx++;
00276     
00277     buffer[indx] = gattEvtMask;
00278     indx++;
00279     
00280     buffer[indx] = encryKeySize;
00281     indx++;
00282     
00283     buffer[indx] = isVariable;
00284     indx++;
00285     
00286     Osal_MemSet(&resp, 0, sizeof(resp));
00287 
00288     Osal_MemSet(&rq, 0, sizeof(rq));
00289     rq.ogf = OGF_VENDOR_CMD;
00290     rq.ocf = OCF_GATT_ADD_CHAR;
00291     rq.cparam = (void *)buffer;
00292     rq.clen = indx;
00293     rq.rparam = &resp;
00294     rq.rlen = GATT_ADD_CHAR_RP_SIZE;
00295 
00296     if (hci_send_req(&rq) < 0)
00297         return -1;
00298 
00299     if (resp.status) {
00300         return resp.status;
00301     }
00302     
00303     *charHandle = resp.handle;
00304 
00305     return 0;
00306 }
00307 
00308 tBleStatus aci_gatt_add_char_desc(tHalUint16 serviceHandle,
00309                                   tHalUint16 charHandle,
00310                                   tUuidType descUuidType,
00311                                   const tHalUint8* uuid, 
00312                                   tHalUint8 descValueMaxLen,
00313                                   tHalUint8 descValueLen,
00314                                   const void* descValue, 
00315                                   tAttrSecurityFlags secPermissions,
00316                                   tAttrSecurityFlags accPermissions,
00317                                   tGattServerEvent gattEvtMask,
00318                                   tHalUint8 encryKeySize,
00319                                   tHalUint8 isVariable,
00320                                   tHalUint16* descHandle)
00321                       
00322                       
00323 {
00324     struct hci_request rq;
00325     gatt_add_char_desc_rp resp;
00326     uint8_t buffer[HCI_MAX_PACKET_SIZE];
00327     uint8_t uuid_len;
00328     uint8_t indx = 0;
00329     
00330     Osal_MemCpy(buffer + indx, &serviceHandle, 2);
00331     indx += 2;
00332     
00333     Osal_MemCpy(buffer + indx, &charHandle, 2);
00334     indx += 2;
00335     
00336     buffer[indx] = descUuidType;
00337     indx++;
00338     
00339     if(descUuidType == 0x01){
00340         uuid_len = 2;
00341     }
00342     else {
00343         uuid_len = 16;
00344     }        
00345     Osal_MemCpy(buffer + indx, uuid, uuid_len);
00346     indx +=  uuid_len;
00347     
00348     buffer[indx] = descValueMaxLen;
00349     indx++;
00350     
00351     buffer[indx] = descValueLen;
00352     indx++;
00353     
00354     Osal_MemCpy(buffer + indx, descValue, descValueLen);
00355     indx += descValueLen;
00356     
00357     buffer[indx] = secPermissions;
00358     indx++;
00359     
00360     buffer[indx] = accPermissions;
00361     indx++;
00362     
00363     buffer[indx] = gattEvtMask;
00364     indx++;
00365     
00366     buffer[indx] = encryKeySize;
00367     indx++;
00368     
00369     buffer[indx] = isVariable;
00370     indx++;
00371     
00372     Osal_MemSet(&resp, 0, sizeof(resp));
00373 
00374     Osal_MemSet(&rq, 0, sizeof(rq));
00375     rq.ogf = OGF_VENDOR_CMD;
00376     rq.ocf = OCF_GATT_ADD_CHAR_DESC;
00377     rq.cparam = (void *)buffer;
00378     rq.clen = indx;
00379     rq.rparam = &resp;
00380     rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE;
00381 
00382     if (hci_send_req(&rq) < 0)
00383         return -1;
00384 
00385     if (resp.status) {
00386         return resp.status;
00387     }
00388     
00389     *descHandle = resp.handle;
00390 
00391     return 0;
00392 }
00393 
00394 
00395 tBleStatus aci_gatt_update_char_value(tHalUint16 servHandle, 
00396                                     tHalUint16 charHandle,
00397                                     tHalUint8 charValOffset,
00398                                     tHalUint8 charValueLen,   
00399                                     const tHalUint8 *charValue)
00400 {
00401     struct hci_request rq;
00402     uint8_t status;
00403     uint8_t buffer[HCI_MAX_PACKET_SIZE];
00404     uint8_t indx = 0;
00405     
00406     Osal_MemCpy(buffer + indx, &servHandle, 2);
00407     indx += 2;
00408     
00409     Osal_MemCpy(buffer + indx, &charHandle, 2);
00410     indx += 2;
00411     
00412     buffer[indx] = charValOffset;
00413     indx++;
00414     
00415     buffer[indx] = charValueLen;
00416     indx++;
00417         
00418     Osal_MemCpy(buffer + indx, charValue, charValueLen);
00419     indx +=  charValueLen;
00420 
00421     Osal_MemSet(&rq, 0, sizeof(rq));
00422     rq.ogf = OGF_VENDOR_CMD;
00423     rq.ocf = OCF_GATT_UPD_CHAR_VAL;
00424     rq.cparam = (void *)buffer;
00425     rq.clen = indx;
00426     rq.rparam = &status;
00427     rq.rlen = 1;
00428 
00429     if (hci_send_req(&rq) < 0)
00430         return -1;
00431 
00432     if (status) {
00433         return status;
00434     }
00435 
00436     return 0;
00437 }
00438 
00439 tBleStatus aci_gatt_allow_read(tHalUint16 conn_handle)
00440 {
00441     struct hci_request rq;
00442     gatt_allow_read_cp cp;
00443     tHalUint8 status;
00444     
00445     cp.conn_handle = conn_handle;
00446 
00447     Osal_MemSet(&rq, 0, sizeof(rq));
00448     rq.ogf = OGF_VENDOR_CMD;
00449     rq.ocf = OCF_GATT_ALLOW_READ;
00450     rq.cparam = &cp;
00451     rq.clen = GATT_ALLOW_READ_CP_SIZE;
00452     rq.rparam = &status;
00453     rq.rlen = 1;
00454 
00455     if (hci_send_req(&rq) < 0)
00456         return -1;
00457 
00458     if (status) {
00459         return status;
00460     }
00461 
00462     return 0;
00463 }
00464 
00465 tBleStatus aci_gatt_set_desc_value(tHalUint16 servHandle, 
00466                                     tHalUint16 charHandle,
00467                                     tHalUint16 charDescHandle,
00468                                     tHalUint16 charDescValOffset,
00469                                     tHalUint8 charDescValueLen,   
00470                                     const tHalUint8 *charDescValue)
00471 {
00472     struct hci_request rq;
00473     uint8_t status;
00474     uint8_t buffer[HCI_MAX_PACKET_SIZE];
00475     uint8_t indx = 0;
00476     
00477     Osal_MemCpy(buffer + indx, &servHandle, 2);
00478     indx += 2;
00479     
00480     Osal_MemCpy(buffer + indx, &charHandle, 2);
00481     indx += 2;
00482     
00483     Osal_MemCpy(buffer + indx, &charDescHandle, 2);
00484     indx += 2;
00485     
00486     Osal_MemCpy(buffer + indx, &charDescValOffset, 2);
00487     indx += 2;
00488     
00489     buffer[indx] = charDescValueLen;
00490     indx++;
00491         
00492     Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen);
00493     indx +=  charDescValueLen;
00494 
00495     Osal_MemSet(&rq, 0, sizeof(rq));
00496     rq.ogf = OGF_VENDOR_CMD;
00497     rq.ocf = OCF_GATT_SET_DESC_VAL;
00498     rq.cparam = (void *)buffer;
00499     rq.clen = indx;
00500     rq.rparam = &status;
00501     rq.rlen = 1;
00502 
00503     if (hci_send_req(&rq) < 0)
00504         return -1;
00505 
00506     if (status) {
00507         return status;
00508     }
00509 
00510     return 0;
00511 }
00512 
00513 tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle)
00514 {
00515   struct hci_request rq;
00516   uint8_t status;
00517   gatt_disc_all_prim_services_cp cp;
00518 
00519   cp.conn_handle = conn_handle;
00520 
00521   Osal_MemSet(&rq, 0, sizeof(rq));
00522   rq.ogf = OGF_VENDOR_CMD;
00523   rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES;
00524   rq.cparam = &cp;
00525   rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE;
00526   rq.event = EVT_CMD_STATUS;
00527   rq.rparam = &status;
00528   rq.rlen = 1;
00529 
00530   if (hci_send_req(&rq) < 0)
00531     return -1;
00532 
00533   return status;
00534 }
00535 
00536 tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, 
00537                        uint16_t end_service_handle)
00538 {
00539   struct hci_request rq;
00540   uint8_t status;
00541   gatt_find_included_services_cp cp;
00542 
00543   cp.conn_handle = conn_handle;
00544   cp.start_handle = start_service_handle;
00545   cp.end_handle = end_service_handle;
00546 
00547   Osal_MemSet(&rq, 0, sizeof(rq));
00548   rq.ogf = OGF_VENDOR_CMD;
00549   rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES;
00550   rq.cparam = &cp;
00551   rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE;
00552   rq.event = EVT_CMD_STATUS;
00553   rq.rparam = &status;
00554   rq.rlen = 1;
00555 
00556   if (hci_send_req(&rq) < 0)
00557     return -1;
00558 
00559   return status;
00560 }
00561 
00562 tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, 
00563                         uint16_t end_attr_handle)
00564 {
00565   struct hci_request rq;
00566   uint8_t status;
00567   gatt_disc_all_charac_of_serv_cp cp;
00568 
00569   cp.conn_handle = conn_handle;
00570   cp.start_attr_handle = start_attr_handle;
00571   cp.end_attr_handle = end_attr_handle;
00572 
00573   Osal_MemSet(&rq, 0, sizeof(rq));
00574   rq.ogf = OGF_VENDOR_CMD;
00575   rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV;
00576   rq.cparam = &cp;
00577   rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE;
00578   rq.event = EVT_CMD_STATUS;
00579   rq.rparam = &status;
00580   rq.rlen = 1;
00581 
00582   if (hci_send_req(&rq) < 0)
00583     return -1;
00584 
00585   return status;
00586 }
00587 
00588 tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, 
00589                         uint16_t char_end_handle)
00590 {
00591   struct hci_request rq;
00592   uint8_t status;
00593   gatt_disc_all_charac_descriptors_cp cp;
00594 
00595   cp.conn_handle = conn_handle;
00596   cp.char_val_handle = char_val_handle;
00597   cp.char_end_handle = char_end_handle;
00598 
00599   Osal_MemSet(&rq, 0, sizeof(rq));
00600   rq.ogf = OGF_VENDOR_CMD;
00601   rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS;
00602   rq.cparam = &cp;
00603   rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE;
00604   rq.event = EVT_CMD_STATUS;
00605   rq.rparam = &status;
00606   rq.rlen = 1;
00607 
00608   if (hci_send_req(&rq) < 0)
00609     return -1;
00610 
00611   return status;
00612 }
00613 
00614 tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, 
00615                        uint8_t value_len, uint8_t *attr_value)
00616 {
00617   struct hci_request rq;
00618   uint8_t status;
00619   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00620   uint8_t indx = 0;
00621     
00622   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00623   indx += 2;
00624     
00625   Osal_MemCpy(buffer + indx, &attr_handle, 2);
00626   indx += 2;
00627 
00628   buffer[indx] = value_len;
00629   indx++;
00630         
00631   Osal_MemCpy(buffer + indx, attr_value, value_len);
00632   indx +=  value_len;
00633 
00634   Osal_MemSet(&rq, 0, sizeof(rq));
00635   rq.ogf = OGF_VENDOR_CMD;
00636   rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE;
00637   rq.cparam = (void *)buffer;
00638   rq.clen = indx;
00639   rq.rparam = &status;
00640   rq.rlen = 1;
00641 
00642   if (hci_send_req(&rq) < 0)
00643     return -1;
00644 
00645   return status;
00646 
00647 }
00648 
00649 tBleStatus aci_gatt_write_response(uint16_t conn_handle,
00650                                    uint16_t attr_handle,
00651                                    uint8_t write_status,
00652                                    uint8_t err_code,
00653                                    uint8_t att_val_len,
00654                                    uint8_t *att_val)
00655 {
00656     struct hci_request rq;
00657     uint8_t status;
00658     uint8_t buffer[HCI_MAX_PACKET_SIZE];
00659     uint8_t indx = 0;
00660     
00661     Osal_MemCpy(buffer + indx, &conn_handle, 2);
00662     indx += 2;
00663     
00664     Osal_MemCpy(buffer + indx, &attr_handle, 2);
00665     indx += 2;
00666     
00667     buffer[indx] = write_status;
00668     indx += 1;
00669     
00670     buffer[indx] = err_code;
00671     indx += 1;
00672     
00673     buffer[indx] = att_val_len;
00674     indx += 1;
00675     
00676     Osal_MemCpy(buffer + indx, &att_val, att_val_len);
00677     indx += att_val_len;
00678 
00679     Osal_MemSet(&rq, 0, sizeof(rq));
00680     rq.ogf = OGF_VENDOR_CMD;
00681     rq.ocf = OCF_GATT_WRITE_RESPONSE;
00682     rq.cparam = (void *)buffer;
00683     rq.clen = indx;
00684     rq.rparam = &status;
00685     rq.rlen = 1;
00686 
00687     if (hci_send_req(&rq) < 0)
00688         return -1;
00689 
00690     if (status) {
00691         return status;
00692     }
00693 
00694     return 0;
00695 }
00696 
00697 tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
00698 {
00699   struct hci_request rq;
00700   uint8_t status;
00701   gatt_read_charac_val_cp cp;
00702 
00703   cp.conn_handle = conn_handle;
00704   cp.attr_handle = attr_handle;
00705 
00706   Osal_MemSet(&rq, 0, sizeof(rq));
00707   rq.ogf = OGF_VENDOR_CMD;
00708   rq.ocf = OCF_GATT_READ_CHARAC_VAL;
00709   rq.cparam = &cp;
00710   rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE;
00711   rq.event = EVT_CMD_STATUS;
00712   rq.rparam = &status;
00713   rq.rlen = 1;
00714 
00715   if (hci_send_req(&rq) < 0)
00716     return -1;
00717   
00718   return status;
00719 }
00720 
00721 tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, 
00722                      uint16_t val_offset)
00723 {
00724   struct hci_request rq;
00725   uint8_t status;
00726   gatt_read_long_charac_val_cp cp;
00727 
00728   cp.conn_handle = conn_handle;
00729   cp.attr_handle = attr_handle;
00730   cp.val_offset = val_offset;
00731 
00732   Osal_MemSet(&rq, 0, sizeof(rq));
00733   rq.ogf = OGF_VENDOR_CMD;
00734   rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL;
00735   rq.cparam = &cp;
00736   rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE;
00737   rq.event = EVT_CMD_STATUS;
00738   rq.rparam = &status;
00739   rq.rlen = 1;
00740 
00741   if (hci_send_req(&rq) < 0)
00742     return -1;
00743 
00744   return status;
00745 }
00746 
00747 tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, 
00748                        uint8_t value_len, uint8_t *attr_value)
00749 {
00750   struct hci_request rq;
00751   uint8_t status;
00752   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00753   uint8_t indx = 0;
00754     
00755   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00756   indx += 2;
00757     
00758   Osal_MemCpy(buffer + indx, &attr_handle, 2);
00759   indx += 2;
00760 
00761   buffer[indx] = value_len;
00762   indx++;
00763         
00764   Osal_MemCpy(buffer + indx, attr_value, value_len);
00765   indx +=  value_len;
00766 
00767   Osal_MemSet(&rq, 0, sizeof(rq));
00768   rq.ogf = OGF_VENDOR_CMD;
00769   rq.ocf = OCF_GATT_WRITE_CHAR_VALUE;
00770   rq.cparam = (void *)buffer;
00771   rq.clen = indx;
00772   rq.event = EVT_CMD_STATUS;
00773   rq.rparam = &status;
00774   rq.rlen = 1;
00775 
00776   if (hci_send_req(&rq) < 0)
00777     return -1;
00778 
00779   return status;
00780 }
00781 
00782 tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, 
00783                        uint8_t value_len, uint8_t *attr_value)
00784 {
00785   struct hci_request rq;
00786   uint8_t status;
00787   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00788   uint8_t indx = 0;
00789     
00790   Osal_MemCpy(buffer + indx, &conn_handle, 2);
00791   indx += 2;
00792     
00793   Osal_MemCpy(buffer + indx, &attr_handle, 2);
00794   indx += 2;
00795 
00796   buffer[indx] = value_len;
00797   indx++;
00798         
00799   Osal_MemCpy(buffer + indx, attr_value, value_len);
00800   indx +=  value_len;
00801 
00802   Osal_MemSet(&rq, 0, sizeof(rq));
00803   rq.ogf = OGF_VENDOR_CMD;
00804   rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR;
00805   rq.cparam = (void *)buffer;
00806   rq.clen = indx;
00807   rq.rparam = &status;
00808   rq.rlen = 1;
00809 
00810   if (hci_send_req(&rq) < 0)
00811     return -1;
00812 
00813   return status;
00814 }
00815 
00816 tBleStatus aci_hal_write_config_data(tHalUint8 offset, 
00817                                     tHalUint8 len,
00818                                     const tHalUint8 *val)
00819 {
00820     struct hci_request rq;
00821     uint8_t status;
00822     uint8_t buffer[HCI_MAX_PACKET_SIZE];
00823     uint8_t indx = 0;
00824     
00825     buffer[indx] = offset;
00826     indx++;
00827     
00828     buffer[indx] = len;
00829     indx++;
00830         
00831     Osal_MemCpy(buffer + indx, val, len);
00832     indx +=  len;
00833 
00834     Osal_MemSet(&rq, 0, sizeof(rq));
00835     rq.ogf = OGF_VENDOR_CMD;
00836     rq.ocf = OCF_HAL_WRITE_CONFIG_DATA;
00837     rq.cparam = (void *)buffer;
00838     rq.clen = indx;
00839     rq.rparam = &status;
00840     rq.rlen = 1;
00841 
00842     if (hci_send_req(&rq) < 0)
00843         return -1;
00844 
00845     if (status) {
00846         return status;
00847     }
00848 
00849     return 0;
00850 }
00851 
00852 tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level)
00853 {
00854     struct hci_request rq;
00855     hal_set_tx_power_level_cp cp;    
00856     uint8_t status;
00857     
00858     cp.en_high_power = en_high_power;
00859     cp.pa_level = pa_level;
00860 
00861     Osal_MemSet(&rq, 0, sizeof(rq));
00862     rq.ogf = OGF_VENDOR_CMD;
00863     rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL;
00864     rq.cparam = &cp;
00865     rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE;
00866     rq.rparam = &status;
00867     rq.rlen = 1;
00868 
00869     if (hci_send_req(&rq) < 0)
00870         return -1;
00871 
00872     if (status) {
00873         return status;
00874     }
00875 
00876     return 0;
00877 }
00878 
00879 tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode,
00880                                         uint8_t oob_enable,
00881                                         uint8_t oob_data[16],
00882                                         uint8_t min_encryption_key_size,
00883                                         uint8_t max_encryption_key_size,
00884                                         uint8_t use_fixed_pin,
00885                                         uint32_t fixed_pin,
00886                                         uint8_t bonding_mode)
00887 {
00888     struct hci_request rq;
00889     gap_set_auth_requirement_cp cp;    
00890     uint8_t status;
00891     
00892     cp.mitm_mode = mitm_mode;
00893     cp.oob_enable = oob_enable;
00894     Osal_MemCpy(cp.oob_data, oob_data, 16);
00895     cp.min_encryption_key_size = min_encryption_key_size;
00896     cp.max_encryption_key_size = max_encryption_key_size;
00897     cp.use_fixed_pin = use_fixed_pin;
00898     cp.fixed_pin = fixed_pin;
00899     cp.bonding_mode = bonding_mode;
00900 
00901     Osal_MemSet(&rq, 0, sizeof(rq));
00902     rq.ogf = OGF_VENDOR_CMD;
00903     rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT;
00904     rq.cparam = &cp;
00905     rq.clen = GAP_SET_AUTH_REQUIREMENT_CP_SIZE;
00906     rq.rparam = &status;
00907     rq.rlen = 1;
00908 
00909     if (hci_send_req(&rq) < 0)
00910         return -1;
00911 
00912     if (status) {
00913         return status;
00914     }
00915     
00916     return 0;
00917 
00918 }
00919 
00920 tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
00921                         uint8_t own_address_type, uint8_t filterDuplicates)
00922 {
00923   struct hci_request rq;
00924   gap_start_limited_discovery_proc_cp cp;
00925   uint8_t status;  
00926 
00927   cp.scanInterval = scanInterval;
00928   cp.scanWindow = scanWindow;
00929   cp.own_address_type = own_address_type;
00930   cp.filterDuplicates = filterDuplicates;
00931 
00932   Osal_MemSet(&rq, 0, sizeof(rq));
00933   rq.ogf = OGF_VENDOR_CMD;
00934   rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC;
00935   rq.cparam = &cp;
00936   rq.clen = GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE;
00937   rq.event = EVT_CMD_STATUS;
00938   rq.rparam = &status;
00939   rq.rlen = 1;
00940   
00941   if (hci_send_req(&rq) < 0)
00942     return -1;
00943 
00944   return status;
00945 }
00946 
00947 tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
00948                         uint8_t own_address_type, uint8_t filterDuplicates)
00949 {
00950   struct hci_request rq;
00951   gap_start_general_discovery_proc_cp cp;
00952   uint8_t status;  
00953 
00954   cp.scanInterval = scanInterval;
00955   cp.scanWindow = scanWindow;
00956   cp.own_address_type = own_address_type;
00957   cp.filterDuplicates = filterDuplicates;
00958 
00959   Osal_MemSet(&rq, 0, sizeof(rq));
00960   rq.ogf = OGF_VENDOR_CMD;
00961   rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC;
00962   rq.cparam = &cp;
00963   rq.clen = GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE;
00964   rq.event = EVT_CMD_STATUS;
00965   rq.rparam = &status;
00966   rq.rlen = 1;
00967   
00968   if (hci_send_req(&rq) < 0)
00969     return -1;
00970 
00971   return status;
00972 }
00973 
00974 
00975 tBleStatus aci_gap_start_auto_conn_establishment(uint16_t scanInterval, uint16_t scanWindow,
00976                          uint8_t own_bdaddr_type, uint16_t conn_min_interval,   
00977                          uint16_t conn_max_interval, uint16_t conn_latency, 
00978                          uint16_t supervision_timeout, uint16_t min_conn_length, 
00979                          uint16_t max_conn_length, uint8_t num_whitelist_entries,
00980                          uint8_t *addr_array)
00981 {
00982   struct hci_request rq;
00983   uint8_t status;
00984   uint8_t buffer[HCI_MAX_PACKET_SIZE];
00985   uint8_t indx = 0;
00986     
00987   Osal_MemCpy(buffer + indx, &scanInterval, 2);
00988   indx += 2;
00989     
00990   Osal_MemCpy(buffer + indx, &scanWindow, 2);
00991   indx += 2;
00992 
00993   buffer[indx] = own_bdaddr_type;
00994   indx++;
00995         
00996   Osal_MemCpy(buffer + indx, &conn_min_interval, 2);
00997   indx +=  2;
00998 
00999   Osal_MemCpy(buffer + indx, &conn_max_interval, 2);
01000   indx +=  2;
01001 
01002   Osal_MemCpy(buffer + indx, &conn_latency, 2);
01003   indx +=  2;
01004 
01005   Osal_MemCpy(buffer + indx, &supervision_timeout, 2);
01006   indx +=  2;
01007 
01008   Osal_MemCpy(buffer + indx, &min_conn_length, 2);
01009   indx +=  2;
01010 
01011   Osal_MemCpy(buffer + indx, &max_conn_length, 2);
01012   indx +=  2;
01013 
01014   buffer[indx] = num_whitelist_entries;
01015   indx++;
01016 
01017   Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7));
01018   indx +=  num_whitelist_entries * 7;
01019 
01020   Osal_MemSet(&rq, 0, sizeof(rq));
01021   rq.ogf = OGF_VENDOR_CMD;
01022   rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISHMENT;
01023   rq.cparam = (void *)buffer;
01024   rq.clen = indx;
01025   rq.event = EVT_CMD_STATUS;
01026   rq.rparam = &status;
01027   rq.rlen = 1;
01028 
01029   if (hci_send_req(&rq) < 0)
01030     return -1;
01031 
01032   return status;  
01033 }
01034 
01035 tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow,
01036                      uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, 
01037                      uint8_t own_bdaddr_type, uint16_t conn_min_interval,   
01038                      uint16_t conn_max_interval, uint16_t conn_latency, 
01039                      uint16_t supervision_timeout, uint16_t min_conn_length, 
01040                      uint16_t max_conn_length)
01041 {
01042   struct hci_request rq;
01043   gap_create_connection_cp cp;
01044   uint8_t status;  
01045 
01046   cp.scanInterval = scanInterval;
01047   cp.scanWindow = scanWindow;
01048   cp.peer_bdaddr_type = peer_bdaddr_type;
01049   Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6);
01050   cp.own_bdaddr_type = own_bdaddr_type;
01051   cp.conn_min_interval = conn_min_interval;
01052   cp.conn_max_interval = conn_max_interval;
01053   cp.conn_latency = conn_latency;
01054   cp.supervision_timeout = supervision_timeout;
01055   cp.min_conn_length = min_conn_length;
01056   cp.max_conn_length = max_conn_length;
01057 
01058   Osal_MemSet(&rq, 0, sizeof(rq));
01059   rq.ogf = OGF_VENDOR_CMD;
01060   rq.ocf = OCF_GAP_CREATE_CONNECTION;
01061   rq.cparam = &cp;
01062   rq.clen = GAP_CREATE_CONNECTION_CP_SIZE;
01063   rq.event = EVT_CMD_STATUS;
01064   rq.rparam = &status;
01065   rq.rlen = 1;
01066   
01067   if (hci_send_req(&rq) < 0)
01068     return -1;
01069 
01070   return status;
01071 }
01072 
01073 tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code)
01074 {
01075   struct hci_request rq;
01076   uint8_t status;  
01077 
01078   Osal_MemSet(&rq, 0, sizeof(rq));
01079   rq.ogf = OGF_VENDOR_CMD;
01080   rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE;
01081   rq.cparam = &procedure_code;
01082   rq.clen = 1;
01083   rq.rparam = &status;
01084   rq.rlen = 1;
01085   
01086   if (hci_send_req(&rq) < 0)
01087     return -1;
01088 
01089   return status;
01090 
01091 }
01092 
01093 tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason)
01094 {
01095   struct hci_request rq;
01096   gap_terminate_cp cp;
01097   uint8_t status;  
01098 
01099   cp.handle = conn_handle;
01100   cp.reason = reason;
01101 
01102   Osal_MemSet(&rq, 0, sizeof(rq));
01103   rq.ogf = OGF_VENDOR_CMD;
01104   rq.ocf = OCF_GAP_TERMINATE;
01105   rq.cparam = &cp;
01106   rq.clen = GAP_TERMINATE_CP_SIZE;
01107   rq.event = EVT_CMD_STATUS;
01108   rq.rparam = &status;
01109   rq.rlen = 1;
01110   
01111   if (hci_send_req(&rq) < 0)
01112     return -1;
01113 
01114   return status; 
01115 }
01116 
01117 tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, uint16_t interval_max, 
01118                                             uint16_t slave_latency, uint16_t timeout_mult)
01119 {
01120     struct hci_request rq;
01121     l2cap_conn_param_upd_cp cp;
01122     tHalUint8 status;
01123  
01124     cp.handle               = conn_handle;
01125     cp.interval_min         = interval_min;
01126     cp.interval_max         = interval_max; 
01127     cp.slave_latency        = slave_latency;
01128     cp.timeout_multiplier   = timeout_mult;
01129     
01130     Osal_MemSet(&rq, 0, sizeof(rq));
01131     rq.ogf = OGF_VENDOR_CMD;
01132     rq.ocf = OCF_L2CAP_CONN_PARAM_UPD_REQ;
01133     rq.event = EVT_CMD_STATUS;
01134     rq.cparam = &cp;
01135     rq.clen = L2CAP_CONN_PARAM_UPD_REQ_CP_SIZE;
01136     rq.rparam = &status;
01137     rq.rlen = 1;
01138  
01139     if (hci_send_req(&rq) < 0)
01140         return -1;
01141  
01142     return status;
01143 }
01144 
01145 
01146 tBleStatus aci_hal_tone_start(uint8_t rf_channel)
01147 {
01148     struct hci_request rq;
01149     hal_tone_start_cp cp;    
01150     uint8_t status;
01151     
01152     cp.rf_channel = rf_channel;
01153 
01154     Osal_MemSet(&rq, 0, sizeof(rq));
01155     rq.ogf = OGF_VENDOR_CMD;
01156     rq.ocf = OCF_HAL_TONE_START;
01157     rq.cparam = &cp;
01158     rq.clen = HAL_TONE_START_CP_SIZE;
01159     rq.rparam = &status;
01160     rq.rlen = 1;
01161 
01162     if (hci_send_req(&rq) < 0)
01163         return -1;
01164 
01165     if (status) {
01166         return status;
01167     }
01168     
01169     return 0;
01170 }
01171 
01172 tBleStatus aci_updater_start(void)
01173 {
01174     struct hci_request rq;
01175     tHalUint8 status;
01176 
01177     Osal_MemSet(&rq, 0, sizeof(rq));
01178     rq.ogf = OGF_VENDOR_CMD;
01179     rq.ocf = OCF_UPDATER_START;
01180     rq.rparam = &status;
01181     rq.rlen = 1;
01182 
01183     if (hci_send_req(&rq) < 0)
01184         return -1;
01185 
01186     return status;  
01187 }
01188 
01189 tBleStatus aci_updater_reboot()
01190 {
01191     struct hci_request rq;
01192     tHalUint8 status;
01193 
01194     Osal_MemSet(&rq, 0, sizeof(rq));
01195     rq.ogf = OGF_VENDOR_CMD;
01196     rq.ocf = OCF_UPDATER_REBOOT;
01197     rq.rparam = &status;
01198     rq.rlen = 1;
01199 
01200     if (hci_send_req(&rq) < 0)
01201         return -1;
01202 
01203     return status;  
01204 }
01205 
01206 tBleStatus aci_get_updater_version(uint8_t *version)
01207 {
01208     struct hci_request rq;
01209     get_updater_version_rp resp;
01210 
01211     Osal_MemSet(&resp, 0, sizeof(resp));
01212 
01213     Osal_MemSet(&rq, 0, sizeof(rq));
01214     rq.ogf = OGF_VENDOR_CMD;
01215     rq.ocf = OCF_GET_UPDATER_VERSION;
01216     rq.rparam = &resp;
01217     rq.rlen = GET_UPDATER_VERSION_RP_SIZE;
01218 
01219     if (hci_send_req(&rq) < 0)
01220         return -1;
01221     
01222     *version = resp.version;
01223 
01224     return resp.status;
01225 }
01226 
01227 tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size)
01228 {
01229     struct hci_request rq;
01230     get_updater_bufsize_rp resp;
01231 
01232     Osal_MemSet(&resp, 0, sizeof(resp));
01233 
01234     Osal_MemSet(&rq, 0, sizeof(rq));
01235     rq.ogf = OGF_VENDOR_CMD;
01236     rq.ocf = OCF_GET_UPDATER_BUFSIZE;
01237     rq.rparam = &resp;
01238     rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE;
01239 
01240     if (hci_send_req(&rq) < 0)
01241         return -1;
01242     
01243     *buffer_size = resp.buffer_size;
01244 
01245     return resp.status;
01246 }
01247 
01248 tBleStatus aci_erase_blue_flag()
01249 {
01250     struct hci_request rq;
01251     tHalUint8 status;
01252 
01253     Osal_MemSet(&rq, 0, sizeof(rq));
01254     rq.ogf = OGF_VENDOR_CMD;
01255     rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG;
01256     rq.rparam = &status;
01257     rq.rlen = 1;
01258 
01259     if (hci_send_req(&rq) < 0)
01260         return -1;
01261 
01262     return status;  
01263 }
01264 
01265 tBleStatus aci_reset_blue_flag()
01266 {
01267     struct hci_request rq;
01268     tHalUint8 status;
01269 
01270     Osal_MemSet(&rq, 0, sizeof(rq));
01271     rq.ogf = OGF_VENDOR_CMD;
01272     rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG;
01273     rq.rparam = &status;
01274     rq.rlen = 1;
01275 
01276     if (hci_send_req(&rq) < 0)
01277         return -1;
01278 
01279     return status;  
01280 }
01281 
01282 tBleStatus aci_updater_erase_sector(uint32_t address)
01283 {
01284     struct hci_request rq;
01285     updater_erase_sector_cp cp;    
01286     uint8_t status;
01287     
01288     cp.address = address;
01289 
01290     Osal_MemSet(&rq, 0, sizeof(rq));
01291     rq.ogf = OGF_VENDOR_CMD;
01292     rq.ocf = OCF_UPDATER_ERASE_SECTOR;
01293     rq.cparam = &cp;
01294     rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE;
01295     rq.rparam = &status;
01296     rq.rlen = 1;
01297 
01298     if (hci_send_req(&rq) < 0)
01299         return -1;
01300 
01301     return status;
01302 }
01303 
01304 tBleStatus aci_updater_program_data_block(uint32_t address, 
01305                                     uint16_t len,
01306                                     const uint8_t *data)
01307 {
01308     struct hci_request rq;
01309     uint8_t status;
01310     uint8_t buffer[HCI_MAX_PACKET_SIZE];
01311     uint8_t indx = 0;
01312     
01313     if(len > HCI_MAX_PACKET_SIZE)
01314         return -1;
01315     
01316     Osal_MemCpy(buffer + indx, &address, 4);
01317     indx += 4;
01318     
01319     Osal_MemCpy(buffer + indx, &len, 2);
01320     indx += 2;
01321         
01322     Osal_MemCpy(buffer + indx, data, len);
01323     indx +=  len;
01324 
01325     Osal_MemSet(&rq, 0, sizeof(rq));
01326     rq.ogf = OGF_VENDOR_CMD;
01327     rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK;
01328     rq.cparam = (void *)buffer;
01329     rq.clen = indx;
01330     rq.rparam = &status;
01331     rq.rlen = 1;
01332 
01333     if (hci_send_req(&rq) < 0)
01334         return -1;
01335     
01336     return status;
01337 }
01338 
01339 tBleStatus aci_updater_read_data_block(uint32_t address,
01340                                        uint16_t data_len,
01341                                        uint8_t *data)
01342 {
01343     struct hci_request rq;
01344     updater_read_data_block_cp cp;
01345     uint8_t buffer[HCI_MAX_PACKET_SIZE];
01346     
01347     if(data_len > HCI_MAX_PACKET_SIZE - 1)
01348         return -1;
01349     
01350     cp.address = address;
01351     cp.data_len = data_len;
01352 
01353     Osal_MemSet(&rq, 0, sizeof(rq));
01354     rq.ogf = OGF_VENDOR_CMD;
01355     rq.ocf = OCF_UPDATER_READ_DATA_BLOCK;
01356     rq.cparam = &cp;
01357     rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE;
01358     rq.rparam = buffer;
01359     rq.rlen = data_len + 1;
01360 
01361     if (hci_send_req(&rq) < 0)
01362         return -1;
01363     
01364     Osal_MemCpy(data, buffer+1, data_len);
01365 
01366     return buffer[0];
01367 }
01368 
01369 tBleStatus aci_updater_calc_crc(uint32_t address,
01370                          uint8_t num_sectors,
01371                          uint32_t *crc)
01372 {
01373     struct hci_request rq;
01374     updater_calc_crc_cp cp;
01375     updater_calc_crc_rp resp;
01376     
01377     Osal_MemSet(&resp, 0, sizeof(resp));
01378     
01379     cp.address = address;
01380     cp.num_sectors = num_sectors;
01381 
01382     Osal_MemSet(&rq, 0, sizeof(rq));
01383     rq.ogf = OGF_VENDOR_CMD;
01384     rq.ocf = OCF_UPDATER_CALC_CRC;
01385     rq.cparam = &cp;
01386     rq.clen = UPDATER_CALC_CRC_CP_SIZE;
01387     rq.rparam = &resp;
01388     rq.rlen = UPDATER_CALC_CRC_RP_SIZE;
01389 
01390     if (hci_send_req(&rq) < 0)
01391         return -1;
01392     
01393     *crc = resp.crc;
01394     
01395     return resp.status;
01396 }
01397 
01398 tBleStatus aci_updater_hw_version(uint8_t *version)
01399 {
01400     struct hci_request rq;
01401     updater_hw_version_rp resp;
01402 
01403     Osal_MemSet(&resp, 0, sizeof(resp));
01404 
01405     Osal_MemSet(&rq, 0, sizeof(rq));
01406     rq.ogf = OGF_VENDOR_CMD;
01407     rq.ocf = OCF_UPDATER_HW_VERSION;
01408     rq.rparam = &resp;
01409     rq.rlen = UPDATER_HW_VERSION_RP_SIZE;
01410 
01411     if (hci_send_req(&rq) < 0)
01412         return -1;
01413     
01414     *version = resp.version;
01415 
01416     return resp.status;
01417 }