4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hayoon Ko <hayoon.ko@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
31 #include <core_object.h>
42 #define ID_RESERVED_AT 0x0229
44 #define MAX_VERSION_LEN 32
45 #define TAPI_MISC_ME_SN_LEN_MAX 32
46 #define TAPI_MISC_PRODUCT_CODE_LEN_MAX 32
47 #define TAPI_MISC_MODEL_ID_LEN_MAX 17
48 #define TAPI_MISC_PRL_ERI_VER_LEN_MAX 17
50 #define CPAS_RES_READY 0
51 #define CPAS_RES_UNAVAIL 1
52 #define CPAS_RES_UNKNOWN 2
53 #define CPAS_RES_RINGING 3
54 #define CPAS_RES_CALL_PROGRESS 4
55 #define CPAS_RES_ASLEEP 5
65 CP_STATE_NV_REBUILDING,
70 TAPI_MISC_ME_IMEI = 0x00, /**< 0x00: IMEI, GSM/UMTS device */
71 TAPI_MISC_ME_ESN = 0x01, /**< 0x01: ESN(Electronic Serial Number), It`s essentially run out. CDMA device */
72 TAPI_MISC_ME_MEID = 0x02, /**< 0x02: MEID, This value can have hexa decimal digits. CDMA device */
73 TAPI_MISC_ME_MAX = 0xff /**< 0xff: reserved */
74 } TelMiscSNIndexType_t;
77 TelMiscSNIndexType_t sn_index; /**< serial number index */
78 int sn_len; /**< Length */
79 unsigned char szNumber[TAPI_MISC_ME_SN_LEN_MAX]; /**< Number */
80 } TelMiscSNInformation;
83 * Mobile Equipment Version Information
86 unsigned char ver_mask; /**< version mask - 0x01:SW_ver, 0x02:HW_ver, 0x04:RF_CAL_date, 0x08:Product_code, 0x10:Model_ID, 0x20:PRL, 0x04:ERI, 0xff:all */
87 unsigned char szSwVersion[MAX_VERSION_LEN]; /**< Software version, null termination */
88 unsigned char szHwVersion[MAX_VERSION_LEN]; /**< Hardware version, null termination */
89 unsigned char szRfCalDate[MAX_VERSION_LEN]; /**< Calculation Date, null termination */
90 unsigned char szProductCode[TAPI_MISC_PRODUCT_CODE_LEN_MAX]; /**< product code, null termination */
91 unsigned char szModelId[TAPI_MISC_MODEL_ID_LEN_MAX]; /**< model id (only for CDMA), null termination */
92 unsigned char prl_nam_num; /**< number of PRL NAM fields */
93 unsigned char szPrlVersion[TAPI_MISC_PRL_ERI_VER_LEN_MAX * 3];/**< prl version (only for CDMA), null termination */
94 unsigned char eri_nam_num; /**< number of PRL NAM fields */
95 unsigned char szEriVersion[TAPI_MISC_PRL_ERI_VER_LEN_MAX * 3];/**< eri version (only for CDMA), null termination */
96 } TelMiscVersionInformation;
98 void prepare_and_send_pending_request(TcorePlugin *plugin, char *co_name, const char *at_cmd, const char* prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback);
99 static void on_confirmation_modem_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
100 void on_response_bootup_subscription(TcorePending *p, gboolean result, void *user_data);
101 void on_response_last_bootup_subscription(TcorePending *p, gboolean result, void *user_data);
102 static void on_timeout_modem_poweron(TcorePending *p, void *user_data);
104 static void on_timeout_modem_poweron(TcorePending *p, void *user_data)
106 unsigned int data_len = 0;
107 char data[] = "AT+CPAS\r";
108 dbg("TIMEOUT for 1st AT Command !!!!! NO Response for initial AT command. Resending it");
109 data_len = sizeof(data);
111 /* Retransmit 1st AT command directly via HAL, don't disturb pending queue. */
112 /* HAL was passed as user_data, re-use it */
115 tcore_hal_send_data(user_data, data_len, (void *)data);
119 static void on_confirmation_modem_message_send(TcorePending *p, gboolean result, void *user_data)
121 dbg("on_confirmation_modem_message_send - msg out from queue.\n");
123 if (result == FALSE) {
132 void prepare_and_send_pending_request(TcorePlugin *plugin, char *co_name, const char *at_cmd, const char* prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
134 TcoreATRequest *req = NULL;
137 TcorePending *pending = NULL;
140 o = tcore_plugin_ref_core_object(plugin, co_name);
141 hal = tcore_object_get_hal(o);
143 pending = tcore_pending_new(o, 0);
145 dbg("Pending is NULL");
146 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
148 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
150 tcore_pending_set_request_data(pending, 0, req);
151 tcore_pending_set_response_callback(pending, callback, NULL);
152 tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
153 tcore_pending_link_user_request(pending, NULL); //set user request to NULL - this is intenal request
154 ret = tcore_hal_send_request(hal, pending);
158 void on_response_bootup_subscription(TcorePending *p, gboolean result, void *user_data)
160 dbg("enry of on_response_bootup_subscription() - response comes\n");
162 if (result == FALSE) {
171 void on_response_last_bootup_subscription(TcorePending *p, gboolean result, void *user_data)
173 dbg("enry of on_response_last_bootup_subscription() - final response comes\n");
175 if (result == FALSE) {
183 dbg("Response for AT+CLIP. Boot-up configration completed for IMC modem. Bring CP to online based on Flightmode status\n");
184 on_event_modem_power(NULL, NULL, tcore_pending_ref_plugin(p));
189 static void on_response_power_off(TcorePending *p, int data_len, const void *data, void *user_data)
193 o = tcore_pending_ref_core_object(p);
194 h = tcore_object_get_hal(o);
196 dbg("modem power off");
198 tcore_hal_set_power_state(h, FALSE);
201 static void on_response_set_flight_mode(TcorePending *p, int data_len, const void *data, void *user_data)
203 CoreObject *o = user_data;
204 UserRequest *ur = NULL;
205 const TcoreATResponse *resp = data;
208 struct tresp_modem_set_flightmode res;
212 struct tnoti_modem_flight_mode modem_flight_mode;
214 o = tcore_pending_ref_core_object(p);
217 if(resp->success > 0){
218 dbg("RESPONSE OK - flight mode operation finished");
219 res.result = TCORE_RETURN_SUCCESS;
223 line = (const char*)resp->final_response;
224 tokens = tcore_at_tok_new(line);
226 if (g_slist_length(tokens) < 1) {
227 dbg("err cause not specified or string corrupted");
228 res.result = TCORE_RETURN_3GPP_ERROR;
231 response = atoi(g_slist_nth_data(tokens, 0));
232 /* TODO: CMEE error mapping is required. */
233 res.result = TCORE_RETURN_3GPP_ERROR;
237 ur = tcore_pending_ref_user_request(p);
239 dbg("No user request ");
242 tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE, sizeof(struct tresp_modem_set_flightmode), &res);
245 if(resp->success > 0){
246 modem_flight_mode.enable = tcore_modem_get_flight_mode_state(o);
248 dbg("sucess case - Sending Flight Mode Notification (%d) to Server",modem_flight_mode.enable);
250 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_FLIGHT_MODE,
251 sizeof(struct tnoti_modem_flight_mode), &modem_flight_mode);
254 tcore_at_tok_free(tokens);
257 static void on_response_imei(TcorePending *p, int data_len, const void *data, void *user_data)
259 const TcoreATResponse* resp = data;
261 struct tresp_modem_get_imei res;
262 TelMiscSNInformation *imei_property;
263 UserRequest* ur = NULL;
269 memset(&res, 0, sizeof(struct tresp_modem_get_imei));
271 if(resp->success > 0)
275 line = (const char*)resp->lines->data;
276 tokens = tcore_at_tok_new(line);
277 if (g_slist_length(tokens) != 1) {
278 msg("invalid message");
282 res.result = TCORE_RETURN_SUCCESS;
283 strncpy(res.imei, g_slist_nth_data(tokens, 0), 16);
285 dbg("imei = [%s]", res.imei);
287 plugin = tcore_pending_ref_plugin(p);
288 imei_property = tcore_plugin_ref_property(plugin, "IMEI");
291 imei_property->sn_index = TAPI_MISC_ME_IMEI;
292 imei_property->sn_len = strlen(res.imei);
293 memcpy(imei_property->szNumber, res.imei, imei_property->sn_len);
300 line = (const char*)resp->lines->data;
301 tokens = tcore_at_tok_new(line);
304 memset(&res, 0, sizeof(struct tresp_modem_get_version));
307 if (g_slist_length(tokens) < 1) {
308 dbg("err cause not specified or string corrupted");
309 res.result = TCORE_RETURN_3GPP_ERROR;
313 response = atoi(g_slist_nth_data(tokens, 0));
314 /* TODO: CMEE error mapping is required. */
315 res.result = TCORE_RETURN_3GPP_ERROR;
319 ur = tcore_pending_ref_user_request(p);
320 tcore_user_request_send_response(ur, TRESP_MODEM_GET_IMEI, sizeof(struct tresp_modem_get_imei), &res);
323 tcore_at_tok_free(tokens);
327 static void on_response_version(TcorePending *p, int data_len, const void *data, void *user_data)
329 const TcoreATResponse *resp = data;
331 TelMiscVersionInformation *vi;
332 TelMiscVersionInformation *vi_property;
333 struct tresp_modem_get_version res;
335 GSList* tokens = NULL;
336 const char* line=NULL;
337 char *swver= NULL,*hwver=NULL, *caldate=NULL,*pcode=NULL,*id=NULL;
341 if(resp->success > 0)
345 line = (const char*)resp->lines->data;
346 tokens = tcore_at_tok_new(line);
347 if (g_slist_length(tokens) != 5) {
348 msg("invalid message");
353 swver = g_slist_nth_data(tokens, 0);
354 hwver = g_slist_nth_data(tokens, 1);
355 caldate = g_slist_nth_data(tokens, 2);
356 pcode = g_slist_nth_data(tokens, 3);
357 id = g_slist_nth_data(tokens, 4);
359 dbg("version: sw=[%s], hw=[%s], rf_cal=[%s], product_code=[%s], model_id=[%s]", swver, hwver, caldate, pcode, id);
361 vi = calloc(sizeof(TelMiscVersionInformation), 1);
363 memcpy(vi->szSwVersion, swver, strlen(swver));
365 memcpy(vi->szHwVersion, hwver, strlen(hwver));
367 memcpy(vi->szRfCalDate, caldate, strlen(caldate));
369 memcpy(vi->szProductCode, pcode,strlen(pcode));
371 memcpy(vi->szModelId, id, strlen(id));
373 memset(&res, 0, sizeof(struct tresp_modem_get_version));
376 snprintf(res.software, (AT_VER_LEN >strlen(swver) ?strlen(swver):AT_VER_LEN), "%s", swver);
378 snprintf(res.hardware, (AT_VER_LEN >strlen(hwver) ?strlen(hwver):AT_VER_LEN), "%s", hwver);
380 plugin = tcore_pending_ref_plugin(p);
381 vi_property = tcore_plugin_ref_property(plugin, "VERSION");
382 memcpy(vi_property, vi, sizeof(TelMiscVersionInformation));
388 line = (const char*)resp->lines->data;
389 tokens = tcore_at_tok_new(line);
392 memset(&res, 0, sizeof(struct tresp_modem_get_version));
395 if (g_slist_length(tokens) < 1) {
396 dbg("err cause not specified or string corrupted");
397 res.result = TCORE_RETURN_3GPP_ERROR;
401 response = atoi(g_slist_nth_data(tokens, 0));
402 /* TODO: CMEE error mapping is required. */
403 res.result = TCORE_RETURN_3GPP_ERROR;
407 ur = tcore_pending_ref_user_request(p);
408 tcore_user_request_send_response(ur, TRESP_MODEM_GET_VERSION, sizeof(struct tresp_modem_get_version), &res);
411 tcore_at_tok_free(tokens);
415 static gboolean on_event_bootup_sim_status(CoreObject *o, const void *event_info, void *user_data)
418 GSList *lines = NULL;
422 lines = (GSList*)event_info;
423 if (1 != g_slist_length(lines)) {
424 dbg("unsolicited msg but multiple line");
427 line = (char*)(lines->data);
428 dbg("on_bootup_event_sim_status notification : %s", line);
430 tok = tcore_at_tok_new(line);
431 value = atoi(g_slist_nth_data(tok, 0));
434 dbg("SIM ready. request COPS & remove callback");
435 prepare_and_send_pending_request(tcore_object_ref_plugin(o), "umts_network", "AT+COPS=0", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
445 gboolean on_event_modem_power(TcoreAT *at, const char *line, TcorePlugin *p)
448 struct treq_modem_set_flightmode flight_mode_set;
449 struct tnoti_modem_power modem_power;
453 o = tcore_plugin_ref_core_object(p, "modem");
455 strg = tcore_server_find_storage(tcore_plugin_ref_server(p), "vconf");
456 flight_mode_set.enable = tcore_storage_get_bool(strg, STORAGE_KEY_SETAPPL_FLIGHT_MODE_BOOL);
458 tcore_hal_set_power_state(h, TRUE);
460 /* Set Flight mode as per AP settings */
461 if (flight_mode_set.enable)
463 prepare_and_send_pending_request(p, "modem", "AT+CFUN=4", NULL, TCORE_AT_NO_RESULT, on_response_set_flight_mode);
464 tcore_modem_set_flight_mode_state(o, TRUE);
468 prepare_and_send_pending_request(p, "modem", "AT+CFUN=1", NULL, TCORE_AT_NO_RESULT, on_response_set_flight_mode);
469 tcore_modem_set_flight_mode_state(o, FALSE);
473 prepare_and_send_pending_request(p, "modem", "AT+CGSN", NULL, TCORE_AT_NUMERIC, on_response_imei);
475 /* Get Version Number */
476 prepare_and_send_pending_request(p, "modem", "AT+CGMR", NULL, TCORE_AT_SINGLELINE, on_response_version);
478 tcore_modem_set_powered(o, TRUE);
480 modem_power.state = MODEM_STATE_ONLINE;
482 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_POWER,
483 sizeof(struct tnoti_modem_power), &modem_power);
491 static void on_response_setupmux(TcorePending *p, int data_len, const void *data, void *user_data)
493 TcorePlugin *plugin = NULL;
495 plugin = tcore_pending_ref_plugin(p);
497 /* TODO: Initialize MUX module.
498 * Append each MUX HAL to each Co-Object while initialization.
499 * API: tcore_object_set_hal(CoreObject *o, TcoreHal *h)
501 * After MUX setup, AT parse functionality of PHY HAL
502 * should be disabled.
503 * e.g.) plugin = tcore_pending_ref_plugin((TcorePending*) p);
504 * hal = tcore_plugin_ref_hal((TcorePlugin*) plugin);
505 * tcore_hal_disable_queue((TcoreHal*) hal);
508 /* TODO: Should be moved to ...
509 * Proceed power up noti process after MUX initialization.
511 s_modem_send_poweron(NULL, NULL, plugin);
516 static void setup_mux(CoreObject *o)
520 TcorePending *pending = NULL;
523 prepare_and_send_pending_request(p, "modem", "AT+CMUX=0,0,,1509,10,3,30,,", +CMUX, TCORE_AT_NO_RESULT, on_response_set_flight_mode);
525 /* HAL has type itself,
526 * e.g.) TCORE_HAL_MODE_AT
528 hal = tcore_object_get_hal(o);
529 pending = tcore_pending_new(o, 0);
531 /* Set Metainfo into TcorePending directly
532 * using TcoreATRequest
533 * command type: e.g.) SINGLELINE
536 req = tcore_at_request_new("AT+CMUX=0,0,,1509,10,3,30,,", "+CMUX", TCORE_AT_NO_RESULT);
538 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
540 tcore_pending_set_request_data(pending, 0, req);
541 tcore_pending_set_response_callback(pending, on_response_setupmux, hal);
542 tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
544 tcore_hal_send_request(hal, pending);
549 static void on_response_enable_logging(TcorePending *p, int data_len, const void *data, void *user_data)
551 const TcoreATResponse *resp = data;
552 TcorePlugin *plugin = NULL;
554 plugin = tcore_pending_ref_plugin(p);
556 /* DELETE ME: only for DEBUG */
560 dbg("response...(result = %d, final_response = '%s')", resp->success, resp->final_response);
564 dbg("Enabling CP logging is success !!!\n");
568 dbg("Enabling CP logging is failed !!!\n");
573 dbg("call setup_mux");
574 prepare_and_send_pending_request(plugin, "modem", "AT+CMUX=0,0,,1509,10,3,30,,", +CMUX, TCORE_AT_NO_RESULT, on_response_setupmux);
575 /*setup_mux(tcore_pending_ref_core_object(p));*/
578 /* XCALLSTAT subscription */
579 prepare_and_send_pending_request(plugin, "call", "at+xcallstat=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
581 /* XSIMSTATE subscription */
582 prepare_and_send_pending_request(plugin, "sim", "at+xsimstate=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
584 /* CREG subscription */
585 prepare_and_send_pending_request(plugin, "umts_network", "at+creg=2", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
587 /* CGREG subscription */
588 prepare_and_send_pending_request(plugin, "umts_network", "at+cgreg=2", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
590 /* XMER subscription */
591 prepare_and_send_pending_request(plugin, "umts_network", "at+xmer=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
593 /* CGEREP subscription */
594 prepare_and_send_pending_request(plugin, "umts_ps", "at+cgerep=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
596 /* XDATASTAT subscription */
597 prepare_and_send_pending_request(plugin, "umts_ps", "at+xdatastat=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
599 /* CMGF subscription */
600 prepare_and_send_pending_request(plugin, "umts_sms", "at+cmgf=0", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
602 /* CSSN subscription */
603 prepare_and_send_pending_request(plugin, "call", "at+cssn=1,1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
605 /* CUSD subscription */
606 prepare_and_send_pending_request(plugin, "call", "at+cusd=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
608 /* XDNS subscription */
609 prepare_and_send_pending_request(plugin, "umts_ps", "at+xdns=1,1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
611 /* CLIP subscription */
612 prepare_and_send_pending_request(plugin, "call", "at+clip=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
614 /*CMEE subscription*/
615 prepare_and_send_pending_request(plugin,"umts_ps","at+cmee=2",NULL,TCORE_AT_NO_RESULT, on_response_bootup_subscription);
618 /*incoming sms and cb subscription*/
619 prepare_and_send_pending_request(plugin,"umts_sms","at+cnmi=1,2,2,2,0",NULL,TCORE_AT_NO_RESULT, on_response_bootup_subscription);
621 /*message service subscription*/
622 prepare_and_send_pending_request(plugin,"umts_sms","at+csms=1",NULL,TCORE_AT_NO_RESULT, on_response_bootup_subscription);
624 /* text/pdu mode subscription*/
625 prepare_and_send_pending_request(plugin,"umts_sms","at+cmgf=0",NULL,TCORE_AT_NO_RESULT, on_response_last_bootup_subscription);
627 /* Check for SIM PIN status */
628 prepare_and_send_pending_request(plugin, "sim", "at+cpin?", on_response_bootup_subscription);
634 static void _send_enable_logging_command(CoreObject *o)
638 TcorePending *pending;
641 dbg("Send Trace enabling command for CP logging. \n");
644 dbg("Co-object is Null !!\n");
648 hal = tcore_object_get_hal(o);
649 pending = tcore_pending_new(o, 0);
650 req = tcore_at_request_new("at+xsystrace=1,\"digrf=1;bb_sw=1;3g_sw=1\",\"digrf=0x84\",\"oct=4\";+xsystrace=11;+trace=1", NULL, TCORE_AT_NO_RESULT);
652 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
654 tcore_pending_set_request_data(pending, 0, req);
655 tcore_pending_set_response_callback(pending, on_response_enable_logging, hal);
656 tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
658 ret = tcore_hal_send_request(hal, pending);
659 if(ret != TCORE_RETURN_SUCCESS)
660 dbg("tcore_hal_send_request fail !!! (hal: 0x%x, pending: 0x%x)\n", hal, pending);
664 static void on_response_poweron(TcorePending *p, int data_len, const void *data, void *user_data)
666 const TcoreATResponse *resp = data;
668 const char *line=NULL;
669 gboolean bpoweron = FALSE;
675 /* Parse AT Response */
677 line = (const char *)resp->lines->data;
678 tokens = tcore_at_tok_new(line);
679 if (g_slist_length(tokens) != 1) {
680 dbg("invalid message");
686 response = atoi(g_slist_nth_data(tokens, 0));
688 dbg("CPAS: response %d",response);
693 case CPAS_RES_RINGING:
694 case CPAS_RES_CALL_PROGRESS:
695 case CPAS_RES_ASLEEP:
699 case CPAS_RES_UNAVAIL:
700 case CPAS_RES_UNKNOWN:
702 dbg("unvail/unknown,but response received - CP can communicate - proceed bootup");
708 dbg("CPAS: RESPONSE NOK");
713 /* DELE ME: AT request & response are freed after AT processing in HAL.
714 * ref.) _emit_pending_response (libtcore/src/at.c)
716 tcore_at_tok_free(tokens);
718 if(bpoweron == TRUE){
719 dbg("Power on NOTI received, (pending: 0x%x, co: 0x%x)\n", p, tcore_pending_ref_core_object(p));
721 _send_enable_logging_command(tcore_pending_ref_core_object(p));
724 dbg("CP is not ready, send CPAS once again");
725 s_modem_send_poweron(tcore_object_ref_plugin(tcore_pending_ref_core_object(p)));
729 static TReturn power_on(CoreObject *o, UserRequest *ur)
732 return TCORE_RETURN_SUCCESS;
735 static TReturn power_off(CoreObject *o, UserRequest *ur)
739 TcorePending *pending = NULL;
741 /* FIXME: Before MUX setup, use PHY HAL directly. */
742 hal = tcore_object_get_hal(o);
744 pending = tcore_pending_new(o, 0);
747 * Need to mapping or define AT command
748 * including prefix if neccessary otherwise NULL.
749 * Response type (e.g. TCORE_AT_SINGLELINE)
751 req = tcore_at_request_new("AT+CFUN=0", NULL, TCORE_AT_NO_RESULT);
753 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
755 tcore_pending_set_request_data(pending, 0, req);
756 tcore_pending_set_response_callback(pending, on_response_power_off, hal);
757 tcore_pending_link_user_request(pending, ur);
758 tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
760 tcore_hal_send_request(hal, pending);
762 return TCORE_RETURN_SUCCESS;
765 static TReturn power_reset(CoreObject *o, UserRequest *ur)
768 return TCORE_RETURN_SUCCESS;
771 static TReturn get_imei(CoreObject *o, UserRequest *ur)
775 TcorePending *pending = NULL;
777 hal = tcore_object_get_hal(o);
778 pending = tcore_pending_new(o, 0);
780 req = tcore_at_request_new("AT+CGSN", NULL, TCORE_AT_NUMERIC);
782 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
784 tcore_pending_set_request_data(pending, 0, req);
785 tcore_pending_set_response_callback(pending, on_response_imei, hal);
786 tcore_pending_link_user_request(pending, ur);
787 tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
789 tcore_hal_send_request(hal, pending);
791 return TCORE_RETURN_SUCCESS;
795 static TReturn get_version(CoreObject *o, UserRequest *ur)
799 TcorePending *pending = NULL;
801 hal = tcore_object_get_hal(o);
802 pending = tcore_pending_new(o, 0);
804 req = tcore_at_request_new("AT+CGMR", NULL, TCORE_AT_SINGLELINE);
806 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
808 tcore_pending_set_request_data(pending, 0, req);
809 tcore_pending_set_response_callback(pending, on_response_version, hal);
810 tcore_pending_link_user_request(pending, ur);
811 tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
813 tcore_hal_send_request(hal, pending);
815 return TCORE_RETURN_SUCCESS;
818 static TReturn set_flight_mode(CoreObject *o, UserRequest *ur)
822 TcorePending *pending = NULL;
823 const struct treq_modem_set_flightmode *req_data;
824 char* cmd_str = NULL;
826 hal = tcore_object_get_hal(o);
827 pending = tcore_pending_new(o, 0);
829 req_data = tcore_user_request_ref_data(ur, NULL);
831 if (req_data->enable) {
832 dbg("Flight mode on/n");
833 cmd_str = g_strdup("AT+CFUN=4\r");
836 dbg("Flight mode off/n");
837 cmd_str = g_strdup("AT+CFUN=1\r");
840 req = tcore_at_request_new((const char*)cmd_str, NULL, TCORE_AT_NO_RESULT);
842 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
844 tcore_pending_set_request_data(pending, 0, req);
845 tcore_pending_set_response_callback(pending, on_response_set_flight_mode, hal);
846 tcore_pending_link_user_request(pending, ur);
847 tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
849 tcore_hal_send_request(hal, pending);
851 return TCORE_RETURN_SUCCESS;
855 static struct tcore_modem_operations modem_ops =
857 .power_on = power_on,
858 .power_off = power_off,
859 .power_reset = power_reset,
860 .set_flight_mode = set_flight_mode,
861 .get_imei = get_imei,
862 .get_version = get_version,
864 .dun_pin_ctrl = NULL,
867 gboolean s_modem_init(TcorePlugin *p, TcoreHal *h)
871 TelMiscVersionInformation *vi_property;
872 TelMiscSNInformation *imei_property;
873 TelMiscSNInformation *sn_property;
875 o = tcore_modem_new(p, "modem", &modem_ops, h);
879 work_queue = g_queue_new();
880 tcore_object_link_user_data(o, work_queue);
882 vi_property = calloc(sizeof(TelMiscVersionInformation), 1);
883 tcore_plugin_link_property(p, "VERSION", vi_property);
885 imei_property = calloc(sizeof(TelMiscSNInformation), 1);
886 tcore_plugin_link_property(p, "IMEI", imei_property);
888 sn_property = calloc(sizeof(TelMiscSNInformation), 1);
889 tcore_plugin_link_property(p, "SN", sn_property);
891 tcore_object_add_callback(o, "+XSIM", on_event_bootup_sim_status, NULL);
895 void s_modem_exit(TcorePlugin *p)
899 TelMiscVersionInformation *vi_property;
900 TelMiscSNInformation *imei_property;
901 TelMiscSNInformation *sn_property;
906 o = tcore_plugin_ref_core_object(p, "modem");
908 work_queue = tcore_object_ref_user_data(o);
909 g_queue_free(work_queue);
911 vi_property = tcore_plugin_ref_property(p, "VERSION");
915 imei_property = tcore_plugin_ref_property(p, "IMEI");
919 sn_property = tcore_plugin_ref_property(p, "SN");
926 gboolean s_modem_send_poweron(TcorePlugin *p)
930 TcorePending *pending = NULL;
933 o = tcore_plugin_ref_core_object(p, "modem");
934 hal = tcore_object_get_hal(o);
935 /* HAL has type itself,
936 * e.g.) TCORE_HAL_MODE_AT
938 pending = tcore_pending_new(o, 0);
940 /* Set Metainfo into TcorePending directly
941 * using TcoreATRequest
942 * command type: e.g.) SINGLELINE
946 req = tcore_at_request_new("AT+CPAS", "+CPAS", TCORE_AT_SINGLELINE);
948 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
950 tcore_pending_set_timeout(pending, 10);
951 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
952 tcore_pending_set_timeout_callback(pending, on_timeout_modem_poweron, hal);
954 tcore_pending_set_request_data(pending, 0, req);
955 tcore_pending_set_response_callback(pending, on_response_poweron, hal);
956 tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
958 tcore_hal_send_request(hal, pending);