]> git.alsa-project.org Git - alsa-lib.git/blob - include/use-case.h
b54f2124fa781dc8b2a6c911ec0b8fadf471e465
[alsa-lib.git] / include / use-case.h
1 /**
2  * \file include/use-case.h
3  * \brief use case interface for the ALSA driver
4  * \author Liam Girdwood <lrg@slimlogic.co.uk>
5  * \author Stefan Schmidt <stefan@slimlogic.co.uk>
6  * \author Jaroslav Kysela <perex@perex.cz>
7  * \author Justin Xu <justinx@slimlogic.co.uk>
8  * \date 2008-2010
9  */
10 /*
11  *
12  *  This library is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU Lesser General Public License as
14  *  published by the Free Software Foundation; either version 2.1 of
15  *  the License, or (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU Lesser General Public License for more details.
21  *
22  *  You should have received a copy of the GNU Lesser General Public
23  *  License along with this library; if not, write to the Free Software
24  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
25  *
26  *  Copyright (C) 2008-2010 SlimLogic Ltd
27  *  Copyright (C) 2010 Wolfson Microelectronics PLC
28  *  Copyright (C) 2010 Texas Instruments Inc.
29  *
30  *  Support for the verb/device/modifier core logic and API,
31  *  command line tool and file parser was kindly sponsored by
32  *  Texas Instruments Inc.
33  *  Support for multiple active modifiers and devices,
34  *  transition sequences, multiple client access and user defined use
35  *  cases was kindly sponsored by Wolfson Microelectronics PLC.
36  */
37
38 #ifndef __ALSA_USE_CASE_H
39 #define __ALSA_USE_CASE_H
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 #include <alsa/asoundlib.h>
46
47 /**
48  *  \defgroup ucm Use Case Interface
49  *  The ALSA Use Case manager interface.
50  *  See \ref Usecase page for more details.
51  *  \{
52  */
53
54 /*! \page Usecase ALSA Use Case Interface
55  *
56  * The use case manager works by configuring the sound card ALSA kcontrols to
57  * change the hardware digital and analog audio routing to match the requested
58  * device use case. The use case manager kcontrol configurations are stored in
59  * easy to modify text files.
60  *
61  * An audio use case can be defined by a verb and device parameter. The verb
62  * describes the use case action i.e. a phone call, listening to music, recording
63  * a conversation etc. The device describes the physical audio capture and playback
64  * hardware i.e. headphones, phone handset, bluetooth headset, etc.
65  *
66  * It's intended clients will mostly only need to set the use case verb and
67  * device for each system use case change (as the verb and device parameters
68  * cover most audio use cases).
69  *
70  * However there are times when a use case has to be modified at runtime. e.g.
71  *
72  *  + Incoming phone call when the device is playing music
73  *  + Recording sections of a phone call
74  *  + Playing tones during a call.
75  *
76  * In order to allow asynchronous runtime use case adaptations, we have a third
77  * optional modifier parameter that can be used to further configure
78  * the use case during live audio runtime.
79  *
80  * This interface allows clients to :-
81  *
82  *  + Query the supported use case verbs, devices and modifiers for the machine.
83  *  + Set and Get use case verbs, devices and modifiers for the machine.
84  *  + Get the ALSA PCM playback and capture device PCMs for use case verb,
85  *     use case device and modifier.
86  *  + Get the TQ parameter for each use case verb, use case device and
87  *     modifier.
88  *  + Get the ALSA master playback and capture volume/switch kcontrols
89  *     or mixer elements for each use case.
90  */
91
92
93 /*
94  * Use Case Verb.
95  *
96  * The use case verb is the main device audio action. e.g. the "HiFi" use
97  * case verb will configure the audio hardware for HiFi Music playback
98  * and capture.
99  */
100 #define SND_USE_CASE_VERB_INACTIVE              "Inactive"              /**< Inactive Verb */
101 #define SND_USE_CASE_VERB_HIFI                  "HiFi"                  /**< HiFi Verb */
102 #define SND_USE_CASE_VERB_HIFI_LOW_POWER        "HiFi Low Power"        /**< HiFi Low Power Verb */
103 #define SND_USE_CASE_VERB_VOICE                 "Voice"                 /**< Voice Verb */
104 #define SND_USE_CASE_VERB_VOICE_LOW_POWER       "Voice Low Power"       /**< Voice Low Power Verb */
105 #define SND_USE_CASE_VERB_VOICECALL             "Voice Call"            /**< Voice Call Verb */
106 #define SND_USE_CASE_VERB_IP_VOICECALL          "Voice Call IP"         /**< Voice Call IP Verb */
107 #define SND_USE_CASE_VERB_ANALOG_RADIO          "FM Analog Radio"       /**< FM Analog Radio Verb */
108 #define SND_USE_CASE_VERB_DIGITAL_RADIO         "FM Digital Radio"      /**< FM Digital Radio Verb */
109 /* add new verbs to end of list */
110
111
112 /*
113  * Use Case Device.
114  *
115  * Physical system devices the render and capture audio. Devices can be OR'ed
116  * together to support audio on simultaneous devices.
117  *
118  * If multiple devices with the same name exists, the number suffixes should
119  * be added to these names like HDMI1,HDMI2,HDMI3 etc. No number gaps are
120  * allowed. The names with numbers must be continuous. It is allowed to put
121  * a whitespace between name and index (like 'Line 1') for the better
122  * readability. The device names 'Line 1' and 'Line1' are equal for
123  * this purpose.
124  *
125  * If EnableSequence/DisableSequence controls independent paths in the hardware
126  * it is also recommended to split playback and capture UCM devices and use
127  * the number suffixes. Example use case: Use the integrated microphone
128  * in the laptop instead the microphone in headphones.
129  *
130  * The preference of the devices is determined by the priority value.
131  */
132 #define SND_USE_CASE_DEV_NONE           "None"          /**< None Device */
133 #define SND_USE_CASE_DEV_SPEAKER        "Speaker"       /**< Speaker Device */
134 #define SND_USE_CASE_DEV_LINE           "Line"          /**< Line Device */
135 #define SND_USE_CASE_DEV_MIC            "Mic"           /**< Microphone Device */
136 #define SND_USE_CASE_DEV_HEADPHONES     "Headphones"    /**< Headphones Device */
137 #define SND_USE_CASE_DEV_HEADSET        "Headset"       /**< Headset Device */
138 #define SND_USE_CASE_DEV_HANDSET        "Handset"       /**< Handset Device */
139 #define SND_USE_CASE_DEV_BLUETOOTH      "Bluetooth"     /**< Bluetooth Device */
140 #define SND_USE_CASE_DEV_EARPIECE       "Earpiece"      /**< Earpiece Device */
141 #define SND_USE_CASE_DEV_SPDIF          "SPDIF"         /**< SPDIF Device */
142 #define SND_USE_CASE_DEV_HDMI           "HDMI"          /**< HDMI / DisplayPort Device */
143 #define SND_USE_CASE_DEV_USB            "USB"           /**< USB Device (multifunctional) */
144 #define SND_USE_CASE_DEV_DIRECT         "Direct"        /**< Direct Device (no channel remapping), (e.g. ProAudio usage) */
145 /* add new devices to end of list */
146
147
148 /*
149  * Use Case Modifiers.
150  *
151  * The use case modifier allows runtime configuration changes to deal with
152  * asynchronous events.
153  *
154  * If multiple modifiers with the same name exists, the number suffixes should
155  * be added to these names like 'Echo Reference 1','Echo Reference 2' etc.
156  * No number gaps are allowed. The names with numbers must be continuous.
157  * It is allowed to put a whitespace between name and index for the better
158  * readability. The modifier names 'Something 1' and 'Something1' are equal
159  * for this purpose.
160  *
161  * e.g. to record a voice call :-
162  *  1. Set verb to SND_USE_CASE_VERB_VOICECALL (for voice call)
163  *  2. Set modifier SND_USE_CASE_MOD_CAPTURE_VOICE when capture required.
164  *  3. Call snd_use_case_get("CapturePCM") to get ALSA source PCM name
165  *     with captured voice pcm data.
166  *
167  * e.g. to play a ring tone when listenin to MP3 Music :-
168  *  1. Set verb to SND_USE_CASE_VERB_HIFI (for MP3 playback)
169  *  2. Set modifier to SND_USE_CASE_MOD_PLAY_TONE when incoming call happens.
170  *  3. Call snd_use_case_get("PlaybackPCM") to get ALSA PCM sink name for
171  *     ringtone pcm data.
172  */
173 #define SND_USE_CASE_MOD_CAPTURE_VOICE          "Capture Voice"         /**< Capture Voice Modifier */
174 #define SND_USE_CASE_MOD_CAPTURE_MUSIC          "Capture Music"         /**< Capture Music Modifier */
175 #define SND_USE_CASE_MOD_PLAY_MUSIC             "Play Music"            /**< Play Music Modifier */
176 #define SND_USE_CASE_MOD_PLAY_VOICE             "Play Voice"            /**< Play Voice Modifier */
177 #define SND_USE_CASE_MOD_PLAY_TONE              "Play Tone"             /**< Play Tone Modifier */
178 #define SND_USE_CASE_MOD_ECHO_REF               "Echo Reference"        /**< Echo Reference Modifier */
179 /* add new modifiers to end of list */
180
181
182 /**
183  * TQ - Tone Quality
184  *
185  * The interface allows clients to determine the audio TQ required for each
186  * use case verb and modifier. It's intended as an optional hint to the
187  * audio driver in order to lower power consumption.
188  *
189  */
190 #define SND_USE_CASE_TQ_MUSIC           "Music"         /**< Music Tone Quality */
191 #define SND_USE_CASE_TQ_VOICE           "Voice"         /**< Voice Tone Quality */
192 #define SND_USE_CASE_TQ_TONES           "Tones"         /**< Tones Tone Quality */
193
194 /** use case container */
195 typedef struct snd_use_case_mgr snd_use_case_mgr_t;
196
197 /**
198  * \brief Create an identifier
199  * \param fmt Format (sprintf like)
200  * \param ... Optional arguments for sprintf like format
201  * \return Allocated string identifier or NULL on error
202  */
203 char *snd_use_case_identifier(const char *fmt, ...);
204
205 /**
206  * \brief Free a string list
207  * \param list The string list to free
208  * \param items Count of strings
209  * \return Zero if success, otherwise a negative error code
210  */
211 int snd_use_case_free_list(const char *list[], int items);
212
213 /**
214  * \brief Obtain a list of entries
215  * \param uc_mgr Use case manager (may be NULL - card list)
216  * \param identifier (may be NULL - card list)
217  * \param list Returned allocated list
218  * \return Number of list entries if success, otherwise a negative error code
219  *
220  * Defined identifiers:
221  *   - NULL                     - get card list
222  *                               (in pair cardname+comment)
223  *   - _verbs                   - get verb list
224  *                                (in pair verb+comment)
225  *   - _devices[/{verb}]        - get list of supported devices
226  *                                (in pair device+comment)
227  *   - _modifiers[/{verb}]      - get list of supported modifiers
228  *                                (in pair modifier+comment)
229  *   - TQ[/{verb}]              - get list of TQ identifiers
230  *   - _enadevs                 - get list of enabled devices
231  *   - _enamods                 - get list of enabled modifiers
232  *
233  *   - _identifiers/{modifier}|{device}[/{verb}]     - list of value identifiers
234  *   - _supporteddevs/{modifier}|{device}[/{verb}]   - list of supported devices
235  *   - _conflictingdevs/{modifier}|{device}[/{verb}] - list of conflicting devices
236  *
237  *   Note that at most one of the supported/conflicting devs lists has
238  *   any entries, and when neither is present, all devices are supported.
239  *
240  */
241 int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
242                           const char *identifier,
243                           const char **list[]);
244
245
246 /**
247  * \brief Get current - string
248  * \param uc_mgr Use case manager
249  * \param identifier 
250  * \param value Value pointer
251  * \return Zero if success, otherwise a negative error code
252  *
253  * Note: The returned string is dynamically allocated, use free() to
254  * deallocate this string. (Yes, the value parameter shouldn't be marked as
255  * "const", but it's too late to fix it, sorry about that.)
256  *
257  * Known identifiers:
258  *   - NULL             - return current card
259  *   - _verb            - return current verb
260  *   - _file            - return configuration file loaded for current card
261  *   - _alibcfg         - return private alsa-lib's configuration for current card
262  *   - _alibpref        - return private alsa-lib's configuration device prefix for current card
263  *
264  *   - [=]{NAME}[/[{modifier}|{/device}][/{verb}]]
265  *                      - value identifier {NAME}
266  *                      - Search starts at given modifier or device if any,
267  *                          else at a verb
268  *                      - Search starts at given verb if any,
269  *                          else current verb
270  *                      - Searches modifier/device, then verb, then defaults
271  *                      - Specify a leading "=" to search only the exact
272  *                        device/modifier/verb specified, and not search
273  *                        through each object in turn.
274  *                      - Examples:
275  *                          - "PlaybackPCM/Play Music"
276  *                          - "CapturePCM/SPDIF"
277  *                          - From ValueDefaults only:
278  *                              "=Variable"
279  *                          - From current active verb:
280  *                              "=Variable//"
281  *                          - From verb "Verb":
282  *                              "=Variable//Verb"
283  *                          - From "Modifier" in current active verb:
284  *                              "=Variable/Modifier/"
285  *                          - From "Modifier" in "Verb":
286  *                              "=Variable/Modifier/Verb"
287  *
288  * Recommended names for values:
289  *   - Linked
290  *      - value "True" or "1" (case insensitive)
291  *      - this is a linked UCM card
292  *      - don't use this UCM card, because the other UCM card refers devices
293  *      - valid only in the ValueDefaults section (query '=Linked')
294  *   - TQ
295  *      - Tone Quality
296  *   - Priority
297  *      - priority value (1-10000), higher value means higher priority
298  *      - valid only for verbs
299  *      - for devices - PlaybackPriority and CapturePriority
300  *   - PlaybackPCM
301  *      - full PCM playback device name
302  *   - PlaybackPCMIsDummy
303  *      - Valid values: "yes" and "no". If set to "yes", the PCM named by the
304  *        PlaybackPCM value is a dummy device, meaning that opening it enables
305  *        an audio path in the hardware, but writing to the PCM device has no
306  *        effect.
307  *   - CapturePCM
308  *      - full PCM capture device name
309  *   - CapturePCMIsDummy
310  *      - Valid values: "yes" and "no". If set to "yes", the PCM named by the
311  *        CapturePCM value is a dummy device, meaning that opening it enables
312  *        an audio path in the hardware, but reading from the PCM device has no
313  *        effect.
314  *   - PlaybackRate
315  *      - playback device sample rate
316  *   - PlaybackChannels
317  *      - playback device channel count
318  *   - PlaybackChannel#
319  *      - describe index of the logical channel in the PCM stream
320  *      - e.g. "PlaybackChannel0 2" - logical channel 0 is third channel in the PCM stream
321  *   - PlaybackChannelPos#
322  *      - describe sound position of the logical channel (ALSA chmap names)
323  *      - e.g. "PlaybackChannel0 FR" - logical channel 0 is at front left
324  *   - PlaybackCTL
325  *      - playback control device name
326  *   - PlaybackVolume
327  *      - playback control volume identifier string
328  *      - can be parsed using #snd_use_case_parse_ctl_elem_id()
329  *   - PlaybackSwitch
330  *      - playback control switch identifier string
331  *          - can be parsed using #snd_use_case_parse_ctl_elem_id()
332  *   - PlaybackPriority
333  *      - priority value (1-10000), higher value means higher priority
334  *   - CaptureRate
335  *      - capture device sample rate
336  *   - CaptureChannels
337  *      - capture device channel count
338  *   - CaptureChannel#
339  *      - describe index of the logical channel in the PCM stream
340  *      - e.g. "CaptureChannel0 2" - logical channel 0 is third channel in the PCM stream
341  *   - CaptureChannelPos#
342  *      - describe sound position of the logical channel (ALSA chmap names)
343  *      - e.g. "CaptureChannel0 FR" - logical channel 0 is at front left
344  *   - CaptureCTL
345  *      - capture control device name
346  *   - CaptureVolume
347  *      - capture control volume identifier string
348  *          - can be parsed using #snd_use_case_parse_ctl_elem_id()
349  *   - CaptureSwitch
350  *      - capture control switch identifier string
351  *          - can be parsed using #snd_use_case_parse_ctl_elem_id()
352  *   - CapturePriority
353  *      - priority value (1-10000), higher value means higher priority
354  *   - PlaybackMixer
355  *      - name of playback mixer
356  *   - PlaybackMixerElem
357  *      - mixer element playback identifier
358  *          - can be parsed using #snd_use_case_parse_selem_id()
359  *   - PlaybackMasterElem
360  *      - mixer element playback identifier for the master control
361  *          - can be parsed using #snd_use_case_parse_selem_id()
362  *   - PlaybackMasterType
363  *      - type of the master volume control
364  *      - Valid values: "soft" (software attenuation)
365  *   - CaptureMixer
366  *      - name of capture mixer
367  *   - CaptureMixerElem
368  *      - mixer element capture identifier
369  *          - can be parsed using #snd_use_case_parse_selem_id()
370  *   - CaptureMasterElem
371  *      - mixer element playback identifier for the master control
372  *          - can be parsed using #snd_use_case_parse_selem_id()
373  *   - CaptureMasterType
374  *      - type of the master volume control
375  *      - Valid values: "soft" (software attenuation)
376  *   - CaptureMicInfoFile
377  *      - json file with the microphone array placement and type description
378  *        (e.g. output from nhlt-dmic-info)
379  *   - EDIDFile
380  *      - Path to EDID file for HDMI devices
381  *   - JackCTL
382  *      - jack control device name
383  *   - JackControl
384  *      - jack control identificator
385  *      - can be parsed using snd_use_case_parse_ctl_elem_id()
386  *      - UCM configuration files should contain both JackControl and JackDev
387  *        when possible, because applications are likely to support only one
388  *        or the other
389  *   - JackDev
390  *      - the input device id of the jack (if the full input device path is
391  *        /dev/input/by-id/foo, the JackDev value should be "foo")
392  *      - UCM configuration files should contain both JackControl and JackDev
393  *        when possible, because applications are likely to support only one
394  *        or the other
395  *   - JackHWMute
396  *        If this value is set, it indicates that when the jack is plugged
397  *        in, the hardware automatically mutes some other device(s). The
398  *        value is a space-separated list of device names. If the device
399  *        name contains space, it must be enclosed to ' or ", e.g.:
400  *              JackHWMute "'Dock Headphone' Headphone"
401  *        Note that JackHWMute should be used only when the hardware enforces
402  *        the automatic muting. If the hardware doesn't enforce any muting, it
403  *        may still be tempting to set JackHWMute to trick upper software layers
404  *        to e.g. automatically mute speakers when headphones are plugged in,
405  *        but that's application policy configuration that doesn't belong
406  *        to UCM configuration files.
407  *   - MinBufferLevel
408  *       - This is used on platform where reported buffer level is not accurate.
409  *         E.g. "512", which holds 512 samples in device buffer. Note: this will
410  *         increase latency.
411  */
412 int snd_use_case_get(snd_use_case_mgr_t *uc_mgr,
413                      const char *identifier,
414                      const char **value);
415
416 /**
417  * \brief Get current - integer
418  * \param uc_mgr Use case manager
419  * \param identifier 
420  * \param value result 
421  * \return Zero if success, otherwise a negative error code
422  *
423  * Known identifiers:
424  *   - _devstatus/{device}      - return status for given device
425  *   - _modstatus/{modifier}    - return status for given modifier
426  */
427 int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
428                       const char *identifier,
429                       long *value);
430
431 /**
432  * \brief Set new
433  * \param uc_mgr Use case manager
434  * \param identifier
435  * \param value Value
436  * \return Zero if success, otherwise a negative error code
437  *
438  * Known identifiers:
439  *   - _fboot           - execute the fixed boot sequence (value = NULL)
440  *   - _boot            - execute the boot sequence (value = NULL)
441  *                      - only when driver controls identifiers are changed
442  *                        (otherwise the old control values are restored)
443  *   - _defaults        - execute the 'defaults' sequence (value = NULL)
444  *   - _verb            - set current verb = value
445  *   - _enadev          - enable given device = value
446  *   - _disdev          - disable given device = value
447  *   - _swdev/{old_device} - new_device = value
448  *                      - disable old_device and then enable new_device
449  *                      - if old_device is not enabled just return
450  *                      - check transmit sequence firstly
451  *   - _enamod          - enable given modifier = value
452  *   - _dismod          - disable given modifier = value
453  *   - _swmod/{old_modifier}    - new_modifier = value
454  *                      - disable old_modifier and then enable new_modifier
455  *                      - if old_modifier is not enabled just return
456  *                      - check transmit sequence firstly
457  */
458 int snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
459                      const char *identifier,
460                      const char *value);
461
462 /**
463  * \brief Open and initialise use case core for sound card
464  * \param uc_mgr Returned use case manager pointer
465  * \param card_name Sound card name.
466  * \return zero if success, otherwise a negative error code
467  *
468  * By default only first card is used when the driver card
469  * name or long name is passed in the card_name argument.
470  *
471  * The "strict:" prefix in the card_name defines that
472  * there is no driver name / long name matching. The straight
473  * configuration is used.
474  *
475  * The "hw:" prefix in the card_name will load the configuration
476  * for the ALSA card specified by the card index (value) or
477  * the card string identificator.
478  *
479  * The sound card might be also composed from several physical
480  * sound cards (for the default and strict card_name).
481  * The application cannot expect that the device names will refer
482  * only one ALSA sound card in this case.
483  */
484 int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr,
485                           const char *card_name);
486
487
488 /**
489  * \brief Reload and re-parse use case configuration files for sound card.
490  * \param uc_mgr Use case manager
491  * \return zero if success, otherwise a negative error code
492  */
493 int snd_use_case_mgr_reload(snd_use_case_mgr_t *uc_mgr);
494
495 /**
496  * \brief Close use case manager
497  * \param uc_mgr Use case manager
498  * \return zero if success, otherwise a negative error code
499  */
500 int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr);
501
502 /**
503  * \brief Reset use case manager verb, device, modifier to deafult settings.
504  * \param uc_mgr Use case manager
505  * \return zero if success, otherwise a negative error code
506  */
507 int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr);
508
509 /*
510  * helper functions
511  */
512
513 /**
514  * \brief Obtain a list of cards
515  * \param list Returned allocated list
516  * \return Number of list entries if success, otherwise a negative error code
517  */
518 static __inline__ int snd_use_case_card_list(const char **list[])
519 {
520         return snd_use_case_get_list(NULL, NULL, list);
521 }
522
523 /**
524  * \brief Obtain a list of verbs
525  * \param uc_mgr Use case manager
526  * \param list Returned list of verbs
527  * \return Number of list entries if success, otherwise a negative error code
528  */
529 static __inline__ int snd_use_case_verb_list(snd_use_case_mgr_t *uc_mgr,
530                                          const char **list[])
531 {
532         return snd_use_case_get_list(uc_mgr, "_verbs", list);
533 }
534
535 /**
536  * \brief Parse control element identifier
537  * \param dst Element identifier
538  * \param ucm_id Use case identifier
539  * \param value String value to be parsed
540  * \return Zero if success, otherwise a negative error code
541  */
542 int snd_use_case_parse_ctl_elem_id(snd_ctl_elem_id_t *dst,
543                                    const char *ucm_id,
544                                    const char *value);
545
546 /**
547  * \brief Parse mixer element identifier
548  * \param dst Simple mixer element identifier
549  * \param ucm_id Use case identifier
550  * \param value String value to be parsed
551  * \return Zero if success, otherwise a negative error code
552  */
553 int snd_use_case_parse_selem_id(snd_mixer_selem_id_t *dst,
554                                 const char *ucm_id,
555                                 const char *value);
556
557 /**
558  *  \}
559  */
560
561 #ifdef __cplusplus
562 }
563 #endif
564
565 #endif /* __ALSA_USE_CASE_H */