4 * Copyright(C) 2007,2008 Ixonos Plc
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Boston, MA 02111.
35 #include <glib/gstdio.h>
37 #include "../src/modem.h"
38 #include "../src/utils.h"
39 #include "../src/call_interface.h"
41 #define GSMD_VENDOR_KEY_ECAM "ecam"
47 CALLTYPE_VOICE
= 1, /**< Voice Call*/
48 CALLTYPE_DATA
/**< Data Call*/
64 ENABLE_ECAM
= VENDOR_COMMAND
67 SYMBOL_ECAM
= VENDOR_SYMBOL
71 static void vendor_unsolicite_handler_init (ModemInterface
* modem
,
72 VendorInterface
*vendor
);
73 static AtCommandHandlerStatus
vendor_unsolicite_handler (ModemInterface
* modem
,
77 static gboolean
vendor_at_init_sim_ready (VendorInterface
* vendor
);
78 static void gsm_ecam_parse (GScanner
* scanner
,
83 static void vendor_sim_auth_status (SIMIPCInterface
*sim_ipc
, const char *status
);
85 static AtCommandHandlerStatus
telit_call_initiate_handler(ModemInterface
*modem
,
88 static const AtCommand
91 { ENABLE_ECAM
, "AT#ECAM=1\r\n", 100, TRUE
, 1,
92 NULL
,NULL
,SIM_UNKNOWN
,NULL
}
93 }, *command_p
= commands
;
95 static const SymbolTable
97 { "ECAM", SYMBOL_ECAM
, },//vendor command
99 }, *symbol_p
= symbols
;
101 typedef struct _Vendor
{
102 ModemInterface
*modem
;
104 void (*orig_sim_auth_status
) (SIMIPCInterface
*sim_ipc
, const char *status
);
105 AtCommandHandlerStatus (*orig_call_initiate_handler
) (ModemInterface
*modem
,
106 AtCommandContext
*at
,
110 static Vendor
*vendor_priv
= NULL
;
112 /** vendor_handle_init should be called from modem.c when the lib loaded*/
113 gboolean
vendor_handle_init (VendorInterface
*vendor
, ModemInterface
* modem
)
116 g_warning("%s : Already initialized!", __func__
);
119 vendor_priv
= g_new0(Vendor
, 1);
120 g_debug("%s", __func__
);
121 vendor
->init_at
= NULL
;
122 vendor
->init_at_sim_ready
= vendor_at_init_sim_ready
;
123 vendor
->priv
= (gpointer
)vendor_priv
;
124 vendor_unsolicite_handler_init (modem
, vendor
);
125 vendor_priv
->modem
= modem
;
127 vendor_priv
->orig_sim_auth_status
= modem
->sim_ipc
->auth_status
;
128 modem
->sim_ipc
->auth_status
= &vendor_sim_auth_status
;
130 AtCommand
*call_initiate
= gsmd_modem_get_command(modem
, INITIATE_CALL
);
131 vendor_priv
->orig_call_initiate_handler
= call_initiate
->handler
;
132 call_initiate
->handler
= &telit_call_initiate_handler
;
135 /*************************************/
136 /* if need replace default at_command, vendor at_init bellow*/
140 static gboolean
vendor_at_init_sim_ready (VendorInterface
* vendor
)
142 ModemInterface
*modem
= vendor_priv
->modem
;
144 g_debug("%s", __func__
);
146 gsmd_modem_general_at_init_sim_ready (modem
);
148 gsmd_modem_post_at_command_id(modem
,
157 /********************************/
159 static void vendor_sim_auth_status (SIMIPCInterface
*sim_ipc
, const char *status
)
161 g_debug("%s : Status changed to %s", __func__
, status
);
162 vendor_priv
->orig_sim_auth_status( sim_ipc
, status
);
165 static void vendor_unsolicite_handler_init(ModemInterface
*modem
,
166 VendorInterface
*vendor
)
168 g_debug("%s", __func__
);
169 //add the symbol to the modem scanner
170 while (symbol_p
->symbol_name
) {
171 g_scanner_add_symbol (modem
->scanner
, symbol_p
->symbol_name
,
172 GINT_TO_POINTER(symbol_p
->symbol_token
));
176 //add the command to the modem command table
177 while (command_p
->command
) {
178 gsmd_modem_register_command(modem
, command_p
);
181 vendor
->unsolicite_handler
= vendor_unsolicite_handler
;
185 static void gsm_ecam_parse (GScanner
* scanner
,
190 //: call_id, call_state, call_type
191 g_scanner_get_next_token (scanner
);
192 if (scanner
->token
== ':') {
193 g_scanner_get_next_token (scanner
);
194 *call_id
= scanner
->value
.v_int
;
196 g_scanner_get_next_token (scanner
);//get ;
197 g_scanner_get_next_token (scanner
);
198 *state
= scanner
->value
.v_int
;
200 g_scanner_get_next_token (scanner
);//get ;
201 g_scanner_get_next_token (scanner
);
202 *call_type
= scanner
->value
.v_int
;
204 g_warning ("unexpexted symbol in ecam_parse\n");
208 void vendor_handle_voice_ecam(ModemInterface
*modem
,
213 g_debug("%s : call vendor id: %d, state: %d", __func__
, vendor_id
,state
);
216 //Phone call established
218 g_debug("%s: ECAM_ACTIVE",__func__
);
219 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
221 gsmd_utils_call_send_status(modem
,
225 call
->status
= CALL_CONNECTED
;
231 g_debug("%s: ECAM_CALL_IDLE",__func__
);
232 gsmd_utils_remove_call_vendor_id(modem
,vendor_id
,TRUE
);
234 //Someone's calling us
236 g_debug("%s: ECAM_ALERTING",__func__
);
237 //CLIP didn't have information on call id
238 //So we'll find first call with id -1
240 gsmd_utils_set_unknown_vendor_id(modem
, vendor_id
);
243 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
245 gsmd_utils_table_insert_int(call
->vendor_properties
,GSMD_VENDOR_KEY_ECAM
,state
);
246 gsmd_utils_call_send_status(modem
,
255 g_debug("%s: ECAM_BUSY",__func__
);
256 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
260 if ( call
->status
== CALL_IDLE
) {
261 gsmd_utils_remove_call_vendor_id(modem
,vendor_id
,TRUE
);
266 //We are calling someone
267 case ECAM_CALL_CALLING
:
268 g_debug("%s: ECAM_CALL_CALLING",__func__
);
269 gsmd_utils_set_unknown_vendor_id(modem
,vendor_id
);
270 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
272 gsmd_utils_table_insert_int(call
->vendor_properties
,GSMD_VENDOR_KEY_ECAM
,state
);
273 gsmd_utils_call_send_status(modem
,
279 //We are waiting on hold
280 case ECAM_CALL_WAITING
:
281 g_debug("%s: ECAM_CALL_WAITING",__func__
);
282 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
284 gsmd_utils_call_send_status(modem
,
287 call
->status
= CALL_WAITING
;
290 case ECAM_CONNECTING
:
291 g_debug("%s: ECAM_CONNECTING",__func__
);
292 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
294 call
->status
= CALL_CALLING
;
295 gsmd_utils_call_send_status(modem
,
302 g_debug("%s: ECAM_CALL_HOLD",__func__
);
303 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
305 gsmd_utils_call_send_status(modem
,
315 AtCommandHandlerStatus
telit_call_initiate_handler(ModemInterface
*modem
,
316 AtCommandContext
*at
,
320 GScanner
* scanner
= modem
->scanner
;
321 EcamState state
= ECAM_CALL_IDLE
;
322 CallType call_type
= CALLTYPE_VOICE
;
323 g_debug("%s", __func__
);
324 switch (scanner
->token
) {
326 g_scanner_get_next_token(scanner
);
328 switch (scanner
->token
) {
329 case SYMBOL_ECAM
://line status
330 gsm_ecam_parse(scanner
,&vendor_id
,&state
,&call_type
);
331 g_debug("%s : call vendor id: %d", __func__
, vendor_id
);
333 if (call_type
== CALLTYPE_VOICE
) {
334 vendor_handle_voice_ecam(modem
,state
,vendor_id
);
336 return AT_HANDLER_NEED_MORE
;
338 g_scanner_input_text (scanner
, response
->str
, response
->len
);
339 g_scanner_get_next_token (scanner
);
340 g_scanner_peek_next_token (scanner
);
347 return vendor_priv
->orig_call_initiate_handler(modem
,at
,response
);
351 AtCommandHandlerStatus
vendor_unsolicite_handler (ModemInterface
*modem
,
352 AtCommandContext
*at
,
355 // only reponse for parse the vendor token such as #ECAM
357 GScanner
* scanner
= modem
->scanner
;
358 EcamState state
= ECAM_CALL_IDLE
;
359 CallType call_type
= CALLTYPE_VOICE
;
360 g_debug("%s",__func__
);
362 switch (scanner
->token
) {
364 //Override busy and no carrier and don't do anything
365 //instead wait for the same information to come from ecam along with
367 /* case SYMBOL_BUSY: */
368 /* return AT_HANDLER_DONE; */
369 /* case SYMBOL_NO: */
370 /* g_scanner_get_next_token(scanner); */
371 /* if (scanner->token == SYMBOL_CARRIER) */
372 /* return AT_HANDLER_DONE; */
375 g_scanner_get_next_token(scanner
);
377 switch (scanner
->token
) {
378 case SYMBOL_ECAM
://line status
379 //#ECAM: 0,3,,,: call start
380 gsm_ecam_parse(scanner
,&vendor_id
,&state
,&call_type
);
381 g_debug("%s : call vendor id: %d", __func__
, vendor_id
);
382 if (call_type
== CALLTYPE_VOICE
) {
383 vendor_handle_voice_ecam(modem
,state
,vendor_id
);
385 g_message ("data call\n");
387 return AT_HANDLER_DONE
;
394 return AT_HANDLER_DONT_UNDERSTAND
;