1d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent/* 2d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** 3d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** Copyright 2015, The Android Open Source Project 4d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** 5d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** Licensed under the Apache License, Version 2.0 (the "License"); 6d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** you may not use this file except in compliance with the License. 7d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** You may obtain a copy of the License at 8d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** 9d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** http://www.apache.org/licenses/LICENSE-2.0 10d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** 11d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** Unless required by applicable law or agreed to in writing, software 12d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** distributed under the License is distributed on an "AS IS" BASIS, 13d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** See the License for the specific language governing permissions and 15d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent** limitations under the License. 16d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent*/ 17d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 18d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#define LOG_TAG "BpRadioService" 19d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent// 20d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#define LOG_NDEBUG 0 21d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 22d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <utils/Log.h> 23d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <utils/Errors.h> 24d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 25d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <stdint.h> 26d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <sys/types.h> 27d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <binder/IMemory.h> 28d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <binder/Parcel.h> 29d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <binder/IPCThreadState.h> 30d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <binder/IServiceManager.h> 31d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 32d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <radio/IRadioService.h> 33d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <radio/IRadio.h> 34d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#include <radio/IRadioClient.h> 35d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 36d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentnamespace android { 37d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 38d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentenum { 39d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION, 40d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent ATTACH, 41d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent}; 42d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 43d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent#define MAX_ITEMS_PER_LIST 1024 44d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 45d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentclass BpRadioService: public BpInterface<IRadioService> 46d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent{ 47d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentpublic: 48d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent BpRadioService(const sp<IBinder>& impl) 49d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent : BpInterface<IRadioService>(impl) 50d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent { 51d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 52d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 53d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent virtual status_t listModules(struct radio_properties *properties, 54d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent uint32_t *numModules) 55d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent { 56d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (numModules == NULL || (*numModules != 0 && properties == NULL)) { 57d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent return BAD_VALUE; 58d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 59d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent Parcel data, reply; 60d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.writeInterfaceToken(IRadioService::getInterfaceDescriptor()); 61d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent unsigned int numModulesReq = (properties == NULL) ? 0 : *numModules; 62d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.writeInt32(numModulesReq); 63d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent status_t status = remote()->transact(LIST_MODULES, data, &reply); 64d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (status == NO_ERROR) { 65d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent status = (status_t)reply.readInt32(); 66d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent *numModules = (unsigned int)reply.readInt32(); 67d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 68d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent ALOGV("listModules() status %d got *numModules %d", status, *numModules); 69d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (status == NO_ERROR) { 70d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (numModulesReq > *numModules) { 71d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent numModulesReq = *numModules; 72d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 73d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (numModulesReq > 0) { 74d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply.read(properties, numModulesReq * sizeof(struct radio_properties)); 75d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 76d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 77d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent return status; 78d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 79d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 80d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent virtual status_t attach(radio_handle_t handle, 81d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent const sp<IRadioClient>& client, 82d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent const struct radio_band_config *config, 83d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent bool withAudio, 84d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent sp<IRadio>& radio) 85d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent { 86d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent Parcel data, reply; 87d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.writeInterfaceToken(IRadioService::getInterfaceDescriptor()); 88d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.writeInt32(handle); 89d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.writeStrongBinder(IInterface::asBinder(client)); 90d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent ALOGV("attach() config %p withAudio %d region %d type %d", config, withAudio, config->region, config->band.type); 91d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (config == NULL) { 92d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.writeInt32(0); 93d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } else { 94d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.writeInt32(1); 95d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.write(config, sizeof(struct radio_band_config)); 96d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 97d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.writeInt32(withAudio ? 1 : 0); 98d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent status_t status = remote()->transact(ATTACH, data, &reply); 99d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (status != NO_ERROR) { 100d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent return status; 101d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 102d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent status = reply.readInt32(); 103d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (reply.readInt32() != 0) { 104d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent radio = interface_cast<IRadio>(reply.readStrongBinder()); 105d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 106d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent return status; 107d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 108d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent}; 109d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 110d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric LaurentIMPLEMENT_META_INTERFACE(RadioService, "android.hardware.IRadioService"); 111d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 112d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent// ---------------------------------------------------------------------- 113d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 114d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurentstatus_t BnRadioService::onTransact( 115d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 116d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent{ 117d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent switch(code) { 118d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent case LIST_MODULES: { 119d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent CHECK_INTERFACE(IRadioService, data, reply); 120d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent unsigned int numModulesReq = data.readInt32(); 121d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (numModulesReq > MAX_ITEMS_PER_LIST) { 122d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent numModulesReq = MAX_ITEMS_PER_LIST; 123d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 124d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent unsigned int numModules = numModulesReq; 125d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent struct radio_properties *properties = 126d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent (struct radio_properties *)calloc(numModulesReq, 127d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent sizeof(struct radio_properties)); 128d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (properties == NULL) { 129d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply->writeInt32(NO_MEMORY); 130d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply->writeInt32(0); 131d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent return NO_ERROR; 132d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 133d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 134d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent status_t status = listModules(properties, &numModules); 135d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply->writeInt32(status); 136d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply->writeInt32(numModules); 137d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent ALOGV("LIST_MODULES status %d got numModules %d", status, numModules); 138d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 139d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (status == NO_ERROR) { 140d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (numModulesReq > numModules) { 141d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent numModulesReq = numModules; 142d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 143d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply->write(properties, 144d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent numModulesReq * sizeof(struct radio_properties)); 145d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 146d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent free(properties); 147d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent return NO_ERROR; 148d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } break; 149d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 150d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent case ATTACH: { 151d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent CHECK_INTERFACE(IRadioService, data, reply); 152d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent radio_handle_t handle = data.readInt32(); 153d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent sp<IRadioClient> client = 154d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent interface_cast<IRadioClient>(data.readStrongBinder()); 155d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent struct radio_band_config config; 156d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent struct radio_band_config *configPtr = NULL; 157d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (data.readInt32() != 0) { 158d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent data.read(&config, sizeof(struct radio_band_config)); 159d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent configPtr = &config; 160d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 161d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent bool withAudio = data.readInt32() != 0; 162d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent ALOGV("ATTACH configPtr %p withAudio %d", configPtr, withAudio); 163d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent sp<IRadio> radio; 164d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent status_t status = attach(handle, client, configPtr, withAudio, radio); 165d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply->writeInt32(status); 166d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent if (radio != 0) { 167d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply->writeInt32(1); 168d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply->writeStrongBinder(IInterface::asBinder(radio)); 169d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } else { 170d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent reply->writeInt32(0); 171d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 172d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent return NO_ERROR; 173d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } break; 174d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent default: 175d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent return BBinder::onTransact(code, data, reply, flags); 176d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent } 177d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent} 178d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 179d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent// ---------------------------------------------------------------------------- 180d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent 181d73697b9b61be2fa227b93b5c4c8e30badd32e71Eric Laurent}; // namespace android 182