4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
7 * Sooyoung Ha <yoosah.ha@samsung.com>
8 * Sungmin Ha <sungmin82.ha@samsung.com>
9 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
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)
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.
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
34 #include "oem_tx_ss.h"
35 #include "server_common_ss.h"
38 #include "vgsm_phone.h"
39 #include "state.h" // gen_resp()
40 #include "phoneserver.h"
41 #include "server_rx_ss.h"
42 #include "server_rx_call.h"
43 #include "vgsm_debug.h"
47 #include "at_gen_resp.h"
49 #define SS_ERR_NEGATIVE_PW_CHECK 0x8126
50 #define SS_PW_ATTEMPS_VIOLATION 0x812b
53 int server_rx_ss_cw_get(int tel_class)
57 call_waiting_entry_t * cw_entry;
62 log_msg(MSGL_VGSM_INFO,"tel_class = %d \n", tel_class);
63 cw_entry = find_call_waiting_entry(tel_class);
64 if(cw_entry->ss_mode == SS_MODE_ACT)
65 ss_status = AT_SS_STATUS_ACTIVE;
67 ss_status = AT_SS_STATUS_NOT_ACTIVE;
69 data = malloc(sizeof(char) * data_len);
71 sprintf(&data[strlen(data)], "%d", ss_status);
73 sprintf(&data[strlen(data)], "%d", AT_CALL_CLASS_VOICE);
76 log_msg(MSGL_VGSM_INFO,"found & resp: tel_class = %d, ss_mode = %d, ss_status = %d \n"
77 , cw_entry->tel_class, cw_entry->ss_mode, ss_status);
79 ret = oem_tx_ss_cw_resp(data, strlen(data));
85 int server_rx_ss_cb_get(int tel_class, int cb_type)
89 call_barring_entry_t * cb_entry;
91 log_msg(MSGL_VGSM_INFO,"tel_class = %d, cb_type = %d \n", tel_class, cb_type);
93 cb_entry = find_call_barring_entry(tel_class, cb_type);
95 return at_gen_resp_send(AT_GEN_ERR_NO_ERROR);
98 int server_rx_ss_cf_get(int tel_class, int cf_type)
102 call_forwarding_entry_t * cf_entry;
104 char sndbuf[SEND_BUF_SIZE];
105 memset(sndbuf, '\0', sizeof(sndbuf));
107 log_msg(MSGL_VGSM_INFO,"tel_class = %d, cf_type = %d \n", tel_class, cf_type);
108 cf_entry = find_call_forwarding_entry(tel_class, cf_type);
110 log_msg(MSGL_VGSM_INFO," entry->count = %d \n", cf_entry->count);
112 if(cf_entry->ss_mode == SS_MODE_REG || cf_entry->ss_mode == SS_MODE_ACT)
113 ss_status = AT_SS_STATUS_ACTIVE;
115 ss_status = AT_SS_STATUS_NOT_ACTIVE;
117 sprintf(sndbuf, "%s%d,%d", CCFC, ss_status, cf_entry->tel_class);
118 if(ss_status == AT_SS_STATUS_ACTIVE)
120 log_msg(MSGL_VGSM_INFO, "cf number:%s\n", cf_entry->number);
121 sprintf(&sndbuf[strlen(sndbuf)], ",%s", cf_entry->number);
123 strcat(sndbuf, CRLF);
125 ret = oem_tx_ss_cf_resp(sndbuf, strlen(sndbuf));
130 int server_rx_ss_cli(char *api)
132 at_unimplemented(api);
136 int server_rx_ss_cw_set(int tel_class, int ss_mode)
143 TAPIMessageInit(&packet);
145 log_msg(MSGL_VGSM_INFO,"tel_class = %d, ss_mode = %d \n", tel_class, ss_mode);
148 call_waiting_entry_t * entry = malloc(sizeof(call_waiting_entry_t));
150 log_msg(MSGL_VGSM_ERR,"malloc fail \n");
153 memset(entry, 0, sizeof(call_waiting_entry_t));
154 entry->tel_class = tel_class;
155 entry->ss_mode = ss_mode;
156 strcpy(entry->number, SUBSCRIBER_NUM);
157 log_msg(MSGL_VGSM_INFO, "%s", entry->number);
158 if( ( db_err = vgsm_ss_database_add(SS_CMD_CW, entry) ) > 0){
159 log_msg(MSGL_WARN,"vgsm_ss_database_add() is failed!!db_err = %d \n", db_err);
167 call_waiting_entry_t * resp_entry = get_call_waiting_entry();
170 log_msg(MSGL_WARN,"entry is NULL!!!\n");
174 for(i=0; i<resp_entry[0].count; i++){
175 log_msg(MSGL_VGSM_INFO,"i : %d, tel_class : %d, ss_mode : %d\n"
176 , i, resp_entry[i].tel_class, resp_entry[i].ss_mode);
180 resp_entry[0].tel_class = 255;// temporary
181 packet.data = resp_entry;
182 packet.group = GSM_SUPS;
183 packet.action = GSM_SUPS_SET_CW_REQ;
184 packet.length = (sizeof(call_waiting_entry_t) * resp_entry[0].count);
186 FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
187 resp_entry[0].tel_class = 1;
192 //int server_rx_ss_cf_set(int ss_mode, int type, int tel_class, int replyTime, int num_len, char *number, int num_type, int satype, char* subaddr)
193 int server_rx_ss_cf_set(int ss_mode, int type, int tel_class, int replyTime, int num_len, char *number, int num_type)
199 TAPIMessageInit(&packet);
201 call_forwarding_entry_t * entry = malloc(sizeof(call_forwarding_entry_t));
204 memset(entry, 0, sizeof(call_forwarding_entry_t));
206 entry->ss_mode = ss_mode;
208 entry->tel_class = tel_class;
209 entry->replyTime = replyTime;
210 // entry->number_type = num_type;
211 // entry->satype = satype;
212 // memcpy(entry->subaddr, subaddr, MAX_GSM_DIALED_DIGITS_NUMBER);
216 strcpy(entry->number, number);
217 log_msg(MSGL_VGSM_INFO,"============ %s(%d) \n", entry->number, num_len);
222 log_msg(MSGL_VGSM_INFO,"=check=========== (%x)(%x) \n", entry->type, entry->ss_mode);
223 if(entry->ss_mode == SS_MODE_DEACT || entry->ss_mode == SS_MODE_DEREG)
226 //if(entry->type == SS_CF_TYPE_CF_ALL && entry->ss_mode == SS_MODE_DEACT) //disable all call forwarding
227 if(entry->type == SS_CF_TYPE_CF_ALL) //disable all call forwarding
229 // 090327 SS_CF_TYPE_CFU ---> SS_CF_TYPE_CF_ALL
230 if(vgsm_ss_database_remove(SS_CMD_CF, entry->tel_class, SS_CF_TYPE_CF_ALL) > 0)
231 log_msg(MSGL_WARN,"vgsm_ss_database_remove() SS_CF_TYPE_CFU is failed!!\n");
235 //else if(entry->type == SS_CF_TYPE_CFC && entry->ss_mode == SS_MODE_DEACT) //disable all conditional call forwarding
236 else if(entry->type == SS_CF_TYPE_CFC) //disable all conditional call forwarding
238 if(vgsm_ss_database_remove(SS_CMD_CF, entry->tel_class, SS_CF_TYPE_CFB) > 0)
239 log_msg(MSGL_WARN,"vgsm_ss_database_remove() SS_CF_TYPE_CFB is failed!!\n");
241 if(vgsm_ss_database_remove(SS_CMD_CF, entry->tel_class, SS_CF_TYPE_CFNRy) > 0)
242 log_msg(MSGL_WARN,"vgsm_ss_database_remove() SS_CF_TYPE_CFNRy is failed!!\n");
244 if(vgsm_ss_database_remove(SS_CMD_CF, entry->tel_class, SS_CF_TYPE_CFNRc) > 0)
245 log_msg(MSGL_WARN,"vgsm_ss_database_remove() SS_CF_TYPE_CFNRc is failed!!\n" );
250 if(entry->type == SS_CF_TYPE_CFU)
252 if(vgsm_ss_database_remove(SS_CMD_CF, entry->tel_class, SS_CF_TYPE_CFU) > 0)
253 log_msg(MSGL_WARN, "vgsm_ss_database_remove() SS_CF_TYPE_CFU is failed!!\n");
255 else if(entry->type == SS_CF_TYPE_CFB)
257 if(vgsm_ss_database_remove(SS_CMD_CF, entry->tel_class, SS_CF_TYPE_CFB) > 0)
258 log_msg(MSGL_WARN, "vgsm_ss_database_remove() SS_CF_TYPE_CFB is failed!!\n");
260 else if(entry->type == SS_CF_TYPE_CFNRy)
262 if(vgsm_ss_database_remove(SS_CMD_CF, entry->tel_class, SS_CF_TYPE_CFNRy) > 0)
263 log_msg(MSGL_WARN, "vgsm_ss_database_remove() SS_CF_TYPE_CFNRy is failed!!\n" );
265 else if(entry->type == SS_CF_TYPE_CFNRc)
267 if(vgsm_ss_database_remove(SS_CMD_CF, entry->tel_class, SS_CF_TYPE_CFNRc) > 0)
268 log_msg(MSGL_WARN,"vgsm_ss_database_remove() SS_CF_TYPE_CFNRc is failed!!\n");
274 //call forwarding table update
275 if(vgsm_ss_database_add(SS_CMD_CF, entry) > 0)
276 log_msg(MSGL_VGSM_INFO,"vgsm_ss_database_add() is failed!!\n" );
282 // send data to eventinjector -> ui update
283 call_forwarding_entry_t * resp_entry = get_call_forwarding_entry();
287 log_msg(MSGL_WARN,"entry is NULL!!! \n" );
290 for(i=0; i<resp_entry[0].count; i++)
292 log_msg(MSGL_WARN,"i: %d, tel_class : 0x%x, type : %d, number : %s, ss_mode : %d\n",
293 i, resp_entry[i].tel_class, resp_entry[i].type, resp_entry[i].number, resp_entry[i].ss_mode);
297 packet.data = resp_entry;
298 packet.group = GSM_SUPS;
299 packet.action = GSM_SUPS_SET_CCFC_REQ;
300 packet.length = (sizeof(call_forwarding_entry_t) * resp_entry[0].count);
302 FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
307 int server_rx_ss_cb_set(int cb_type, int ss_mode, int tel_class, char *passwd)
313 TAPIMessageInit(&packet);
314 int cb_pwd_fail_count = 0;
316 call_barring_entry_t * entry = malloc(sizeof(call_barring_entry_t));
319 memset(entry, 0, sizeof(call_barring_entry_t));
321 entry->type =cb_type;
322 entry->ss_mode = ss_mode;
323 entry->tel_class = tel_class;
324 char* tmp_cb_pwd = get_callbarring_pwd();
325 VGSM_DEBUG("orig_pwd:%s, input_pwd:%s\n", tmp_cb_pwd, passwd);
327 if( strcmp(passwd, tmp_cb_pwd) != 0)
329 VGSM_DEBUG("Wrong CallBarring Passwd\n");
330 cb_pwd_fail_count = increase_callbarring_pwd_fail_count();
331 VGSM_DEBUG("cb_pwd_fail_count = %d\n",cb_pwd_fail_count);
333 if(cb_pwd_fail_count >= 3)
334 gen_resp_err = SS_PW_ATTEMPS_VIOLATION; // numberOfPW_AttemptsViolation
336 gen_resp_err = SS_ERR_NEGATIVE_PW_CHECK; // NegativePasswordCheck
338 oem_tx_ss_gen_resp(AT_CME_ERR_INCORRECT_PWD);
343 VGSM_DEBUG("Right CallBarring Passwd\n");
345 clear_callbarring_pwd_fail_count();
348 set_ss_current_general_response_error( get_ss_general_response_error() );
349 gen_resp_err = get_ss_current_general_response_error();
350 oem_tx_ss_gen_resp(AT_GEN_ERR_NO_ERROR);
352 if(gen_resp_err != 0x8000)
354 log_msg(MSGL_WARN, "gen_resp_err : %d \n", gen_resp_err);
359 if(entry->tel_class == AT_CALL_SS_CLASS_VIDEO)
361 if(entry->type == SS_CB_TYPE_AB)
363 set_outgoing_video_call_barring_state(entry->ss_mode);
364 set_incoming_video_call_barring_state(entry->ss_mode);
366 else if(entry->type == SS_CB_TYPE_BAOC)
368 set_outgoing_video_call_barring_state(entry->ss_mode);
370 else if(entry->type == SS_CB_TYPE_BAIC)
372 set_incoming_video_call_barring_state(entry->ss_mode);
377 if(entry->type == SS_CB_TYPE_AB)
379 set_outgoing_voice_call_barring_state(entry->ss_mode);
380 set_incoming_voice_call_barring_state(entry->ss_mode);
382 else if(entry->type == SS_CB_TYPE_BAOC)
384 set_outgoing_voice_call_barring_state(entry->ss_mode);
386 else if(entry->type == SS_CB_TYPE_BAIC)
388 set_incoming_voice_call_barring_state(entry->ss_mode);
392 if( (entry->type == SS_CB_TYPE_AB ) && (entry->ss_mode == SS_MODE_DEREG || entry->ss_mode == SS_MODE_DEACT)) // cancel all.
394 entry->type = SS_CB_TYPE_BAOC;
395 if(vgsm_ss_database_add(SS_CMD_CB, entry) > 0)
396 log_msg(MSGL_WARN, "vgsm_ss_database_add() is failed!!\n" );
398 entry->type = SS_CB_TYPE_BOIC;
399 if(vgsm_ss_database_add(SS_CMD_CB, entry) > 0)
400 log_msg(MSGL_WARN, "vgsm_ss_database_add() is failed!!\n" );
402 entry->type = SS_CB_TYPE_BOIC_NOT_HC;
403 if(vgsm_ss_database_add(SS_CMD_CB, entry) > 0)
404 log_msg(MSGL_WARN, "vgsm_ss_database_add() is failed!!\n" );
406 entry->type = SS_CB_TYPE_BAIC;
407 if(vgsm_ss_database_add(SS_CMD_CB, entry) > 0)
408 log_msg(MSGL_WARN, "vgsm_ss_database_add() is failed!!\n" );
410 entry->type = SS_CB_TYPE_BIC_ROAM;
411 if(vgsm_ss_database_add(SS_CMD_CB, entry) > 0)
412 log_msg(MSGL_WARN, "vgsm_ss_database_add() is failed!!\n" );
414 entry->type = SS_CB_TYPE_AB; //rollback.
418 if(vgsm_ss_database_add(SS_CMD_CB, entry) > 0)
419 log_msg(MSGL_WARN, "vgsm_ss_database_add() is failed!!\n" );
425 call_barring_entry_t * resp_entry = get_call_barring_entry();
429 log_msg(MSGL_WARN, "entry is NULL!!! \n" );
432 for(i=0; i<resp_entry[0].count; i++)
434 log_msg(MSGL_VGSM_INFO,"i : %d, tel_class : %d, ss_mode : %d\n",
435 i, resp_entry[i].tel_class, resp_entry[i].ss_mode);
439 packet.data = resp_entry;
440 packet.group = GSM_SUPS;
441 packet.action = GSM_SUPS_SET_CB_REQ;
442 packet.length = (sizeof(call_barring_entry_t) * resp_entry[0].count);
444 FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
450 int server_rx_ss_cb_passwd_set(char* curr_passwd, char* new_passwd)
453 if(!curr_passwd || !new_passwd)
458 TAPIMessageInit(&packet);
459 int cb_pwd_fail_count = 0;
461 char* tmp_cb_pwd = get_callbarring_pwd();
463 if( memcmp(tmp_cb_pwd, curr_passwd, 4 ) != 0)
465 VGSM_DEBUG("Wrong CallBarring Passwd\n");
466 cb_pwd_fail_count = increase_callbarring_pwd_fail_count();
467 VGSM_DEBUG("cb_pwd_fail_count = %d\n",cb_pwd_fail_count);
469 if(cb_pwd_fail_count >= 3)
470 gen_resp_err = SS_PW_ATTEMPS_VIOLATION; // numberOfPW_AttemptsViolation
472 gen_resp_err = SS_ERR_NEGATIVE_PW_CHECK; // NegativePasswordCheck
474 oem_tx_ss_gen_resp(gen_resp_err);
478 VGSM_DEBUG("Right CallBarring Passwd\n");
480 clear_callbarring_pwd_fail_count();
483 set_ss_current_general_response_error( get_ss_general_response_error() );
484 gen_resp_err = get_ss_current_general_response_error();
485 oem_tx_ss_gen_resp(gen_resp_err);
486 if(gen_resp_err != 0x8000)
488 log_msg(MSGL_WARN,"gen_resp_err : %d \n", gen_resp_err);
492 set_callbarring_pwd(new_passwd);
494 VGSM_DEBUG("CallBarring Passwd changed\n");
496 packet.data = new_passwd;
497 packet.group = GSM_SUPS;
498 packet.action = GSM_SUPS_PWDSET_CB_REQ;
499 packet.length = strlen(new_passwd);
501 VGSM_DEBUG("CallBarring Passwd changed\n");
503 FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
504 /* EI receives this event then,
505 * popup(callbarring password changed!!) --> callbarring password : new_passwd
511 int server_rx_ss_aoc_get(void) // 090215 vgsm -> EI
514 unsigned char * data = 0;
524 data_len = sizeof(tmp);
530 data = malloc(sizeof(unsigned char) * data_len);
531 memset(data, 0, data_len);
532 memcpy(data, &tmp, data_len);
534 VGSM_DEBUG("Send AOC DATA to EI\n");
536 packet.group = GSM_SUPS;
537 packet.action = GSM_SUPS_AOC_GET;
538 packet.length = data_len;
540 VGSM_DEBUG("Send AOC DATA to EI\n");
541 FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
547 int server_rx_ss_ussd_get(void) // 090215 vgsm -> EI
550 unsigned char * data = 0;
554 strcpy(tmp.time, "12:00:00, 2000");
555 strcpy(tmp.weather, "Fine");
557 data_len = sizeof(tmp);
561 get_ussd_data( &tmp);
563 data = malloc(sizeof(unsigned char) * data_len);
564 memset(data, 0, data_len);
565 memcpy(data, &tmp, data_len);
567 VGSM_DEBUG("Send USSD DATA to EI\n");
568 VGSM_DEBUG("time : %s\n", tmp.time);
569 VGSM_DEBUG("weather : %s\n", tmp.weather);
571 packet.group = GSM_SUPS;
572 packet.action = GSM_SUPS_USSD_GET;
573 packet.length = data_len;
575 VGSM_DEBUG("Send ussd DATA to EI\n");
576 FuncServer->Cast(&GlobalPS, LXT_ID_CLIENT_EVENT_INJECTOR, &packet);
584 int server_rx_ss_manage_call_set(char* ptr_data, int data_len)
588 char* data = strchr(ptr_data, '=');
593 ret = strtok(data+1, token);
597 if(signal == AT_GSM_SS_CM_0_SEND) // release all held call
599 rtn = server_rx_call_release_incoming();
601 rtn = server_rx_call_release_all_held();
603 else if(signal == AT_GSM_SS_CM_1_SEND) // release all active call and the other (held or waiting) call
605 rtn = server_rx_call_release_all_active();
607 else if(signal == AT_GSM_SS_CM_2_SEND) // active call on hold and held or waiting call on active
609 VGSM_DEBUG("g_ss_hold_response_error: err =%x \n", g_ss_hold_response_error);
610 //at_gen_resp_send( g_ss_hold_response_error);
611 if ( g_ss_hold_response_error == 0x8000 )
612 rtn = server_rx_call_swap();
614 VGSM_DEBUG("g_ss_hold_response_error: err =%x \n", g_ss_hold_response_error);
616 else if(signal == AT_GSM_SS_CM_3_SEND) // add a held call to the conversation
618 VGSM_DEBUG("g_ss_join_response_error: err =%x \n", g_ss_join_response_error);
619 //at_gen_resp_send( g_ss_join_response_error);
620 if ( g_ss_join_response_error == 0x8000 )
621 rtn = server_rx_call_join_conf(); // TODO: call id is needed?? check....
623 VGSM_DEBUG("g_ss_join_response_error: err =%x \n", g_ss_join_response_error);
625 else if(signal >= 10 && signal < 20 ) // AT_GSM_SS_CM_1X_SEND : connect the two call and disconnect the subscriber from both calls
627 call_id = signal - 11;
628 rtn = server_rx_call_release_single(call_id);
630 else if(signal >= 20 && signal < 30 ) // AT_GSM_SS_CM_2X_SEND : Places all active calls on hold except call X with which communication shall be supported.
632 call_id = signal - 21;
633 VGSM_DEBUG("server_rx_call_split_conf : err =%x \n", g_ss_split_response_error);
634 //at_gen_resp_send( g_ss_split_response_error);
635 if ( g_ss_split_response_error == 0x8000 )
636 rtn = server_rx_call_split_conf(call_id);
638 VGSM_DEBUG("server_rx_call_split_conf : err =%x \n", g_ss_split_response_error);
642 VGSM_DEBUG (" not supported ID = %d \n" , signal);