more abstraction in network.* and input.*, first display stuff in ivac.*
[my-code/ivac.git] / src / ivac.c
1 /* ivac.c -- main ivac file
2  *
3  * author: hackbard@hackdaworld.dyndns.org
4  *         frank.zirkelbach@physik.uni-augsburg.de
5  *
6  * Copyright (C) 2004 Frank Zirkelbach
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include "ivac.h"
25
26 int main(int argc,char **argv) {
27
28   /* TESTING BY NOW */
29
30   t_ivac ivac;
31
32   /* set username (futur: read from config or entered later) */
33   strcpy(ivac.username,"hackbard");
34
35   /* set capabilities (futur: set by check routines) */
36   ivac.g_cap=NETWORK;
37   ivac.av_cap=AUDIO|VIDEO|DUPLEX;
38
39   /* set event timeout */
40   ivac.event.timeout.tv_sec=IVAC_S_SEC;
41   ivac.event.timeout.tv_usec=IVAC_S_USEC;
42
43   /* set listen port (futur: read from config or entered later) */
44   network_set_listen_port(&(ivac.net),IVAC_LISTEN_PORT);
45
46   /* event init */
47   event_init(&(ivac.event));
48
49   /* input init */
50   ivac.input.mode=CONTENT_BUFFER;
51   input_init(&(ivac.input));
52
53   /* network init */
54   if(network_init(&(ivac.net))==N_ERROR) {
55     printf("[ivac] use 'fuser -n tcp %d' to kill that process",ivac.net.l_port);
56     return ERROR;
57   }
58
59   /* add listening port + stdin to (read) event system */
60   event_math(ivac.net.l_fd,&(ivac.event),READ,ADD);
61   event_math(0,&(ivac.event),READ,ADD);
62
63   /* display */
64   ivac_display(&(ivac));
65
66   /* start event system - callbacks used: ivac_event_cb + ivac_regular_cb */
67   event_start(&(ivac.event),(void *)&ivac,ivac_event_cb,ivac_regular_cb);
68
69   network_shutdown(&(ivac.net));
70
71   input_shutdown(&(ivac.input));
72
73   return SUCCESS;
74 }
75
76 int ivac_send_info(int channel,t_ivac *ivac) {
77
78   char data[SEND_N_MAX];
79   int size;
80
81   size=strlen(ivac->username);
82
83   data[0]=IVAC_SEND_NAME;
84   data[1]=size;
85   strncpy(data+2,ivac->username,size);
86   size+=2;
87
88   data[size]=IVAC_SEND_G_CAP;
89   data[size+1]=1;
90   data[size+2]=ivac->g_cap;
91   size+=3;
92
93   data[size]=IVAC_SEND_AV_CAP;
94   data[size+1]=2;
95   data[size+2]=(ivac->av_cap)>>8;
96   data[size+3]=(ivac->av_cap)&0xff;
97   size+=4;
98
99   if(network_send(ivac->net.connection[channel].fd,data,size)==N_ERROR) {
100     puts("[ivac] ivac_send_info failed");
101     return ERROR;
102   }
103
104   return SUCCESS;
105 }
106
107 int ivac_receive_info(int channel,t_ivac *ivac) {
108
109   char data[SEND_N_MAX];
110   int count,length;
111
112   count=0;
113
114   if((length=network_receive(ivac->net.connection[channel].fd,
115                              data,SEND_N_MAX))==N_ERROR) {
116     puts("[ivac] ivac_receive_info failed");
117     return ERROR;
118   }
119
120   while(length-count) {
121     switch(data[count]) {
122       case IVAC_SEND_NAME:
123         strncpy(ivac->challenger[channel].name,data+count+2,data[count+1]);
124         ivac->challenger[channel].name[data[count+1]]='\0';
125         count+=(data[count+1]+2);
126         break;
127       case IVAC_SEND_G_CAP:
128         ivac->challenger[channel].g_cap=data[count+2];
129         count+=3;
130         break;
131       case IVAC_SEND_AV_CAP:
132         ivac->challenger[channel].av_cap=data[count+2]<<8;
133         ivac->challenger[channel].av_cap|=data[count+3];
134         count+=4;
135         break;
136       default:
137         puts("[ivac] ivac_receive_info, unknown character");
138         return ERROR;
139         break;
140     }
141   }
142
143   return SUCCESS;
144 }
145
146 int ivac_event_cb(t_event *event,void *ptr) {
147  
148   t_ivac *ivac;
149   int channel;
150
151   ivac=(t_ivac *)ptr;
152
153   if(FD_ISSET(ivac->net.l_fd,&(event->rfds))) {
154     /* manage incoming + send info */
155     channel=network_manage_incoming(&(ivac->net));
156     event_math(ivac->net.connection[channel].fd,event,READ,ADD);
157     ivac_send_info(channel,ivac);
158   }
159
160   /* receive info */
161   for(channel=0;channel<MAX_CONNECTIONS;channel++)
162     if(ivac->net.connection[channel].status&C_ESTABL)
163       if(FD_ISSET(ivac->net.connection[channel].fd,&(event->rfds)))
164         ivac_receive_info(channel,ivac);
165
166   /* user interaction */
167   if(FD_ISSET(0,&(event->rfds)))
168     input_get_event(&(ivac->input),ivac_parse_command,ivac);
169
170   /* display ivac gui */
171   ivac_display(ivac);
172     
173   return SUCCESS;
174 }
175
176 int ivac_regular_cb(t_event *event,void *ptr) {
177
178   /* usual jobs like audio & video transmit ... */
179
180   return SUCCESS;
181 }
182
183 int ivac_parse_command(t_input *input,void *ptr) {
184
185   t_ivac *ivac;
186   int channel;
187
188   ivac=(t_ivac *)ptr;
189
190   /* parse command routines */
191
192   if(input->content[input->c_count-1]=='\n') {
193     /* delete content buffer + reset counter */
194     memset(input->content,0,input->c_count);
195     input->c_count=0;
196   }
197
198   return SUCCESS;
199 }
200
201 int ivac_display_head(void) {
202
203   /* 23 x 80 */
204   int column,line;
205
206   for(column=0;column<COLUMN;column++) printf("#");
207   printf("\n");
208
209   printf("##");
210   for(column=2;column<(COLUMN-8)/2;column++) printf(" ");
211   printf("- ivac -");
212   for(column=2;column<(COLUMN-8)/2;column++) printf(" ");
213   printf("##\n");
214
215   for(column=0;column<COLUMN;column++) printf("#");
216   printf("\n");
217
218   return SUCCESS;
219 }
220
221 int ivac_display_prompt(t_ivac *ivac) {
222
223   int column,line;
224
225   for(column=0;column<COLUMN;column++) printf("#");
226   printf("\n");
227   printf("## command: ");
228   for(column=12;column<12+ivac->input.c_count;column++)
229     printf("%c",ivac->input.content[column-12]);
230   for(column=12+ivac->input.c_count;column<COLUMN-2;column++) printf(" ");
231   printf("##");
232   printf("\n");
233   for(column=0;column<COLUMN;column++) printf("#");
234
235   return SUCCESS;
236 }
237
238 int ivac_display(t_ivac *ivac) {
239
240   int line,column;
241
242   /* display head */
243   ivac_display_head();
244
245   /* build content of middle part + display */
246   for(line=3;line<LINE-3;line++) {
247     printf("#");
248     for(column=1;column<COLUMN-1;column++) printf(" ");
249     printf("#\n");
250   }
251
252   /* display command prompt */
253   ivac_display_prompt(ivac);
254
255   return SUCCESS;
256 }