1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 * Neither the name of The Linux Foundation nor
12 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include <fcntl.h>
33 #include <errno.h>
34
35 #include <aenc_svr.h>
36
37 /**
38 @brief This function processes posted messages
39
40 Once thread is being spawned, this function is run to
41 start processing commands posted by client
42
43 @param info pointer to context
44
45 */
omx_qcelp13_msg(void * info)46 void *omx_qcelp13_msg(void *info)
47 {
48 struct qcelp13_ipc_info *qcelp13_info = (struct qcelp13_ipc_info*)info;
49 unsigned char id;
50 ssize_t n;
51
52 DEBUG_DETAIL("\n%s: message thread start\n", __FUNCTION__);
53 while (!qcelp13_info->dead)
54 {
55 n = read(qcelp13_info->pipe_in, &id, 1);
56 if (0 == n) break;
57 if (1 == n)
58 {
59 DEBUG_DETAIL("\n%s-->pipe_in=%d pipe_out=%d\n",
60 qcelp13_info->thread_name,
61 qcelp13_info->pipe_in,
62 qcelp13_info->pipe_out);
63
64 qcelp13_info->process_msg_cb(qcelp13_info->client_data, id);
65 }
66 if ((n < 0) && (errno != EINTR)) break;
67 }
68 DEBUG_DETAIL("%s: message thread stop\n", __FUNCTION__);
69
70 return 0;
71 }
72
omx_qcelp13_events(void * info)73 void *omx_qcelp13_events(void *info)
74 {
75 struct qcelp13_ipc_info *qcelp13_info = (struct qcelp13_ipc_info*)info;
76 unsigned char id = 0;
77
78 DEBUG_DETAIL("%s: message thread start\n", qcelp13_info->thread_name);
79 qcelp13_info->process_msg_cb(qcelp13_info->client_data, id);
80 DEBUG_DETAIL("%s: message thread stop\n", qcelp13_info->thread_name);
81 return 0;
82 }
83
84 /**
85 @brief This function starts command server
86
87 @param cb pointer to callback function from the client
88 @param client_data reference client wants to get back
89 through callback
90 @return handle to msging thread
91 */
omx_qcelp13_thread_create(message_func cb,void * client_data,char * th_name)92 struct qcelp13_ipc_info *omx_qcelp13_thread_create(
93 message_func cb,
94 void* client_data,
95 char* th_name)
96 {
97 int r;
98 int fds[2];
99 struct qcelp13_ipc_info *qcelp13_info;
100
101 qcelp13_info = calloc(1, sizeof(struct qcelp13_ipc_info));
102 if (!qcelp13_info)
103 {
104 return 0;
105 }
106
107 qcelp13_info->client_data = client_data;
108 qcelp13_info->process_msg_cb = cb;
109 strlcpy(qcelp13_info->thread_name, th_name,
110 sizeof(qcelp13_info->thread_name));
111
112 if (pipe(fds))
113 {
114 DEBUG_PRINT_ERROR("\n%s: pipe creation failed\n", __FUNCTION__);
115 goto fail_pipe;
116 }
117
118 qcelp13_info->pipe_in = fds[0];
119 qcelp13_info->pipe_out = fds[1];
120
121 r = pthread_create(&qcelp13_info->thr, 0, omx_qcelp13_msg, qcelp13_info);
122 if (r < 0) goto fail_thread;
123
124 DEBUG_DETAIL("Created thread for %s \n", qcelp13_info->thread_name);
125 return qcelp13_info;
126
127
128 fail_thread:
129 close(qcelp13_info->pipe_in);
130 close(qcelp13_info->pipe_out);
131
132 fail_pipe:
133 free(qcelp13_info);
134
135 return 0;
136 }
137
138 /**
139 * @brief This function starts command server
140 *
141 * @param cb pointer to callback function from the client
142 * @param client_data reference client wants to get back
143 * through callback
144 * @return handle to msging thread
145 * */
omx_qcelp13_event_thread_create(message_func cb,void * client_data,char * th_name)146 struct qcelp13_ipc_info *omx_qcelp13_event_thread_create(
147 message_func cb,
148 void* client_data,
149 char* th_name)
150 {
151 int r;
152 int fds[2];
153 struct qcelp13_ipc_info *qcelp13_info;
154
155 qcelp13_info = calloc(1, sizeof(struct qcelp13_ipc_info));
156 if (!qcelp13_info)
157 {
158 return 0;
159 }
160
161 qcelp13_info->client_data = client_data;
162 qcelp13_info->process_msg_cb = cb;
163 strlcpy(qcelp13_info->thread_name, th_name,
164 sizeof(qcelp13_info->thread_name));
165
166 if (pipe(fds))
167 {
168 DEBUG_PRINT("\n%s: pipe creation failed\n", __FUNCTION__);
169 goto fail_pipe;
170 }
171
172 qcelp13_info->pipe_in = fds[0];
173 qcelp13_info->pipe_out = fds[1];
174
175 r = pthread_create(&qcelp13_info->thr, 0, omx_qcelp13_events, qcelp13_info);
176 if (r < 0) goto fail_thread;
177
178 DEBUG_DETAIL("Created thread for %s \n", qcelp13_info->thread_name);
179 return qcelp13_info;
180
181
182 fail_thread:
183 close(qcelp13_info->pipe_in);
184 close(qcelp13_info->pipe_out);
185
186 fail_pipe:
187 free(qcelp13_info);
188
189 return 0;
190 }
191
omx_qcelp13_thread_stop(struct qcelp13_ipc_info * qcelp13_info)192 void omx_qcelp13_thread_stop(struct qcelp13_ipc_info *qcelp13_info) {
193 DEBUG_DETAIL("%s stop server\n", __FUNCTION__);
194 close(qcelp13_info->pipe_in);
195 close(qcelp13_info->pipe_out);
196 pthread_join(qcelp13_info->thr,NULL);
197 qcelp13_info->pipe_out = -1;
198 qcelp13_info->pipe_in = -1;
199 DEBUG_DETAIL("%s: message thread close fds%d %d\n", qcelp13_info->thread_name,
200 qcelp13_info->pipe_in,qcelp13_info->pipe_out);
201 free(qcelp13_info);
202 }
203
omx_qcelp13_post_msg(struct qcelp13_ipc_info * qcelp13_info,unsigned char id)204 void omx_qcelp13_post_msg(struct qcelp13_ipc_info *qcelp13_info, unsigned char id) {
205 DEBUG_DETAIL("\n%s id=%d\n", __FUNCTION__,id);
206
207 write(qcelp13_info->pipe_out, &id, 1);
208 }
209