Ignore:
Timestamp:
2012-08-20T11:28:46Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fb6c98f
Parents:
20840922
Message:

audio: Move event callback into separate API calls.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/generic/remote_audio_pcm.c

    r20840922 r018ab50  
    4646        IPC_M_AUDIO_PCM_GET_INFO_STR,
    4747        IPC_M_AUDIO_PCM_QUERY_CAPS,
     48        IPC_M_AUDIO_PCM_REGISTER_EVENTS,
     49        IPC_M_AUDIO_PCM_UNREGISTER_EVENTS,
    4850        IPC_M_AUDIO_PCM_TEST_FORMAT,
    4951        IPC_M_AUDIO_PCM_GET_BUFFER,
     
    235237
    236238/**
     239 * Register callback for device generated events.
     240 *
     241 * @param sess Audio device session.
     242 * @param event_rec Event callback function.
     243 * @param arg Event callback custom parameter.
     244 *
     245 * @return Error code.
     246 */
     247int audio_pcm_register_event_callback(audio_pcm_sess_t *sess,
     248    async_client_conn_t event_callback, void *arg)
     249{
     250        if (!event_callback)
     251                return EINVAL;
     252
     253        async_exch_t *exch = async_exchange_begin(sess);
     254        int ret = async_req_1_0(exch, DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
     255            IPC_M_AUDIO_PCM_REGISTER_EVENTS);
     256        if (ret == EOK) {
     257                ret = async_connect_to_me(exch, 0, 0, 0, event_callback, arg);
     258        }
     259        async_exchange_end(exch);
     260        return ret;
     261}
     262
     263/**
     264 * Unregister callback for device generated events.
     265 *
     266 * @param sess Audio device session.
     267 *
     268 * @return Error code.
     269 */
     270int audio_pcm_unregister_event_callback(audio_pcm_sess_t *sess)
     271{
     272        async_exch_t *exch = async_exchange_begin(sess);
     273        const int ret = async_req_1_0(exch,
     274            DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
     275            IPC_M_AUDIO_PCM_UNREGISTER_EVENTS);
     276        async_exchange_end(exch);
     277        return ret;
     278}
     279
     280/**
    237281 * Get device accessible playback/capture buffer.
    238282 *
     
    240284 * @param buffer Place to store pointer to the buffer.
    241285 * @param size Place to store buffer size (bytes).
    242  * @param event_rec Event callback function.
    243  * @param arg Event callback custom parameter.
    244  *
    245  * @return Error code.
    246  */
    247 int audio_pcm_get_buffer(audio_pcm_sess_t *sess, void **buffer, size_t *size,
    248     async_client_conn_t event_rec, void* arg)
     286 *
     287 * @return Error code.
     288 */
     289int audio_pcm_get_buffer(audio_pcm_sess_t *sess, void **buffer, size_t *size)
    249290{
    250291        if (!buffer || !size)
     
    254295
    255296        sysarg_t buffer_size = *size;
    256         const int ret = async_req_2_1(exch,
    257             DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE), IPC_M_AUDIO_PCM_GET_BUFFER,
    258             (sysarg_t)buffer_size, &buffer_size);
     297        int ret = async_req_2_1(exch, DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
     298            IPC_M_AUDIO_PCM_GET_BUFFER, (sysarg_t)buffer_size, &buffer_size);
    259299        if (ret == EOK) {
    260300                void *dst = NULL;
    261                 int ret = async_share_in_start_0_0(exch, buffer_size, &dst);
     301                ret = async_share_in_start_0_0(exch, buffer_size, &dst);
    262302                if (ret != EOK) {
    263303                        async_exchange_end(exch);
    264304                        return ret;
    265305                }
    266                 ret = async_connect_to_me(exch, 0, 0, 0, event_rec, arg);
    267                 if (ret != EOK) {
    268                         async_exchange_end(exch);
    269                         return ret;
    270                 }
    271 
    272306                *buffer = dst;
    273307                *size = buffer_size;
     
    391425static void remote_audio_pcm_get_info_str(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    392426static void remote_audio_pcm_query_caps(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     427static void remote_audio_pcm_events_register(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     428static void remote_audio_pcm_events_unregister(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    393429static void remote_audio_pcm_get_buffer_pos(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    394430static void remote_audio_pcm_test_format(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     
    404440        [IPC_M_AUDIO_PCM_GET_INFO_STR] = remote_audio_pcm_get_info_str,
    405441        [IPC_M_AUDIO_PCM_QUERY_CAPS] = remote_audio_pcm_query_caps,
     442        [IPC_M_AUDIO_PCM_REGISTER_EVENTS] = remote_audio_pcm_events_register,
     443        [IPC_M_AUDIO_PCM_UNREGISTER_EVENTS] = remote_audio_pcm_events_unregister,
    406444        [IPC_M_AUDIO_PCM_GET_BUFFER_POS] = remote_audio_pcm_get_buffer_pos,
    407445        [IPC_M_AUDIO_PCM_TEST_FORMAT] = remote_audio_pcm_test_format,
     
    461499        }
    462500}
     501
     502static void remote_audio_pcm_events_register(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
     503{
     504        const audio_pcm_iface_t *pcm_iface = iface;
     505        if (!pcm_iface->get_event_session ||
     506            !pcm_iface->set_event_session) {
     507                async_answer_0(callid, ENOTSUP);
     508                return;
     509        }
     510
     511        async_answer_0(callid, EOK);
     512
     513        ipc_call_t callback_call;
     514        ipc_callid_t callback_id = async_get_call(&callback_call);
     515        async_sess_t *sess =
     516            async_callback_receive_start(EXCHANGE_ATOMIC, &callback_call);
     517        if (sess == NULL) {
     518                ddf_msg(LVL_DEBUG, "Failed to create event callback");
     519                pcm_iface->release_buffer(fun);
     520                async_answer_0(callback_id, EAGAIN);
     521                return;
     522        }
     523        const int ret = pcm_iface->set_event_session(fun, sess);
     524        if (ret != EOK) {
     525                ddf_msg(LVL_DEBUG, "Failed to set event callback.");
     526                pcm_iface->release_buffer(fun);
     527                async_hangup(sess);
     528                async_answer_0(callback_id, ret);
     529                return;
     530        }
     531        ddf_msg(LVL_DEBUG2, "Event session setup OK.");
     532        async_answer_0(callback_id, EOK);
     533}
     534
     535static void remote_audio_pcm_events_unregister(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
     536{
     537        const audio_pcm_iface_t *pcm_iface = iface;
     538        if (!pcm_iface->get_event_session ||
     539            !pcm_iface->set_event_session) {
     540                async_answer_0(callid, ENOTSUP);
     541                return;
     542        }
     543        async_sess_t *sess = pcm_iface->get_event_session(fun);
     544        if (sess) {
     545                async_hangup(sess);
     546                pcm_iface->set_event_session(fun, NULL);
     547        }
     548        async_answer_0(callid, EOK);
     549}
     550
    463551void remote_audio_pcm_get_buffer_pos(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
    464552{
     
    487575
    488576        if (!pcm_iface->get_buffer ||
    489             !pcm_iface->release_buffer ||
    490             !pcm_iface->set_event_session) {
     577            !pcm_iface->release_buffer) {
    491578                async_answer_0(callid, ENOTSUP);
    492579                return;
     
    528615        }
    529616
    530         ddf_msg(LVL_DEBUG2, "Buffer shared with size %zu, creating callback.",
    531             share_size);
    532         {
    533                 ipc_call_t call;
    534                 ipc_callid_t callid = async_get_call(&call);
    535                 async_sess_t *sess =
    536                     async_callback_receive_start(EXCHANGE_ATOMIC, &call);
    537                 if (sess == NULL) {
    538                         ddf_msg(LVL_DEBUG, "Failed to create event callback");
    539                         pcm_iface->release_buffer(fun);
    540                         async_answer_0(callid, EAGAIN);
    541                         return;
    542                 }
    543                 ret = pcm_iface->set_event_session(fun, sess);
    544                 if (ret != EOK) {
    545                         ddf_msg(LVL_DEBUG, "Failed to set event callback.");
    546                         pcm_iface->release_buffer(fun);
    547                         async_answer_0(callid, ret);
    548                         return;
    549                 }
    550                 ddf_msg(LVL_DEBUG2, "Buffer and event session setup OK.");
    551                 async_answer_0(callid, EOK);
    552         }
     617        ddf_msg(LVL_DEBUG2, "Buffer shared with size %zu.", share_size);
    553618}
    554619
Note: See TracChangeset for help on using the changeset viewer.