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.
33 #include <glib/gstdio.h>
35 #include "../src/modem.h"
36 #include "../src/utils.h"
37 #include "../src/call_interface.h"
38 #include "../src/at_error.h"
39 #include "../src/sim.h"
42 ENABLE_WIND
= VENDOR_COMMAND
45 SYMBOL_WIND
= VENDOR_SYMBOL
49 static void wavecom_unsolicite_handler_init (ModemInterface
* modem
,
50 VendorInterface
*vendor
);
51 static AtCommandHandlerStatus
wavecom_unsolicite_handler (ModemInterface
* modem
,
55 static gboolean
vendor_at_init_sim_ready (VendorInterface
* vendor
);
57 static AtCommandHandlerStatus
wavecom_call_initiate_handler(ModemInterface
*modem
,
60 static const AtCommand
63 { ENABLE_WIND
, "AT+WIND=50\r\n", 100, TRUE
, 1,
65 }, *command_p
= commands
;
67 static const SymbolTable
69 { "WIND", SYMBOL_WIND
, },//vendor command
71 }, *symbol_p
= symbols
;
73 typedef struct _Vendor
{
74 ModemInterface
*modem
;
75 void (*orig_sim_auth_status
) (SIMIPCInterface
*sim_ipc
,
78 AtCommandHandlerStatus (*orig_call_initiate_handler
) (ModemInterface
*modem
,
83 static Vendor
*vendor_priv
= NULL
;
86 AtCommandHandlerStatus
wavecom_handler_query_pin_status (ModemInterface
*modem
,
90 /** vendor_handle_init should be called from modem.c when the lib loaded*/
91 gboolean
vendor_handle_init (VendorInterface
*vendor
, ModemInterface
* modem
)
94 g_warning("%s : Already initialized!", __func__
);
97 vendor_priv
= g_new0(Vendor
, 1);
98 g_debug("%s", __func__
);
99 vendor
->init_at
= NULL
;
100 vendor
->init_at_sim_ready
= vendor_at_init_sim_ready
;
101 vendor
->priv
= (gpointer
)vendor_priv
;
102 wavecom_unsolicite_handler_init (modem
, vendor
);
103 vendor_priv
->modem
= modem
;
105 AtCommand
*call_initiate
= gsmd_modem_get_command(modem
, INITIATE_CALL
);
106 vendor_priv
->orig_call_initiate_handler
= call_initiate
->handler
;
107 call_initiate
->handler
= &wavecom_call_initiate_handler
;
109 AtCommand
*query_pin
= gsmd_modem_get_command(modem
, PIN_QUERY
);
110 query_pin
->handler
= &wavecom_handler_query_pin_status
;
115 /*************************************/
119 * @brief Handler to modems response from queryPinStatus command
121 * @param modem modem whose response to handle
122 * @return true if responses were recognized
125 AtCommandHandlerStatus
wavecom_handler_query_pin_status (ModemInterface
*modem
,
126 AtCommandContext
*at
,
129 g_debug("%s",__func__
);
130 GScanner
* scanner
= modem
->scanner
;
134 if (gsmd_utils_send_error_from_response(at
,
136 "ERROR READING PIN STATUS",
137 "TIMEOUT READING PIN STATUS"))
138 return AT_HANDLER_DONE_ERROR
;
140 if (scanner
->token
!= '+') {
141 return AT_HANDLER_DONT_UNDERSTAND
;
144 g_scanner_get_next_token (scanner
);
145 switch (scanner
->token
) {
148 g_scanner_get_next_token (scanner
);
149 //g_scanner_get_next_token (scanner);
150 if (scanner
->token
== SYMBOL_ERROR
) {
151 g_scanner_peek_next_token(scanner
);
152 if (scanner
->next_token
== ':') {
153 g_scanner_get_next_token (scanner
);
154 g_scanner_get_next_token(scanner
);//arrive error value
155 if ( ERR_NO_SIM_CARD
== scanner
->value
.v_int
) {
156 gsmd_sim_change_auth_status(modem
,
162 gsmd_sim_change_auth_status(modem
,
169 return AT_HANDLER_DONE
;
171 g_scanner_unexp_token (scanner
, ':', NULL
, "symbol",
176 g_scanner_unexp_token (scanner
, SYMBOL_ERROR
, NULL
, "symbol",
181 g_scanner_get_next_token (scanner
);//get ':'
182 g_scanner_get_next_token (scanner
);
183 if (scanner
->token
== SYMBOL_READY
) {
184 g_debug("%s: READY",__func__
);
185 gsmd_sim_change_auth_status(modem
,
192 return AT_HANDLER_DONE
;
194 } else if (scanner
->token
== SYMBOL_SIM
) {
196 g_scanner_get_next_token (scanner
);
197 g_scanner_peek_next_token(scanner
);
198 if (scanner
->token
== SYMBOL_PIN
) {
199 gsmd_sim_change_auth_status(modem
,
204 } else if (scanner
->token
== SYMBOL_PUK
) {
205 g_debug("%s: SIM PUK",__func__
);
206 gsmd_sim_change_auth_status(modem
,
213 return AT_HANDLER_DONE
;
215 g_scanner_unexp_token (scanner
, SYMBOL_READY
, NULL
, "symbol",
220 g_warning("No match after getting + \n");
228 return AT_HANDLER_DONT_UNDERSTAND
;
232 static gboolean
vendor_at_init_sim_ready (VendorInterface
* vendor
)
234 ModemInterface
*modem
= vendor_priv
->modem
;
236 g_debug("%s", __func__
);
238 gsmd_modem_general_at_init_sim_ready (modem
);
240 gsmd_modem_post_at_command_id(modem
,
249 /********************************/
253 static void wavecom_unsolicite_handler_init(ModemInterface
*modem
,
254 VendorInterface
*vendor
)
256 g_debug("%s", __func__
);
257 //add the symbol to the modem scanner
258 while (symbol_p
->symbol_name
) {
259 g_scanner_add_symbol (modem
->scanner
, symbol_p
->symbol_name
,
260 GINT_TO_POINTER(symbol_p
->symbol_token
));
264 //add the command to the modem command table
265 while (command_p
->command
) {
266 gsmd_modem_register_command(modem
, command_p
);
269 vendor
->unsolicite_handler
= wavecom_unsolicite_handler
;
274 AtCommandHandlerStatus
wavecom_handle_wind(ModemInterface
*modem
,
275 AtCommandContext
*at
,
279 g_debug("%s",__func__
);
284 call
= gsmd_utils_find_first_call_status(modem
,CALL_CALLING
);
286 call
->status
= CALL_WAITING
;
290 gsmd_utils_print_calls(modem
);
292 return AT_HANDLER_NEED_MORE
;
295 g_debug("%s : Call created with id %d",__func__
,callid
);
296 g_debug("%s : Current calls: ",__func__
);
298 gsmd_utils_print_calls(modem
);
299 call
= gsmd_utils_find_first_call_status(modem
,CALL_IDLE
);
301 call
->vendor_id
= callid
;
302 call
->status
= CALL_CALLING
;
303 if (modem
->call_ipc
->initiate_reply
&& at
)
304 modem
->call_ipc
->initiate_reply(modem
->call_ipc
,
308 gsmd_utils_call_send_status(modem
,
313 return AT_HANDLER_NEED_MORE
;
316 gsmd_utils_remove_calls(modem
,TRUE
);
317 return AT_HANDLER_NEED_MORE
;
321 return AT_HANDLER_DONT_UNDERSTAND
;
325 AtCommandHandlerStatus
wavecom_parse_wind(ModemInterface
*modem
,
326 AtCommandContext
*at
,
329 g_debug("%s",__func__
);
330 AtCommandHandlerStatus result
= AT_HANDLER_DONT_UNDERSTAND
;
331 GError
**error
= NULL
;
332 GRegex
*regex
= g_regex_new ("\\+WIND:\\s(?<value>\\d+),?(?<call>\\d+)?", 0, 0, error
);
333 GMatchInfo
*match_info
;
336 if (g_regex_match (regex
, response
->str
, 0, &match_info
)) {
337 if (gsmd_utils_match_exists(match_info
,"value")) {
338 match
= g_match_info_fetch_named(match_info
,"value");
339 gint value
= atoi(match
);
343 if (gsmd_utils_match_exists(match_info
,"call")) {
344 match
= g_match_info_fetch_named(match_info
,"call");
349 result
= wavecom_handle_wind(modem
,at
,value
,id
);
354 g_match_info_free (match_info
);
355 g_regex_unref (regex
);
361 AtCommandHandlerStatus
wavecom_call_initiate_handler(ModemInterface
*modem
,
362 AtCommandContext
*at
,
366 AtCommandHandlerStatus status
= wavecom_parse_wind(modem
,at
,response
);
367 GScanner
* scanner
= modem
->scanner
;
370 if (scanner
->token
== SYMBOL_OK
) {
372 Call
*call
= gsmd_utils_find_first_call_status(modem
,CALL_WAITING
);
376 call
= gsmd_utils_find_first_call_status(modem
,CALL_CALLING
);
380 call
->status
= CALL_CONNECTED
;
381 gsmd_utils_call_send_status(modem
,
386 g_warning("%s : OK reply to a call that doesn't existst. Current calls:",__func__
);
387 gsmd_utils_print_calls(modem
);
390 return AT_HANDLER_DONE
;
391 } else if (scanner
->token
== SYMBOL_BUSY
|| scanner
->token
== SYMBOL_NO
) {
392 Call
*call
= gsmd_utils_get_first_call(modem
);
394 gsmd_utils_remove_call(modem
,call
->id
, TRUE
);
397 return AT_HANDLER_DONE
;
401 if (status
!= AT_HANDLER_NEED_MORE
)
402 return vendor_priv
->orig_call_initiate_handler(modem
,at
,response
);
408 AtCommandHandlerStatus
wavecom_unsolicite_handler (ModemInterface
*modem
,
409 AtCommandContext
*at
,
412 g_debug("%s",__func__
);
413 return wavecom_parse_wind(modem
,at
,response
);