ignore in lint/
[oweals/gnunet.git] / src / conversation / microphone.c
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2013 GNUnet e.V.
4
5   GNUnet is free software: you can redistribute it and/or modify it
6   under the terms of the GNU Affero General Public License as published
7   by the Free Software Foundation, either version 3 of the License,
8   or (at your option) any later version.
9
10   GNUnet is distributed in the hope that it will be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Affero General Public License for more details.
14  
15   You should have received a copy of the GNU Affero General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file conversation/microphone.c
23  * @brief API to access an audio microphone; provides access to hardware microphones;
24  *        actually just wraps the gnunet-helper-audio-record
25  * @author Simon Dieterle
26  * @author Andreas Fuchs
27  * @author Christian Grothoff
28  */
29 #include "platform.h"
30 #include "gnunet_microphone_lib.h"
31 #include "conversation.h"
32
33
34 /**
35  * Internal data structures for the microphone.
36  */
37 struct Microphone
38 {
39
40   /**
41    * Our configuration.
42    */
43   const struct GNUNET_CONFIGURATION_Handle *cfg;
44
45   /**
46    * Handle for the record helper
47    */
48   struct GNUNET_HELPER_Handle *record_helper;
49
50   /**
51    * Function to call with audio data (if we are enabled).
52    */
53   GNUNET_MICROPHONE_RecordedDataCallback rdc;
54
55   /**
56    * Closure for @e rdc.
57    */
58   void *rdc_cls;
59
60 };
61
62
63 /**
64  * Function to process the audio from the record helper
65  *
66  * @param cls clsoure with our `struct Microphone`
67  * @param msg the message from the helper
68  * @return #GNUNET_OK on success,
69  *    #GNUNET_NO to stop further processing (no error)
70  *    #GNUNET_SYSERR to stop further processing with error
71  */
72 static int
73 process_record_messages (void *cls,
74                          const struct GNUNET_MessageHeader *msg)
75 {
76   struct Microphone *mic = cls;
77   const struct AudioMessage *am;
78
79   if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO)
80   {
81     GNUNET_break (0);
82     return GNUNET_SYSERR;
83   }
84   am = (const struct AudioMessage *) msg;
85   mic->rdc (mic->rdc_cls,
86             ntohs (msg->size) - sizeof (struct AudioMessage),
87             &am[1]);
88   return GNUNET_OK;
89 }
90
91
92 /**
93  * Enable a microphone.
94  *
95  * @param cls clsoure with our `struct Microphone`
96  * @param rdc function to call with recorded data
97  * @param rdc_cls closure for @a dc
98  */
99 static int
100 enable (void *cls,
101         GNUNET_MICROPHONE_RecordedDataCallback rdc,
102         void *rdc_cls)
103 {
104   struct Microphone *mic = cls;
105   static char * const record_helper_argv[] =
106   {
107     "gnunet-helper-audio-record",
108     NULL
109   };
110
111   mic->rdc = rdc;
112   mic->rdc_cls = rdc_cls;
113   mic->record_helper = GNUNET_HELPER_start (GNUNET_NO,
114                                             "gnunet-helper-audio-record",
115                                             record_helper_argv,
116                                             &process_record_messages,
117                                             NULL, mic);
118   if (NULL == mic->record_helper)
119   {
120     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
121                 _("Could not start record audio helper\n"));
122     return GNUNET_SYSERR;
123   }
124   return GNUNET_OK;
125 }
126
127
128 /**
129  * Function that disables a microphone.
130  *
131  * @param cls clsoure
132  */
133 static void
134 disable (void *cls)
135 {
136   struct Microphone *mic = cls;
137
138   if (NULL == mic->record_helper)
139   {
140     GNUNET_break (0);
141     return;
142   }
143   GNUNET_break (GNUNET_OK ==
144                 GNUNET_HELPER_kill (mic->record_helper, GNUNET_NO));
145   GNUNET_HELPER_destroy (mic->record_helper);
146   mic->record_helper = NULL;
147 }
148
149
150 /**
151  * Function to destroy a microphone.
152  *
153  * @param cls clsoure
154  */
155 static void
156 destroy (void *cls)
157 {
158   struct Microphone *mic = cls;
159
160   if (NULL != mic->record_helper)
161     disable (mic);
162 }
163
164
165 /**
166  * Create a microphone that corresponds to the microphone hardware
167  * of our system.
168  *
169  * @param cfg configuration to use
170  * @return NULL on error
171  */
172 struct GNUNET_MICROPHONE_Handle *
173 GNUNET_MICROPHONE_create_from_hardware (const struct GNUNET_CONFIGURATION_Handle *cfg)
174 {
175   struct GNUNET_MICROPHONE_Handle *microphone;
176   struct Microphone *mic;
177
178   mic = GNUNET_new (struct Microphone);
179   mic->cfg = cfg;
180   microphone = GNUNET_new (struct GNUNET_MICROPHONE_Handle);
181   microphone->cls = mic;
182   microphone->enable_microphone = &enable;
183   microphone->disable_microphone = &disable;
184   microphone->destroy_microphone = &destroy;
185   return microphone;
186 }
187
188
189 /**
190  * Destroy a microphone.
191  *
192  * @param microphone microphone to destroy
193  */
194 void
195 GNUNET_MICROPHONE_destroy (struct GNUNET_MICROPHONE_Handle *microphone)
196 {
197   microphone->destroy_microphone (microphone->cls);
198   GNUNET_free (microphone);
199 }
200
201 /* end of microphone.c */