-towards IdP2
[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
6   it under the terms of the GNU General Public License as published
7   by the Free Software Foundation; either version 3, or (at your
8   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   General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with GNUnet; see the file COPYING.  If not, write to the
17   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18   Boston, MA 02110-1301, USA.
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, #GNUNET_SYSERR on error
69  */
70 static int
71 process_record_messages (void *cls,
72                          const struct GNUNET_MessageHeader *msg)
73 {
74   struct Microphone *mic = cls;
75   const struct AudioMessage *am;
76
77   if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO)
78   {
79     GNUNET_break (0);
80     return GNUNET_SYSERR;
81   }
82   am = (const struct AudioMessage *) msg;
83   mic->rdc (mic->rdc_cls,
84             ntohs (msg->size) - sizeof (struct AudioMessage),
85             &am[1]);
86   return GNUNET_OK;
87 }
88
89
90 /**
91  * Enable a microphone.
92  *
93  * @param cls clsoure with our `struct Microphone`
94  * @param rdc function to call with recorded data
95  * @param rdc_cls closure for @a dc
96  */
97 static int
98 enable (void *cls,
99         GNUNET_MICROPHONE_RecordedDataCallback rdc,
100         void *rdc_cls)
101 {
102   struct Microphone *mic = cls;
103   static char * const record_helper_argv[] =
104   {
105     "gnunet-helper-audio-record",
106     NULL
107   };
108
109   mic->rdc = rdc;
110   mic->rdc_cls = rdc_cls;
111   mic->record_helper = GNUNET_HELPER_start (GNUNET_NO,
112                                             "gnunet-helper-audio-record",
113                                             record_helper_argv,
114                                             &process_record_messages,
115                                             NULL, mic);
116   if (NULL == mic->record_helper)
117   {
118     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
119                 _("Could not start record audio helper\n"));
120     return GNUNET_SYSERR;
121   }
122   return GNUNET_OK;
123 }
124
125
126 /**
127  * Function that disables a microphone.
128  *
129  * @param cls clsoure
130  */
131 static void
132 disable (void *cls)
133 {
134   struct Microphone *mic = cls;
135
136   if (NULL == mic->record_helper)
137   {
138     GNUNET_break (0);
139     return;
140   }
141   GNUNET_break (GNUNET_OK ==
142                 GNUNET_HELPER_kill (mic->record_helper, GNUNET_NO));
143   GNUNET_HELPER_destroy (mic->record_helper);
144   mic->record_helper = NULL;
145 }
146
147
148 /**
149  * Function to destroy a microphone.
150  *
151  * @param cls clsoure
152  */
153 static void
154 destroy (void *cls)
155 {
156   struct Microphone *mic = cls;
157
158   if (NULL != mic->record_helper)
159     disable (mic);
160 }
161
162
163 /**
164  * Create a microphone that corresponds to the microphone hardware
165  * of our system.
166  *
167  * @param cfg configuration to use
168  * @return NULL on error
169  */
170 struct GNUNET_MICROPHONE_Handle *
171 GNUNET_MICROPHONE_create_from_hardware (const struct GNUNET_CONFIGURATION_Handle *cfg)
172 {
173   struct GNUNET_MICROPHONE_Handle *microphone;
174   struct Microphone *mic;
175
176   mic = GNUNET_new (struct Microphone);
177   mic->cfg = cfg;
178   microphone = GNUNET_new (struct GNUNET_MICROPHONE_Handle);
179   microphone->cls = mic;
180   microphone->enable_microphone = &enable;
181   microphone->disable_microphone = &disable;
182   microphone->destroy_microphone = &destroy;
183   return microphone;
184 }
185
186
187 /**
188  * Destroy a microphone.
189  *
190  * @param microphone microphone to destroy
191  */
192 void
193 GNUNET_MICROPHONE_destroy (struct GNUNET_MICROPHONE_Handle *microphone)
194 {
195   microphone->destroy_microphone (microphone->cls);
196   GNUNET_free (microphone);
197 }
198
199 /* end of microphone.c */