modified nlsop_client.c + added nlsop_server code
[physik/nlsop.git] / nlsop_server.c
1 /*
2  * nlsop server code
3  *
4  * author: frank zirkelbach (frank.zirkelbach@physik.uni-augsburg.de)
5  *
6  * this program tries helping to understand the amorphous depuration
7  * and recrystallization of SiCx while ion implantation at temperatures
8  * below 400 degree celsius.
9  * hopefully the program will simulate the stabilization of the
10  * selforganizing lamella structure in the observed behaviour.
11  *
12  * refs: 
13  *  - J. K. N. Lindner. Habil.Schrift, Universitaet Augsburg.
14  *  - Maik Haeberlen. Diplomarbeit, Universitaet Augsburg.
15  *
16  * Copyright (C) 2004 Frank Zirkelbach
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
31  *
32  */
33
34 #define _GNU_SOURCE
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42
43 #include "nlsop.h"
44 #include "dfbapi.h"
45 #include "random.h"
46
47 #include "network.h"
48 #include "event.h"
49 #include "list.h"
50
51 #define NLSOP_GUI 'g'
52 #define NLSOP_CLIENT 'c'
53 #define NLSOP_NJOB 'N'
54 #define NLSOP_CJOB 'C'
55
56 typedef struct s_client {
57   int channel;
58   unsigned char status;
59 #define IDLE (1<<0)
60 #define WORK (1<<1)
61 } t_client;
62
63 typedef struct s_job {
64   int channel;
65   unsigned char status;
66 #define IN_QUEUE (1<<0)
67 #define IN_WORK (1<<1)
68   int progress;
69   unsigned char *ac;
70   int *cc;
71   int x,y,z;
72   info info;
73   int step;
74 } t_job;
75
76 int usage(char *prog)
77 {
78  puts("usage:");
79  printf("%s <listen port>\n",prog);
80  return 1;
81 }
82
83 /*
84  * server specific stuff
85  */
86
87 int add_node(t_net *net,t_event *event,t_list *c_list,t_list *g_list) {
88
89   int channel;
90   unsigned char data;
91   t_client client;
92   t_job job;
93   int gui_chan;
94
95   channel=network_manage_incoming(net);
96   if(channel==N_E_ACCEPT) {
97     printf("accept failed!\n");
98     return -1;
99   }
100   if(channel==N_E_MAXC) {
101     printf("maximum connections reached!\n");
102     return -1;
103   }
104   printf("connection from %s port %d (ch: %d)\n",net->connection[channel].ip,
105                                                  net->connection[channel].port,
106                                                  channel);
107
108   /* are you client or gui? */
109   network_receive_chan(net,chanel,&data,1);
110   if(data==NLSOP_GUI) {
111     gui_chan=channel;
112     list_add_element(g_list,&gui_chan,sizeof(int));
113   }
114   else if(data==NLSOP_CLIENT) {
115     client.status=IDLE;
116     client.channel=channel;
117     list_add_element(c_list,&client,sizeof(t_client));
118   }
119   else {
120     printf("not a client or gui - lets kick that ass out of here!\n");
121     network_close(net,channel);
122     return -1;
123   }
124
125   /* if we have a new node - care for it! */
126   event_math(net->connection[channel].fd,event,READ,ADD);
127
128   return 1;
129 }
130
131 int save_job(t_net *net,int channel,t_job *job,unsigned char dc) {
132
133   char filename[128];
134   inf fd;
135   int ret;
136
137   ret=network_receive_chan(net,channel,job->ac,job->size*sizeof(unsigned char));
138   if(ret==N_ERROR) printf("FATAL: getting ac status failed\n");
139   ret=network_receice_chan(net,channel,job->cc,job->size*sizeof(int));
140   if(ret==N_ERROR) printf("FATAL: getting cc failed\n");
141   ret=network_receive_chan(net,channel,&(job->step),sizeof(int));
142   if(ret==N_ERROR) printf("FATAL: getting step number failed\n");
143
144   if(dc!=DC_QUIT) {
145     snprintf(filename,"nlsop_b%f_c%f_s%f_ds%d_dr%f_Z%c__%d_of_%d.save",
146              job->info->b,job->info->c,job->info->s,
147              job->info->diff_rate,job->info->dr_ac,
148              job->info->z_diff?'y':'n',
149              job->step,job->info->steps);
150     if((fd=open(filename,O_WRONLY|O_CREAT))<0) {
151       printf("FATAL: unable to open file %s\n",filename);
152       return -1;
153     }
154
155
156     
157   }
158
159   return 1;
160 }
161
162 int handle_node(net,event,c_list,g_list,job) {
163
164   int i;
165   unsigned char data;
166   t_client *c;
167   t_job *j;
168
169   for(i=0;i<MAX_CONNECTIONS;i++) {
170     if(FD_ISSET(net->connection[i].fd,&(event->rfds))) {
171
172       if(network_receive_chan(net,i,&data,1)==N_ERROR) {
173         printf("connection to client (ch %d) fucked up!\n",i);
174         event_math(net->connection[i].fd,event,READ,REMOVE);
175         network_close(net,i);
176         list_del_current(c_list);
177         return -1;
178       }
179
180       if(list_search_data(c_list,&i,sizeof(int))==L_SUCCESS) {
181         /* it's a client */
182         list_search_data(job,&i,sizeof(int));
183         j=(t_job *)job->current->data;
184         c=(t_client *)c_list->current-data;
185
186         if(data==DC_END) {
187           save_job(net,i,j,DC_END);
188           /* reset client */
189           c->channel=i;
190           c->status=IDLE;
191           /* delete job entry */
192           list_del_current(job);
193         }
194
195         if(data==DC_OK) {
196           save_job(net,i,j,DC_OK);
197           /* inc progress state */
198           j->progress+=1;
199         }
200
201         if(data==DC_QUIT) {
202           save_job(net,i,j,DC_QUIT);
203           /* network disconnect */
204           event_math(net->connection[i].fd,event,READ,REMOVE);
205           network_close(net,i);
206           /* del from client list */
207           list_del_current(c_list);
208           /* change job state */
209           j->status=IN_QUEUE;
210         }
211       }
212
213       else if(list_search_data(g_list,&i,sizeof(int))==L_SUCCESS) {
214         /* its a gui */
215           
216       }
217
218       else {
219         printf("this chan is not in client or gui list! i disconnect now!\n");
220         event_math(net->connection[i].fd,event,READ,REMOVE);
221         network_close(net,i);
222       }
223     }
224   }
225    
226   return 1;
227 }
228
229 int parse_incoming(t_event *event,void *allineed) {
230
231   t_net *net;
232   t_list *c_list,*g_list,*job;
233
234   net=(t_net *)allineed;
235   c_list=(t_list *)(allineed+sizeof(t_net));
236   g_list=(t_list *)(allineed+sizeof(t_net)+sizeof(t_list));
237   job=(t_list *)(allineed+sizeof(t_net)+2*sizeof(t_list));
238
239   /* decide what to do */
240   if(FD_ISSET(net->l.fd,&(event->rfds))) {
241     /* new node */
242     printf("new node ...\n");
243     add_node(net,event,c_list,g_list);
244   }
245   else {
246     /* client/gui interaction */
247     printf("node interaction ...\n");
248     handle_node(net,event,c_list,g_list,job);
249   }
250     
251   return 1;
252 }
253
254 /*
255  * main program
256  */
257
258 int main(int argc,char **argv)
259 {
260
261   int port;
262   t_net net;
263   t_event event;
264   t_list c_list;
265   t_list g_list;
266   t_list job;
267   void *allyouneed;
268
269   /* tzzz ... */
270   allyouneed=malloc(sizeof(t_net)+3*sizeof(t_list));
271   memcpy(allyouneed,&net,sizeof(t_net));
272   memcpy(allyouneed+sizeof(t_net),&c_list,sizeof(list));
273   memcpy(allyouneed+sizeof(t_net)+sizeof(t_list),&g_list,sizeof(list));
274   memcpy(allyouneed+sizeof(t_net)+2*sizeof(t_list),&job,sizeof(list));
275   
276   /* default values */
277   port=1025;
278
279   /* parse argv */
280   if(argc==2) port=atoi(argv[1]);
281
282   /* event init */
283   event_init(&event,1);
284   event_set_timeout(&event,0,0);
285
286   /* connect to server */
287   network_init(&net,1);
288   network_set_listen_port(&net,port);
289   if(network_listen(&net)!=N_SUCCESS) {
290     printf("unable to listen on port %d, aborting!\n",port);
291     return -1;
292   }
293
294   /* wait for events :) */
295   event_math(net.l_fd,&event,READ,ADD);
296   event_start(&event,allyouneed,parse_incoming,NULL);
297
298   return 1;
299 }
300