1 /*****************************************************************************
2    Major portions of this software are copyrighted by the Medical College
3    of Wisconsin, 1994-2000, and are released under the Gnu General Public
4    License, Version 2.  See the file README.Copyright for details.
5 ******************************************************************************/
6 
7 #include "def_epi.h"
8 #include "ep_afni.h"
9 
10 EXT struct im_info imX[] ;
11 
12 /*****************************************************************************/
13 
AFNI_exit(void)14 void AFNI_exit(void)                   /* Function to be called to make sure */
15 {                                      /* the AFNI data channels get closed. */
16    iochan_close(AFNI_ioc) ;
17    return ;
18 }
19 
20 /*****************************************************************************
21   Do I/O startup stuff; nim images are in the imX buffer at this time.
22 
23   At any given moment, this routine is in one of a number of modes
24   (the AFNI_mode variable).
25   The first time in, AFNI_mode == AFNI_OPEN_CONTROL_MODE.  In each mode,
26   certain tasks must be accomplished and this program must be synchronized
27   with AFNI.  When the necessary deeds are done, the routine advances to
28   the next mode.  If the deeds cannot be done when this routine is called,
29   then it will stay in the same mode, and the next time it is called it
30   will try to do them again.  This routine should be called repeatedly
31   until it progresses to the last mode (AFNI_CONTINUE_MODE), which is for
32   normal transmission of images (one at a time) to AFNI.  This operation
33   is handled in the separate routine AFNI_send_image (infra).
34 
35   If an error occurs, so that this program can no longer talk to AFNI, then
36   AFNI_mode is set to 0, which means "do nothing further".  The rest of
37   the data acquisition software will continue, but these routines will
38   be stopped dead.
39 ******************************************************************************/
40 
AFNI_start_io(int nim)41 void AFNI_start_io( int nim )
42 {
43    int ii , jj ;
44 
45    /***** Check for illegal conditions *****/
46 
47    if( AFNI_mode <= 0 || AFNI_mode == AFNI_CONTINUE_MODE ) return ;
48 
49    /***** If we are at the first time in,
50           try to open a control socket to talk to AFNI *****/
51 
52    if( AFNI_mode == AFNI_OPEN_CONTROL_MODE ){
53 
54       sprintf( AFNI_iochan , "tcp:%s:%d" ,
55                AFNI_host , get_port_named("AFNI_CONTROL_PORT") ) ;
56 
57       if( AFNI_verbose )
58          fprintf(stderr,"Opening control channel %s to AFNI.\n",AFNI_iochan) ;
59 
60       AFNI_ioc = iochan_init( AFNI_iochan , "w" ) ;
61 
62       if( AFNI_ioc == NULL ){
63          fprintf(stderr,"Can't open control channel %s to AFNI!\a\n",AFNI_iochan) ;
64          AFNI_mode = 0 ;                       /* disable AFNI */
65          return ;
66       } else {
67          if( AFNI_verbose ) fprintf(stderr,"Entering AFNI_WAIT_CONTROL_MODE.\n") ;
68          AFNI_mode = AFNI_WAIT_CONTROL_MODE ;  /* begin waiting for AFNI connection */
69       }
70    }
71 
72    /***** Check if the control socket is connected to AFNI *****/
73 
74    if( AFNI_mode == AFNI_WAIT_CONTROL_MODE ){
75 
76       ii = iochan_writecheck( AFNI_ioc , 1 ) ;  /* Check; wait at most 1 msec */
77 
78       /** if ii == 0, then the channel is still pending,
79           so do nothing; otherwise, take some action.    **/
80 
81       if( ii < 0 ){
82          fprintf(stderr,"Control channel to AFNI failed!\a\n") ;
83          IOCHAN_CLOSE(AFNI_ioc) ;
84          AFNI_mode = 0 ;                    /* disable AFNI */
85          return ;
86       } else if( ii > 0 ){
87          if( AFNI_verbose ) fprintf(stderr,"Control channel connected to AFNI."
88                                            "  Entering AFNI_OPEN_DATA_MODE.\n") ;
89          AFNI_mode = AFNI_OPEN_DATA_MODE ;  /* prepare to send data to AFNI */
90       }
91    }
92 
93    /***** Send the control information, which says
94           how we will talk to AFNI in the future (shmem or TCP/IP),
95           then close the control channel and open this new data channel *****/
96 
97    if( AFNI_mode == AFNI_OPEN_DATA_MODE ){
98 
99       /* decide name of data channel: it can be TCP/IP or shared memory */
100 
101       if( AFNI_use_tcp ) sprintf(AFNI_iochan,"tcp:%s:%d",
102                                  AFNI_host,get_port_named("AFNI_TCP_PORT")) ;
103       else               strcpy(AFNI_iochan,"shm:eps:1M") ;
104 
105       strcpy(AFNI_buf,AFNI_iochan) ;     /* tell AFNI where to read data */
106       if( AFNI_infocom[0] != '\0' ){
107          strcat(AFNI_buf,"\n") ;
108          strcat(AFNI_buf,AFNI_infocom) ; /* tell it where to get 3T info */
109       }
110 
111       if( AFNI_verbose )
112          fprintf(stderr,"Sending control information to AFNI:\n%s\n",AFNI_buf) ;
113 
114       ii = iochan_sendall( AFNI_ioc , AFNI_buf , strlen(AFNI_buf)+1 ) ;
115 
116       /** A negative return is bad news **/
117 
118       if( ii < 0 ){
119          fprintf(stderr,"Transmission of control data to AFNI failed!\a\n") ;
120          IOCHAN_CLOSE(AFNI_ioc) ;
121          AFNI_mode = 0 ;
122          return ;
123       } else {
124          while( ! iochan_clearcheck(AFNI_ioc,2) ) /* wait for control data to clear */
125             iochan_sleep(2) ;
126          IOCHAN_CLOSE(AFNI_ioc) ;                 /* close control channel */
127 
128          if( AFNI_verbose )
129             fprintf(stderr,"Opening data channel %s to AFNI.\n",AFNI_iochan) ;
130 
131          AFNI_ioc = iochan_init( AFNI_iochan , "w" ) ; /* open data channel */
132          if( AFNI_ioc == NULL ){
133             fprintf(stderr,"Can't open data channel %s to AFNI!\a\n",AFNI_iochan) ;
134             AFNI_mode = 0 ;
135             return ;
136          } else {
137             if( AFNI_verbose ) fprintf(stderr,"Entering AFNI_CATCHUP_MODE.\n") ;
138             AFNI_mode = AFNI_CATCHUP_MODE ;
139          }
140       }
141    }
142 
143    /***** Wait for the data channel to be connected to AFNI,
144           and then send any images that are reconstructed and ready to go *****/
145 
146    if( AFNI_mode == AFNI_CATCHUP_MODE ){
147 
148       ii = iochan_writecheck( AFNI_ioc , 1 ) ;  /* wait at most 1 msec */
149       if( ii < 0 ){
150          fprintf(stderr,"AFNI data channel aborted before any data was sent!\a\n") ;
151          IOCHAN_CLOSE( AFNI_ioc ) ;
152          AFNI_mode = 0 ;
153          return ;
154       } else if( ii > 0 ){                      /* can now send data to AFNI! */
155          if( AFNI_verbose )
156             fprintf(stderr,"AFNI data channel %s is connected.\n"
157                            "Entering AFNI_CONTINUE_MODE.\n" , AFNI_iochan) ;
158          AFNI_mode = AFNI_CONTINUE_MODE ;
159 
160          /* if there are any images already accumulated, send them now! */
161 
162          if( nim > 0 && AFNI_verbose )
163             fprintf(stderr,"Playing AFNI catchup with %d images.\n",nim) ;
164 
165          for( ii=0 ; ii < nim ; ii++ ) AFNI_send_image( ii ) ;
166       }
167    }
168 
169    return ;
170 }
171 
172 /*******************************************************************************/
173 
174 /** send image in imX[nim] to AFNI **/
175 
AFNI_send_image(int nim)176 void AFNI_send_image( int nim )
177 {
178    int lx = imX[nim].x , ly = imX[nim].y , nbytes = 2*lx*ly , soff , jj ;
179 
180    if( AFNI_mode != AFNI_CONTINUE_MODE ) return ;
181 
182    if ( (lx*ly) == 65536 ) soff = OFFSET;  /* for Signa */
183    else                    soff = 0;
184 
185    /** before very 1st image, send data type and matrix size **/
186 
187    if( nim == 0 ){
188       if( AFNI_verbose ) fprintf(stderr,"Sending 1st info+image to AFNI.\n") ;
189       sprintf( AFNI_buf , "DATUM short\nXYMATRIX %d %d\n" , lx,ly ) ;
190       iochan_sendall( AFNI_ioc , AFNI_buf , strlen(AFNI_buf)+1 ) ;
191    } else if( AFNI_verbose ){
192       fprintf(stderr,"Sending image %d to AFNI.\n",nim+1) ;
193    }
194 
195    jj = iochan_sendall( AFNI_ioc , imX[nim].arr + soff , nbytes ) ;
196 
197    /** if the data channel failed, stop **/
198 
199    if( jj < 0 ){
200       fprintf(stderr,"Image transmission to AFNI fails at #%d.\a\n",nim) ;
201       IOCHAN_CLOSE(AFNI_ioc) ;
202       AFNI_mode = 0 ;
203    }
204 
205    return ;
206 }
207