4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
28 #include <core_object.h>
36 #include "imc_modem.h"
37 #include "imc_common.h"
40 static gboolean on_event_imc_nvm_update(CoreObject *co,
41 const void *event_info, void *user_data);
44 __imc_modem_convert_cme_error_tel_modem_result(const TcoreAtResponse *at_resp)
46 TelModemResult result = TEL_MODEM_RESULT_FAILURE;
48 GSList *tokens = NULL;
52 if (!at_resp || !at_resp->lines) {
53 err("Invalid response data");
57 line = (const gchar *)at_resp->lines->data;
58 tokens = tcore_at_tok_new(line);
59 if (g_slist_length(tokens) > 0) {
63 resp_str = g_slist_nth_data(tokens, 0);
65 err("Invalid CME Error data");
66 tcore_at_tok_free(tokens);
69 cme_err = atoi(resp_str);
70 dbg("CME error[%d]", cme_err);
74 result = TEL_MODEM_RESULT_OPERATION_NOT_PERMITTED;
78 result = TEL_MODEM_RESULT_OPERATION_NOT_SUPPORTED;
82 result = TEL_MODEM_RESULT_MEMORY_FAILURE;
86 result = TEL_MODEM_RESULT_INVALID_PARAMETER;
90 result = TEL_MODEM_RESULT_UNKNOWN_FAILURE;
94 result = TEL_MODEM_RESULT_FAILURE;
97 tcore_at_tok_free(tokens);
102 /* NVM Req/Response */
103 static gboolean __imc_modem_check_nvm_response(const void *data, int command)
105 const TcoreAtResponse *at_resp = data;
108 GSList *tokens = NULL;
109 gboolean ret = FALSE;
113 /* +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>] */
114 if (NULL == at_resp) {
115 err("Input data is NULL");
119 if (at_resp->success > 0) {
121 line = (const char *) (((GSList *) at_resp->lines)->data);
122 tokens = tcore_at_tok_new(line);
125 resp_str = g_slist_nth_data(tokens, 0);
126 if (NULL == resp_str) {
127 err("Group ID is missing ");
130 else if (IUFP_GROUP_ID != atoi(resp_str)) {
131 err("Group ID mismatch");
136 resp_str = g_slist_nth_data(tokens, 1);
137 if (NULL == resp_str) {
138 err("Function ID is missing ");
141 else if (command != atoi(resp_str)) {
142 err("Function ID mismatch");
147 resp_str = g_slist_nth_data(tokens, 2);
148 if (NULL == resp_str) {
149 err("XDRV result is missing ");
152 else if (XDRV_RESULT_OK != atoi(resp_str)) {
153 err("XDRV result[%d] ", atoi(resp_str));
158 resp_str = g_slist_nth_data(tokens, 3);
159 if (NULL == resp_str) {
160 err("UTA result is missing ");
163 else if (UTA_SUCCESS != atoi(resp_str)) {
164 err("uta result[%d] ", atoi(resp_str));
174 tcore_at_tok_free(tokens);
180 static void __on_response_modem_unsuspend_nvm_updates(TcorePending *p,
181 guint data_len, const void *data, void *user_data)
183 /* Check NVM response */
184 if (TRUE == __imc_modem_check_nvm_response(data, IUFP_SUSPEND)) {
185 dbg("Priority level is set to get all updates since Boot-up");
187 /* Create NV data file */
188 if (nvm_create_nvm_data() == FALSE) {
189 err("Failed to Create NV data file");
195 err("Response NOT OK");
198 static void __imc_modem_unsuspend_nvm_updates(CoreObject *co)
203 /* Prepare AT-Command */
204 cmd_str = g_strdup_printf("AT+XDRV=%d, %d, %d, %d",
205 IUFP_GROUP_ID, IUFP_SUSPEND,
206 0, UTA_FLASH_PLUGIN_PRIO_UNSUSPEND_ALL);
208 /* Send Request to modem */
209 ret = tcore_at_prepare_and_send_request(co,
211 TCORE_AT_COMMAND_TYPE_SINGLELINE,
213 __on_response_modem_unsuspend_nvm_updates, NULL,
214 on_send_imc_request, NULL);
215 IMC_CHECK_REQUEST_RET(ret, NULL, "Unsuspend Nvm Updates");
220 static void __on_response_modem_send_nvm_update_ack(TcorePending *p,
221 guint data_len, const void *data, void *user_data)
223 /* Check NVM response */
224 if (TRUE == __imc_modem_check_nvm_response(data, IUFP_UPDATE_ACK)) {
225 dbg("[UPDATE ACK] OK");
229 err("[UPDATE ACK] NOT OK");
232 static void __imc_modem_send_nvm_update_ack(CoreObject *co)
237 /* Prepare AT-Command */
238 cmd_str = g_strdup_printf("AT+XDRV=%s, %s", IUFP_GROUP, IUFP_UPDATE_ACK_STR);
240 /* Send Request to modem */
241 ret = tcore_at_prepare_and_send_request(co,
243 TCORE_AT_COMMAND_TYPE_SINGLELINE,
245 __on_response_modem_send_nvm_update_ack, NULL,
246 on_send_imc_request, NULL);
247 IMC_CHECK_REQUEST_RET(ret, NULL, "Nvm Update Ack");
252 static void __on_response_modem_send_nvm_update_request_ack(TcorePending *p,
253 guint data_len, const void *data, void *user_data)
255 /* Check NVM response */
256 if (TRUE == __imc_modem_check_nvm_response(data, IUFP_UPDATE_REQ_ACK)) {
257 dbg("[REQUEST ACK] OK");
261 err("[REQUEST ACK] NOT OK");
264 static void __imc_modem_send_nvm_update_request_ack(CoreObject *co)
269 /* Prepare AT-Command */
270 cmd_str = g_strdup_printf("AT+XDRV=%s, %s", IUFP_GROUP, IUFP_UPDATE_REQ_ACK_STR);
272 /* Send Request to modem */
273 ret = tcore_at_prepare_and_send_request(co,
275 TCORE_AT_COMMAND_TYPE_SINGLELINE,
277 __on_response_modem_send_nvm_update_request_ack, NULL,
278 on_send_imc_request, NULL);
279 IMC_CHECK_REQUEST_RET(ret, NULL, "Nvm Update Request Ack");
284 static void __on_response_modem_register_nvm(TcorePending *p,
285 guint data_len, const void *data, void *user_data)
287 /* Check NVM response */
288 if (TRUE == __imc_modem_check_nvm_response(data, IUFP_REGISTER)) {
289 dbg("Registering successful");
291 /* Send SUSPEND_UPDATE for all UPDATES */
292 __imc_modem_unsuspend_nvm_updates(tcore_pending_ref_core_object(p));
298 err("Response NOT OK");
301 /* System function responses */
302 static void on_response_modem_set_flight_mode_internal(TcorePlugin *plugin,
303 gint result, const void *response, void *user_data)
306 gboolean flight_mode;
309 co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM);
310 tcore_check_return_assert(co != NULL);
312 tcore_check_return(result == TEL_MODEM_RESULT_SUCCESS);
314 /* Get Flight mode state */
315 (void)tcore_modem_get_flight_mode_state(co, &flight_mode);
317 dbg("Setting Modem Fiight mode (internal) - [%s] - [SUCCESS]",
318 (flight_mode ? "ON": "OFF"));
323 * This is an internal request to set Flight mode, which is sent during
324 * boot-up based on AP-side configuration (VCONF).
326 * Need to notify TAPI through Notiifcation -
327 * TCORE_NOTIFICATION_MODEM_FLIGHT_MODE
329 (void)tcore_object_send_notification(co,
330 TCORE_NOTIFICATION_MODEM_FLIGHT_MODE,
331 sizeof(gboolean), &flight_mode);
334 /* System functions */
335 gboolean imc_modem_power_on_modem(TcorePlugin *plugin)
339 gboolean flight_mode;
340 TelModemPowerStatus power_status;
342 co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM);
343 tcore_check_return_value_assert(co != NULL, FALSE);
345 /* Set Modem Power State to 'ON' */
346 tcore_modem_set_powered(co, TRUE);
349 * Set Flight mode (as per AP settings -VCONF)
351 /* Get Flight mode from VCONFKEY */
352 strg = tcore_server_find_storage(tcore_plugin_ref_server(plugin), "vconf");
353 tcore_check_return_value_assert(strg != NULL, FALSE);
355 flight_mode = tcore_storage_get_bool(strg, STORAGE_KEY_FLIGHT_MODE);
358 * Set Flight mode request is dispatched to Core Object (Modem)
359 * to ensure that 'Request Hooks' get executed.
361 (void)tcore_object_dispatch_request(co, TRUE,
362 TCORE_COMMAND_MODEM_SET_FLIGHTMODE,
363 &flight_mode, sizeof(gboolean),
364 on_response_modem_set_flight_mode_internal, NULL);
369 * Need to notify Modem is Powered UP through Notiifcation -
370 * TCORE_NOTIFICATION_MODEM_POWER
372 power_status = TEL_MODEM_POWER_ON;
373 (void)tcore_object_send_notification(co,
374 TCORE_NOTIFICATION_MODEM_POWER,
375 sizeof(TelModemPowerStatus), &power_status);
380 /* Modem Responses */
381 static void on_response_imc_modem_set_power_status(TcorePending *p,
382 guint data_len, const void *data, void *user_data)
384 const TcoreAtResponse *at_resp = data;
385 CoreObject *co = tcore_pending_ref_core_object(p);
386 ImcRespCbData *resp_cb_data = user_data;
387 TelModemPowerStatus *status;
388 gboolean powered = FALSE;
390 TelModemResult result = TEL_MODEM_RESULT_FAILURE;
393 tcore_check_return_assert(co != NULL);
394 tcore_check_return_assert(resp_cb_data != NULL);
396 if (at_resp && at_resp->success){
398 result = TEL_MODEM_RESULT_SUCCESS;
401 result = __imc_modem_convert_cme_error_tel_modem_result(at_resp);
405 status = (TelModemPowerStatus *)
406 IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
408 /* Update Core Object */
410 case TEL_MODEM_POWER_ON:
411 dbg("Setting Modem Power status [ON] - [%s]",
412 (result == TEL_MODEM_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
415 case TEL_MODEM_POWER_OFF:
416 dbg("Setting Modem Power status [OFF] - [%s]",
417 (result == TEL_MODEM_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
421 warn("Unexpected - Setting Modem Power status [RESET] - [%s]",
422 (result == TEL_MODEM_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
425 tcore_modem_set_powered(co, powered);
428 /* Invoke callback */
429 if (resp_cb_data->cb)
430 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
432 /* Free callback data */
433 imc_destroy_resp_cb_data(resp_cb_data);
436 static void on_response_imc_modem_set_flight_mode(TcorePending *p,
437 guint data_len, const void *data, void *user_data)
439 const TcoreAtResponse *at_resp = data;
440 CoreObject *co = tcore_pending_ref_core_object(p);
441 ImcRespCbData *resp_cb_data = user_data;
444 TelModemResult result = TEL_MODEM_RESULT_FAILURE;
447 tcore_check_return_assert(co != NULL);
448 tcore_check_return_assert(resp_cb_data != NULL);
450 if (at_resp && at_resp->success){
452 result = TEL_MODEM_RESULT_SUCCESS;
455 result = __imc_modem_convert_cme_error_tel_modem_result(at_resp);
459 enable = (gboolean *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
461 dbg("Setting Modem Fiight mode - [%s] - [%s]",
462 (*enable ? "ON": "OFF"),
463 (result == TEL_MODEM_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
465 /* Update Core Object */
466 (void)tcore_modem_set_flight_mode_state(co, *enable);
469 /* Invoke callback */
470 if (resp_cb_data->cb)
471 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
473 /* Free callback data */
474 imc_destroy_resp_cb_data(resp_cb_data);
477 * In case Flight mode is set to OFF, we need to trigger
478 * Network Registration.
480 * This is taken care by Network module which hooks on
481 * Set Flight mode Request of Modem module.
485 /* Current modem does not support this operation */
487 static void on_response_imc_modem_get_version(TcorePending *p,
488 guint data_len, const void *data, void *user_data)
490 const TcoreAtResponse *at_resp = data;
491 CoreObject *co = tcore_pending_ref_core_object(p);
492 ImcRespCbData *resp_cb_data = user_data;
493 TelModemVersion version = {{0}, {0}, {0}, {0}};
495 TelModemResult result = TEL_MODEM_RESULT_FAILURE;
498 tcore_check_return_assert(co != NULL);
499 tcore_check_return_assert(resp_cb_data != NULL);
502 if (at_resp->lines) {
504 GSList *tokens = NULL;
506 line = (const gchar *)at_resp->lines->data;
507 tokens = tcore_at_tok_new(line);
508 if (g_slist_length(tokens) > 0) {
509 if (at_resp->success) {
510 gchar *sw_ver = NULL, *hw_ver = NULL;
511 gchar *calib_date = NULL, *p_code = NULL;
513 sw_ver = g_slist_nth_data(tokens, 0);
514 hw_ver = g_slist_nth_data(tokens, 1);
515 calib_date = g_slist_nth_data(tokens, 2);
516 p_code = g_slist_nth_data(tokens, 3);
518 g_strlcpy(version.software_version,
520 TEL_MODEM_VERSION_LENGTH_MAX + 1);
523 g_strlcpy(version.hardware_version,
525 TEL_MODEM_VERSION_LENGTH_MAX + 1);
527 if (calib_date != NULL){
528 g_strlcpy(version.calibration_date,
530 TEL_MODEM_VERSION_LENGTH_MAX + 1);
533 g_strlcpy(version.product_code,
535 TEL_MODEM_VERSION_LENGTH_MAX + 1);
537 dbg("Version - Software: [%s] Hardware: [%s] "
538 "Calibration date: [%s] Product "
539 "Code: [%s]", sw_ver, hw_ver,
542 result = TEL_MODEM_RESULT_SUCCESS;
544 err("RESPONSE - [NOK]");
545 err("[%s]", g_slist_nth_data(tokens, 0));
548 err("Invalid response message");
549 result = TEL_MODEM_RESULT_UNKNOWN_FAILURE;
551 tcore_at_tok_free(tokens);
555 /* Invoke callback */
556 if (resp_cb_data->cb)
557 resp_cb_data->cb(co, (gint)result, &version, resp_cb_data->cb_data);
559 /* Free callback data */
560 imc_destroy_resp_cb_data(resp_cb_data);
564 static void on_response_imc_modem_get_imei(TcorePending *p,
565 guint data_len, const void *data, void *user_data)
567 const TcoreAtResponse *at_resp = data;
568 CoreObject *co = tcore_pending_ref_core_object(p);
569 ImcRespCbData *resp_cb_data = user_data;
570 gchar imei[TEL_MODEM_IMEI_LENGTH_MAX +1] = {0};
572 TelModemResult result = TEL_MODEM_RESULT_FAILURE;
575 tcore_check_return_assert(co != NULL);
576 tcore_check_return_assert(resp_cb_data != NULL);
579 if (at_resp->lines) {
581 GSList *tokens = NULL;
583 line = (const gchar *)at_resp->lines->data;
584 tokens = tcore_at_tok_new(line);
585 if (g_slist_length(tokens) == 1) {
586 if (at_resp->success) {
587 dbg("RESPONSE - [OK]");
589 (const gchar *)g_slist_nth_data(tokens, 0),
590 TEL_MODEM_IMEI_LENGTH_MAX+1);
591 dbg("IMEI: [%s]", imei);
593 result = TEL_MODEM_RESULT_SUCCESS;
595 err("RESPONSE - [NOK]");
596 err("[%s]", g_slist_nth_data(tokens, 0));
597 result = __imc_modem_convert_cme_error_tel_modem_result(at_resp);
600 err("Invalid response message");
601 result = TEL_MODEM_RESULT_UNKNOWN_FAILURE;
603 tcore_at_tok_free(tokens);
607 /* Invoke callback */
608 if (resp_cb_data->cb)
609 resp_cb_data->cb(co, (gint)result, imei, resp_cb_data->cb_data);
611 /* Free callback data */
612 imc_destroy_resp_cb_data(resp_cb_data);
615 /* Modem Operations */
617 * Operation - set_power_status
620 * AT-Command: AT+CFUN=<fun>
623 * 0 Mode to switch off MS
624 * ... Other modes are available for other oprations
627 * Success: (No Result)
630 * +CME ERROR: <error>
632 static TelReturn imc_modem_set_power_status(CoreObject *co,
633 TelModemPowerStatus status,
634 TcoreObjectResponseCallback cb, void *cb_data)
639 ImcRespCbData *resp_cb_data;
642 if (status == TEL_MODEM_POWER_ON) {
643 warn("Modem Power ON - Not supported by CP");
644 return TEL_RETURN_OPERATION_NOT_SUPPORTED;
645 } else if (status == TEL_MODEM_POWER_ERROR) {
646 err("Modem Power ERROR - Invalid mode");
647 return TEL_RETURN_INVALID_PARAMETER;
649 dbg("Modem Power OFF");
654 at_cmd = g_strdup_printf("AT+CFUN=%d", power_mode);
656 /* Response callback data */
657 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
658 &status, sizeof(TelModemPowerStatus));
660 /* Send Request to modem */
661 ret = tcore_at_prepare_and_send_request(co,
663 TCORE_AT_COMMAND_TYPE_NO_RESULT,
665 on_response_imc_modem_set_power_status, resp_cb_data,
666 on_send_imc_request, NULL);
667 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Power Status");
676 * Operation - set_flight_mode
679 * AT-Command: AT+CFUN=<fun>
682 * 0 Mode to switch off MS
683 * 1 Full functionality
684 * 4 Mode to disable phone both transmit and receive
685 * RF circuits. Airplane mode.
686 * ... Other modes are available for other oprations
689 * Success: (No Result)
692 * +CME ERROR: <error>
694 static TelReturn imc_modem_set_flight_mode(CoreObject *co, gboolean enable,
695 TcoreObjectResponseCallback cb, void *cb_data)
700 ImcRespCbData *resp_cb_data;
704 dbg("Flight mode - [ON]");
707 dbg("Flight mode - [OFF]");
712 at_cmd = g_strdup_printf("AT+CFUN=%d", power_mode);
714 /* Response callback data */
715 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
716 &enable, sizeof(gboolean));
718 /* Send Request to modem */
719 ret = tcore_at_prepare_and_send_request(co,
721 TCORE_AT_COMMAND_TYPE_NO_RESULT,
723 on_response_imc_modem_set_flight_mode, resp_cb_data,
724 on_send_imc_request, NULL);
725 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Flight mode");
734 * Operation - get_flight_mode
738 * Fetch information from Core Object
740 * Response - flight_mode (gboolean)
742 static TelReturn imc_modem_get_flight_mode(CoreObject *co,
743 TcoreObjectResponseCallback cb, void *cb_data)
745 gboolean flight_mode;
747 /* Fetch Flight mode from Core Object */
748 (void)tcore_modem_get_flight_mode_state(co, &flight_mode);
749 dbg("Modem Flight mode - [%s]", (flight_mode ? "ON": "OFF"));
751 /* Invoke response callback */
753 cb(co, (gint)TEL_MODEM_RESULT_SUCCESS, &flight_mode, cb_data);
755 return TEL_RETURN_SUCCESS;
759 * Operation - get_version
762 * AT-Command: AT+CGMR
764 * Response - version (TelModemVersion)
765 * Success: (Single line) -
766 * <sw_ver>, <hw_ver>, <calib_date>, <p_code>
769 * Success Response is different from standard 3GPP AT-Command (+CGMR)
771 * +CME ERROR: <error>
773 static TelReturn imc_modem_get_version(CoreObject *co,
774 TcoreObjectResponseCallback cb, void *cb_data)
778 /* Current modem does not support this operation */
780 ImcRespCbData *resp_cb_data;
783 /* Response callback data */
784 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
787 /* Send Request to modem */
788 ret = tcore_at_prepare_and_send_request(co,
790 TCORE_AT_COMMAND_TYPE_SINGLELINE,
791 TCORE_PENDING_PRIORITY_DEFAULT,
793 on_response_imc_modem_get_version, resp_cb_data,
794 on_send_imc_request, NULL,
796 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Version");
802 return TEL_RETURN_OPERATION_NOT_SUPPORTED;
806 * Operation - get_imei
809 * AT-Command: AT+CGSN
811 * Response - imei (gchar array of length 20+'\0' bytes)
812 * Success: (Single line)
816 * +CME ERROR: <error>
818 static TelReturn imc_modem_get_imei(CoreObject *co,
819 TcoreObjectResponseCallback cb, void *cb_data)
821 ImcRespCbData *resp_cb_data;
826 /* Response callback data */
827 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
830 /* Send Request to modem */
831 ret = tcore_at_prepare_and_send_request(co,
833 TCORE_AT_COMMAND_TYPE_NUMERIC,
835 on_response_imc_modem_get_imei, resp_cb_data,
836 on_send_imc_request, NULL);
837 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get IMEI");
842 /* Modem Operations */
843 static TcoreModemOps imc_modem_ops = {
844 .set_power_status = imc_modem_set_power_status,
845 .set_flight_mode = imc_modem_set_flight_mode,
846 .get_flight_mode = imc_modem_get_flight_mode,
847 .get_version = imc_modem_get_version,
848 .get_imei = imc_modem_get_imei
851 gboolean imc_modem_init(TcorePlugin *p, CoreObject *co)
856 tcore_modem_set_ops(co, &imc_modem_ops);
859 tcore_object_add_callback(co, "+XDRVI:", on_event_imc_nvm_update, NULL);
865 void imc_modem_exit(TcorePlugin *p, CoreObject *co)
871 * NV Manager - Support for Remote File System
874 static gboolean __imc_nvm_modem_rfs_hook(const char *data)
877 if (data[NVM_FUNCTION_ID_OFFSET] == XDRV_INDICATION)
884 gboolean on_event_imc_nvm_update(CoreObject *co,
885 const void *event_info, void *user_data)
887 GSList *tokens = NULL;
895 lines = (GSList *)event_info;
897 dbg("Line: [%s]", line);
899 function_id = nvm_sum_4_bytes(&line[NVM_FUNCTION_ID_OFFSET]);
900 dbg("Function ID: [%d]", function_id);
901 if (IUFP_UPDATE == function_id) {
902 dbg("Calling process nvm_update");
905 * Process NV Update indication
907 * +XDRVI: IUFP_GROUP, IUFP_UPDATE, <xdrv_result>, <data>
909 if (NVM_NO_ERR == nvm_process_nv_update(line)) {
910 dbg("NV data processed successfully");
912 /* Acknowledge NV Update */
913 __imc_modem_send_nvm_update_ack(co);
917 err("NV data processing failed");
921 tokens = tcore_at_tok_new(line);
922 if (g_slist_length(tokens) < 3) {
923 err("XDRVI event with less number of tokens, Ignore!!!");
926 else if (IUFP_GROUP_ID != atoi(g_slist_nth_data(tokens, 0))) {
927 err("Group ID mismatch, Ignore!!!");
931 switch (atoi(g_slist_nth_data(tokens, 1))) {
932 case IUFP_UPDATE_REQ:
933 dbg("NV Update Request");
935 /* Acknowledge the Update Request */
936 __imc_modem_send_nvm_update_request_ack(co);
939 case IUFP_NO_PENDING_UPDATE:
940 dbg("NO pending NV Update(s)!!!");
941 /* Can send FLUSH request to get fresh updates */
945 err("Unspported Function ID [%d], Ignore", atoi(g_slist_nth_data(tokens, 1)));
950 tcore_at_tok_free(tokens);
958 void imc_modem_register_nvm(CoreObject *co)
963 /* Prepare AT-Command */
964 cmd_str = g_strdup_printf("AT+XDRV=%s, %s, %s",
965 IUFP_GROUP, IUFP_REGISTER_STR, XDRV_ENABLE);
967 /* Send Request to modem */
968 ret = tcore_at_prepare_and_send_request(co,
970 TCORE_AT_COMMAND_TYPE_SINGLELINE,
972 __on_response_modem_register_nvm, NULL,
973 on_send_imc_request, NULL);
974 if (ret != TEL_RETURN_SUCCESS) {
975 err("Failed to process request - [Register NVM]");
979 dbg("Adding NVM hook");
980 tcore_at_add_hook(tcore_object_get_hal(co), __imc_nvm_modem_rfs_hook);