4 * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
5 * Copyright (c) 2002-2011, Professor Benoit Macq
6 * Copyright (c) 2010-2011, Kaori Hagihara
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
34 #include "auxtrans_manager.h"
43 #include "fcgi_stdio.h"
44 #define logstream FCGI_stdout
46 #define FCGI_stdout stdout
47 #define FCGI_stderr stderr
48 #define logstream stderr
51 auxtrans_param_t init_aux_transport( int tcp_auxport, int udp_auxport)
53 auxtrans_param_t auxtrans;
55 auxtrans.tcpauxport = tcp_auxport;
56 auxtrans.udpauxport = udp_auxport;
58 if( 49152 <= tcp_auxport && tcp_auxport <= 65535)
59 auxtrans.tcplistensock = open_listeningsocket( (uint16_t)tcp_auxport);
61 auxtrans.tcplistensock = -1;
63 auxtrans.udplistensock = -1;
64 /* open listening socket for udp later */
69 void close_aux_transport( auxtrans_param_t auxtrans)
71 if( auxtrans.tcplistensock != -1)
72 if( close_socket( auxtrans.tcplistensock) != 0)
75 if( auxtrans.udplistensock != -1)
76 if( close_socket( auxtrans.udplistensock) != 0)
81 /*!< auxiliary response parameters */
82 typedef struct aux_response_param{
83 char *cid; /*!< channel ID */
84 unsigned char *data; /*!< sending data */
85 OPJ_SIZE_T datalen; /*!< length of data */
86 OPJ_SIZE_T maxlenPerFrame; /*!< maximum data length to send per frame */
87 SOCKET listensock; /*!< listeing socket */
89 HANDLE hTh; /*!< thread handle */
91 } aux_response_param_t;
93 aux_response_param_t * gene_auxresponse( opj_bool istcp, auxtrans_param_t auxtrans, const char cid[], void *data, OPJ_SIZE_T datalen, OPJ_SIZE_T maxlenPerFrame);
95 void delete_auxresponse( aux_response_param_t **auxresponse);
99 unsigned __stdcall aux_streaming( void *arg);
101 void * aux_streaming( void *arg);
104 void send_responsedata_on_aux( opj_bool istcp, auxtrans_param_t auxtrans, const char cid[], void *data, OPJ_SIZE_T datalen, OPJ_SIZE_T maxlenPerFrame)
106 aux_response_param_t *auxresponse;
108 unsigned int threadId;
115 if( auxtrans.tcplistensock == -1){
116 fprintf( FCGI_stderr, "Error: error in send_responsedata_on_aux(), tcp listening socket no open\n");
120 auxresponse = gene_auxresponse( istcp, auxtrans, cid, data, datalen, maxlenPerFrame);
123 auxresponse->hTh = (HANDLE)_beginthreadex( NULL, 0, &aux_streaming, auxresponse, 0, &threadId);
124 if( auxresponse->hTh == 0)
125 fprintf( FCGI_stderr,"ERRO: pthread_create() %s", strerror( (int)auxresponse->hTh));
127 status = pthread_create( &thread, NULL, &aux_streaming, auxresponse);
129 fprintf( FCGI_stderr,"ERROR: pthread_create() %s",strerror(status));
133 fprintf( FCGI_stderr, "Error: error in send_responsedata_on_aux(), udp not implemented\n");
136 aux_response_param_t * gene_auxresponse( opj_bool istcp, auxtrans_param_t auxtrans, const char cid[], void *data, OPJ_SIZE_T datalen, OPJ_SIZE_T maxlenPerFrame)
138 aux_response_param_t *auxresponse;
140 auxresponse = (aux_response_param_t *)opj_malloc( sizeof(aux_response_param_t));
142 auxresponse->cid = strdup( cid);
143 auxresponse->data = data;
144 auxresponse->datalen = datalen;
145 auxresponse->maxlenPerFrame = maxlenPerFrame;
146 auxresponse->listensock = istcp ? auxtrans.tcplistensock : auxtrans.udplistensock;
151 void delete_auxresponse( aux_response_param_t **auxresponse)
153 opj_free( (*auxresponse)->cid);
154 opj_free( (*auxresponse)->data);
155 opj_free( *auxresponse);
159 * Identify cid sent from client
161 * @param [in] connected_socket file descriptor of the connected socket
162 * @param [in] refcid refenrece channel ID
163 * @param [in] fp file pointer for log of aux stream
164 * @return true if identified, false otherwise
166 opj_bool identify_cid( SOCKET connected_socket, char refcid[], FILE *fp);
168 opj_bool recv_ack( SOCKET connected_socket, void *data);
171 unsigned __stdcall aux_streaming( void *arg)
173 void * aux_streaming( void *arg)
176 SOCKET connected_socket;
177 unsigned char *chunk, *ptr;
178 OPJ_SIZE_T maxLenOfBody, remlen, chunklen;
179 const OPJ_SIZE_T headlen = 8;
181 aux_response_param_t *auxresponse = (aux_response_param_t *)arg;
184 CloseHandle( auxresponse->hTh);
186 pthread_detach( pthread_self());
189 chunk = (unsigned char *)opj_malloc( auxresponse->maxlenPerFrame);
190 maxLenOfBody = auxresponse->maxlenPerFrame - headlen;
191 remlen = auxresponse->datalen;
193 while((connected_socket = accept_socket( auxresponse->listensock)) != -1){
194 if( identify_cid( connected_socket, auxresponse->cid, FCGI_stderr)){
195 ptr = auxresponse->data;
197 memset( chunk, 0, auxresponse->maxlenPerFrame);
199 chunklen = remlen<maxLenOfBody?remlen:maxLenOfBody;
202 chunk[0] = (chunklen >> 8) & 0xff;
203 chunk[1] = chunklen & 0xff;
205 memcpy( chunk+headlen, ptr, chunklen-headlen);
208 send_stream( connected_socket, chunk, chunklen);
209 }while( !recv_ack( connected_socket, chunk));
211 remlen -= maxLenOfBody;
214 if( close_socket( connected_socket) != 0)
221 delete_auxresponse( &auxresponse);
233 opj_bool identify_cid( SOCKET connected_socket, char refcid[], FILE *fp)
238 if(!(cid = receive_string( connected_socket))){
239 fprintf( fp, "Error: error in identify_cid(), while receiving cid from client\n");
244 if( strncmp( refcid, cid, strlen( refcid)) == 0)
252 opj_bool recv_ack( SOCKET connected_socket, void *data)
257 header = receive_stream( connected_socket, 8);
259 if( memcmp( header, data, 8) != 0)