• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 #define LOG_TAG "radio_hal_tool"
18 
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include <cutils/log.h>
23 #include <hardware/hardware.h>
24 #include <hardware/radio.h>
25 #include <system/radio.h>
26 #include <system/radio_metadata.h>
27 
28 
29 // Global state variables.
30 const struct radio_tuner *hal_tuner = NULL;
31 
usage()32 void usage() {
33     printf("Usage: "
34             "./radio_hal_tool -l\n"
35             "-l: List properties global to the Radio.\n"
36     );
37 }
38 
list_all_properties(radio_hw_device_t * device)39 void list_all_properties(radio_hw_device_t *device) {
40     radio_hal_properties_t hal_properties;
41     device->get_properties(device, &hal_properties);
42     printf("Class: %d\n"
43            "Impl: %s\n"
44            "Tuners: %d\n"
45            "Bands: %d\n\n",
46            hal_properties.class_id, hal_properties.implementor, hal_properties.num_tuners,
47            hal_properties.num_bands);
48 
49     uint32_t i;
50     for (i = 0; i < hal_properties.num_bands; i++) {
51         printf("Band Information\n"
52                "Type: %d\n"
53                "Connected: %d\n"
54                "Lower limit: %d\n"
55                "Upper limit: %d\n"
56                "Spacing: %d\n\n",
57                hal_properties.bands[i].type,
58                hal_properties.bands[i].antenna_connected,
59                hal_properties.bands[i].lower_limit,
60                hal_properties.bands[i].upper_limit,
61                hal_properties.bands[i].num_spacings);
62     }
63 }
64 
callback(radio_hal_event_t * event,void * cookie)65 void callback(radio_hal_event_t *event, void *cookie) {
66     printf("\nEvent detected\n"
67            "Type: %d\n", event->type);
68 }
69 
tune(radio_hw_device_t * device,int band_number)70 void tune(radio_hw_device_t *device, int band_number) {
71     int ret;
72     radio_hal_properties_t hal_properties;
73     ret = device->get_properties(device, &hal_properties);
74     if (ret != 0) {
75         printf("Err: get_properties returned: %d\n", ret);
76         return;
77     }
78 
79     if ((uint32_t) band_number >= hal_properties.num_bands) {
80         printf("Tuner number range should be: [0, %d]\n", hal_properties.num_bands);
81     }
82     printf("Setting band config as:\n"
83            "Type: %d\n"
84            "Connected: %d\n"
85            "Lower limit: %d\n"
86            "Upper limit: %d\n"
87            "Spacing: %d\n\n",
88            hal_properties.bands[band_number].type,
89            hal_properties.bands[band_number].antenna_connected,
90            hal_properties.bands[band_number].lower_limit,
91            hal_properties.bands[band_number].upper_limit,
92            hal_properties.bands[band_number].num_spacings);
93     int cookie = 0;
94     ret = device->open_tuner(
95         device, (const radio_hal_band_config_t *) (&(hal_properties.bands[band_number])), false,
96         callback, &cookie, &hal_tuner);
97     if (ret != 0) {
98         printf("Err: open_tuner returned: %d\n", ret);
99         return;
100     }
101     // It takes some time to apply the config which is currently set as 500ms in
102     // the stub implementation.
103     sleep(1);
104 
105     // Stub tuner implementation will regard this magic channel as a valid channel to tune.
106     ret = hal_tuner->tune(hal_tuner, 87916, 0);
107     if (ret != 0) {
108         printf("Err: tune returned: %d\n", ret);
109         return;
110     }
111     // In the stub implementation it takes ~100ms to tune to the channel and the
112     // data is set rightafter.
113     sleep(1);
114 }
115 
get_tuner_metadata(radio_hw_device_t * device)116 void get_tuner_metadata(radio_hw_device_t *device) {
117     // Get the metadata and print it.
118     radio_program_info_t info;
119     radio_metadata_allocate(&info.metadata, 87916, 0);
120     int ret;
121     ret = hal_tuner->get_program_information(hal_tuner, &info);
122     if (ret != 0) {
123         printf("Err: Get program info ret code: %d\n", ret);
124         return;
125     }
126 
127     // Print the info.
128     printf("Metadata from the band\n");
129     int i;
130     for (i = 0; i < radio_metadata_get_count(info.metadata); i++) {
131         radio_metadata_key_t key;
132         radio_metadata_type_t type;
133         void *value;
134         uint32_t size;
135 
136         radio_metadata_get_at_index(info.metadata, i, &key, &type, &value, &size);
137 
138         printf("\nMetadata key: %d\n"
139                "Type: %d\n", key, type);
140 
141         switch (type) {
142             case RADIO_METADATA_TYPE_INT:
143                 printf("Int value: %d\n", *((int *) value));
144                 break;
145             case RADIO_METADATA_TYPE_TEXT:
146                 printf("Text value: %s\n", (char *) value);
147                 break;
148             case RADIO_METADATA_TYPE_RAW:
149                 printf("Raw value, skipping\n");
150                 break;
151             case RADIO_METADATA_TYPE_CLOCK:
152                 printf("UTC Epoch: %lld\n"
153                        "UTC Offset: %d\n",
154                        (long long)((radio_metadata_clock_t *) value)->utc_seconds_since_epoch,
155                        ((radio_metadata_clock_t *) value)->timezone_offset_in_minutes);
156         }
157     }
158 
159     // Close the tuner when we are done.
160     ret = device->close_tuner(device, hal_tuner);
161     if (ret != 0) {
162         printf("Err: close_tuner returned: %d\n", ret);
163     }
164 }
165 
main(int argc,char ** argv)166 int main(int argc, char** argv) {
167     // Open the radio module and just ask for the list of properties.
168     const hw_module_t *hw_module = NULL;
169     int rc;
170     rc = hw_get_module_by_class(RADIO_HARDWARE_MODULE_ID, RADIO_HARDWARE_MODULE_ID_FM, &hw_module);
171     if (rc != 0) {
172         printf("Cannot open the hw module. Does the HAL exist? %d\n", rc);
173         return -1;
174     }
175 
176     radio_hw_device_t *dev;
177     rc = radio_hw_device_open(hw_module, &dev);
178     if (rc != 0) {
179         printf("Cannot open the device. Check that HAL implementation. %d\n", rc);
180         return -1;
181     }
182     printf("HAL Loaded!\n");
183 
184     // If this is a list properties command - we check for -l command.
185     int list_properties = 0;
186     // Get metadata.
187     int get_metadata = 0;
188     // Tune. Takes a tuner number (see bands obtainaed by list_properties).
189     int should_tune = 0;
190     int band_number = -1;
191 
192     int opt;
193     while ((opt = getopt(argc, argv, "lmt:")) != -1) {
194         switch (opt) {
195             case 'l':
196                 list_properties = 1;
197                 break;
198             case 't':
199                 should_tune = 1;
200                 band_number = atoi(optarg);
201                 break;
202             case 'm':
203                 get_metadata = 1;
204                 break;
205         }
206     }
207 
208     if (list_properties) {
209         printf("Listing properties...\n");
210         list_all_properties(dev);
211     } else {
212         if (should_tune) {
213             if (band_number < 0) {
214                 printf("Tuner number should be positive");
215                 return -1;
216             }
217             printf("Tuning to a station...\n");
218             tune(dev, band_number);
219         }
220         if (get_metadata) {
221             if (!hal_tuner) {
222                 printf("Please pass -t <band_number> to tune to a valid station to get metadata.");
223                 exit(1);
224             }
225             get_tuner_metadata(dev);
226         }
227     }
228     return 0;
229 }
230