summaryrefslogtreecommitdiffstats
path: root/ucs2-lib/doc/html/struct_c_programming_aae5da389e9fa9462cd96740a8e288825.html
blob: 96015810a5bd160883c66048aa8db9cc7fe48799 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>UNICENS: CProgramming::prg_memopen</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="style_html.css" rel="stylesheet" type="text/css" />
<link href="inic.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="GlobalWrapper">
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr>
  <td><a href="index.html"><img alt="Logo" src="logo.png"/></a></td>
  <td>
   <div id="projectname">UNICENS&#160;<span id="projectnumber">V2.1.0-3491</span></div>
   <div id="projectbrief">User Manual and API Reference</div>
    <div id="searchbox">        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.2 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('struct_c_programming.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Pages</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="contents">
<a class="anchor" id="aae5da389e9fa9462cd96740a8e288825"></a>
<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">CSingleObserver prg_memopen</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Observes the MemSessionOpen result. </p>

</div>
</div>
</div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="navelem"><a class="el" href="struct_c_programming.html">CProgramming</a></li>
    <li class="footer">&copy; 2017 Microchip Technology Inc. All rights reserved. <a href="http://www.microchip.com" target="_blank">www.microchip.com</a></li>
  </ul>
</div>
</body>
<!--
Generated on Mon Apr 3 2017 13:53:00 for UNICENS by
Doxygen 1.8.2
-->
<script language="javascript">
<!--
$('#MSearchResults').wrap('<div style="position: absolute; margin-left: 444px;"></div>');
-->
</script>
</html>
class="p">("PCM_HOOK: Fail to close\n"); break; case ACTION_START: err = snd_pcm_resume (afbClient->pcm); if (err < 0) SNDERR ("PCM_HOOK: Fail to start\n"); break; default: SNDERR ("PCM_HOOK: Unsupported Event uri=%s action=%s", afbClient->uri, action); goto OnErrorExit; } if (afbClient->verbose) printf("ON-EVENT action=%s value=%d\n", action, value); return; OnErrorExit: SNDERR("ON-EVENT %s(%s)\n", event, afb_wsj1_msg_object_s(msg)); return; } // callback interface for wsj1 static struct afb_wsj1_itf itf = { .on_hangup = OnHangupCB, .on_call = OnRequestCB, .on_event = OnEventCB }; void OnResponseCB(void *handle, struct afb_wsj1_msg *msg) { afbRequestT *afbRequest= (afbRequestT*)handle; afbClientT *afbClient=(afbClientT*)afbRequest->afbClient; if (afbClient->verbose) printf("ON-RESPONSE call=%s response=%s\n", afbRequest->callIdTag, afb_wsj1_msg_object_s(msg)); // Cancel timeout for this request sd_event_source_unref(afbRequest->evtSource); if (! afb_wsj1_msg_is_reply_ok(msg)) goto OnErrorExit; // When not more waiting call release semaphore afbClient->count--; if (afbClient->count == 0) { if (afbClient->verbose) printf("ON-RESPONSE No More Waiting Request\n"); afbClient->error=0; sem_post (&afbClient->semaphore); } return; OnErrorExit: fprintf(stderr, "ON-RESPONSE ERROR call=%s response=%s\n", afbRequest->callIdTag, afb_wsj1_msg_object_s(msg)); afbClient->error=1; sem_post (&afbClient->semaphore); } int OnTimeoutCB (sd_event_source* source, uint64_t timer, void* handle) { afbClientT *afbClient= (afbClientT*)handle; SNDERR("\nON-TIMEOUT Call Request Fail URI=%s\n", afbClient->uri); // Close PCM and release waiting client afbClient->error=1; sem_post (&afbClient->semaphore); return 0; } // Call AGL binder asynchronously by with a timeout static int CallWithTimeout(afbClientT *afbClient, afbRequestT *afbRequest, int count, hookActionT action) { uint64_t usec; int err; const char *query; // create a unique tag for request (void) asprintf(&afbRequest->callIdTag, "%d:%s/%s", count, afbRequest->api, afbRequest->verb); // create a timer with ~250us accuracy sd_event_now(afbClient->sdLoop, CLOCK_MONOTONIC, &usec); sd_event_add_time(afbClient->sdLoop, &afbRequest->evtSource, CLOCK_MONOTONIC, usec+afbRequest->timeout*1000, 250, OnTimeoutCB, afbClient); if (action == HOOK_INSTALL) query=afbRequest->query; else query="{'closing': 1}"; err = afb_wsj1_call_s(afbClient->wsj1, afbRequest->api, afbRequest->verb, query, OnResponseCB, afbRequest); if (err) goto OnErrorExit; // save client handle in request afbRequest->afbClient = afbClient; afbClient->count ++; return 0; OnErrorExit: return -1; } static int LaunchCallRequest(afbClientT *afbClient, hookActionT action) { pthread_t tid; int err, idx; afbRequestT **afbRequest= afbClient->request; if (action == HOOK_INSTALL) { // init waiting counting semaphore if (sem_init(&afbClient->semaphore, 1, 0) == -1) { fprintf(stderr, "LaunchCallRequest: Fail Semaphore Init: %s\n", afbClient->uri); } // Create a main loop err = sd_event_default(&afbClient->sdLoop); if (err < 0) { fprintf(stderr, "LaunchCallRequest: Connection to default event loop failed: %s\n", strerror(-err)); goto OnErrorExit; } // start a thread with a mainloop to monitor Audio-Agent err = pthread_create(&tid, NULL, &LoopInThread, afbClient); if (err) goto OnErrorExit; // connect the websocket wsj1 to the uri given by the first argument afbClient->wsj1 = afb_ws_client_connect_wsj1(afbClient->sdLoop, afbClient->uri, &itf, afbClient); if (afbClient->wsj1 == NULL) { fprintf(stderr, "LaunchCallRequest: Connection to %s failed\n", afbClient->uri); goto OnErrorExit; } } // send call request to audio-agent asynchronously (respond with thread mainloop context) for (idx = 0; afbRequest[idx] != NULL; idx++) { err = CallWithTimeout(afbClient, afbRequest[idx], idx, action); if (err) { fprintf(stderr, "LaunchCallRequest: Fail call %s//%s/%s&%s", afbClient->uri, afbRequest[idx]->api, afbRequest[idx]->verb, afbRequest[idx]->query); goto OnErrorExit; } } // launch counter to keep track of waiting request call afbClient->count=idx; return 0; OnErrorExit: return -1; } static int AlsaCloseHook(snd_pcm_hook_t *hook) { afbClientT *afbClient = (afbClientT*) snd_pcm_hook_get_private (hook); // launch call request and create a waiting mainloop thread int err = LaunchCallRequest(afbClient, HOOK_CLOSE); if (err < 0) { fprintf (stderr, "PCM Fail to Enter Mainloop\n"); goto OnErrorExit; } // wait for all call request to return sem_wait(&afbClient->semaphore); if (afbClient->error) { fprintf (stderr, "AlsaCloseHook: Audio Agent Fail to respond\n"); goto OnErrorExit; } if (afbClient->verbose) fprintf(stdout, "\nAlsaHook Close Success PCM=%s URI=%s\n", snd_pcm_name(afbClient->pcm), afbClient->uri); return 0; OnErrorExit: fprintf(stderr, "\nAlsaPcmHook Plugin Close Fail PCM=%s\n", snd_pcm_name(afbClient->pcm)); return 0; } // Function call when Plugin PCM is OPEN int PLUGIN_ENTRY_POINT (snd_pcm_t *pcm, snd_config_t *conf) { afbRequestT **afbRequest; snd_pcm_hook_t *h_close = NULL; snd_config_iterator_t it, next; afbClientT *afbClient = malloc(sizeof (afbClientT)); afbRequest = malloc(MAX_API_CALL * sizeof (afbRequestT)); int err; // start populating client handle afbClient->pcm = pcm; afbClient->verbose = 0; afbClient->request = afbRequest; // Get PCM arguments from asoundrc snd_config_for_each(it, next, conf) { snd_config_t *node = snd_config_iterator_entry(it); const char *id; // ignore comment en empty lines if (snd_config_get_id(node, &id) < 0) continue; if (strcmp(id, "comment") == 0 || strcmp(id, "hint") == 0) continue; if (strcmp(id, "uri") == 0) { const char *uri; if (snd_config_get_string(node, &uri) < 0) { SNDERR("Invalid String for %s", id); goto OnErrorExit; } afbClient->uri=strdup(uri); continue; } if (strcmp(id, "verbose") == 0) { afbClient->verbose= snd_config_get_bool(node); if (afbClient->verbose < 0) { SNDERR("Invalid Boolean for %s", id); goto OnErrorExit; } continue; } if (strcmp(id, "request") == 0) { const char *callConf, *callLabel; snd_config_type_t ctype; snd_config_iterator_t currentCall, follow; snd_config_t *itemConf; int callCount=0; ctype = snd_config_get_type(node); if (ctype != SND_CONFIG_TYPE_COMPOUND) { snd_config_get_string(node, &callConf); SNDERR("Invalid compound type for %s", callConf); goto OnErrorExit; } // loop on each call snd_config_for_each(currentCall, follow, node) { snd_config_t *ctlconfig = snd_config_iterator_entry(currentCall); // ignore empty line if (snd_config_get_id(ctlconfig, &callLabel) < 0) continue; // each clt should be a valid config compound ctype = snd_config_get_type(ctlconfig); if (ctype != SND_CONFIG_TYPE_COMPOUND) { snd_config_get_string(node, &callConf); SNDERR("Invalid call element for %s", callLabel); goto OnErrorExit; } // allocate an empty call request afbRequest[callCount] = calloc(1, sizeof (afbRequestT)); err = snd_config_search(ctlconfig, "api", &itemConf); if (!err) { const char *api; if (snd_config_get_string(itemConf, &api) < 0) { SNDERR("Invalid api string for %s", callLabel); goto OnErrorExit; } afbRequest[callCount]->api=strdup(api); } err = snd_config_search(ctlconfig, "verb", &itemConf); if (!err) { const char *verb; if (snd_config_get_string(itemConf, &verb) < 0) { SNDERR("Invalid verb string %s", id); goto OnErrorExit; } afbRequest[callCount]->verb=strdup(verb); } err = snd_config_search(ctlconfig, "timeout", &itemConf); if (!err) { if (snd_config_get_integer(itemConf, &afbRequest[callCount]->timeout) < 0) { SNDERR("Invalid timeout Integer %s", id); goto OnErrorExit; } } err = snd_config_search(ctlconfig, "query", &itemConf); if (!err) { const char *query; if (snd_config_get_string(itemConf, &query) < 0) { SNDERR("Invalid query string %s", id); goto OnErrorExit; } // cleanup string for json_tokener afbRequest[callCount]->query = strdup(query); for (int idx = 0; query[idx] != '\0'; idx++) { if (query[idx] == '\'') afbRequest[callCount]->query[idx] = '"'; else afbRequest[callCount]->query[idx] = query[idx]; } json_object *queryJ = json_tokener_parse(query); if (!queryJ) { SNDERR("Invalid Json %s query=%s format \"{'tok1':'val1', 'tok2':'val2'}\" ", id, query); goto OnErrorExit; } } // Simple check on call request validity if (!afbRequest[callCount]->query) afbRequest[callCount]->query= ""; if (!afbRequest[callCount]->timeout) afbRequest[callCount]->timeout=REQUEST_DEFAULT_TIMEOUT ; if (!afbRequest[callCount]->verb || !afbRequest[callCount]->api) { SNDERR("Missing api/verb %s in asoundrc", callLabel); goto OnErrorExit; } // move to next call if any callCount ++; if (callCount == MAX_API_CALL) { SNDERR("Too Many call MAX_API_CALL=%d", MAX_API_CALL); goto OnErrorExit; } afbRequest[callCount]=NULL; // afbRequest array is NULL terminated } continue; } } if (afbClient->verbose) fprintf(stdout, "\nAlsaHook Install Start PCM=%s URI=%s\n", snd_pcm_name(afbClient->pcm), afbClient->uri); err = snd_pcm_hook_add(&h_close, afbClient->pcm, SND_PCM_HOOK_TYPE_CLOSE, AlsaCloseHook, afbClient); if (err < 0) goto OnErrorExit; // launch call request and create a waiting mainloop thread err = LaunchCallRequest(afbClient, HOOK_INSTALL); if (err < 0) { fprintf (stderr, "PCM Fail to Enter Mainloop\n"); goto OnErrorExit; } // wait for all call request to return sem_wait(&afbClient->semaphore); if (afbClient->error) { fprintf (stderr, "PCM Authorisation from Audio Agent Refused\n"); goto OnErrorExit; } if (afbClient->verbose) fprintf(stdout, "\nAlsaHook Install Success PCM=%s URI=%s\n", snd_pcm_name(afbClient->pcm), afbClient->uri); return 0; OnErrorExit: fprintf(stderr, "\nAlsaPcmHook Plugin Install Fail PCM=%s\n", snd_pcm_name(afbClient->pcm)); if (h_close) snd_pcm_hook_remove(h_close); return -EINVAL; }