BtStatus FmpReadServiceDB(BD_ADDR *bd_addr, FmpServiceDB **servicedb) { S32 fd; BD_ADDR addr; FmpServiceDB *db; S32 pos_file_end; S32 pos_end; U16 service_size; fd = btmtk_fs_open((const U8*)FMP_SERVICE_DATABASE_FILE, BTMTK_FS_READ_ONLY); if (fd < 0) { // file is not exist return BT_STATUS_FAILED; } service_size = sizeof(FmpServiceDB); pos_file_end = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_END); pos_end = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_BEGIN); /* Seach database file util the end of the file */ while (pos_end != pos_file_end) { btmtk_fs_read(fd, (U8 *)&addr, 6); Report(("[FMP] read service db, addr: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5])); if (!fmp_dev_addr_equal(bd_addr, &addr)) { pos_end = btmtk_fs_seek(fd, service_size - 6, BTMTK_FS_SEEK_CURRENT); continue; } break; } if (pos_end == pos_file_end) { /* No matched device database has been found */ btmtk_fs_close(fd); return BT_STATUS_FAILED; } db = (FmpServiceDB *)fmp_malloc(sizeof(FmpServiceDB)); if (db == NULL) { return BT_STATUS_NO_RESOURCES; } btmtk_fs_seek(fd, pos_end, BTMTK_FS_SEEK_BEGIN); btmtk_fs_read(fd, (U8 *)db, service_size); Report(("[FMP] read service db, handle: 0x%x 0x%x 0x%x ", db->start_handle, db->end_handle, db->char_value_handle)); btmtk_fs_close(fd); *servicedb = db; return BT_STATUS_SUCCESS; }
void BleServiceDbLoadRecord(void) { if (BleDbCtx(loadCount) == 0) { Report(("[BleDB] Loading record...")); // kal_trace(BT_TRACE_BLE_PROFILES, BLEDB_LOADRECORD); BT_GattRegisterConnectedEvent(&BleDbCtx(gattHandler), BleServiceDbGattEventCallback); BleDbCtx(bondingHandler).callback = BleServiceDbBondingCb; ATTDB_RegisterBondStatus(&BleDbCtx(bondingHandler)); if (btmtk_fs_is_dir_exist((const U8*)BLE_SERVICE_DATABASE_FILE)) { S32 fd; S32 pos_current; S32 pos_end; ble_service_db *db_node; fd = btmtk_fs_open((const U8*)BLE_SERVICE_DATABASE_FILE, BTMTK_FS_READ_ONLY); if (fd < 0) { // file is not exist goto exit; } pos_end = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_END); pos_current = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_BEGIN); while (pos_current < pos_end) { db_node = (ble_service_db *)get_ctrl_buffer(sizeof(ble_service_db)); OS_MemSet((U8 *)db_node, 0, sizeof(ble_service_db)); btmtk_fs_read(fd, (U8 *)db_node + sizeof(ListEntry), sizeof(ble_service_db) - sizeof(ListEntry)); pos_current += (sizeof(ble_service_db) - sizeof(ListEntry)); InsertTailList(&BleDbCtx(servicedbList), &db_node->node); } btmtk_fs_close(fd); } } exit: BleDbCtx(loadCount)++; }
void BleServiceDbUpdateRecord(ble_service_db *servicedb) { S32 fd; S32 pos_current; S32 pos_end; U32 mode = BTMTK_FS_READ_WRITE; U8 *db_buff; if (!btmtk_fs_is_dir_exist((const U8*)BLE_SERVICE_DATABASE_FILE)) { mode |= BTMTK_FS_CREATE; } fd = btmtk_fs_open((const U8*)BLE_SERVICE_DATABASE_FILE, mode); if (fd < 0) { return; } pos_end = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_END); pos_current = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_BEGIN); db_buff = (U8 *)get_ctrl_buffer(sizeof(ble_service_db) - sizeof(ListEntry)); while (pos_current < pos_end) { btmtk_fs_read(fd, db_buff, sizeof(ble_service_db) - sizeof(ListEntry)); if (OS_MemCmp(db_buff, 6, servicedb->bdAddr.addr, 6)) { btmtk_fs_seek(fd, pos_current, BTMTK_FS_SEEK_BEGIN); break; } pos_current += (sizeof(ble_service_db) - sizeof(ListEntry)); } free_ctrl_buffer(db_buff); Report(("[BleDB] Update record in file, seek offset: %d", pos_current)); // kal_trace(BT_TRACE_BLE_PROFILES, BLEDB_UPDATERECORD_OFFSET, pos_current); btmtk_fs_write(fd, ((U8 *)servicedb) + sizeof(ListEntry), sizeof(ble_service_db) - sizeof(ListEntry)); btmtk_fs_close(fd); }
void FmpWriteServiceDB(FmpServiceDB *servicedb) { S32 fd; U32 mode = BTMTK_FS_READ_WRITE; if (!btmtk_fs_is_dir_exist((const U8*)FMP_SERVICE_DATABASE_FILE)) { mode |= BTMTK_FS_CREATE; } fd = btmtk_fs_open((const U8*)FMP_SERVICE_DATABASE_FILE, mode); if (fd < 0) { return; } btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_END); /* There might be paddings in file caused by 4 bytes alignment in structure */ btmtk_fs_write(fd, (U8 *)servicedb, sizeof(FmpServiceDB)); btmtk_fs_close(fd); }
static void BleServiceDbRemoveRecord(const BD_ADDR *bd_addr) { S32 fd; S32 fd_temp; S32 pos_current; S32 pos_end; U8 *db_buff; U8 *buffer; if (!btmtk_fs_is_dir_exist((const U8*)BLE_SERVICE_DATABASE_FILE)) { return; } fd = btmtk_fs_open((const U8*)BLE_SERVICE_DATABASE_FILE, BTMTK_FS_READ_WRITE); if (fd < 0) { return; } pos_end = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_END); pos_current = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_BEGIN); db_buff = (U8 *)get_ctrl_buffer(sizeof(ble_service_db) - sizeof(ListEntry)); while (pos_current < pos_end) { btmtk_fs_read(fd, db_buff, sizeof(ble_service_db) - sizeof(ListEntry)); if (OS_MemCmp(db_buff, 6, bd_addr->addr, 6)) { break; } pos_current += (sizeof(ble_service_db) - sizeof(ListEntry)); } free_ctrl_buffer(db_buff); if (pos_current == pos_end) { Report(("[BleDB] Remove record, NOT FOUND!")); // kal_trace(BT_TRACE_BLE_PROFILES, BLEDB_REMOVERECORD_NOTFOUND);. return; } /* Case 1: If there is only one database, delete the file directly */ if (pos_end - pos_current == sizeof(ble_service_db) - sizeof(ListEntry)) { Report(("[BleDB] Remove record, delete file directly...")); // kal_trace(BT_TRACE_BLE_PROFILES, BLEDB_REMOVERECORD_DELETEFILE); btmtk_fs_delete((const U8 *)BLE_SERVICE_DATABASE_FILE); return; } /* Case 2: If there is more than one database, create a new temp file, * move the left database to the temp file, delete the original database * file, and rename the temp file as the new database file. */ fd_temp = btmtk_fs_open((const U8*)BLE_SERVICE_DATABASE_TEMP_FILE, BTMTK_FS_READ_WRITE | BTMTK_FS_CREATE); if (fd_temp < 0) { return; } if (pos_current > 0) { /* Move first half of the database to temp file */ buffer = (U8 *)get_ctrl_buffer(pos_current); btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_BEGIN); btmtk_fs_read(fd, buffer, pos_current); btmtk_fs_write(fd_temp, buffer, pos_current); free_ctrl_buffer(buffer); } pos_current = btmtk_fs_seek(fd, sizeof(ble_service_db) - sizeof(ListEntry), BTMTK_FS_SEEK_CURRENT); if (pos_current < pos_end) { /* Move first half of the database to temp file */ buffer = (U8 *)get_ctrl_buffer(pos_end - pos_current); btmtk_fs_read(fd, buffer, pos_end - pos_current); btmtk_fs_write(fd_temp, buffer, pos_end - pos_current); free_ctrl_buffer(buffer); } Report(("[BleDB] pos cur: %d, pos end: %d", pos_current, pos_end)); btmtk_fs_close(fd); btmtk_fs_close(fd_temp); btmtk_fs_delete((const U8 *)BLE_SERVICE_DATABASE_FILE); btmtk_fs_rename((const U8 *)BLE_SERVICE_DATABASE_TEMP_FILE, (const U8 *)BLE_SERVICE_DATABASE_FILE); }
void FmpRemoveServiceDB(BD_ADDR *bd_addr) { S32 fd; S32 fd_temp; BD_ADDR addr; U16 service_size; S32 pos_file_end; S32 pos_start; S32 pos_end; U8 *buffer; fd = btmtk_fs_open((const U8*)FMP_SERVICE_DATABASE_FILE, BTMTK_FS_READ_ONLY); if (fd < 0) { // file is not exist return; } service_size = sizeof(FmpServiceDB); pos_file_end = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_END); pos_start = btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_BEGIN); pos_end = pos_start; /* Seach database file util the end of the file */ while (pos_end != pos_file_end) { btmtk_fs_read(fd, (U8 *)&addr, 6); Report(("[FMP] write service db, addr: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5])); if (!fmp_dev_addr_equal(bd_addr, &addr)) { pos_end = btmtk_fs_seek(fd, service_size - 6, BTMTK_FS_SEEK_CURRENT); continue; } break; } if (pos_end == pos_file_end) { /* No matched device database has been found */ kal_trace(BT_TRACE_BLE_PROFILES, FMP_REMOVEDATABASE_NO_MATCHED); btmtk_fs_close(fd); return; } /* Case 1: If there is only one database, delete the file directly */ if (pos_file_end - pos_start == service_size) { kal_trace(BT_TRACE_BLE_PROFILES, HTP_REMOVEDATABASE_DELETEFILE); btmtk_fs_delete((const U8 *)FMP_SERVICE_DATABASE_FILE); return; } /* Case 2: If there is more than one database, create a new temp file, * move the left database to the temp file, delete the original database * file, and rename the temp file as the new database file. */ fd_temp = btmtk_fs_open((const U8*)FMP_SERVICE_DATABASE_TEMP_FILE, BTMTK_FS_READ_WRITE | BTMTK_FS_CREATE); if (fd_temp < 0) { return; } if (pos_end != pos_start) { /* Move first half of the database to temp file */ buffer = (U8 *)fmp_malloc(pos_end - pos_start); btmtk_fs_seek(fd, 0, BTMTK_FS_SEEK_BEGIN); btmtk_fs_read(fd, buffer, pos_end - pos_start); btmtk_fs_write(fd_temp, buffer, pos_end - pos_start); fmp_free(buffer); pos_start = btmtk_fs_seek(fd, service_size, BTMTK_FS_SEEK_CURRENT); } else { pos_start = btmtk_fs_seek(fd, service_size - 6, BTMTK_FS_SEEK_CURRENT); } if (pos_start != pos_file_end) { /* Move first half of the database to temp file */ buffer = (U8 *)fmp_malloc(pos_file_end - pos_start); btmtk_fs_read(fd, buffer, pos_file_end - pos_start); btmtk_fs_write(fd_temp, buffer, pos_file_end - pos_start); fmp_free(buffer); } btmtk_fs_close(fd); btmtk_fs_close(fd_temp); btmtk_fs_delete((const U8 *)FMP_SERVICE_DATABASE_FILE); btmtk_fs_rename((const U8 *)FMP_SERVICE_DATABASE_TEMP_FILE, (const U8 *)FMP_SERVICE_DATABASE_FILE); }