6db7a3089617d67c8f8990447174f38a7799a597
[platform/adaptation/emulator/vmodem-daemon-emulator.git] / vmodem / server / server_tx_call.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 /////////////////////////////////////////////////////////////////////
31 // server_tx_calll.c
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include <assert.h>
36
37 #include "state.h" // linuxtapi.h
38 #include "misc.h"
39
40 #include "phoneserver.h"
41
42 #include "vgsm_call.h"
43 #include "oem_tx_call.h"
44 #include "server_tx_call.h"
45 #include "server_common_call.h"
46 #include "server_tx_ss.h"
47 #include "logmsg.h"
48 #include "at_gen_resp.h"
49 #include "at_func.h"
50
51 // caution: MAX_GSM_DIALED_DIGITS_NUMBER and MAX_GSM_DIALED_DIGITS_NUM are confusingly similar
52
53 int server_tx_call_msg(void)
54 {
55         _ENTER();
56
57         STATE state;
58
59         get_current_state_machine(&state );
60
61         switch(STATE_SUB_CMD(state))
62         {
63                 case GSM_CALL_STATUS:
64                         server_tx_call_status();
65                         break;
66                 case GSM_CALL_LIST:
67                         server_tx_call_list_resp();
68                         break;
69                 default:
70                         log_msg(MSGL_WARN, "unknown subcommand %d\n", STATE_SUB_CMD(state));
71         }
72
73         _LEAVE();
74
75         return 1;
76 }
77
78 //int TxCall_CallStatus()
79 int server_tx_call_status(void) // it means call state.
80 {
81         int ret = 0;
82         STATE prev;
83         int i;
84         int call_state = 0;
85
86         TRACE(MSGL_VGSM_INFO, "\n");
87
88         LXT_MESSAGE packet;
89         gsm_call_list_t * callList = malloc(sizeof(gsm_call_list_t));
90         if(!callList)
91                 return -1;
92         memset(callList, 0, sizeof(gsm_call_list_t));
93
94         get_prev_state_machine( &prev );
95
96         //      if( STATE_SUB_CMD(prev) == GSM_CALL_OUTGOING )
97         if( STATE_TYPE(prev) == STATE_STANDBY ) // it means GSM_CALL_OUTGOING in state_machine.
98         {
99                 call_state = GSM_CALL_STATE_OUTGOING;
100                 log_msg(MSGL_VGSM_INFO, "STATE_STANBY\n");
101                 set_call_list_status( get_call_id(), 0, GSM_CALL_STATUS_DIALING );
102                 get_call_list(callList);
103         }
104         else if( STATE_TYPE(prev) == STATE_CALL_WAITING_OUTGOING || STATE_TYPE(prev) == STATE_CALL_WAITING_INCOMING )
105         {
106                 call_state = GSM_CALL_STATE_CONNECTED;
107
108                 // find client id of incoming call & set active
109                 get_call_list(callList);
110                 for( i=0; i<MAX_CALL_COUNT; ++i ) {
111                         if(callList->CallInfo[i].stat  == GSM_CALL_STATUS_INCOMING || callList->CallInfo[i].stat == GSM_CALL_STATUS_WAITING){
112                                 log_msg(MSGL_VGSM_INFO,"call id(%d) is GSM_CALL_STATUS_INCOMING \n", i);
113                                 set_call_id( i );
114                                 break;
115                         }
116                 }
117                 set_call_list_status( get_call_id(), 0, GSM_CALL_STATUS_ACTIVE );
118                 at_gen_resp_send(AT_GEN_ERR_CONNECT);
119
120                 // re get call list
121                 get_call_list(callList);
122
123                 for(i = 0; i < callList->CallCount; i++){
124                         log_msg(MSGL_VGSM_INFO,"call id : %d, number : %s, multiparty : %d, stat : %d \n",
125                                         callList->CallInfo[i].idx, callList->CallInfo[i].number,
126                                         callList->CallInfo[i].mpty, callList->CallInfo[i].stat);
127                 }
128
129                 packet.data = (gsm_call_list_t*)callList;
130                 packet.group  = GSM_CALL;
131                 packet.action = GSM_CALL_CONNECTED_LINE_NOTI;
132                 packet.length = sizeof(gsm_call_list_t);
133
134                 FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
135                 if(get_call_id() >= callList->CallCount) {
136                         callback_callist();
137                 }
138         }
139         else if( STATE_TYPE(prev) == STATE_CALL_RELEASED )
140         {
141                 call_state = GSM_CALL_STATE_RELEASED;
142                 at_gen_resp_send(AT_GEN_ERR_RELEASE);           
143
144                 get_call_list(callList);
145                 packet.data = (gsm_call_list_t*)callList;
146                 packet.group  = GSM_CALL;
147                 packet.action = GSM_CALL_STATUS_NOTI;
148                 packet.length = sizeof(gsm_call_list_t);
149
150                 FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
151                 set_call_list_status( get_call_id(), 0, GSM_CALL_STATUS_NONE );
152                 get_call_list(callList);
153         }
154         /* Why does not it exist in case of STATE_CALL_CONVERSATION */
155
156         /*       In call status msg, incoming msg do not exist.
157                  else if( STATE_SUB_CMD(prev) == GSM_CALL_INCOMING )
158                  {
159                  pdata[2] = GSM_CALL_STATE_INCOMING;
160                  }
161          */
162
163         unsigned char pdata[128];
164         int at_stat = change_stat_for_at(callList->CallInfo[get_call_id()].stat);
165         TRACE(MSGL_VGSM_INFO, "call id:%d, orignal stat: %d, send stat: %d\n", get_call_id(), callList->CallInfo[get_call_id()].stat, at_stat);
166         
167         if(strcmp(callList->CallInfo[get_call_id()].number, ""))
168         {
169                 sprintf((char*)pdata, "%d,%d,%d,%d,%d,%s,%d", get_call_id() + 1, change_dir_for_at(callList->CallInfo[get_call_id()].dir), 
170                                                                 at_stat, AT_CALL_MODE_VOICE, AT_CALL_MPTY_FALSE, 
171                                                                 callList->CallInfo[get_call_id()].number,callList->CallInfo[get_call_id()].num_type); 
172         }
173         else
174         {
175                 sprintf((char*)pdata, "%d,%d,%d,%d,%d", get_call_id() + 1, change_dir_for_at(callList->CallInfo[get_call_id()].dir), at_stat, AT_CALL_MODE_VOICE, AT_CALL_MPTY_FALSE);
176         }
177  
178         free(callList);
179         set_current_call_status_error( 0x00 );
180
181         ret = oem_tx_call_status_noti(pdata, strlen((char*)pdata));
182
183         _LEAVE();
184
185         return ret;
186 }
187
188 int server_tx_call_list_noti(void)
189 {
190         _ENTER();
191
192         int i = 0, j = 0, ret = 0;
193         int CallCount = 0;
194         int len = 0;
195         unsigned char *data = NULL;
196         LXT_MESSAGE packet;
197         gsm_call_list_t         * callList = malloc(sizeof(gsm_call_list_t));
198
199         get_call_list(callList);
200         CallCount = callList->CallCount;
201         // FIXME: probably want MAX_GSM_DIALED_DIGITS_NUM here
202         len = 32 + (8+MAX_GSM_DIALED_DIGITS_NUMBER);
203         data = malloc(len*2);
204         log_msg(MSGL_VGSM_INFO,"CallCount %d\n", CallCount);
205         j = 1;
206         for (i=0; i < MAX_CALL_COUNT; i++) {
207                 if( callList->CallInfo[i].stat == GSM_CALL_STATUS_NONE )
208                         continue;
209                 log_msg(MSGL_VGSM_INFO,"index = %d    : Call_STATUS %d\n", i, callList->CallInfo[i].stat);
210                 
211                 assert(valid_call_type(callList->CallInfo[i].call_type));
212                 memset( data, 0, len * 2 );
213                 sprintf((char*)data, "%d,%d,%d,%d,%d,%s,%d%s", callList->CallInfo[i].idx + 1,
214                                                         change_dir_for_at(callList->CallInfo[i].dir),
215                                                         change_stat_for_at(callList->CallInfo[i].stat), AT_CALL_MODE_VOICE, callList->CallInfo[i].mpty, 
216                                                         callList->CallInfo[i].number, callList->CallInfo[i].num_type, CRLF);
217                 log_msg(MSGL_VGSM_INFO, "%s", data);
218                 ret = oem_tx_call_status_noti(data, strlen((char*)data));
219         }
220         
221         /* send to EI */
222         packet.data = (gsm_call_list_t*)callList;
223         packet.length = sizeof(gsm_call_list_t);
224         packet.group  = GSM_CALL;
225         packet.action = GSM_CALL_CALL_LIST_IND;
226
227         FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
228
229         free(data);
230         free(callList);
231
232         _LEAVE();
233
234         return ret;
235 }
236
237 int change_stat_for_at(int gsm_stat)
238 {
239         int stat = 0;
240         switch(gsm_stat)
241         {
242         case GSM_CALL_STATUS_NONE:
243                 stat = AT_CALL_STAT_RELEASED;
244                 break;
245         case GSM_CALL_STATUS_ACTIVE:
246                 stat = AT_CALL_STAT_ACTIVE;
247                 break;
248         case GSM_CALL_STATUS_HELD:
249                 stat = AT_CALL_STAT_HELD;
250                 break;
251         case GSM_CALL_STATUS_DIALING:
252                 stat = AT_CALL_STAT_DIALING;
253                 break;
254         case GSM_CALL_STATUS_ALERT:
255                 stat = AT_CALL_STAT_ALERTING;
256                 break;
257         case GSM_CALL_STATUS_INCOMING:
258                 stat = AT_CALL_STAT_INCOMING;
259                 break;
260         case GSM_CALL_STATUS_WAITING:
261                 stat = AT_CALL_STAT_WAITING;
262                 break;
263         case GSM_CALL_STATUS_MAX:
264         default:
265                 stat = AT_CALL_STAT_DIALING;
266                 break;
267         }
268
269         return stat;
270 }
271
272 int change_dir_for_at(int gsm_dir)
273 {
274         int dir = 0;
275
276         switch(gsm_dir)
277         {
278         case GSM_CALL_DIR_MO:
279                 dir = 0;
280                 break;
281         case GSM_CALL_DIR_MT:
282                 dir = 1;
283                 break;
284         default:
285                 dir = 0;
286                 break;
287         }
288         return dir;
289 }
290
291 int server_tx_call_list_resp(void)
292 {
293         int i = 0, ret = 0;
294         int CallCount = 0;
295         int len = 0;
296         unsigned char *data = NULL;
297         gsm_call_list_t * callList = malloc(sizeof(gsm_call_list_t));
298
299         _ENTER();
300
301         get_call_list(callList);
302         CallCount = callList->CallCount;
303         len = 32 + (8+MAX_GSM_DIALED_DIGITS_NUMBER);
304         data = malloc(len*2);
305         log_msg(MSGL_VGSM_INFO,"CallCount %d\n", CallCount);
306         for (i=0; i < MAX_CALL_COUNT; i++) {
307                 if( callList->CallInfo[i].stat == GSM_CALL_STATUS_NONE )
308                         continue;
309                 log_msg(MSGL_VGSM_INFO,"index = %d    : Call_STATUS %d\n",  i, callList->CallInfo[i].stat);
310
311                 assert(valid_call_type(callList->CallInfo[i].call_type));
312                 memset( data, 0, len * 2);
313                 sprintf((char*)data, "%s%d,%d,%d,%d,%d,%s,%d%s", CLCC,callList->CallInfo[i].idx + 1, 
314                                                         change_dir_for_at(callList->CallInfo[i].dir),
315                                                         change_stat_for_at(callList->CallInfo[i].stat), 
316                                                         AT_CALL_MODE_VOICE, callList->CallInfo[i].mpty, 
317                                                         callList->CallInfo[i].number, callList->CallInfo[i].num_type, CRLF);
318                 log_msg(MSGL_VGSM_INFO, "%s", data);    
319                 ret = oem_tx_call_list_resp(data, strlen((char*)data));
320         }
321         at_gen_resp_send(AT_GEN_ERR_NO_ERROR);
322
323         free(data);
324         free(callList);
325
326         _LEAVE();
327
328         return ret;
329 }
330
331 static void cast_call_incomming(unsigned char call_id)
332 {
333         _ENTER();
334
335         unsigned char data[1];
336         LXT_MESSAGE packet;
337         TAPIMessageInit(&packet);
338
339         /*   check general response error & call status error    */
340
341         data[0] = call_id;              //The object is simulator,   0x01 : Outgoing Call, 0x02 : Answer Call, 0x03 : Release Call
342
343         packet.data = data;
344         packet.length = 1;
345         packet.group  = GSM_CALL;
346         packet.action = GSM_CALL_ID;
347
348         FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
349
350         log_msg(MSGL_VGSM_INFO," -------------------------incoming call id : %d\n",call_id);
351 }
352
353
354 int server_tx_call_incoming_noti( LXT_MESSAGE * packet ) //¸ÁÀÔÀå¿¡¼± outgoing call.
355 {
356         int num_len = 0, ret = 0, tmp = 0;
357         char number[MAX_GSM_DIALED_DIGITS_NUMBER];
358         char *p, data[MAX_GSM_DIALED_DIGITS_NUMBER*2];
359         unsigned char ss_present_indi ;
360         unsigned char ss_call_type ;
361         unsigned char ss_no_cli_cause ;
362         unsigned char call_id ;
363         STATE state;
364         gsm_call_list_t list;
365         gsm_call_status_e_type call_status = GSM_CALL_STATUS_INCOMING;
366         char clir = GSM_CALL_CLIR_STATUS_NOT_CHANGED;           //gsm_clir_status_e_type
367         int call_exist = 0;  //  ÇöÀç call list¿¡, callÀÌ ¾ø´Ù¸é incoming noti Àü¼ÛÇÑ´Ù.
368         unsigned short call_type;
369
370         int i;
371         call_barring_entry_t * resp_entry = get_call_barring_entry() ;
372
373         TRACE(MSGL_VGSM_INFO, "\n");
374
375         if(!resp_entry)
376                 TRACE(MSGL_VGSM_INFO, "CB entry is NULL!!!\n");
377         else {
378                 for(i=0; i<resp_entry[0].count; i++) {
379                         TRACE(MSGL_VGSM_INFO,"i : %d,  type : %d\n", i, resp_entry[i].type);
380                         if(resp_entry[i].type == 4 && resp_entry[i].ss_mode == 3) { // 'All incoming calls' has set
381                                 TRACE(MSGL_VGSM_ERR, "Incoming Call Barring is set \n");
382                                 callback_callist();
383                                 return -1;
384                         }
385                 }
386         }
387
388         get_current_state_machine( &state );
389         if( ( state.state_type == STATE_CALL_WAITING_OUTGOING ) ||
390                         ( state.state_type == STATE_CALL_WAITING_INCOMING ) )
391         {
392                 log_msg(MSGL_WARN,"state_type = %d\n",state.state_type);
393                 return 0;
394         }
395
396         if( check_call() == 0 )
397         {
398                 log_msg(MSGL_WARN, "1 active and 1 hold \n");
399                 // delete for multi call ( 6 call ) return 0;
400         }
401
402         get_call_list( &list );
403         if( list.CallCount > 0 ) {
404                 call_status = GSM_CALL_STATUS_WAITING;
405
406                 // sub_cmd = GSM_CALL_WAITING;
407                 call_exist = 1; // call list¿¡ call ÀÌ Á¸ÀçÇϸé, incoming noti ´ë½Å¿¡ waiting noti¸¦ Àü¼ÛÇÑ´Ù.
408         }
409
410         assert(packet->length >= 8);
411         p = packet->data;
412
413         call_id = make_call_id();
414         call_type = p[0] << 8;
415         cast_call_incomming(call_id);
416         set_call_type(call_type);
417
418         memset(number, 0, MAX_GSM_DIALED_DIGITS_NUMBER);
419
420         clir = p[2];
421
422         if(clir == GSM_CALL_CLIR_STATUS_INVOCATION)
423         {
424                 log_msg(MSGL_VGSM_INFO,"  GSM_CALL_CLIR_STATUS_INVOCATION -> no num  \n");
425                 num_len = 0; // È®ÀÎÇÏÀÚ. num_len °¡ MAX_GSM_DIALED_DIGITS_NUMBER µÇ¾î¾ßÇÏ´ÂÁö check...
426                 memset(number, 0, MAX_GSM_DIALED_DIGITS_NUMBER);
427                 ss_present_indi = p[5];
428                 ss_no_cli_cause = p[6];
429
430         }
431         else
432         {
433                 tmp = (int)p[3];
434                 if(tmp < 0){
435                         TRACE(MSGL_VGSM_INFO, "ERROR!! Invalid value of packet.data.\n");
436                         callback_callist();
437                         return -1;
438                 } else if ( tmp >= MAX_GSM_DIALED_DIGITS_NUMBER){
439                         TRACE(MSGL_VGSM_INFO, "The number is too long. It will be cut.\n");
440                         num_len = MAX_GSM_DIALED_DIGITS_NUMBER - 1;
441                 } else {
442                         num_len = tmp;
443                 }
444                 memcpy(number, &p[7], num_len);
445                 number[num_len] = '\0';
446                 log_msg(MSGL_VGSM_INFO,"  call num len %d  \n", num_len);
447                 ss_present_indi = 0;
448                 ss_no_cli_cause = 0;
449         }
450
451         set_call_list( GSM_CALL_DIR_MT, call_status, call_type, number, num_len );
452
453         //090314
454         callback_callist();
455
456         char* number_type;
457         if(number[0] == '+')
458                 number_type = "129";
459         else
460                 number_type = "145";    // default
461         
462         if(call_exist == 0)
463         {
464                 sprintf(data, "%d,%d,%d,%d,%d,%s,%s", call_id + 1, AT_CALL_DIR_MT, AT_CALL_STAT_INCOMING, AT_CALL_MODE_VOICE, AT_CALL_MPTY_FALSE, number, number_type);
465                 TRACE(MSGL_VGSM_INFO, "data: %s\n", data);
466                 ret = oem_tx_call_incoming_noti(data, strlen(data));
467         }
468         else
469         {
470                 sprintf(data, "%s,%s,%d", number, number_type, AT_CALL_CLASS_VOICE);
471                 TRACE(MSGL_VGSM_INFO, "data: %s\n", data);
472                 ret = oem_tx_call_waiting_noti(data, strlen(data));
473
474                 memset(data, '\0', strlen(data));
475                 sprintf(data, "%d,%d,%d,%d,%d,%s,%s", call_id + 1, AT_CALL_DIR_MT, AT_CALL_STAT_WAITING, AT_CALL_MODE_VOICE, AT_CALL_MPTY_FALSE, number, number_type);
476                 TRACE(MSGL_VGSM_INFO, "data: %s\n", data);
477                 return oem_tx_call_status_noti(data, strlen(data));
478         }
479
480         //log_msg(MSGL_VGSM_INFO,"!!!!!!!!server_tx_call_incoming_noti!!!!!!!!!!! number : %d, number len : %d \n", number[0], num_len);
481         if( GSM_CALL_TYPE_FORWARDED == p[1] )
482         {
483                 ss_call_type = 0x33 ;
484                 // forwardcall
485         }
486         else
487         {
488                 ss_call_type = 0x31 ; //calling party
489         }
490
491         log_msg(MSGL_VGSM_INFO,"  call type = %d,  num len=%d  PI=%d  Cli-cause %d \n", p[0], num_len,ss_present_indi,ss_no_cli_cause);
492
493         server_tx_ss_cli(ss_call_type, ss_present_indi, ss_no_cli_cause); // TODO:  it will be changed..
494
495         _LEAVE();
496
497         return ret;
498 }
499
500 //int TxCall_ExecRelease( LXT_MESSAGE * packet )
501 int server_tx_call_release_exec(LXT_MESSAGE * packet )
502 {
503         int i, ret = 0;
504         int call_id = 0;
505         unsigned char *p = 0;
506         STATE state;
507         int call_gen_resp_err =-1;
508
509         log_msg(MSGL_VGSM_INFO, "\n");
510
511         get_current_state_machine( &state );
512
513         if( state.state_type == STATE_STANDBY )
514         {
515                 // general error send
516                 call_gen_resp_err = check_call_error();
517                 //oem_tx_call_gen_resp(call_gen_resp_err);
518                 set_general_response_error(0x8000);
519         }
520
521         // STATE_CALL_WAITING_INCOMING
522
523         gsm_call_list_t *callList = malloc(sizeof(gsm_call_list_t));
524         if(!callList)
525                 return -1;
526
527         p = (unsigned char *)packet->data; // call id
528
529         log_msg(MSGL_VGSM_INFO," release call id = %d \n", p[0]);
530
531         call_id = p[0];
532
533         get_call_list(callList);
534         for (i=0; i < MAX_CALL_COUNT; i++)
535         {
536                 if( callList->CallInfo[i].stat == GSM_CALL_STATUS_NONE )
537                         continue;
538                 if( callList->CallInfo[i].idx == call_id)
539                 {
540                         ret = server_tx_call_release_internal( call_id );
541                         break;
542                 }
543         }
544
545         _LEAVE();
546         free(callList);
547         return ret;
548 }
549
550 //int TxCall_ExecAnswer()
551 int server_tx_call_answer_exec(void)
552 {
553         STATE next;
554
555         TRACE(MSGL_VGSM_INFO, "\n");
556
557         /*
558            GSM_CallList list;
559
560            get_call_list( &list );
561            if( list.CallCount <= 0 )
562            return 0;
563
564            if( ( list.CallInfo[get_call_id()].stat == GSM_CALL_STATE_ACTIVE ) ||
565            ( list.CallInfo[get_call_id()].stat == GSM_Call_Held ) )
566            return 0;
567          */
568         int i = 0;
569         int alerted_id = -1;
570
571         gsm_call_list_t * callList = malloc(sizeof(gsm_call_list_t));
572
573         if(!callList) {
574                 return -1;
575         }
576
577         get_call_list(callList);
578
579         if(callList->CallCount < 1) {
580                 TRACE(MSGL_VGSM_ERR, "The call-count is %d!!\n", callList->CallCount);
581                 free(callList);
582                 return -1;
583         }
584
585         for (i=0; i < MAX_CALL_COUNT; i++) {
586                 if( callList->CallInfo[i].stat == GSM_CALL_STATUS_ALERT ) {
587                         alerted_id = callList->CallInfo[i].idx;
588                         break;
589                 }
590         }
591
592         if(alerted_id != get_call_id()) {
593                 TRACE(MSGL_VGSM_INFO, "Current g_call_id(%d) is not the alerted_id(%d)\n", get_call_id(), alerted_id);
594                 set_call_id(alerted_id);
595         }
596
597
598         set_current_state( STATE_CALL_WAITING_OUTGOING, GSM_CALL_CMD, GSM_CALL_ANSWER);
599
600         if( find_next_state( &next, STATE_FLAG_ALL ) ) {
601                 set_state_machine( next );
602                 send_msg();
603         }
604
605         free(callList);
606
607         _LEAVE();
608         return 1;
609 }
610
611
612 int server_tx_call_alert_ind(void *ptr_data, int data_len )
613 {
614         //    STATE next;
615
616         TRACE(MSGL_VGSM_INFO, "\n");
617
618         //send resp ( no error ) to Phone
619         //      oem_tx_call_gen_resp(0x8000);
620
621         //send noti ( outgoing  )to Phone
622         //      set_current_state( STATE_STANDBY, GSM_CALL_CMD, GSM_CALL_OUTGOING);
623
624         /*      
625                 if( find_next_state( &next, STATE_FLAG_ALL ) ) {
626         // call server_tx_call_msg()
627         set_state_machine( next );
628         send_msg();
629         }
630          */
631
632         //send noti ( alert  )to Phone
633         unsigned short call_type = get_call_type();
634         int i = 0;
635         int dialing_id = -1;
636
637         gsm_call_list_t * callList = malloc(sizeof(gsm_call_list_t));
638
639         if(!callList) {
640                 return -1;
641         }
642
643         get_call_list(callList);
644
645         if(callList->CallCount < 1) {
646                 TRACE(MSGL_VGSM_ERR, "The call-count is %d!!\n", callList->CallCount);
647                 free(callList);
648                 return -1;
649         }
650
651         for (i=0; i < MAX_CALL_COUNT; i++) {
652                 if( callList->CallInfo[i].stat == GSM_CALL_STATUS_DIALING ) {
653                         dialing_id = callList->CallInfo[i].idx;
654                         break;
655                 }
656         }
657
658         if(dialing_id != get_call_id()) {
659                 TRACE(MSGL_VGSM_INFO, "Current g_call_id(%d) is not the dialing_id(%d)\n", get_call_id(), dialing_id);
660                 set_call_id(dialing_id);
661         }
662
663         char sndbuf[SEND_BUF_SIZE];
664         memset(sndbuf, '\0', sizeof(sndbuf));
665         sprintf(sndbuf, "%d,%d,%d,%d,%d", get_call_id() + 1, AT_CALL_DIR_MO, AT_CALL_STAT_ALERTING, AT_CALL_CLASS_VOICE, AT_CALL_MPTY_FALSE);
666
667         set_current_call_status_error( 0x00 );
668
669         set_call_list_status( get_call_id(), 0, GSM_CALL_STATUS_ALERT );
670
671         callback_callist();             // renewal call_list in the EI
672
673         free(callList);
674         return oem_tx_call_status_noti(sndbuf, strlen(sndbuf));
675 }
676
677
678 //int release_call( int call_id )
679 int server_tx_call_release_internal(int call_id)
680 {
681         char data[1];
682         LXT_MESSAGE packet;
683         STATE next;
684         gsm_call_list_t * list = malloc(sizeof(gsm_call_list_t));
685         if(!list)
686                 return -1;
687
688         TRACE(MSGL_VGSM_INFO, "\n");
689
690         set_call_id( call_id ); // ³ªÁß¿¡  server_tx_call_status() º¸³»´Â °æ¿ì¿¡, g_call_id¸¦ °¡Á®¿À¹Ç·Î ¿©±â¼­ set ÇؾßÇÑ´Ù.
691
692         TAPIMessageInit(&packet);
693
694         data[0] = 0x03; //0x01 : Outgoing Call, 0x02 : Answer Call, 0x03 : Release Call
695
696         packet.data = data;
697         packet.length = 1;
698         packet.group  = GSM_CALL;
699         packet.action = GSM_CALL_STATE;
700
701         FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
702
703         set_current_state( STATE_CALL_RELEASED, GSM_CALL_CMD, GSM_CALL_RELEASE);
704
705         set_ss_state(SS_NONE);
706
707         log_msg(MSGL_VGSM_INFO,"deleted call id : %d \n", call_id);
708         delete_call_list( call_id );
709
710         if( find_next_state( &next, STATE_FLAG_ALL ) ) {
711                 set_state_machine( next );
712                 send_msg();
713         }
714
715         get_call_list(list);
716         if(list){
717                 packet.data = list;
718                 packet.length = sizeof(gsm_call_list_t);
719         }/* Execution cannot reach this statement
720         else{
721                 packet.data = NULL;
722                 packet.length = 0;
723         }*/
724
725         packet.group  = GSM_CALL;
726         packet.action = GSM_CALL_STATUS_NOTI;
727
728         FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
729
730         free(list);
731
732         return 1;
733 }
734
735 int server_tx_call_all_release(void)
736 {
737         int i = 0;
738         gsm_call_list_t * list = malloc(sizeof(gsm_call_list_t));
739         get_call_list(list);
740
741         TRACE(MSGL_VGSM_INFO, "\n");
742
743         for( i=0; i<MAX_CALL_COUNT; ++i ) {
744                 if( list->CallInfo[i].stat != GSM_CALL_STATUS_NONE )
745                         server_tx_call_release_internal( list->CallInfo[i].idx );
746         }
747
748         free(list);
749
750         return 1;
751 }
752
753
754 void server_tx_call_burst_dtmf_noti(int success)
755 {
756         int n = 0;
757         unsigned char data[1];
758
759         data[n++] = success;
760
761         oem_tx_call_burst_dtmf_noti(data, n);
762 }
763
764 int server_tx_call_line_id_resp(void)
765 {
766         int n = 0;
767         unsigned char data[1];
768
769         data[n++] = get_call_line_id();
770
771         oem_tx_call_line_id_resp(data, n);
772         return 1;
773 }
774
775
776 void callback_callist(void)
777 {
778         _ENTER();
779
780         LXT_MESSAGE packet;
781         gsm_call_list_t * callList = malloc(sizeof(gsm_call_list_t));
782
783         get_call_list(callList);
784
785         /* send to EI */
786         packet.data = (gsm_call_list_t*)callList;
787         packet.length = sizeof(gsm_call_list_t);
788         packet.group  = GSM_CALL;
789         packet.action = GSM_CALL_CALL_LIST_IND;         // 0x29 in vgsm_phone.h
790
791         FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
792         free(callList);
793         _LEAVE();
794 }