Add basic change for v1453
Change-Id: I9497a61bbc3717f66413794a4e7dee0347c0bc33
diff --git a/mbtk/libql_lib_v2_rilv2/ql_sms.c b/mbtk/libql_lib_v2_rilv2/ql_sms.c
new file mode 100755
index 0000000..7323949
--- /dev/null
+++ b/mbtk/libql_lib_v2_rilv2/ql_sms.c
@@ -0,0 +1,660 @@
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @file ql_sms.h
+ @brief SMS service API.
+*/
+/*-----------------------------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------------------------------
+ Copyright (c) 2019 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
+ Quectel Wireless Solution Proprietary and Confidential.
+-------------------------------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------------------------------
+ EDIT HISTORY
+ This section contains comments describing changes made to the file.
+ Notice that changes are listed in reverse chronological order.
+ $Header: $
+ when who what, where, why
+ -------- --- ----------------------------------------------------------
+ 20200107 solomon.cui Add GSM-7bit and ISO 8859-1 conversion.
+ 20191225 solomon.cui Modify fucntion description.
+ 20191017 solomon.cui Free async reponse not user data.
+ 20190815 solomon.cui Add service type for sending message.
+ 20190627 solomon.cui Support asynchronously send msg and pdu
+ 20190625 solomon.cui Convert timestamp frome hex to dec.
+ 20190614 solomon.cui Created .
+-------------------------------------------------------------------------------------------------*/
+#include "mbtk_type.h"
+#include "mbtk_pdu_sms.h"
+#include "mbtk_ril_api.h"
+#include "mbtk_log.h"
+#include "ql_sms.h"
+#include "ql_type.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/epoll.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+
+#define MBTK_ERR_OK 0
+#define TELEPHONE_NUM_MAX 16
+#define MSM_NUMBER_MAX 2048+1
+#define RES_NUM_MIN 128
+#define TIME_ZONE_CN 32
+#define HAL_SMS_CONTENT_LEN 1024
+
+typedef struct {
+ mbtk_ril_handle* handle;
+ ql_sms_msg_recv_cb_f recv_cb;
+ ql_sms_service_error_cb_f server_cb;
+}ql_sms_info_handle_t;
+
+
+static ql_sms_info_handle_t* sms_handle = NULL;
+
+static void ql_sms_state_change_cb(const void* data, int data_len)
+{
+ LOGV("sms_state_change_cb()----------start\n");
+ mbtk_ril_sms_state_info_t *ptr = (mbtk_ril_sms_state_info_t *)data;
+
+ ql_sms_msg_t sms_msg;
+ ql_sms_timestamp_t sms_timestamp;
+ ql_sms_user_data_head_t sms_user_data_head;
+
+ memset(&sms_msg,0x00, sizeof(ql_sms_msg_t));
+ memset(&sms_timestamp,0x00, sizeof(ql_sms_timestamp_t));
+ memset(&sms_user_data_head,0x00, sizeof(ql_sms_user_data_head_t));
+
+ char smsc[MDAPI_MAX_PDU_SIZE] = {0};
+ char received_pdu[MDAPI_MAX_PDU_SIZE] = {0};
+ char msg[MDAPI_MAX_PDU_SIZE] = {0};
+ char num[MDAPI_MAX_PDU_SIZE] = {0};
+ uint8 year[8] = {0};
+ uint8 month[4] = {0};
+ uint8 day[4] = {0};
+ uint8 hour[4] = {0};
+ uint8 minutes[4]= {0};
+ uint8 seconds[4]= {0};
+ //char timezone[4] = {0};
+ char date[32] = {0};
+ int charset = 0;
+ int ret = -1;
+ int curr_pack = 1;
+ int total_pack = 1;
+ if(ptr == NULL)
+ {
+ LOGE("ptr is null");
+ }
+ LOGE("ptr: %s\n,data_len = %d\n", (char *)ptr->pdu, data_len);
+ if(data_len > MDAPI_MAX_PDU_SIZE)
+ {
+ strncpy(received_pdu, (const char *)ptr->pdu, MDAPI_MAX_PDU_SIZE-1);
+ }
+ else
+ {
+ strncpy(received_pdu, (const char *)ptr->pdu, data_len);
+ }
+ ret = smsPduDecode((const char *)received_pdu, data_len, num, smsc, msg, &charset, &curr_pack, &total_pack,date);
+ if(ret != 0)
+ {
+ LOGE("smsPduDecode fail ret: %d\n",ret);
+ return ;
+ }
+
+ LOGE("[EVENT][MT_SMS]PDU decode:smsc: %s\n, phone number: %s\ncharset: %d\n msg_len: %d\n message content: %s\n curr_pack: %d\n total_pack: %d\n date: %s", smsc, num, charset, strlen(msg), msg, curr_pack, total_pack, date);
+
+ sms_msg.format = charset;
+ memcpy(sms_msg.addr, num, strlen(num));
+ sms_msg.content_size = strlen(msg);
+ memcpy(sms_msg.content, msg, strlen(msg));
+
+ if(sscanf(date, "%4[^-]-%2[^-]-%2[^ ] %2[^:]:%2[^:]:%2s", year, month, day, hour, minutes, seconds)<=0)
+ {
+ LOGE("sscanf failed\n");
+ }
+
+ int tmp_year = atoi((char *)year);
+
+ sms_timestamp.year = tmp_year-2000;
+ sms_timestamp.month = atoi((char *)month);
+ sms_timestamp.day = atoi((char *)day);
+ sms_timestamp.hours = atoi((char *)hour);
+ sms_timestamp.minutes = atoi((char *)minutes);
+ sms_timestamp.seconds = atoi((char *)seconds);
+ sms_timestamp.timezone = TIME_ZONE_CN;
+
+ LOGE("Year: %d\n", sms_timestamp.year);
+ LOGE("Month: %d\n", sms_timestamp.month);
+ LOGE("Day: %d\n", sms_timestamp.day);
+ LOGE("Hour: %d\n", sms_timestamp.hours);
+ LOGE("Minute: %d\n", sms_timestamp.minutes);
+ LOGE("Second: %d\n", sms_timestamp.seconds);
+
+ if(total_pack > 1 && curr_pack < total_pack)
+ {
+ sms_user_data_head.valid = TRUE;
+ sms_user_data_head.total_seg = total_pack;
+ sms_user_data_head.cur_seg_num = curr_pack;
+ }
+ else
+ {
+ sms_user_data_head.valid = FALSE;
+ sms_user_data_head.total_seg = total_pack;
+ sms_user_data_head.cur_seg_num = curr_pack;
+ }
+
+ if(sms_handle->recv_cb)
+ {
+ sms_handle->recv_cb(&sms_msg, &sms_timestamp, &sms_user_data_head);
+ }
+
+}
+
+static void ql_sms_server_change_cb(const void* data, int data_len)
+{
+ if(data_len != sizeof(int))
+ {
+ LOGE("[ql_sms_server_change_cb] data_len[%d] than int[%d] fail. ", data_len, sizeof(int));
+ }
+ else
+ {
+ int server_state = *(int *)data;
+ if(server_state == 1 && sms_handle->server_cb)
+ {
+ sms_handle->server_cb(QL_ERR_ABORTED);
+ }
+ }
+}
+
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Initializes SMS service.
+ @return Whether the SMS service was initialized successfully.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_init(void)
+{
+ if(NULL == sms_handle)
+ {
+ sms_handle = (ql_sms_info_handle_t*)malloc(sizeof(ql_sms_info_handle_t));
+ if(NULL == sms_handle)
+ {
+ LOGE("[ql_sms_init] sms handle malloc fail.");
+ return QL_ERR_FAILED;
+ }
+
+ sms_handle->handle = mbtk_ril_open(MBTK_AT_PORT_DEF);
+ if(NULL == sms_handle->handle)
+ {
+ LOGE("[ql_sms_init] mbtk handle init fail.");
+ if(sms_handle)
+ {
+ free(sms_handle);
+ sms_handle = NULL;
+ return QL_ERR_FAILED;
+ }
+ }
+
+ int err = mbtk_sms_cnmi_set(sms_handle->handle);
+ if(err)
+ {
+ LOGE("set cnmi fail");
+ return QL_ERR_FAILED;
+ }
+
+ int ret = mbtk_sms_state_change_cb_reg( ql_sms_state_change_cb);
+ if(ret != MBTK_ERR_OK)
+ {
+ LOGE("[ql_sms_init] set sms state cb fail.[%d]", ret);
+ if(sms_handle->handle)
+ {
+ mbtk_ril_close(MBTK_AT_PORT_DEF);
+ sms_handle->handle = NULL;
+ return QL_ERR_FAILED;
+ }
+ }
+
+ ret = mbtk_net_reg_state_change_cb_reg(ql_sms_server_change_cb);
+ if(ret != MBTK_ERR_OK)
+ {
+ LOGE("[ql_sim_init] set sim server cb fail.[%d]", ret);
+ if(sms_handle->handle)
+ {
+ mbtk_ril_close(MBTK_AT_PORT_DEF);
+ sms_handle->handle = NULL;
+ return QL_ERR_FAILED;
+ }
+ }
+
+ sms_handle->recv_cb = NULL;
+ sms_handle->server_cb = NULL;
+ }
+
+ return QL_ERR_OK;
+
+}
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Deinitializes SMS service.
+ @return Whether the SMS service was deinitialized successfully.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_deinit(void)
+{
+ if(NULL == sms_handle)
+ {
+ LOGE("[ql_sms_deinit] sms handle not init.");
+ return QL_ERR_NOT_INIT;
+ }
+
+ int ret = 0;
+ sms_handle->server_cb = NULL;
+ sms_handle->recv_cb = NULL;
+
+ if(NULL != sms_handle->handle)
+ {
+ ret = mbtk_ril_close(MBTK_AT_PORT_DEF);
+ if(ret != MBTK_ERR_OK)
+ {
+ LOGE("[ql_sms_deinit] mbtk handle deinit fail.[%d]", ret);
+ return QL_ERR_FAILED;
+ }
+ sms_handle->handle = NULL;
+ }
+
+ if(ret != QL_ERR_OK)
+ {
+ LOGE("[ql_sms_deinit] cb thread free deinit fail.");
+ return QL_ERR_FAILED;
+ }
+
+ free(sms_handle);
+ sms_handle = NULL;
+ return QL_ERR_OK;
+
+}
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Sets the service center address.
+ @param[in] addr service center address.
+ @param[in] len service center address length.
+ @return Whether the service center address was set successfully.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_INVALID_ARG invalid argument.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_set_service_center_addr(char *addr, int len);
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Gets the service center address.
+ @param[out] addr service center address.
+ @param[in] len service center address length.
+ @return Whether the service center address was successfully obtained.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_INVALID_ARG invalid argument.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_get_service_center_addr(char *addr, int len);
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Sends message synchronously.
+ @param[in] p_msg pointer to ql_sms_msg_t.
+ @return Whether the message was successfully sent synchronously.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_INVALID_ARG invalid argument.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_send_msg(ql_sms_msg_t *p_msg);
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Sends message asynchronously.
+ @param[in] p_msg pointer to ql_sms_msg_t
+ @param[out] id id for this async operation
+ @param[in] cb async callback
+ @return Whether the message was successfully sent asynchronously.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_INVALID_ARG invalid argument.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_send_msg_async(ql_sms_msg_t *p_msg, int *id, ql_sms_msg_async_cb_f cb)
+{
+ if (NULL == sms_handle)
+ {
+ LOGE("handle NULL");
+ return QL_ERR_FAILED;
+ }
+
+ if (NULL == p_msg)
+ {
+ LOGE("p_msgt NULL");
+ return QL_ERR_FAILED;
+ }
+
+ if(NULL == id)
+ {
+ LOGE("id NULL");
+ return QL_ERR_FAILED;
+ }
+
+ int8 *phone_num = NULL;
+ int8 *msg = NULL;
+ int32 msg_len;
+
+ char cmgs[MSM_NUMBER_MAX] = {0};
+ char resp[RES_NUM_MIN] = {0};
+
+ char smscPDU[30] = {0};
+ char **pdu = NULL;
+ char smsc[4] = {0};
+ char msg_e_b[HAL_SMS_CONTENT_LEN] = {0};// +1 for end of string.*2:A char array contains two elements of a string for each value
+
+ int char_set = 0;
+ //int lsms_flag = 0;
+ int err = 0;
+ int i = 0;
+
+ msg = (int8 *)p_msg->content;
+
+ msg_len = strlen(p_msg->content);
+
+ phone_num = (int8 *)p_msg->addr;
+
+ if (p_msg->format == 0)//7
+ char_set = 0;
+ else if (p_msg->format == 1)//8
+ char_set = 1;
+ else if (p_msg->format == 2)//UCS2
+ char_set = 2;
+ else
+ {
+ LOGE("ql_sms_send_msg_async format error");
+ return QL_ERR_FAILED;
+ }
+
+ if(strcmp((char*)msg,"") == 0 || msg[0] == '\0')
+ {
+ LOGE("ql_sms_send_msg_async msg [%s]",msg);
+ return QL_ERR_FAILED;
+ }
+
+ if(strcmp((char*)phone_num,"") == 0 || phone_num[0] == '\0')
+ {
+ LOGE("ql_sms_send_msg_async phone_num [%s]",phone_num);
+ return QL_ERR_FAILED;
+ }
+
+ kal_int32 msg_num = 0;
+ kal_int32 pdu_msg_len = 0;
+ kal_int32 status = MDAPI_RET_ERROR;
+ kal_int32 index = 0;
+
+ if(char_set == 1) //8bit
+ {
+ ArrayToStr((unsigned char *)msg, (unsigned int)msg_len, msg_e_b);
+ status = _mdapi_sms_get_msg_num(msg_e_b, char_set, &msg_num, &pdu_msg_len);
+ }
+ else //7bit usc2
+ {
+ status = _mdapi_sms_get_msg_num((char *)msg, char_set, &msg_num, &pdu_msg_len);
+ }
+
+ LOGE("msg_len = [%d] ,msg_num=[%d]",msg_len, msg_num);
+ if(status == MDAPI_RET_ERROR)
+ {
+ LOGE("get message number failed");
+ return QL_ERR_FAILED;
+ }
+ else
+ {
+ //allocate memery for **pdu
+ pdu = (char **)malloc(sizeof(char *) * msg_num);
+ if(pdu == NULL)
+ {
+ LOGE("allocate memory for pdu failed");
+ return QL_ERR_FAILED;
+ }
+ else
+ {
+ for(index = 0; index < msg_num; index++)
+ {
+ pdu[index] = (char *)malloc(sizeof(char)*MAX_PDU_SIZE);
+ if(pdu[index] == NULL)
+ {
+ for(i = 0; i < index; i++)
+ {
+ free(pdu[i]);
+ pdu[i] = NULL;
+ }
+ free(pdu);
+ pdu = NULL;
+ LOGE("allocate memory for pdu[%d] failed",index);
+ return QL_ERR_FAILED;
+ }
+ else
+ {
+ memset(pdu[index], 0, MAX_PDU_SIZE);
+ LOGE("pdu[%d} init value is: %s ",index, pdu[index]);
+ }
+ }
+ }
+ }
+
+ //allocate memory for **pdu success
+ if(index == msg_num)
+ {
+ if(char_set == 1)//8bit
+ {
+ smsPduEncode(smsc, (char *)phone_num, msg_e_b, char_set, smscPDU, pdu);
+ }
+ else
+ {
+ smsPduEncode(smsc, (char *)phone_num, (char *)msg, char_set, smscPDU, pdu);
+ }
+ for(index = 0; index < msg_num; index++)
+ {
+ char pdu_data[MAX_PDU_SIZE] = {0};
+ char *p = pdu_data;
+
+ LOGE("index:%d",index);
+ LOGE("smscPDU: %s, pdu: %s",smscPDU, pdu[index]);
+ sprintf(p, "%s",smscPDU);
+ LOGE("pdu_data:%s\n", pdu_data);
+ int sc = strlen(pdu_data);
+ sprintf(p+strlen(p), "%s", pdu[index]);
+ LOGE("pdu_data:%s", pdu_data);
+
+ int t = strlen(pdu_data);
+ sprintf(cmgs, "%d,%s", (t-sc)/2, pdu_data);
+ LOGE("cmgs:%s\n", cmgs);
+ memset(resp, 0, sizeof(resp));
+
+ err = mbtk_sms_cmgf_set(sms_handle->handle, 0);
+ if(err)
+ {
+ LOGE("cmgf set error : %d", err);
+ for(index = 0; index < msg_num; index++){
+ free(pdu[index]);
+ pdu[index] = NULL;
+ }
+ free(pdu);
+ pdu = NULL;
+ return QL_ERR_FAILED;
+ }
+ else
+ {
+ LOGD("cmgf set success");
+ }
+
+ err = mbtk_sms_cmgs_set(sms_handle->handle, cmgs, resp);
+ if(err)
+ {
+ LOGE("cmgs send fail (%d)",err);
+ for(index = 0; index < msg_num; index++){
+ free(pdu[index]);
+ pdu[index] = NULL;
+ }
+ free(pdu);
+ pdu = NULL;
+ return QL_ERR_FAILED;
+ }
+ else
+ {
+ LOGD("cmgs send success, resp:%s", resp);
+ }
+
+ }
+ }
+
+ for(index = 0; index < msg_num; index++){
+ free(pdu[index]);
+ pdu[index] = NULL;
+ }
+ free(pdu);
+ pdu = NULL;
+
+ *id = 1;
+ cb(1, 1);
+
+ return QL_ERR_OK;
+}
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Sets SMS message reception callback hanlder.
+ @param[in] cb message reception callback handler.
+ @return Whether the message reception callback hanlder was set successfully.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_INVALID_ARG invalid argument.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_set_msg_recv_cb(ql_sms_msg_recv_cb_f cb)
+{
+ if(NULL == sms_handle)
+ {
+ LOGE("[ql_sms_set_msg_recv_cb] sms handle not init.");
+ return QL_ERR_NOT_INIT;
+ }
+
+ sms_handle->recv_cb = cb;
+
+ return QL_ERR_OK;
+
+}
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Sends PDU synchronously.
+ @param[in] p_pdu SMS PDU.
+ @return Whether the PDU was successfully sent synchronously.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_INVALID_ARG invalid argument.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_send_pdu(ql_sms_pdu_t *p_pdu);
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Sends PDU asynchronously.
+ @param[in] p_pdu sms pdu.
+ @param[out] id id for this async operation.
+ @param[in] cb async callback.
+ @return Whether the PDU was successfully sent asynchronously.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_INVALID_ARG invalid argument.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_send_pdu_async(ql_sms_pdu_t *p_pdu, int *id, ql_sms_pdu_async_cb_f cb);
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Sets SMS PDU reception callback hanlder.
+ @param[in] cb PDU reception callback handler.
+ @return Whether the PDU reception callback hanlder was set successfully.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_INVALID_ARG invalid argument.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_set_pdu_recv_cb(ql_sms_pdu_recv_cb_f cb);
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Registration server error callback. Currently, only if the server exits abnormally,
+ the callback function will be executed, and the error code is QL_ERR_ABORTED;
+ @param[in] cb Callback function
+ @return
+ QL_ERR_OK - successful
+ Other - error code defined by ql_type.h
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_set_service_error_cb(ql_sms_service_error_cb_f cb)
+{
+ if(NULL == sms_handle)
+ {
+ LOGE("[ql_sms_set_service_error_cb] sms handle not init.");
+ return QL_ERR_NOT_INIT;
+ }
+
+ sms_handle->server_cb = cb;
+
+ return QL_ERR_OK;
+}
+
+/*-----------------------------------------------------------------------------------------------*/
+/**
+ @brief Binds the current control point to a specific subscription.
+ @param[in] sub Subscription type.
+ @return Whether the subscription was successfully bound.
+ @retval QL_ERR_OK successful.
+ @retval QL_ERR_INVALID_ARG invalid argument.
+ @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
+ @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
+ @retval Other error code defined by ql_type.h.
+ */
+/*-----------------------------------------------------------------------------------------------*/
+int ql_sms_bind_subscription(QL_SMS_SUBSCRIPTION_E sub);
+