RDK Documentation (Open Sourced RDK Components)
ipOutTestApp.cpp
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 #include <iostream>
20 #include "audiocapturemgr_iarm.h"
21 #include "libIBus.h"
22 #include <pthread.h>
23 #include <fstream>
24 
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include "safec_lib.h"
31 
32 using namespace audiocapturemgr;
33 static const char * instance_name = NULL;
34 void print_menu(void)
35 {
36  std::cout<<"\n--- audio capture test application menu ---\n";
37  std::cout<<"1. open IPOUT session\n";
38  std::cout<<"2. print session details\n";
39  std::cout<<"3. get default props\n";
40  std::cout<<"4. set audio props\n";
41  std::cout<<"5. get output props\n";
42  std::cout<<"6. start\n";
43  std::cout<<"7. stop\n";
44  std::cout<<"8. close IPOUT session.\n";
45  std::cout<<"9. reconnect to known socket.\n";
46  std::cout<<"10. get audio props.\n";
47  std::cout<<"11. quit.\n";
48 }
49 
50 static bool verify_result(IARM_Result_t ret, iarmbus_acm_arg_t &param)
51 {
52  if(IARM_RESULT_SUCCESS != ret)
53  {
54  std::cout<<"Bus call failed.\n";
55  return false;
56  }
57  if(0 != param.result)
58  {
59  std::cout<<"ACM implementation of bus call failed.\n";
60  return false;
61  }
62  return true;
63 }
64 
65 void * read_thread(void * data)
66 {
67  std::string socket_path = *(static_cast <std::string *> (data));
68  if(socket_path.empty())
69  {
70  std::cout<<"read thread returning as socket path is empty.\n";
71  return NULL;
72  }
73  std::cout<<"Connecting to socket "<<socket_path<<std::endl;
74 
75  struct sockaddr_un addr;
76  addr.sun_family = AF_UNIX;
77  strncpy(addr.sun_path, socket_path.c_str(), (socket_path.size() + 1));
78 
79  int read_fd = socket(AF_UNIX, SOCK_STREAM, 0);
80  if(0 > read_fd)
81  {
82  std::cout<<"Couldn't create read socket. Exiting.\n";
83  return NULL;
84  }
85 
86  if(0 != connect(read_fd, (const struct sockaddr *) &addr, sizeof(addr)))
87  {
88  std::cout<<"Couldn't connect to the path. Exiting.\n";
89  perror("read_thread");
90  close(read_fd);
91  return NULL;
92  }
93 
94  std::cout<<"Connection established.\n";
95  unsigned int recvd_bytes = 0;
96  char buffer[1024];
97  std::string filename = "/opt/acm_ipout_dump_";
98  filename += instance_name;
99  std::ofstream file_dump(filename.c_str(), std::ios::binary);
100  while(true)
101  {
102  int ret = read(read_fd, buffer, 1024);
103  if(0 == ret)
104  {
105  std::cout<<"Zero bytes read. Exiting.\n";
106  break;
107  }
108  else if(0 > ret)
109  {
110  std::cout<<"Error reading from socket. Exiting.\n";
111  perror("read error");
112  break;
113  }
114  if((1024*1024*2) > recvd_bytes) //Write up to 2 MB to a file
115  {
116  file_dump.write(buffer, ret);
117  }
118  recvd_bytes += ret;
119  }
120 
121  close(read_fd);
122  std::cout<<"Number of bytes read: "<<recvd_bytes<<std::endl;
123  file_dump.seekp(0, std::ios_base::end);
124  std::cout<<file_dump.tellp()<<" bytes written to file.\n";
125  std::cout<<"Exiting read thread.\n";
126  return NULL;
127 }
128 
129 void connect_and_read_data(std::string &socket_path)
130 {
131  pthread_t thread;
132  int ret = pthread_create(&thread, NULL, read_thread, (void *) &socket_path);
133  if(0 == ret)
134  {
135  std::cout<<"Successfully launched read thread.\n";
136  }
137  else
138  {
139  std::cout<<"Failed to launch read thread.\n";
140  }
141 }
142 
143 void launcher()
144 {
145  bool keep_running = true;
146  session_id_t session = -1;
148  std::string socket_path;
149 
150  while(keep_running)
151  {
152  int choice = 0;
153  std::string filename;
154  iarmbus_acm_arg_t param;
155  IARM_Result_t ret;
156 
157  print_menu();
158  std::cout<<"Enter command:\n";
159  if(!(std::cin >> choice))
160  {
161  std::cout<<"Oops!\n";
162  std::cin.clear();
163  std::cin.ignore(10000, '\n');
164  continue;
165  }
166  switch(choice)
167  {
168  case 1:
169  param.details.arg_open.source = 0; //primary
170  param.details.arg_open.output_type = REALTIME_SOCKET;
171  ret = IARM_Bus_Call(IARMBUS_AUDIOCAPTUREMGR_NAME, IARMBUS_AUDIOCAPTUREMGR_OPEN, (void *) &param, sizeof(param));
172  if(!verify_result(ret, param))
173  {
174  break;
175  }
176  session = param.session_id;
177  std::cout<<"Opened new session "<<session<<std::endl;
178  break;
179 
180  case 2:
181  std::cout<<"Session ID is "<<session<<std::endl;
182  std::cout<<"Socket path is "<<socket_path<<std::endl;
183  break;
184 
185  case 3:
186  param.session_id = session;
187  ret = IARM_Bus_Call(IARMBUS_AUDIOCAPTUREMGR_NAME, IARMBUS_AUDIOCAPTUREMGR_GET_DEFAULT_AUDIO_PROPS, (void *) &param, sizeof(param));
188  if(!verify_result(ret, param))
189  {
190  break;
191  }
192  INFO("Format: 0x%x, delay comp: %dms, fifo size: %d, threshold: %d\n",
193  param.details.arg_audio_properties.format,
194  param.details.arg_audio_properties.delay_compensation_ms,
195  param.details.arg_audio_properties.fifo_size,
196  param.details.arg_audio_properties.threshold);
197  props = param.details.arg_audio_properties;
198  break;
199 
200  case 10:
201  param.session_id = session;
202  ret = IARM_Bus_Call(IARMBUS_AUDIOCAPTUREMGR_NAME, IARMBUS_AUDIOCAPTUREMGR_GET_AUDIO_PROPS, (void *) &param, sizeof(param));
203  if(!verify_result(ret, param))
204  {
205  break;
206  }
207  INFO("Format: 0x%x, delay comp: %dms, fifo size: %d, threshold: %d\n",
208  param.details.arg_audio_properties.format,
209  param.details.arg_audio_properties.delay_compensation_ms,
210  param.details.arg_audio_properties.fifo_size,
211  param.details.arg_audio_properties.threshold);
212  props = param.details.arg_audio_properties;
213  break;
214 
215  case 4:
216  param.session_id = session;
217  param.details.arg_audio_properties = props;
218  param.details.arg_audio_properties.delay_compensation_ms = 190;
219  ret = IARM_Bus_Call(IARMBUS_AUDIOCAPTUREMGR_NAME, IARMBUS_AUDIOCAPTUREMGR_SET_AUDIO_PROPERTIES, (void *) &param, sizeof(param));
220  if(!verify_result(ret, param))
221  {
222  break;
223  }
224  break;
225 
226  case 5:
227  param.session_id = session;
228  ret = IARM_Bus_Call(IARMBUS_AUDIOCAPTUREMGR_NAME, IARMBUS_AUDIOCAPTUREMGR_GET_OUTPUT_PROPS, (void *) &param, sizeof(param));
229  if(!verify_result(ret, param))
230  {
231  break;
232  }
233  socket_path = std::string(param.details.arg_output_props.output.file_path);
234  std::cout<<"Output path is "<<socket_path<<std::endl;
235  break;
236 
237  case 6:
238  if(socket_path.empty())
239  {
240  std::cout<<"No path to socket available.\n";
241  break;
242  }
243  std::cout<<"Launching read thread.\n";
244  connect_and_read_data(socket_path);
245  param.session_id = session;
246  ret = IARM_Bus_Call(IARMBUS_AUDIOCAPTUREMGR_NAME, IARMBUS_AUDIOCAPTUREMGR_START, (void *) &param, sizeof(param));
247  if(!verify_result(ret, param))
248  {
249  break;
250  }
251  std::cout<<"Start procedure complete.\n";
252  break;
253 
254  case 7:
255  param.session_id = session;
256  ret = IARM_Bus_Call(IARMBUS_AUDIOCAPTUREMGR_NAME, IARMBUS_AUDIOCAPTUREMGR_STOP, (void *) &param, sizeof(param));
257  if(!verify_result(ret, param))
258  {
259  break;
260  }
261  std::cout<<"Stop procedure complete.\n";
262  break;
263 
264  case 8:
265  param.session_id = session;
266  ret = IARM_Bus_Call(IARMBUS_AUDIOCAPTUREMGR_NAME, IARMBUS_AUDIOCAPTUREMGR_CLOSE, (void *) &param, sizeof(param));
267  if(!verify_result(ret, param))
268  {
269  break;
270  }
271  std::cout<<"Close procedure complete.\n";
272  session = -1;
273  socket_path.clear();
274  break;
275 
276  case 9:
277  if(socket_path.empty())
278  {
279  std::cout<<"No path to socket available.\n";
280  break;
281  }
282  std::cout<<"Launching read thread.\n";
283  connect_and_read_data(socket_path);
284  break;
285 
286  case 11:
287  std::cout<<"Exiting.\n";
288  keep_running = false;
289  break;
290 
291  default:
292  std::cout<<"Unknown input!\n";
293  }
294  }
295 }
296 
297 
298 #define ACM_TESTAPP_NAME_PRFIX "acm_testapp_"
299 int main(int argc, char *argv[])
300 {
301  if(2 > argc)
302  {
303  std::cout<<"Each exec session needs a name. Invoke it as $<exec name> <session-name>"<<std::endl;
304  std::cout<<"For instance, $acm_ipout_testapp alpha\n";
305  return -1;
306  }
307  errno_t rc = -1;
308  instance_name = argv[1];
309  char bus_registration_name[100];
310  rc = sprintf_s(bus_registration_name, sizeof(bus_registration_name), "%s%s", ACM_TESTAPP_NAME_PRFIX, argv[1]);
311  if( rc < EOK )
312  {
313  ERR_CHK(rc);
314  return -1;
315  }
316 
317  if(0 != IARM_Bus_Init(bus_registration_name))
318  {
319  std::cout<<"Unable to init IARMBus. Try another session name.\n";
320  return -1;
321  }
322  if(0 != IARM_Bus_Connect())
323  {
324  std::cout<<"Unable to connect to IARBus\n";
325  return -1;
326  }
327 
328  launcher();
329 
331  IARM_Bus_Term();
332  return 0;
333 }
IARM_Bus_Term
IARM_Result_t IARM_Bus_Term(void)
This API is used to terminate the IARM-Bus library.
IARM_Bus_Call
IARM_Result_t IARM_Bus_Call(const char *ownerName, const char *methodName, void *arg, size_t argLen)
This API is used to Invoke RPC method by its application name and method name.
Definition: iarm_bus.c:57
IARM_Bus_Disconnect
IARM_Result_t IARM_Bus_Disconnect(void)
This API disconnect Application from IARM Bus so the application will not receive any IARM event or R...
libIBus.h
RDK IARM-Bus API Declarations.
audio_properties_ifce_t
Definition: audiocapturemgr_iarm.h:113
IARM_Bus_Connect
IARM_Result_t IARM_Bus_Connect(void)
This API is used to connect application to the IARM bus daemon. After connected, the application can ...
Definition: iarmMgrMocks.cpp:33
iarmbus_acm_arg_t
Definition: audiocapturemgr_iarm.h:152
print_menu
void print_menu()
This API prints the LED use-cases.
Definition: ledmgrmain.cpp:383
IARM_Bus_Init
IARM_Result_t IARM_Bus_Init(const char *name)
This API is used to initialize the IARM-Bus library.
Definition: iarmMgrMocks.cpp:38