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