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"
40 #include "telit862-gps.h"
43 static void vendor_unsolicite_handler_init (ModemInterface
* modem
,
44 VendorInterface
*vendor
);
45 static AtCommandHandlerStatus
vendor_unsolicite_handler (ModemInterface
* modem
,
49 static gboolean
vendor_at_init_sim_ready (VendorInterface
* vendor
);
50 static gint
vendor_serial_init (VendorInterface
*vendor
, const gchar
*device
);
51 static void gsm_ecam_parse (GScanner
* scanner
,
56 static void vendor_sim_auth_status (SIMIPCInterface
*sim_ipc
, const char *status
);
58 static AtCommandHandlerStatus
telit_call_initiate_handler(ModemInterface
*modem
,
61 static const AtCommand
64 { ENABLE_ECAM
, "AT#ECAM=1\r\n", 100, TRUE
, 1,
66 }, *command_p
= commands
;
68 static const SymbolTable
70 { "ECAM", SYMBOL_ECAM
, },//vendor command
72 }, *symbol_p
= symbols
;
74 typedef struct _Vendor
{
75 ModemInterface
*modem
;
77 void (*orig_sim_auth_status
) (SIMIPCInterface
*sim_ipc
, const char *status
);
78 AtCommandHandlerStatus (*orig_call_initiate_handler
) (ModemInterface
*modem
,
83 static Vendor
*vendor_priv
= NULL
;
85 /** vendor_handle_init should be called from modem.c when the lib loaded*/
86 gboolean
vendor_handle_init (ModemInterface
* modem
, VendorInterface
*vendor
)
89 g_warning("%s : Already initialized!", __func__
);
92 vendor_priv
= g_new0(Vendor
, 1);
93 g_debug("%s", __func__
);
94 vendor
->init_at
= NULL
;
95 vendor
->init_at_sim_ready
= vendor_at_init_sim_ready
;
96 vendor
->init_serial
= vendor_serial_init
;
97 vendor
->priv
= (gpointer
)vendor_priv
;
98 vendor_unsolicite_handler_init (modem
, vendor
);
99 vendor_priv
->modem
= modem
;
101 vendor_priv
->orig_sim_auth_status
= modem
->sim_ipc
->auth_status
;
102 modem
->sim_ipc
->auth_status
= &vendor_sim_auth_status
;
104 AtCommand
*call_initiate
= gsmd_modem_get_command(modem
, INITIATE_CALL
);
105 vendor_priv
->orig_call_initiate_handler
= call_initiate
->handler
;
106 call_initiate
->handler
= &telit_call_initiate_handler
;
109 /*************************************/
110 /* if need replace default at_command, vendor at_init bellow*/
114 static gboolean
vendor_at_init_sim_ready (VendorInterface
* vendor
)
116 ModemInterface
*modem
= vendor_priv
->modem
;
118 g_debug("%s", __func__
);
120 gsmd_modem_general_at_init_sim_ready (modem
);
122 gsmd_modem_post_at_command_id(modem
,
130 static gint
vendor_serial_init (VendorInterface
*vendor
, const gchar
*device
)
132 g_debug("%s", __func__
);
134 gint fd
= g_open (device
, O_RDWR
, 0);
136 g_warning("%s : open failed: '%s'", __func__
, device
);
139 if (tcgetattr(fd
, &t
) < 0) {
140 g_warning("%s : get attr failed '%s'", __func__
, device
);
144 cfsetispeed(&t
, B115200
);
145 cfsetospeed(&t
, B115200
);
148 t
.c_cflag
= CS8
| CLOCAL
| CREAD
| B115200
;
149 t
.c_iflag
= 0; // ICRNL;
156 if (tcsetattr (fd
, TCSANOW
, &t
) < 0) {
157 g_warning("%s : setattr failed", __func__
);
166 /********************************/
168 static void vendor_sim_auth_status (SIMIPCInterface
*sim_ipc
, const char *status
)
170 g_debug("%s : Status changed to %s", __func__
, status
);
171 vendor_priv
->orig_sim_auth_status( sim_ipc
, status
);
174 static void vendor_unsolicite_handler_init(ModemInterface
*modem
,
175 VendorInterface
*vendor
)
177 g_debug("%s", __func__
);
178 //add the symbol to the modem scanner
179 while (symbol_p
->symbol_name
) {
180 g_scanner_add_symbol (modem
->scanner
, symbol_p
->symbol_name
,
181 GINT_TO_POINTER(symbol_p
->symbol_token
));
185 //add the command to the modem command table
186 while (command_p
->command
) {
187 gsmd_modem_register_command(modem
, command_p
);
190 vendor
->unsolicite_handler
= vendor_unsolicite_handler
;
194 static void gsm_ecam_parse (GScanner
* scanner
,
199 //: call_id, call_state, call_type
200 g_scanner_get_next_token (scanner
);
201 if (scanner
->token
== ':') {
202 g_scanner_get_next_token (scanner
);
203 *call_id
= scanner
->value
.v_int
;
205 g_scanner_get_next_token (scanner
);//get ;
206 g_scanner_get_next_token (scanner
);
207 *state
= scanner
->value
.v_int
;
209 g_scanner_get_next_token (scanner
);//get ;
210 g_scanner_get_next_token (scanner
);
211 *call_type
= scanner
->value
.v_int
;
213 g_warning ("unexpexted symbol in ecam_parse\n");
217 void vendor_handle_voice_ecam(ModemInterface
*modem
,
222 g_debug("%s : call vendor id: %d, state: %d", __func__
, vendor_id
,state
);
223 GHashTable
*properties
= gsmd_at_command_create_handler_data();
226 gsmd_utils_cache_insert_int(properties
,GSMD_VENDOR_KEY_ECAM
,state
);
231 //Phone call established
233 g_debug("%s: ECAM_ACTIVE",__func__
);
234 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
238 if (modem
->call_ipc
->call_status
) {
239 //TODO add properties
240 modem
->call_ipc
->call_status(modem
->call_ipc
,
246 call
->status
= CONNECTED
;
251 g_debug("%s: ECAM_IDLE",__func__
);
252 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
254 gsmd_utils_remove_call_vendor_id(modem
,vendor_id
,TRUE
);
256 //Someone's calling us
258 g_debug("%s: ECAM_ALERTING",__func__
);
259 //CLIP didn't have information on call id
260 //So we'll find first call with id -1
262 gsmd_utils_set_unknown_vendor_id(modem
, vendor_id
);
263 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
264 if (modem
->call_ipc
->call_status
) {
265 modem
->call_ipc
->call_status(modem
->call_ipc
,
275 g_debug("%s: ECAM_BUSY",__func__
);
276 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
280 if ( call
->status
== IDLE
) {
281 gsmd_utils_remove_call_vendor_id(modem
,vendor_id
,TRUE
);
285 //We are calling someone
287 g_debug("%s: ECAM_CALLING",__func__
);
288 gsmd_utils_set_unknown_vendor_id(modem
,vendor_id
);
289 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
290 if (modem
->call_ipc
->call_status
) {
291 gsmd_utils_cache_insert_string(properties
,
292 GSMD_MODEM_KEY_PHONE_NUMBER
,
295 modem
->call_ipc
->call_status(modem
->call_ipc
,
302 //We are waiting on hold
304 g_debug("%s: ECAM_WAITING",__func__
);
305 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
307 if (modem
->call_ipc
->call_status
) {
308 //TODO add waiting to properties
310 call
->status
= WAITING
;
312 case ECAM_CONNECTING
:
313 g_debug("%s: ECAM_CONNECTING",__func__
);
314 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
316 call
->status
= CALLING
;
317 if (modem
->call_ipc
->call_status
) {
318 //TODO add connecting to properties
319 modem
->call_ipc
->call_status(modem
->call_ipc
,
328 g_debug("%s: ECAM_HOLD",__func__
);
329 call
= gsmd_utils_find_call_vendor_id(modem
,vendor_id
);
331 if (modem
->call_ipc
->call_status
) {
332 //TODO add properties
333 modem
->call_ipc
->call_status(modem
->call_ipc
,
342 g_hash_table_destroy(properties
);
346 AtCommandHandlerStatus
telit_call_initiate_handler(ModemInterface
*modem
,
347 AtCommandContext
*at
,
351 GScanner
* scanner
= modem
->scanner
;
352 EcamState state
= ECAM_IDLE
;
353 CallType call_type
= CALLTYPE_VOICE
;
354 g_debug("%s", __func__
);
355 switch (scanner
->token
) {
357 g_scanner_get_next_token(scanner
);
359 switch (scanner
->token
) {
360 case SYMBOL_ECAM
://line status
361 gsm_ecam_parse(scanner
,&vendor_id
,&state
,&call_type
);
362 g_debug("%s : call vendor id: %d", __func__
, vendor_id
);
364 if (call_type
== CALLTYPE_VOICE
) {
365 vendor_handle_voice_ecam(modem
,state
,vendor_id
);
367 return AT_HANDLER_NEED_MORE
;
369 g_scanner_input_text (scanner
, response
->str
, response
->len
);
370 g_scanner_get_next_token (scanner
);
371 g_scanner_peek_next_token (scanner
);
378 return vendor_priv
->orig_call_initiate_handler(modem
,at
,response
);
380 AtCommandHandlerStatus
vendor_unsolicite_handler (ModemInterface
*modem
,
381 AtCommandContext
*at
,
384 // only reponse for parse the vendor token such as #ECAM
386 GScanner
* scanner
= modem
->scanner
;
387 EcamState state
= ECAM_IDLE
;
388 CallType call_type
= CALLTYPE_VOICE
;
389 g_debug("%s",__func__
);
391 switch (scanner
->token
) {
393 //Override busy and no carrier and don't do anything
394 //instead wait for the same information to come from ecam along with
396 /* case SYMBOL_BUSY: */
397 /* return AT_HANDLER_DONE; */
398 /* case SYMBOL_NO: */
399 /* g_scanner_get_next_token(scanner); */
400 /* if (scanner->token == SYMBOL_CARRIER) */
401 /* return AT_HANDLER_DONE; */
404 g_scanner_get_next_token(scanner
);
406 switch (scanner
->token
) {
407 case SYMBOL_ECAM
://line status
408 //#ECAM: 0,3,,,: call start
409 gsm_ecam_parse(scanner
,&vendor_id
,&state
,&call_type
);
410 g_debug("%s : call vendor id: %d", __func__
, vendor_id
);
411 if (call_type
== CALLTYPE_VOICE
) {
412 vendor_handle_voice_ecam(modem
,state
,vendor_id
);
414 g_message ("data call\n");
416 return AT_HANDLER_DONE
;
423 return AT_HANDLER_DONT_UNDERSTAND
;