a913fd3bd1ca37c061f81a52359c92e7e73c3b42
[platform/adaptation/emulator/vmodem-daemon-emulator.git] / vmodem / server / server.c
1 /*
2  *  telephony-emulator
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: 
7  * Sooyoung Ha <yoosah.ha@samsung.com>
8  * Sungmin Ha <sungmin82.ha@samsung.com>
9  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
10  * 
11  * This library is free software; you can redistribute it and/or modify it under
12  * the terms of the GNU Lesser General Public License as published by the
13  * Free Software Foundation; either version 2.1 of the License, or (at your option)
14  * any later version.
15  * 
16  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
17  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
19  * License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with this library; if not, write to the Free Software Foundation, Inc., 51
23  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  *
25  * Contributors:
26  * - S-Core Co., Ltd
27  * 
28  */
29
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <sys/un.h>
33 #include <arpa/inet.h>
34 #include <netinet/in.h>
35 #include <errno.h>
36
37
38 #include "phoneserver.h"
39 #include "eloop.h"
40 //#include "data_conn_mgr.h"
41 #include "misc.h"
42 #include "state.h" //define ENTER()
43 #include "logmsg.h"
44
45 #define MAX_LISTEN_COUNT       32
46 //#define DEF_DOMAIN_SOCKET_NAME "/tmp/.phone_socket"
47 #define DEF_DOMAIN_SOCKET_NAME "/tmp/.vgsm_socket"
48
49 int vgsm_server_port=0;
50
51
52 extern GSM_StateMachine           GlobalS;
53
54 static void server_save_message(PhoneServer * ps, LXT_ID_CLIENT klass, LXT_MESSAGE * packet)
55 {
56     int ii;
57
58     Server * server = &ps->ServerSocket;
59     if  (server->mmsg.current >= MAX_MISSED_MESSAGE)
60     {
61                 TRACE(MSGL_WARN, "Warning!!! overrun max missed call\n");
62         server->mmsg.current = 0;
63     }
64
65     // save currunt
66     ii = server->mmsg.current;
67         TRACE(MSGL_VGSM_INFO, "Add current missed cast index: %d (client id: 0x%x)\n", ii, klass);
68         TRACE(MSGL_VGSM_INFO, "packet->group: 0x%x packet->action: 0x%x\n", packet->group, packet->action);
69
70 #ifdef _DEBUG_
71         if (server->mmsg.mmsg_info[ii].klass != LXT_STATE_RELEASED) {
72                 TRACE(MSGL_VGSM_ERR, "CRITICAL!!! overwrite data that not yet sent message to client\n");
73                 TRACE(MSGL_VGSM_ERR, "group:0x%x, action: 0x%x\n", server->mmsg.mmsg_info[ii].group, server->mmsg.mmsg_info[ii].action);
74         }
75 #endif
76     // set id
77     server->mmsg.mmsg_info[ii].klass = klass;
78
79     // clear message
80     TAPIMessageFree(&(server->mmsg.mmsg_info[ii].mmsg));
81
82     // copy message
83     server->mmsg.mmsg_info[ii].mmsg.length = packet->length;
84     server->mmsg.mmsg_info[ii].mmsg.group  = packet->group;
85     server->mmsg.mmsg_info[ii].mmsg.action = packet->action;
86
87     if  (packet->length > 0)
88     {
89         server->mmsg.mmsg_info[ii].mmsg.data =
90             (unsigned char *)PacketDataMalloc(packet->length);
91         memcpy(server->mmsg.mmsg_info[ii].mmsg.data, packet->data, packet->length);
92     }
93
94     server->mmsg.current ++;
95 }
96
97 static int server_send_to_client(int handle, LXT_MESSAGE * packet)
98 {
99         int datasize;
100         int rc = -1;
101
102         TRACE(MSGL_VGSM_INFO, "server_send_to_client : fd = %d, total size = 4+%d ... \n", handle, packet->length);
103         // save size (length of packet is only datasize)
104         datasize = packet->length;
105
106         rc = WriteBytes(handle, packet, 4);
107         if( rc != 4 )
108                 TRACE(MSGL_VGSM_ERR, "server_send_to_client1 : write error : rc = %d\n", rc);
109
110         // FIXME : Broken PIPE ¿À·ù ¼öÁ¤ÇÒ°Í.
111         if  (datasize > 0)
112         {
113                 rc = WriteBytes(handle, packet->data, datasize);
114                 if (rc != datasize )
115                         TRACE(MSGL_VGSM_ERR, "server_send_to_client2 : write error : rc = %d\n", rc);
116         }
117         return rc;
118 }
119
120 static TClientInfo * server_get_client(PhoneServer * ps, int clientid)
121 {
122     Server * server = &ps->ServerSocket;
123
124     TClientInfo * ci = server->current_ci;
125     if  (ci)
126         TRACE(MSGL_VGSM_INFO, "server get client is not null\n");
127
128     while (ci)
129     {
130         //if  (ci->klass == clientid)
131         if  (ci->klass == LXT_ID_CLIENT_EVENT_INJECTOR || ci->klass == clientid)
132             return ci;
133         ci = ci->next;
134     }
135     return NULL;
136 }
137
138 #if 0
139 static void get_domain_socket_name(char * result)
140 {
141     strcpy(result, DEF_DOMAIN_SOCKET_NAME);
142     strcat(result, (const char*)"-");
143     strcat(result, getenv("USER"));
144     return;
145 }
146 #endif
147
148 static void server_initialize(PhoneServer * ps)
149 {
150     Server * server = &ps->ServerSocket;
151     int ii;
152
153         TRACE(MSGL_VGSM_INFO, "\n");
154
155     server->fd = -1;
156     server->inet_fd = -1;
157     server->current_ci = NULL;
158
159     // Å¬¶óÀ̾ðÆ® Á¢¼ÓÀüÀÇ ¸Þ¼¼Áö¸¦ ´ã¾ÆµÎ±â À§ÇØ ÇÊ¿äÇÔ.
160     for (ii = 0; ii < MAX_MISSED_MESSAGE; ii ++)
161     {
162         server->mmsg.mmsg_info[ii].klass = LXT_ID_CLIENT_RESERVED;
163         TAPIMessageInit( &(server->mmsg.mmsg_info[ii].mmsg) );
164     }
165 }
166
167 static int  server_open(PhoneServer * ps)
168 {
169     Server * server = &ps->ServerSocket;
170
171     int rc = -1;
172     int len;
173     struct sockaddr_un serverAddr;
174     char socket_name[64] = {0, };
175
176         TRACE(MSGL_VGSM_INFO, "\n");
177
178         //090501
179     //get_domain_socket_name(socket_name);
180
181     server->fd = socket(AF_UNIX, SOCK_STREAM, 0);
182
183         log_msg(MSGL_VGSM_INFO, "fd =%d \n", server->fd);
184
185     if (server->fd < 0)
186     {
187         TRACE(MSGL_VGSM_ERR, "socket() failed\n");
188         return -1;
189     }
190
191     unlink(socket_name);
192
193     memset(&serverAddr, 0, sizeof(serverAddr));
194     serverAddr.sun_family = AF_UNIX;
195     strcpy(serverAddr.sun_path, socket_name);
196     len = sizeof(serverAddr.sun_family) + strlen(socket_name);
197
198     rc = bind(server->fd, (struct sockaddr *)&serverAddr, len);
199
200     if (rc != 0)
201     {
202         TRACE(MSGL_VGSM_ERR, "bind() failed\n");
203         close(server->fd);
204         return -1;
205     }
206
207     rc = listen(server->fd, MAX_LISTEN_COUNT);
208
209     if  (rc != 0)
210     {
211         TRACE(MSGL_VGSM_ERR, "listen() failed\n");
212         close(server->fd);
213         return -1;
214     }
215
216     return 0;
217 }
218
219
220 static int server_callback(PhoneServer * ps, int fd, EloopCondition cond, void * data)
221 {
222         log_msg(MSGL_VGSM_INFO, "fd = %d \n",fd);
223         Server * server = &ps->ServerSocket;
224
225         struct sockaddr_in addr;
226         int len = sizeof(addr);
227         memset(&addr, 0, len);
228
229         int client_fd = accept(server->fd, (struct sockaddr *)&addr, (socklen_t *)&len);
230
231         TRACE(MSGL_VGSM_INFO, "Client fd %d server fd %d\n", client_fd, server->fd);
232
233         if  (client_fd > 0)
234         {
235                 server->ci = malloc(sizeof (TClientInfo));
236                 server->ci->Functions = NULL;
237                 server->ci->Functions = &ClientHandle;
238                 server->ci->fd = client_fd;
239                 server->ci->klass = -1;
240                 server->ci->next = server->current_ci;
241                 server->current_ci = server->ci;
242                 TAPIMessageInit(&(server->ci->request));
243                 TAPIMessageInit(&(server->ci->notification));
244                 int tag = eloop_add_input(ps, server->ci->fd, ELOOP_READ,
245                             server->ci->Functions->CallBack, server->ci);
246                 server->ci->tag = tag;
247                 TRACE(MSGL_VGSM_INFO, "Server inet callback is registerd at [%d]\n", tag);
248         }
249         else
250         {
251                 perror("accept 2");
252         }
253         return 1;
254 }
255
256
257
258 static int  server_inet_open(PhoneServer * ps)
259 {
260         Server * server = &ps->ServerSocket;
261         struct sockaddr_in server_addr;
262         int val;
263
264         memset(&server_addr, 0, sizeof server_addr);
265         server_addr.sin_family = AF_INET;
266         server_addr.sin_port = htons(3578);
267         server_addr.sin_addr.s_addr = INADDR_ANY;
268
269         TRACE(MSGL_VGSM_INFO, "listening to port %d\n", server_addr.sin_port);
270
271         if((server->inet_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
272         {
273                 perror("socket() failed");
274                 return -1;
275         }
276
277         val = 1;
278         setsockopt(server->inet_fd, SOL_SOCKET, SO_REUSEADDR
279                 , (const char *)&val, sizeof(val));
280
281         if(bind(server->inet_fd, (struct sockaddr *)&server_addr, sizeof server_addr) == -1)
282         {
283                 perror("bind() failed");
284                 close(server->inet_fd);
285                 return -1;
286         }
287
288         if(listen(server->inet_fd, MAX_LISTEN_COUNT) == -1)
289         {
290                 perror("listen() failed");
291                 close(server->inet_fd);
292                 return -1;
293         }
294
295         return 0;
296 }
297
298
299 #if 1
300 static int server_inet_callback(PhoneServer * ps, int fd, EloopCondition cond, void * data)
301 {
302     Server * server = &ps->ServerSocket;
303
304     struct sockaddr_in addr;
305     int len = sizeof(addr);
306         memset(&addr, 0, len);
307
308     int client_fd = accept(server->inet_fd, (struct sockaddr *)&addr, (socklen_t *)&len);
309
310         TRACE(MSGL_VGSM_INFO, "\n\n\ninet socket accept!!!\n\n\n");
311     TRACE(MSGL_VGSM_INFO, "Client fd %d server fd %d\n",
312                                         client_fd, server->inet_fd);
313         /*
314         if  (client_fd > 0)
315         {
316                 DPRAM * dpram = &GlobalPS.Dpram;
317
318                 //      ++ 2008-08-05
319                 //      ++ Data.DPRAM is union. So, DPRAM is not clear whether it is fake or DPRAM.
320                 //      ++ It should be sure what is.
321                 //
322                 GSM_Device_DPRAMData   *d = &GlobalS.Device.Data.DPRAM;
323
324                 d->Power = true;
325                 d->hPhone = client_fd;
326
327                 dpram->fd=client_fd;
328
329                 int iotag;
330                 iotag = eloop_add_input(ps, dpram->fd, ELOOP_READ,
331                                                                 dpram->Functions->CallBack, 0); // dpram_callback
332                 TRACE(MSGL_VGSM_INFO, "Server inet callback is registerd at [%d]\n", iotag);
333         }
334         else
335         {
336                 perror("accept 3");
337         }
338         return 1;
339         */
340
341         if  (client_fd > 0)
342         {
343                 server->ci = malloc(sizeof (TClientInfo));
344                 server->ci->Functions = NULL;
345                 server->ci->Functions = &ClientHandle;
346                 server->ci->fd = client_fd;
347                 server->ci->klass = -1;
348                 server->ci->next = server->current_ci;
349                 server->current_ci = server->ci;
350                 TAPIMessageInit(&(server->ci->request));
351                 TAPIMessageInit(&(server->ci->notification));
352                 int tag = eloop_add_input(ps, server->ci->fd, ELOOP_READ,
353                             server->ci->Functions->CallBack, server->ci);
354                 server->ci->tag = tag;
355                 TRACE(MSGL_VGSM_INFO, "Server inet callback is registerd at [%d]\n", tag);
356         }
357         else
358         {
359                 perror("accept 2");
360         }
361         return 1;
362
363 }
364 #else
365
366 static int server_inet_callback(PhoneServer * ps, int fd, EloopCondition cond, void * data)
367 {
368         log_msg(MSGL_VGSM_INFO, "fd = %d \n",fd);
369         Server * server = &ps->ServerSocket;
370
371         struct sockaddr_in addr;
372         int len = sizeof(addr);
373         memset(&addr, 0, len);
374
375         int client_fd = accept(server->fd, (struct sockaddr *)&addr, (socklen_t *)&len);
376
377         TRACE(MSGL_VGSM_INFO, "Client fd %d server fd %d\n", client_fd, server->fd);
378
379         if  (client_fd > 0)
380         {
381                 server->ci = g_new(TClientInfo, 1);
382                 server->ci->Functions = NULL;
383                 server->ci->Functions = &ClientHandle;
384                 server->ci->fd = client_fd;
385                 server->ci->klass = -1;
386                 server->ci->next = server->current_ci;
387                 server->current_ci = server->ci;
388                 TAPIMessageInit(&(server->ci->request));
389                 TAPIMessageInit(&(server->ci->notification));
390                 int tag = eloop_add_input(ps, server->ci->fd, ELOOP_READ,
391                             server->ci->Functions->CallBack, server->ci);
392                 server->ci->tag = tag;
393                 TRACE(MSGL_VGSM_INFO, "Server inet callback is registerd at [%d]\n", tag);
394         }
395         else
396         {
397                 perror("accept 2");
398         }
399         return 1;
400 }
401
402 #endif
403
404 const char *str_main_cmd[] = {
405         "GSM_COMMON", // 0x00
406 "GSM_CALL",//                             0x01
407 "GSM_NETWORK",//                     0x02
408 "GSM_SUPS",//                             0x03
409 "GSM_SMS",//                              0x04
410 "GSM_MISC", //                             0x05
411 "GSM_DISPLAY", //                          0x06
412 "GSM_SIM", //                              0x07
413 "GSM_DATA", //                             0x08
414 "GSM_SAT", //                                     0x09
415 "GSM_SOUND", //                         0x0A
416 "GSM_EXT",//                              0x0B
417 "GSM_SERVICEMODE",//            0x0C
418 "GSM_EMULATOR ",//                   0x0D
419 "GSM_GPRS", //                            0x0E
420 "GSM_POWER",//                         0x0F
421 "GSM_CLIENT" //                        0x10
422 };
423
424 static void server_cast(PhoneServer * ps, int clientid, LXT_MESSAGE * packet)
425 {
426         _ENTER();
427     Server * server = &ps->ServerSocket;
428
429         TRACE(MSGL_VGSM_INFO, "clientid(%d) \n", clientid);
430
431     if  (server == NULL)
432         TRACE(MSGL_VGSM_INFO, "server cast server is null\n");
433     TClientInfo *ci = 0;
434     int clientfd = -1;
435
436     ci = server_get_client(ps, clientid);
437
438     if  (ci)
439         clientfd = ci->fd;
440     else
441         TRACE(MSGL_VGSM_INFO, "server cast client is null\n");
442
443     if  (clientfd > 0)
444     {
445         TRACE(MSGL_VGSM_INFO, "CAST MESSAGE TO [0x%x], MAIN[%s], SUB[0x%x] : ci fd [%d]\n", ci->klass, str_main_cmd[packet->group], packet->action, clientfd);
446
447         server_send_to_client(clientfd, packet);
448     }
449     else
450     {
451         server_save_message(ps, (LXT_ID_CLIENT)clientid, packet);
452     }
453 }
454
455 static void server_broadcast(PhoneServer * ps, LXT_MESSAGE * packet)
456 {
457         _ENTER();
458         Server * server = &ps->ServerSocket;
459
460         TRACE(MSGL_VGSM_INFO, "\n");
461
462         TClientInfo * ci = server->current_ci;
463         int clientfd = -1;
464
465         if  (ci)
466                 TRACE(MSGL_VGSM_INFO, "server get client is not null\n");
467
468         while (ci)
469         {
470                 if  (ci->fd > 0)
471                 {
472                         if  (ci->klass == 0x10)
473                         {
474                                 ci = ci->next;
475                                 continue;
476                         }
477
478                         WriteBytes(ci->fd, packet, 4);
479                         if  (packet->length > 0)
480                                 WriteBytes(ci->fd, packet->data, packet->length);
481                 }
482
483                 ci = ci->next;
484         }
485
486         // nsclass : Especially, cast internal message to phone indicator, because, phone applet broadcast
487         // phone state to other client.(save missed message)
488         // 1. LXT_ID_CLIENT_INDICATOR
489         ci = server_get_client(ps, LXT_ID_CLIENT_INDICATOR);
490         if (ci)
491                 clientfd = ci->fd;
492
493         if (clientfd < 0)
494                 server_save_message(ps, LXT_ID_CLIENT_INDICATOR, packet);
495
496         // 2. LXT_ID_CLIENT_DATASERVICE
497         clientfd = -1;
498         ci = server_get_client(ps, LXT_ID_CLIENT_DATASERVICE);
499         if (ci)
500                 clientfd = ci->fd;
501
502         if (clientfd < 0)
503                 server_save_message(ps, LXT_ID_CLIENT_DATASERVICE, packet);
504
505         // 3. LXT_ID_CLIENT_CARD_MANAGER
506         clientfd = -1;
507         ci = server_get_client(ps, LXT_ID_CLIENT_CARD_MANAGER);
508         if (ci)
509                 clientfd = ci->fd;
510
511         if (clientfd < 0)
512                 server_save_message(ps, LXT_ID_CLIENT_CARD_MANAGER, packet);
513
514         return;
515 }
516
517 static void clear_client_related_data(int client_id)
518 {
519         TRACE(MSGL_VGSM_INFO, "\n");
520
521         // 1. Multiple PDP related
522         //GetDataConnectMgr()->m_pFunc->ClearClient((unsigned char)client_id);
523
524         // 2. RequestResponse related
525 }
526
527 static void server_remove_client(PhoneServer * ps, TClientInfo *me)
528 {
529         Server * server = &ps->ServerSocket;
530         TClientInfo *curr = server->current_ci, *prev = 0;
531
532         TRACE(MSGL_VGSM_INFO, "\n");
533
534         while (curr)
535         {
536                 if (curr == me)
537                 {
538                         if  (prev)
539                         {
540                                 prev->next = curr->next;
541                         }
542                         else
543                         {
544                                 server->current_ci = curr->next;
545                         }
546                         TAPIMessageFree( &(curr->notification) );
547                         TAPIMessageFree( &(curr->request) );
548                         close(curr->fd);
549
550                         clear_client_related_data(curr->klass);
551
552                         PacketDataFree(curr);
553                         return;
554                 }
555                 prev = curr;
556                 curr = curr->next;
557         }
558 }
559
560 //void server_cast_missed_message(PhoneServer * ps, LXT_ID_CLIENT klass,
561 static void server_cast_missed_message(PhoneServer * ps, int klass, int clientfd)
562 {
563         Server * server = &ps->ServerSocket;
564         //TClientInfo *curr = server->current_ci, *prev = 0;
565         int ii = 0;
566         //int jj;
567         int rc;
568
569         TRACE(MSGL_VGSM_INFO, "\n");
570
571         for (ii = 0; ii < MAX_MISSED_MESSAGE; ii ++)
572         {
573                 if  (server->mmsg.mmsg_info[ii].klass == klass)
574                 {
575                         rc = WriteBytes( clientfd, &(server->mmsg.mmsg_info[ii].mmsg), 4);
576                         if  (server->mmsg.mmsg_info[ii].mmsg.length > 0)
577                         {
578                                 // tx data to client
579                                 rc = WriteBytes(        clientfd,
580                                                                         server->mmsg.mmsg_info[ii].mmsg.data,
581                                                                         server->mmsg.mmsg_info[ii].mmsg.length);
582             }
583
584                         server->mmsg.mmsg_info[ii].klass = LXT_ID_CLIENT_RESERVED;
585                         TRACE(MSGL_VGSM_INFO, "removed missed cast index: %d by client(0x%x)\n", ii, klass);
586
587                         // clear message
588                         TAPIMessageFree(&(server->mmsg.mmsg_info[ii].mmsg));
589                 }
590         }
591 }
592
593 FunctionsServer ServerHandle =
594 {
595         server_initialize,
596         server_open,
597         server_callback,
598         server_inet_open,
599         server_inet_callback,
600         server_cast,
601         server_broadcast,
602         server_remove_client,
603         server_cast_missed_message
604 };
605