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 _Wavecom900e
{
74 ModemInterface
*modem
;
75 AtCommandHandlerStatus (*orig_call_initiate_handler
) (ModemInterface
*modem
,
80 static Wavecom900e
*vendor_priv
= NULL
;
83 AtCommandHandlerStatus
wavecom_handler_query_pin_status (ModemInterface
*modem
,
87 /** vendor_handle_init should be called from modem.c when the lib loaded*/
88 gboolean
vendor_handle_init (VendorInterface
*vendor
, ModemInterface
* modem
)
91 g_warning("%s : Already initialized!", __func__
);
94 vendor_priv
= g_new0(Wavecom900e
, 1);
95 g_debug("%s", __func__
);
96 vendor
->init_at
= NULL
;
97 vendor
->init_at_sim_ready
= vendor_at_init_sim_ready
;
98 vendor
->priv
= (gpointer
)vendor_priv
;
99 wavecom_unsolicite_handler_init (modem
, vendor
);
100 vendor_priv
->modem
= modem
;
102 AtCommand
*call_initiate
= gsmd_modem_get_command(modem
, INITIATE_CALL
);
103 vendor_priv
->orig_call_initiate_handler
= call_initiate
->handler
;
104 call_initiate
->handler
= &wavecom_call_initiate_handler
;
106 AtCommand
*query_pin
= gsmd_modem_get_command(modem
, PIN_QUERY
);
107 query_pin
->handler
= &wavecom_handler_query_pin_status
;
112 /*************************************/
116 * @brief Handler to modems response from queryPinStatus command
118 * @param modem modem whose response to handle
119 * @return true if responses were recognized
122 AtCommandHandlerStatus
wavecom_handler_query_pin_status (ModemInterface
*modem
,
123 AtCommandContext
*at
,
126 g_debug("%s",__func__
);
127 GScanner
* scanner
= modem
->scanner
;
131 if (gsmd_utils_send_error_from_response(at
,
133 "ERROR READING PIN STATUS",
134 "TIMEOUT READING PIN STATUS"))
135 return AT_HANDLER_DONE_ERROR
;
137 if (scanner
->token
!= '+') {
138 return AT_HANDLER_DONT_UNDERSTAND
;
141 g_scanner_get_next_token (scanner
);
142 switch (scanner
->token
) {
145 g_scanner_get_next_token (scanner
);
146 //g_scanner_get_next_token (scanner);
147 if (scanner
->token
== SYMBOL_ERROR
) {
148 g_scanner_peek_next_token(scanner
);
149 if (scanner
->next_token
== ':') {
150 g_scanner_get_next_token (scanner
);
151 g_scanner_get_next_token(scanner
);//arrive error value
152 if ( ERR_NO_SIM_CARD
== scanner
->value
.v_int
) {
153 gsmd_sim_change_auth_status(modem
,
159 gsmd_sim_change_auth_status(modem
,
166 return AT_HANDLER_DONE
;
168 g_scanner_unexp_token (scanner
, ':', NULL
, "symbol",
173 g_scanner_unexp_token (scanner
, SYMBOL_ERROR
, NULL
, "symbol",
178 g_scanner_get_next_token (scanner
);//get ':'
179 g_scanner_get_next_token (scanner
);
180 if (scanner
->token
== SYMBOL_READY
) {
181 g_debug("%s: READY",__func__
);
182 gsmd_sim_change_auth_status(modem
,
189 return AT_HANDLER_DONE
;
191 } else if (scanner
->token
== SYMBOL_SIM
) {
193 g_scanner_get_next_token (scanner
);
194 g_scanner_peek_next_token(scanner
);
195 if (scanner
->token
== SYMBOL_PIN
) {
196 gsmd_sim_change_auth_status(modem
,
201 } else if (scanner
->token
== SYMBOL_PUK
) {
202 g_debug("%s: SIM PUK",__func__
);
203 gsmd_sim_change_auth_status(modem
,
210 return AT_HANDLER_DONE
;
212 g_scanner_unexp_token (scanner
, SYMBOL_READY
, NULL
, "symbol",
217 g_warning("No match after getting + \n");
225 return AT_HANDLER_DONT_UNDERSTAND
;
229 static gboolean
vendor_at_init_sim_ready (VendorInterface
* vendor
)
231 ModemInterface
*modem
= vendor_priv
->modem
;
233 g_debug("%s", __func__
);
235 gsmd_modem_general_at_init_sim_ready (modem
);
237 gsmd_modem_post_at_command_id(modem
,
246 /********************************/
250 static void wavecom_unsolicite_handler_init(ModemInterface
*modem
,
251 VendorInterface
*vendor
)
253 g_debug("%s", __func__
);
254 //add the symbol to the modem scanner
255 while (symbol_p
->symbol_name
) {
256 g_scanner_add_symbol (modem
->scanner
, symbol_p
->symbol_name
,
257 GINT_TO_POINTER(symbol_p
->symbol_token
));
261 //add the command to the modem command table
262 while (command_p
->command
) {
263 gsmd_modem_register_command(modem
, command_p
);
266 vendor
->unsolicite_handler
= wavecom_unsolicite_handler
;
271 AtCommandHandlerStatus
wavecom_handle_wind(ModemInterface
*modem
,
272 AtCommandContext
*at
,
276 g_debug("%s",__func__
);
281 call
= gsmd_utils_find_first_call_status(modem
,CALL_CALLING
);
283 call
->status
= CALL_WAITING
;
287 gsmd_utils_print_calls(modem
);
289 return AT_HANDLER_NEED_MORE
;
292 g_debug("%s : Call created with id %d",__func__
,callid
);
293 g_debug("%s : Current calls: ",__func__
);
295 gsmd_utils_print_calls(modem
);
296 call
= gsmd_utils_find_first_call_status(modem
,CALL_IDLE
);
298 call
->vendor_id
= callid
;
299 call
->status
= CALL_CALLING
;
300 if (modem
->call_ipc
->initiate_reply
&& at
)
301 modem
->call_ipc
->initiate_reply(modem
->call_ipc
,
305 gsmd_utils_call_send_status(modem
,
310 return AT_HANDLER_NEED_MORE
;
313 gsmd_utils_remove_calls(modem
,TRUE
);
314 return AT_HANDLER_NEED_MORE
;
318 return AT_HANDLER_DONT_UNDERSTAND
;
322 AtCommandHandlerStatus
wavecom_parse_wind(ModemInterface
*modem
,
323 AtCommandContext
*at
,
326 g_debug("%s",__func__
);
327 AtCommandHandlerStatus result
= AT_HANDLER_DONT_UNDERSTAND
;
328 GError
**error
= NULL
;
329 GRegex
*regex
= g_regex_new ("\\+WIND:\\s(?<value>\\d+),?(?<call>\\d+)?", 0, 0, error
);
330 GMatchInfo
*match_info
;
333 if (g_regex_match (regex
, response
->str
, 0, &match_info
)) {
334 if (gsmd_utils_match_exists(match_info
,"value")) {
335 match
= g_match_info_fetch_named(match_info
,"value");
336 gint value
= atoi(match
);
340 if (gsmd_utils_match_exists(match_info
,"call")) {
341 match
= g_match_info_fetch_named(match_info
,"call");
346 result
= wavecom_handle_wind(modem
,at
,value
,id
);
351 g_match_info_free (match_info
);
352 g_regex_unref (regex
);
358 AtCommandHandlerStatus
wavecom_call_initiate_handler(ModemInterface
*modem
,
359 AtCommandContext
*at
,
363 AtCommandHandlerStatus status
= wavecom_parse_wind(modem
,at
,response
);
364 GScanner
* scanner
= modem
->scanner
;
367 if (scanner
->token
== SYMBOL_OK
) {
369 Call
*call
= gsmd_utils_find_first_call_status(modem
,CALL_WAITING
);
373 call
= gsmd_utils_find_first_call_status(modem
,CALL_CALLING
);
377 call
->status
= CALL_CONNECTED
;
378 gsmd_utils_call_send_status(modem
,
383 g_warning("%s : OK reply to a call that doesn't existst. Current calls:",__func__
);
384 gsmd_utils_print_calls(modem
);
387 return AT_HANDLER_DONE
;
388 } else if (scanner
->token
== SYMBOL_BUSY
|| scanner
->token
== SYMBOL_NO
) {
389 Call
*call
= gsmd_utils_get_first_call(modem
);
391 gsmd_utils_remove_call(modem
,call
->id
, TRUE
);
394 return AT_HANDLER_DONE
;
398 if (status
!= AT_HANDLER_NEED_MORE
)
399 return vendor_priv
->orig_call_initiate_handler(modem
,at
,response
);
405 AtCommandHandlerStatus
wavecom_unsolicite_handler (ModemInterface
*modem
,
406 AtCommandContext
*at
,
409 g_debug("%s",__func__
);
410 return wavecom_parse_wind(modem
,at
,response
);