1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <sys/socket.h>
18
19#include <common_time/ICommonTimeConfig.h>
20#include <binder/Parcel.h>
21
22#include "utils.h"
23
24namespace android {
25
26/***** ICommonTimeConfig *****/
27
28enum {
29    GET_MASTER_ELECTION_PRIORITY = IBinder::FIRST_CALL_TRANSACTION,
30    SET_MASTER_ELECTION_PRIORITY,
31    GET_MASTER_ELECTION_ENDPOINT,
32    SET_MASTER_ELECTION_ENDPOINT,
33    GET_MASTER_ELECTION_GROUP_ID,
34    SET_MASTER_ELECTION_GROUP_ID,
35    GET_INTERFACE_BINDING,
36    SET_INTERFACE_BINDING,
37    GET_MASTER_ANNOUNCE_INTERVAL,
38    SET_MASTER_ANNOUNCE_INTERVAL,
39    GET_CLIENT_SYNC_INTERVAL,
40    SET_CLIENT_SYNC_INTERVAL,
41    GET_PANIC_THRESHOLD,
42    SET_PANIC_THRESHOLD,
43    GET_AUTO_DISABLE,
44    SET_AUTO_DISABLE,
45    FORCE_NETWORKLESS_MASTER_MODE,
46};
47
48const String16 ICommonTimeConfig::kServiceName("common_time.config");
49
50class BpCommonTimeConfig : public BpInterface<ICommonTimeConfig>
51{
52  public:
53    explicit BpCommonTimeConfig(const sp<IBinder>& impl)
54        : BpInterface<ICommonTimeConfig>(impl) {}
55
56    virtual status_t getMasterElectionPriority(uint8_t *priority) {
57        Parcel data, reply;
58        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
59        status_t status = remote()->transact(GET_MASTER_ELECTION_PRIORITY,
60                                             data,
61                                             &reply);
62        if (status == OK) {
63            status = reply.readInt32();
64            if (status == OK) {
65                *priority = static_cast<uint8_t>(reply.readInt32());
66            }
67        }
68
69        return status;
70    }
71
72    virtual status_t setMasterElectionPriority(uint8_t priority) {
73        Parcel data, reply;
74        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
75        data.writeInt32(static_cast<int32_t>(priority));
76        status_t status = remote()->transact(SET_MASTER_ELECTION_PRIORITY,
77                                             data,
78                                             &reply);
79        if (status == OK) {
80            status = reply.readInt32();
81        }
82
83        return status;
84    }
85
86    virtual status_t getMasterElectionEndpoint(struct sockaddr_storage *addr) {
87        Parcel data, reply;
88        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
89        status_t status = remote()->transact(GET_MASTER_ELECTION_ENDPOINT,
90                                             data,
91                                             &reply);
92        if (status == OK) {
93            status = reply.readInt32();
94            if (status == OK) {
95                deserializeSockaddr(&reply, addr);
96            }
97        }
98
99        return status;
100    }
101
102    virtual status_t setMasterElectionEndpoint(
103            const struct sockaddr_storage *addr) {
104        Parcel data, reply;
105        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
106        if (!canSerializeSockaddr(addr))
107            return BAD_VALUE;
108        if (NULL == addr) {
109            data.writeInt32(0);
110        } else {
111            data.writeInt32(1);
112            serializeSockaddr(&data, addr);
113        }
114        status_t status = remote()->transact(SET_MASTER_ELECTION_ENDPOINT,
115                                             data,
116                                             &reply);
117        if (status == OK) {
118            status = reply.readInt32();
119        }
120
121        return status;
122    }
123
124    virtual status_t getMasterElectionGroupId(uint64_t *id) {
125        Parcel data, reply;
126        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
127        status_t status = remote()->transact(GET_MASTER_ELECTION_GROUP_ID,
128                                             data,
129                                             &reply);
130
131        if (status == OK) {
132            status = reply.readInt32();
133            if (status == OK) {
134                *id = static_cast<uint64_t>(reply.readInt64());
135            }
136        }
137
138        return status;
139    }
140
141    virtual status_t setMasterElectionGroupId(uint64_t id) {
142        Parcel data, reply;
143        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
144        data.writeInt64(id);
145        status_t status = remote()->transact(SET_MASTER_ELECTION_GROUP_ID,
146                                             data,
147                                             &reply);
148
149        if (status == OK) {
150            status = reply.readInt32();
151        }
152
153        return status;
154    }
155
156    virtual status_t getInterfaceBinding(String16& ifaceName) {
157        Parcel data, reply;
158        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
159        status_t status = remote()->transact(GET_INTERFACE_BINDING,
160                                             data,
161                                             &reply);
162        if (status == OK) {
163            status = reply.readInt32();
164            if (status == OK) {
165                ifaceName = reply.readString16();
166            }
167        }
168
169        return status;
170    }
171
172    virtual status_t setInterfaceBinding(const String16& ifaceName) {
173        Parcel data, reply;
174        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
175        data.writeString16(ifaceName);
176        status_t status = remote()->transact(SET_INTERFACE_BINDING,
177                                             data,
178                                             &reply);
179        if (status == OK) {
180            status = reply.readInt32();
181        }
182
183        return status;
184    }
185
186    virtual status_t getMasterAnnounceInterval(int *interval) {
187        Parcel data, reply;
188        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
189        status_t status = remote()->transact(GET_MASTER_ANNOUNCE_INTERVAL,
190                                             data,
191                                             &reply);
192        if (status == OK) {
193            status = reply.readInt32();
194            if (status == OK) {
195                *interval = reply.readInt32();
196            }
197        }
198
199        return status;
200    }
201
202    virtual status_t setMasterAnnounceInterval(int interval) {
203        Parcel data, reply;
204        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
205        data.writeInt32(interval);
206        status_t status = remote()->transact(SET_MASTER_ANNOUNCE_INTERVAL,
207                                             data,
208                                             &reply);
209        if (status == OK) {
210            status = reply.readInt32();
211        }
212
213        return status;
214    }
215
216    virtual status_t getClientSyncInterval(int *interval) {
217        Parcel data, reply;
218        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
219        status_t status = remote()->transact(GET_CLIENT_SYNC_INTERVAL,
220                                             data,
221                                             &reply);
222        if (status == OK) {
223            status = reply.readInt32();
224            if (status == OK) {
225                *interval = reply.readInt32();
226            }
227        }
228
229        return status;
230    }
231
232    virtual status_t setClientSyncInterval(int interval) {
233        Parcel data, reply;
234        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
235        data.writeInt32(interval);
236        status_t status = remote()->transact(SET_CLIENT_SYNC_INTERVAL,
237                                             data,
238                                             &reply);
239        if (status == OK) {
240            status = reply.readInt32();
241        }
242
243        return status;
244    }
245
246    virtual status_t getPanicThreshold(int *threshold) {
247        Parcel data, reply;
248        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
249        status_t status = remote()->transact(GET_PANIC_THRESHOLD,
250                                             data,
251                                             &reply);
252        if (status == OK) {
253            status = reply.readInt32();
254            if (status == OK) {
255                *threshold = reply.readInt32();
256            }
257        }
258
259        return status;
260    }
261
262    virtual status_t setPanicThreshold(int threshold) {
263        Parcel data, reply;
264        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
265        data.writeInt32(threshold);
266        status_t status = remote()->transact(SET_PANIC_THRESHOLD,
267                                             data,
268                                             &reply);
269        if (status == OK) {
270            status = reply.readInt32();
271        }
272
273        return status;
274    }
275
276    virtual status_t getAutoDisable(bool *autoDisable) {
277        Parcel data, reply;
278        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
279        status_t status = remote()->transact(GET_AUTO_DISABLE,
280                                             data,
281                                             &reply);
282        if (status == OK) {
283            status = reply.readInt32();
284            if (status == OK) {
285                *autoDisable = (0 != reply.readInt32());
286            }
287        }
288
289        return status;
290    }
291
292    virtual status_t setAutoDisable(bool autoDisable) {
293        Parcel data, reply;
294        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
295        data.writeInt32(autoDisable ? 1 : 0);
296        status_t status = remote()->transact(SET_AUTO_DISABLE,
297                                             data,
298                                             &reply);
299
300        if (status == OK) {
301            status = reply.readInt32();
302        }
303
304        return status;
305    }
306
307    virtual status_t forceNetworklessMasterMode() {
308        Parcel data, reply;
309        data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
310        status_t status = remote()->transact(FORCE_NETWORKLESS_MASTER_MODE,
311                                             data,
312                                             &reply);
313
314        if (status == OK) {
315            status = reply.readInt32();
316        }
317
318        return status;
319    }
320};
321
322IMPLEMENT_META_INTERFACE(CommonTimeConfig, "android.os.ICommonTimeConfig");
323
324status_t BnCommonTimeConfig::onTransact(uint32_t code,
325                                   const Parcel& data,
326                                   Parcel* reply,
327                                   uint32_t flags) {
328    switch(code) {
329        case GET_MASTER_ELECTION_PRIORITY: {
330            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
331            uint8_t priority;
332            status_t status = getMasterElectionPriority(&priority);
333            reply->writeInt32(status);
334            if (status == OK) {
335                reply->writeInt32(static_cast<int32_t>(priority));
336            }
337            return OK;
338        } break;
339
340        case SET_MASTER_ELECTION_PRIORITY: {
341            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
342            uint8_t priority = static_cast<uint8_t>(data.readInt32());
343            status_t status = setMasterElectionPriority(priority);
344            reply->writeInt32(status);
345            return OK;
346        } break;
347
348        case GET_MASTER_ELECTION_ENDPOINT: {
349            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
350            struct sockaddr_storage addr;
351            status_t status = getMasterElectionEndpoint(&addr);
352
353            if ((status == OK) && !canSerializeSockaddr(&addr)) {
354                status = UNKNOWN_ERROR;
355            }
356
357            reply->writeInt32(status);
358
359            if (status == OK) {
360                serializeSockaddr(reply, &addr);
361            }
362
363            return OK;
364        } break;
365
366        case SET_MASTER_ELECTION_ENDPOINT: {
367            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
368            struct sockaddr_storage addr;
369            int hasAddr = data.readInt32();
370
371            status_t status;
372            if (hasAddr) {
373                deserializeSockaddr(&data, &addr);
374                status = setMasterElectionEndpoint(&addr);
375            } else {
376                status = setMasterElectionEndpoint(&addr);
377            }
378
379            reply->writeInt32(status);
380            return OK;
381        } break;
382
383        case GET_MASTER_ELECTION_GROUP_ID: {
384            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
385            uint64_t id;
386            status_t status = getMasterElectionGroupId(&id);
387            reply->writeInt32(status);
388            if (status == OK) {
389                reply->writeInt64(id);
390            }
391            return OK;
392        } break;
393
394        case SET_MASTER_ELECTION_GROUP_ID: {
395            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
396            uint64_t id = static_cast<uint64_t>(data.readInt64());
397            status_t status = setMasterElectionGroupId(id);
398            reply->writeInt32(status);
399            return OK;
400        } break;
401
402        case GET_INTERFACE_BINDING: {
403            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
404            String16 ret;
405            status_t status = getInterfaceBinding(ret);
406            reply->writeInt32(status);
407            if (status == OK) {
408                reply->writeString16(ret);
409            }
410            return OK;
411        } break;
412
413        case SET_INTERFACE_BINDING: {
414            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
415            String16 ifaceName;
416            ifaceName = data.readString16();
417            status_t status = setInterfaceBinding(ifaceName);
418            reply->writeInt32(status);
419            return OK;
420        } break;
421
422        case GET_MASTER_ANNOUNCE_INTERVAL: {
423            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
424            int interval;
425            status_t status = getMasterAnnounceInterval(&interval);
426            reply->writeInt32(status);
427            if (status == OK) {
428                reply->writeInt32(interval);
429            }
430            return OK;
431        } break;
432
433        case SET_MASTER_ANNOUNCE_INTERVAL: {
434            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
435            int interval = data.readInt32();
436            status_t status = setMasterAnnounceInterval(interval);
437            reply->writeInt32(status);
438            return OK;
439        } break;
440
441        case GET_CLIENT_SYNC_INTERVAL: {
442            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
443            int interval;
444            status_t status = getClientSyncInterval(&interval);
445            reply->writeInt32(status);
446            if (status == OK) {
447                reply->writeInt32(interval);
448            }
449            return OK;
450        } break;
451
452        case SET_CLIENT_SYNC_INTERVAL: {
453            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
454            int interval = data.readInt32();
455            status_t status = setClientSyncInterval(interval);
456            reply->writeInt32(status);
457            return OK;
458        } break;
459
460        case GET_PANIC_THRESHOLD: {
461            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
462            int threshold;
463            status_t status = getPanicThreshold(&threshold);
464            reply->writeInt32(status);
465            if (status == OK) {
466                reply->writeInt32(threshold);
467            }
468            return OK;
469        } break;
470
471        case SET_PANIC_THRESHOLD: {
472            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
473            int threshold = data.readInt32();
474            status_t status = setPanicThreshold(threshold);
475            reply->writeInt32(status);
476            return OK;
477        } break;
478
479        case GET_AUTO_DISABLE: {
480            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
481            bool autoDisable;
482            status_t status = getAutoDisable(&autoDisable);
483            reply->writeInt32(status);
484            if (status == OK) {
485                reply->writeInt32(autoDisable ? 1 : 0);
486            }
487            return OK;
488        } break;
489
490        case SET_AUTO_DISABLE: {
491            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
492            bool autoDisable = (0 != data.readInt32());
493            status_t status = setAutoDisable(autoDisable);
494            reply->writeInt32(status);
495            return OK;
496        } break;
497
498        case FORCE_NETWORKLESS_MASTER_MODE: {
499            CHECK_INTERFACE(ICommonTimeConfig, data, reply);
500            status_t status = forceNetworklessMasterMode();
501            reply->writeInt32(status);
502            return OK;
503        } break;
504    }
505    return BBinder::onTransact(code, data, reply, flags);
506}
507
508}; // namespace android
509
510