高通9X07模块QMI架构使用入门

QMI(Qualcomm Message Interface) 高通用来替代OneRPC/DM的协议,用来与modem通信。
本文是摸索高通QMI机制一点经验,重点解读了如果建立拨号连接,仅供参考。qmi详细使用参考:高通QMI协议

1. QMI协议常用组件

  • DMS(设备管理Device Management)

    提供查询设备信息功能

    参考: qmi/device_management_service_v01.h

  • NAS(网络访问Network Access)

    提供网络管理功能

    参考:qmi/network_access_service_v01.h

  • WDS(数据连接)

    参考:qmi/wireless_data_service_v01.h

  • UIM(管理User Identity Module)

    提供查询UIM卡信息

    参考:qmi/user_identity_module_v01.h

  • CTL(控制服务)

    用户发起其他服务请求前,必须先申请 ClientID, 这个ID就是由控制服务分配的, 这个服务永远在线

    参考:qmi/control_service_v01.h

  • 数据(拨号服务)

    建立数据连接

    参考:data/qualcomm_mobile_access_point_msgr_v01.h

每个服务模块都定义了 请求响应通知Indication, 请求分为同步和异步,其中异步请求的结果通过indication通知。

2. QMI举例

越来越多9X07模块被用于物联网,那么首要解决的问题即建立数据连接,所以本文使用QMI建立数据网络连接示意。

2.1 QMI初始化及释放

9X07模块提供了qcmap_msgr服务来进行拨号,通过与dsi_netctrl对比,qcmap_msgr接口更清晰,而且操作也简单。

AP侧使用QMI架构和modem通信初始化流程是固定的:

qcmap_msgr_get_service_object_v01查询服务对象 =>

qmi_client_notifier_init初始化client通知信息 =>

qmi_client_get_service_list查询支持的服务列表个数 =>

qmi_client_get_service_list查询支持的服务列表信息 =>

qmi_client_init使用其中一个服务信息初始化client

参考代码:

 1 void qcmap_ppp_init(qcmap_ppp_t *self,client_status_ind_t client_cb_ind) {
 2     qmi_idl_service_object_type qcmap_msgr_qmi_idl_service_object;
 3     uint32_t num_services = 0, num_entries = 0;
 4     qmi_service_info info[10];
 5     qmi_client_error_type qmi_error, qmi_err_code = QMI_NO_ERR;
 6
 7     assert(self);
 8
 9     self->qcmap_msgr_enable = FALSE;
10     self->qmi_qcmap_msgr_handle = 0;
11     self->mobile_ap_handle = 0;
12
13     qcmap_msgr_qmi_idl_service_object = qcmap_msgr_get_service_object_v01;//when faild, add your trick for this~
14
15     if (qcmap_msgr_qmi_idl_service_object == NULL)
16     {
17         LOG("qcmap_msgr service object not available");
18         return;
19     }
20
21     qmi_error = qmi_client_notifier_init(qcmap_msgr_qmi_idl_service_object,
22                                         &self->qmi_qcmap_msgr_os_params,
23                                         &self->qmi_qcmap_msgr_notifier);
24     if (qmi_error < 0)
25     {
26         LOG("qmi_client_notifier_init(qcmap_msgr) returned %d", qmi_error);
27         return;
28     }
29
30     /* Check if the service is up, if not wait on a signal */
31     while(1)
32     {
33         qmi_error = qmi_client_get_service_list(qcmap_msgr_qmi_idl_service_object,
34                                                 NULL,
35                                                 NULL,
36                                                 &num_services);
37         LOG("qmi_client_get_service_list: %d",qmi_error);
38
39         if(qmi_error == QMI_NO_ERR)
40             break;
41         /* wait for server to come up */
42         QMI_CCI_OS_SIGNAL_WAIT(&self->qmi_qcmap_msgr_os_params, 0);
43     }
44
45     num_entries = num_services;
46
47     LOG("qmi_client_get_service_list: num_e %d num_s %d", num_entries, num_services);
48     /* The server has come up, store the information in info variable */
49     qmi_error = qmi_client_get_service_list(qcmap_msgr_qmi_idl_service_object,
50                                             info,
51                                             &num_entries,
52                                             &num_services);
53
54     LOG("qmi_client_get_service_list: num_e %d num_s %d error %d", num_entries, num_services, qmi_error);
55
56     if (qmi_error != QMI_NO_ERR)
57     {
58         qmi_client_release(self->qmi_qcmap_msgr_notifier);
59         self->qmi_qcmap_msgr_notifier = NULL;
60         LOG("Can not get qcmap_msgr service list %d",
61             qmi_error);
62         return;
63     }
64
65     qmi_error = qmi_client_init(&info[0],
66                                 qcmap_msgr_qmi_idl_service_object,
67                                 client_cb_ind,
68                                 NULL,
69                                 NULL,
70                                 &self->qmi_qcmap_msgr_handle);
71
72     LOG("qmi_client_init: %d", qmi_error);
73
74     if (qmi_error != QMI_NO_ERR)
75     {
76         qmi_client_release(self->qmi_qcmap_msgr_notifier);
77         self->qmi_qcmap_msgr_notifier = NULL;
78         LOG("Can not init qcmap_msgr client %d", qmi_error);
79         return;
80     }
81 }

对应释放过程比较简单,主要是释放client初始化信息:

 1 static void qcmap_ppp_uninit(qcmap_ppp_t *self) {
 2     qmi_client_error_type qmi_error;
 3     assert(self);
 4
 5     qmi_error = qmi_client_release(self->qmi_qcmap_msgr_notifier);
 6     self->qmi_qcmap_msgr_notifier = NULL;
 7
 8     if (qmi_error != QMI_NO_ERR)
 9     {
10         LOG("Can not release client qcmap notifier %d",qmi_error);
11     }
12
13     qmi_error = qmi_client_release(self->qmi_qcmap_msgr_handle);
14     self->qmi_qcmap_msgr_handle = NULL;
15
16     if (qmi_error != QMI_NO_ERR)
17     {
18         LOG("Can not release client qcmap handle %d",qmi_error);
19     }
20 }
2.2 建立/关闭拨号连接

建立拨号步骤:使能AP,连接服务

  • 使能ap
  1 /* Enable MobileAP */
  2 static boolean qcmap_ppp_enable(qcmap_ppp_t *self) {
  3     qmi_client_error_type qmi_error, qmi_err_code = QMI_NO_ERR;
  4     qcmap_msgr_mobile_ap_enable_resp_msg_v01 qcmap_enable_resp_msg_v01;
  5     qcmap_msgr_mobile_ap_status_ind_register_req_msg_v01 qcmap_mobile_ap_status_ind_reg;
  6     qcmap_msgr_wwan_status_ind_register_req_msg_v01 wwan_status_ind_reg;
  7     qcmap_msgr_station_mode_status_ind_register_req_msg_v01 qcmap_station_mode_status_ind_reg;
  8     qcmap_msgr_mobile_ap_status_ind_register_resp_msg_v01 qcmap_mobile_ap_status_ind_rsp;
  9     qcmap_msgr_wwan_status_ind_register_resp_msg_v01 wwan_status_ind_rsp;
 10     qcmap_msgr_station_mode_status_ind_register_resp_msg_v01 qcmap_station_mode_status_ind_rsp;
 11
 12     memset(&qcmap_enable_resp_msg_v01, 0, sizeof(qcmap_msgr_mobile_ap_enable_resp_msg_v01));
 13     memset(&wwan_status_ind_reg, 0, sizeof(qcmap_msgr_wwan_status_ind_register_req_msg_v01));
 14     memset(&wwan_status_ind_rsp, 0, sizeof(qcmap_msgr_wwan_status_ind_register_resp_msg_v01));
 15     wwan_status_ind_reg.register_indication = 1;
 16
 17     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
 18                                             QMI_QCMAP_MSGR_WWAN_STATUS_IND_REG_REQ_V01,
 19                                             (void*)&wwan_status_ind_reg,
 20                                             sizeof(qcmap_msgr_wwan_status_ind_register_req_msg_v01),
 21                                             (void*)&wwan_status_ind_rsp,
 22                                             sizeof(qcmap_msgr_wwan_status_ind_register_resp_msg_v01),
 23                                             QCMAP_MSGR_QMI_TIMEOUT_VALUE);
 24
 25     LOG("qmi_client_send_msg_sync: error %d result %d",
 26                     qmi_error, wwan_status_ind_rsp.resp.result);
 27
 28     if (( qmi_error == QMI_TIMEOUT_ERR ) ||
 29         ( qmi_error != QMI_NO_ERR ) ||
 30         ( wwan_status_ind_rsp.resp.result != QMI_NO_ERR ))
 31     {
 32         LOG("Can not register for wwan status %d : %d",
 33                     qmi_error, wwan_status_ind_rsp.resp.error);
 34         return FALSE;
 35     }
 36     LOG("Registered for wwan status");
 37
 38     memset(&qcmap_mobile_ap_status_ind_reg, 0, sizeof(qcmap_msgr_mobile_ap_status_ind_register_req_msg_v01));
 39     memset(&qcmap_mobile_ap_status_ind_rsp, 0, sizeof(qcmap_msgr_mobile_ap_status_ind_register_resp_msg_v01));
 40     qcmap_mobile_ap_status_ind_reg.register_indication = 1;
 41
 42     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
 43                                         QMI_QCMAP_MSGR_MOBILE_AP_STATUS_IND_REG_REQ_V01,
 44                                         (void*)&qcmap_mobile_ap_status_ind_reg,
 45                                         sizeof(qcmap_msgr_mobile_ap_status_ind_register_req_msg_v01),
 46                                         (void*)&qcmap_mobile_ap_status_ind_rsp,
 47                                         sizeof(qcmap_msgr_mobile_ap_status_ind_register_resp_msg_v01),
 48                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
 49
 50     LOG("qmi_client_send_msg_sync: error %d result %d",
 51                     qmi_error, qcmap_mobile_ap_status_ind_rsp.resp.result);
 52     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
 53         ( qmi_error != QMI_NO_ERR ) ||
 54         ( qcmap_mobile_ap_status_ind_rsp.resp.result != QMI_NO_ERR ))
 55     {
 56         LOG("Can not register for mobile ap status %d : %d",
 57                     qmi_error, qcmap_mobile_ap_status_ind_rsp.resp.error);
 58         return FALSE;
 59     }
 60     LOG("Registered for mobile ap status");
 61
 62     memset(&qcmap_station_mode_status_ind_reg, 0, sizeof(qcmap_msgr_station_mode_status_ind_register_req_msg_v01));
 63     memset(&qcmap_station_mode_status_ind_rsp, 0, sizeof(qcmap_msgr_station_mode_status_ind_register_resp_msg_v01));
 64     qcmap_station_mode_status_ind_reg.register_indication = 1;
 65
 66     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
 67                         QMI_QCMAP_MSGR_STATION_MODE_STATUS_IND_REG_REQ_V01,
 68                         (void*)&qcmap_station_mode_status_ind_reg,
 69                         sizeof(qcmap_msgr_station_mode_status_ind_register_req_msg_v01),
 70                         (void*)&qcmap_station_mode_status_ind_rsp,
 71                         sizeof(qcmap_msgr_station_mode_status_ind_register_resp_msg_v01),
 72                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
 73
 74     LOG("qmi_client_send_msg_sync: error %d result %d",
 75             qmi_error, qcmap_station_mode_status_ind_rsp.resp.result);
 76     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
 77         ( qmi_error != QMI_NO_ERR ) ||
 78         ( qcmap_station_mode_status_ind_rsp.resp.result != QMI_NO_ERR ))
 79     {
 80         LOG("Can not register for station mode indications %d : %d",
 81                     qmi_error, qcmap_station_mode_status_ind_rsp.resp.error);
 82         return FALSE;
 83     }
 84     LOG("Registered for station mode status");
 85
 86     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
 87                                         QMI_QCMAP_MSGR_MOBILE_AP_ENABLE_REQ_V01,
 88                                         NULL,
 89                                         0,
 90                                         (void*)&qcmap_enable_resp_msg_v01,
 91                                         sizeof(qcmap_msgr_mobile_ap_enable_resp_msg_v01),
 92                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
 93     LOG("qmi_client_send_msg_sync: error %d result %d valid %d",
 94                     qmi_error, qcmap_enable_resp_msg_v01.resp.result, qcmap_enable_resp_msg_v01.mobile_ap_handle_valid);
 95     if (( qmi_error == QMI_TIMEOUT_ERR ) ||
 96         ( qmi_error != QMI_NO_ERR ) ||
 97         ( qcmap_enable_resp_msg_v01.resp.result != QMI_NO_ERR) ||
 98         ( qcmap_enable_resp_msg_v01.mobile_ap_handle_valid != TRUE ))
 99     {
100         LOG("Can not enable qcmap %d : %d",
101             qmi_error, qcmap_enable_resp_msg_v01.resp.error);
102         return FALSE;
103     }
104
105     if( qcmap_enable_resp_msg_v01.mobile_ap_handle > 0 )
106     {
107         self->mobile_ap_handle = qcmap_enable_resp_msg_v01.mobile_ap_handle;
108         self->qcmap_msgr_enable = TRUE;
109         LOG("QCMAP Enabled\n");
110         return TRUE;
111     }
112     else
113     {
114         LOG("QCMAP Enable Failure\n");
115     }
116
117     return FALSE;
118 }
  • 去使能
/* Disable MobileAP */
static boolean qcmap_ppp_disable(qcmap_ppp_t *self) {
    qcmap_msgr_mobile_ap_disable_req_msg_v01 qcmap_disable_req_msg_v01;
    qcmap_msgr_mobile_ap_disable_resp_msg_v01 qcmap_disable_resp_msg_v01;
    qmi_client_error_type qmi_error = QMI_NO_ERR;

    if (!self->qcmap_msgr_enable)
    {
        /* QCMAP is not enabled */
        LOG("QCMAP not enabled\n");
        return FALSE;
    }

    qcmap_disable_req_msg_v01.mobile_ap_handle = self->mobile_ap_handle;
    qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
                                        QMI_QCMAP_MSGR_MOBILE_AP_DISABLE_REQ_V01,
                                        &qcmap_disable_req_msg_v01,
                                        sizeof(qcmap_msgr_mobile_ap_disable_req_msg_v01),
                                        &qcmap_disable_resp_msg_v01,
                                        sizeof(qcmap_msgr_mobile_ap_disable_resp_msg_v01),
                                        QCMAP_MSGR_QMI_TIMEOUT_VALUE);

    if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
        ( qmi_error != QMI_NO_ERR ) ||
        ( (qcmap_disable_resp_msg_v01.resp.error != QMI_ERR_NO_EFFECT_V01 &&
            qcmap_disable_resp_msg_v01.resp.error != QMI_ERR_NONE_V01)) ||
        ( qcmap_disable_resp_msg_v01.resp.result != QMI_NO_ERR ))
    {
        LOG( "Can not disable qcmap %d : %d",
            qmi_error, qcmap_disable_resp_msg_v01.resp.error);
        return FALSE;
    }

    /*.If backhaul is not connected, Mobileap will be disabled instantly. And since
        call back function is being called much before the response pending flag is set to TRUE,
        responses are not sent to the client.
        Hence, we set qcmap_disable_resp_msg_v01.resp.error to QMI_ERR_NO_EFFECT_V01
        So that the caller of this function sends a response back to the client. (Used for IoE 9x25)
        */
    if (qcmap_disable_resp_msg_v01.resp.error == QMI_ERR_NO_EFFECT_V01)
        LOG( "Already disable qcmap %d", qcmap_disable_resp_msg_v01.resp.error);

    self->mobile_ap_handle = 0;
    self->qcmap_msgr_enable = FALSE;
    return TRUE;
}
  • 连接服务
/* ConnectBackHaul */
static boolean qcmap_ppp_connect(qcmap_ppp_t *self) {
    int qcmap_msgr_errno;
    int ret = 0;
    qcmap_msgr_wwan_call_type_v01 call_type = QCMAP_MSGR_WWAN_CALL_TYPE_V4_V01;

    qcmap_msgr_bring_up_wwan_req_msg_v01 qcmap_bring_up_wwan_req_msg;
    qcmap_msgr_bring_up_wwan_resp_msg_v01 qcmap_bring_up_wwan_resp_msg;
    qmi_client_error_type qmi_error;

    /* Bring up the data call. */
    LOG("Bring up wwan");
    qcmap_bring_up_wwan_req_msg.mobile_ap_handle = self->mobile_ap_handle;
    qcmap_bring_up_wwan_req_msg.call_type_valid = TRUE;

    qcmap_bring_up_wwan_req_msg.call_type = call_type;

    qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
                                        QMI_QCMAP_MSGR_BRING_UP_WWAN_REQ_V01,
                                        &qcmap_bring_up_wwan_req_msg,
                                        sizeof(qcmap_msgr_bring_up_wwan_req_msg_v01),
                                        &qcmap_bring_up_wwan_resp_msg,
                                        sizeof(qcmap_msgr_bring_up_wwan_resp_msg_v01),
                                        QCMAP_MSGR_QMI_TIMEOUT_VALUE);

    if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
        ( qmi_error != QMI_NO_ERR ) ||
        ( qcmap_bring_up_wwan_resp_msg.resp.result != QMI_NO_ERR ) )
    {
    LOG("Can not bring up wwan qcmap %d : %d",
        qmi_error, qcmap_bring_up_wwan_resp_msg.resp.error);
    return FALSE;
    }
  /*
    If WWAN is already enabled, and we are trying to enable again from a different client,
    set error number to QMI_ERR_NO_EFFECT_V01, so that the correspondingclient can be
    informed. We hit this scenario in the following case:
    1. Start QCMAP_CLI and enable Backhaul.
    2. Start MCM_MOBILEAP_CLI and try enabling backhaul again.
    */
    if (call_type == QCMAP_MSGR_WWAN_CALL_TYPE_V4_V01 &&
        qcmap_bring_up_wwan_resp_msg.conn_status ==
        QCMAP_MSGR_WWAN_STATUS_CONNECTED_V01)
    {
    LOG("WWAN is already enabled.");
    }
    else if (call_type == QCMAP_MSGR_WWAN_CALL_TYPE_V6_V01 &&
        qcmap_bring_up_wwan_resp_msg.conn_status ==
        QCMAP_MSGR_WWAN_STATUS_IPV6_CONNECTED_V01)
    {
    LOG("IPv6 WWAN is already enabled.");
    }
    else
    LOG("Bringing up wwan...");
    return TRUE;
}
 
  • 断开服务
  1 /* DisconnectBackHual */
  2 static boolean qcmap_ppp_disconnect(qcmap_ppp_t *self) {
  3     qcmap_msgr_wwan_call_type_v01 call_type = QCMAP_MSGR_WWAN_CALL_TYPE_V4_V01;
  4
  5     qcmap_msgr_tear_down_wwan_req_msg_v01 qcmap_tear_down_wwan_req_msg;
  6     qcmap_msgr_tear_down_wwan_resp_msg_v01 qcmap_tear_down_wwan_resp_msg;
  7     qmi_client_error_type qmi_error;
  8
  9
 10     LOG("Bringing down wwan");
 11     qcmap_tear_down_wwan_req_msg.mobile_ap_handle = self->mobile_ap_handle;
 12
 13     qcmap_tear_down_wwan_req_msg.call_type_valid = TRUE;
 14
 15     qcmap_tear_down_wwan_req_msg.call_type = call_type;
 16
 17     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
 18                                         QMI_QCMAP_MSGR_TEAR_DOWN_WWAN_REQ_V01,
 19                                         &qcmap_tear_down_wwan_req_msg,
 20                                         sizeof(qcmap_msgr_tear_down_wwan_req_msg_v01),
 21                                         &qcmap_tear_down_wwan_resp_msg,
 22                                         sizeof(qcmap_msgr_tear_down_wwan_resp_msg_v01),
 23                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
 24
 25     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
 26         ( qmi_error != QMI_NO_ERR) ||
 27         ( qcmap_tear_down_wwan_resp_msg.resp.result != QMI_NO_ERR ) )
 28     {
 29     LOG("Can not tear down wwan qcmap %d : %d",
 30         qmi_error, qcmap_tear_down_wwan_resp_msg.resp.error);
 31     return FALSE;
 32     }
 33
 34     /*
 35         If WWAN is already disabled, and we are trying to disable again from a different client,
 36         set error number to QMI_ERR_NO_EFFECT_V01, so that the correspondingclient can be
 37         informed. We hit this scenario in the following case:
 38         1. Start QCMAP_CLI and enable Backhaul.
 39         2. Start MCM_MOBILEAP_CLI and try enabling backhaul again.
 40         3. Disable backhaul from the 1st client.
 41         4. Now from the 2nd client.
 42     */
 43     if (call_type == QCMAP_MSGR_WWAN_CALL_TYPE_V4_V01 &&
 44         qcmap_tear_down_wwan_resp_msg.conn_status ==
 45         QCMAP_MSGR_WWAN_STATUS_DISCONNECTED_V01)
 46     {
 47         LOG("WWAN is already disabled.");
 48     }
 49     else if (call_type == QCMAP_MSGR_WWAN_CALL_TYPE_V6_V01 &&
 50         qcmap_tear_down_wwan_resp_msg.conn_status ==
 51         QCMAP_MSGR_WWAN_STATUS_IPV6_DISCONNECTED_V01)
 52     {
 53         LOG("IPv6 WWAN is already disabled.");
 54     }
 55     else
 56         LOG("Tearing down wwan...");
 57     return TRUE;
 58 }
 59
 60 /* Get WWAN Statistics. */
 61 static boolean qcmap_ppp_get_statistics(qcmap_ppp_t *self, qcmap_msgr_ip_family_enum_v01 ip_family, qcmap_msgr_wwan_statistics_type_v01 *wwan_stats) {
 62     qcmap_msgr_get_wwan_stats_req_msg_v01 get_wwan_stats_req_msg;
 63     qcmap_msgr_get_wwan_stats_resp_msg_v01 get_wwan_stats_resp_msg;
 64     qmi_client_error_type qmi_error;
 65
 66
 67
 68     get_wwan_stats_req_msg.mobile_ap_handle = self->mobile_ap_handle;
 69     get_wwan_stats_req_msg.ip_family = ip_family;
 70
 71     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
 72                                         QMI_QCMAP_MSGR_GET_WWAN_STATS_REQ_V01,
 73                                         &get_wwan_stats_req_msg,
 74                                         sizeof(qcmap_msgr_get_wwan_stats_req_msg_v01),
 75                                         &get_wwan_stats_resp_msg,
 76                                         sizeof(qcmap_msgr_get_wwan_stats_resp_msg_v01),
 77                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
 78
 79     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
 80         ( qmi_error != QMI_NO_ERR ) ||
 81         ( get_wwan_stats_resp_msg.resp.result != QMI_NO_ERR ) )
 82     {
 83     LOG("Can not get wwan stats %d : %d",
 84         qmi_error, get_wwan_stats_resp_msg.resp.error);
 85     return FALSE;
 86     }
 87
 88     wwan_stats->bytes_rx = get_wwan_stats_resp_msg.wwan_stats.bytes_rx;
 89     wwan_stats->bytes_tx = get_wwan_stats_resp_msg.wwan_stats.bytes_tx;
 90     wwan_stats->pkts_rx = get_wwan_stats_resp_msg.wwan_stats.pkts_rx;
 91     wwan_stats->pkts_tx = get_wwan_stats_resp_msg.wwan_stats.pkts_tx;
 92     wwan_stats->pkts_dropped_rx = get_wwan_stats_resp_msg.wwan_stats.pkts_dropped_rx;
 93     wwan_stats->pkts_dropped_tx = get_wwan_stats_resp_msg.wwan_stats.pkts_dropped_tx;
 94     LOG("Get WWAN Stats succeeded...");
 95     return TRUE;
 96 }
 97
 98 /* Reset WWAN Statistics. */
 99 static boolean qcmap_ppp_reset_statistics(qcmap_ppp_t *self, qcmap_msgr_ip_family_enum_v01 ip_family) {
100     qcmap_msgr_reset_wwan_stats_req_msg_v01 reset_wwan_stats_req_msg;
101     qcmap_msgr_reset_wwan_stats_resp_msg_v01 reset_wwan_stats_resp_msg;
102     qmi_client_error_type qmi_error;
103
104
105
106     reset_wwan_stats_req_msg.mobile_ap_handle = self->mobile_ap_handle;
107     reset_wwan_stats_req_msg.ip_family = ip_family;
108
109     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
110                                         QMI_QCMAP_MSGR_RESET_WWAN_STATS_REQ_V01,
111                                         &reset_wwan_stats_req_msg,
112                                         sizeof(qcmap_msgr_reset_wwan_stats_req_msg_v01),
113                                         &reset_wwan_stats_resp_msg,
114                                         sizeof(qcmap_msgr_reset_wwan_stats_resp_msg_v01),
115                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
116
117     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
118         ( qmi_error != QMI_NO_ERR ) ||
119         ( reset_wwan_stats_resp_msg.resp.result != QMI_NO_ERR ) )
120     {
121         LOG("Can not reset wwan stats %d : %d",
122             qmi_error, reset_wwan_stats_resp_msg.resp.error);
123             return FALSE;
124     }
125
126     LOG("Reset WWAN Stats succeeded...");
127     return TRUE;
128 }
129
130 /* Enable/Disable Autoconnect mode */
131 static boolean qcmap_ppp_set_auto_connect(qcmap_ppp_t *self, boolean enable) {
132     qcmap_msgr_set_auto_connect_req_msg_v01 set_auto_connect_req_msg;
133     qcmap_msgr_set_auto_connect_resp_msg_v01 set_auto_connect_resp_msg;
134     qmi_client_error_type qmi_error;
135
136
137
138     set_auto_connect_req_msg.mobile_ap_handle = self->mobile_ap_handle;
139     set_auto_connect_req_msg.enable = enable;
140
141     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
142                                         QMI_QCMAP_MSGR_SET_AUTO_CONNECT_REQ_V01,
143                                         &set_auto_connect_req_msg,
144                                         sizeof(qcmap_msgr_set_auto_connect_req_msg_v01),
145                                         &set_auto_connect_resp_msg,
146                                         sizeof(qcmap_msgr_set_auto_connect_resp_msg_v01),
147                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
148     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
149         ( qmi_error != QMI_NO_ERR ) ||
150         ( set_auto_connect_resp_msg.resp.result != QMI_NO_ERR ) )
151     {
152     LOG("Can not set auto connect flag %d : %d",
153             qmi_error, set_auto_connect_resp_msg.resp.error);
154         return FALSE;
155     }
156
157     LOG("Auto Connect Mode Set succeeded...");
158     return TRUE;
159 }

至此,就可以完成拨号的连接和断开。

2.3 PPP状态

如果关注状态通知,需要处理知函数client_cb_ind中状态通知。主要包含了建立拨号成功/失败,网络状态变化(切换网络模式)的断开通知等。

 1 static void qcmap_ppp_ind(
 2     qmi_client_type user_handle,
 3     unsigned int msg_id,
 4     void *ind_buf,
 5     unsigned int ind_buf_len,
 6     void *ind_cb_data )
 7 {
 8     qmi_client_error_type qmi_error;
 9     LOG("qcmap_msgr_qmi_qcmap_ind: user_handle %X msg_id %d ind_buf_len %d.", user_handle, msg_id, ind_buf_len);
10 }
2.4 建立连接可选项
  • 禁用ipv6
 1 static boolean qcmap_ppp_disable_ipv6(qcmap_ppp_t *self) {
 2     int qcmap_msgr_errno;
 3     int ret = 0;
 4     qcmap_msgr_disable_ipv6_req_msg_v01 qcmap_disable_ipv6_req_msg;
 5     qcmap_msgr_disable_ipv6_resp_msg_v01 qcmap_disable_ipv6_resp_msg;
 6     qmi_client_error_type qmi_error;
 7
 8     /* Enable IPV6. */
 9     LOG("Disable IPV6");
10     qcmap_disable_ipv6_req_msg.mobile_ap_handle = self->mobile_ap_handle;
11
12     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
13                                         QMI_QCMAP_MSGR_DISABLE_IPV6_REQ_V01,
14                                         &qcmap_disable_ipv6_req_msg,
15                                         sizeof(qcmap_msgr_disable_ipv6_req_msg_v01),
16                                         &qcmap_disable_ipv6_resp_msg,
17                                         sizeof(qcmap_msgr_disable_ipv6_resp_msg_v01),
18                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
19
20     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
21         ( qmi_error != QMI_NO_ERR ) ||
22         ( qcmap_disable_ipv6_resp_msg.resp.result != QMI_NO_ERR ) )
23     {
24     LOG("Can not disable ipv6 %d : %d",
25         qmi_error, qcmap_disable_ipv6_resp_msg.resp.error);
26     return FALSE;
27     }
28
29     LOG("Disabled IPV6...");
30     return TRUE;
31 }
  • 配置自动连接(没测试出效果)
 1 /* Enable/Disable Autoconnect mode */
 2 static boolean qcmap_ppp_set_auto_connect(qcmap_ppp_t *self, boolean enable) {
 3     qcmap_msgr_set_auto_connect_req_msg_v01 set_auto_connect_req_msg;
 4     qcmap_msgr_set_auto_connect_resp_msg_v01 set_auto_connect_resp_msg;
 5     qmi_client_error_type qmi_error;
 6
 7
 8
 9     set_auto_connect_req_msg.mobile_ap_handle = self->mobile_ap_handle;
10     set_auto_connect_req_msg.enable = enable;
11
12     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
13                                         QMI_QCMAP_MSGR_SET_AUTO_CONNECT_REQ_V01,
14                                         &set_auto_connect_req_msg,
15                                         sizeof(qcmap_msgr_set_auto_connect_req_msg_v01),
16                                         &set_auto_connect_resp_msg,
17                                         sizeof(qcmap_msgr_set_auto_connect_resp_msg_v01),
18                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
19     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
20         ( qmi_error != QMI_NO_ERR ) ||
21         ( set_auto_connect_resp_msg.resp.result != QMI_NO_ERR ) )
22     {
23     LOG("Can not set auto connect flag %d : %d",
24             qmi_error, set_auto_connect_resp_msg.resp.error);
25         return FALSE;
26     }
27
28     LOG("Auto Connect Mode Set succeeded...");
29     return TRUE;
30 }
  • 查询wwan统计信息(流量)
 1 /* Get WWAN Status */
 2 static boolean qcmap_ppp_get_status(qcmap_ppp_t *self, qcmap_msgr_wwan_status_enum_v01 *v4_status, qcmap_msgr_wwan_status_enum_v01 *v6_status) {
 3     qmi_client_error_type qmi_error, qmi_err_code = QMI_NO_ERR;
 4     qcmap_msgr_wwan_status_req_msg_v01 wan_status_req;
 5     qcmap_msgr_wwan_status_resp_msg_v01 wan_status_resp;
 6
 7
 8     memset(&wan_status_resp, 0, sizeof(qcmap_msgr_wwan_status_resp_msg_v01));
 9     wan_status_req.mobile_ap_handle = self->mobile_ap_handle;
10     wan_status_req.call_type_valid = 1;
11     wan_status_req.call_type = QCMAP_MSGR_WWAN_CALL_TYPE_V4_V01;
12     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
13                                         QMI_QCMAP_MSGR_WWAN_STATUS_REQ_V01,
14                                         &wan_status_req,
15                                         sizeof(qcmap_msgr_wwan_status_req_msg_v01),
16                                         (void*)&wan_status_resp,
17                                         sizeof(qcmap_msgr_wwan_status_resp_msg_v01),
18                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
19
20     LOG("qmi_client_send_msg_sync(enable): error %d result %d",
21         qmi_error, wan_status_resp.resp.result);
22
23     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
24         ( qmi_error != QMI_NO_ERR ) ||
25         ( wan_status_resp.resp.result != QMI_NO_ERR ) )
26     {
27     LOG("Can not get IPV4 WAN status  %d : %d",
28         qmi_error, wan_status_resp.resp.error);
29     return FALSE;
30     }
31     if(wan_status_resp.conn_status_valid ==1)
32     {
33     *v4_status=wan_status_resp.conn_status;
34     if(wan_status_resp.conn_status == QCMAP_MSGR_WWAN_STATUS_CONNECTING_V01)
35     {
36         LOG(" IPV4 WWAN is Connecting \n");
37     }
38     else if(wan_status_resp.conn_status == QCMAP_MSGR_WWAN_STATUS_CONNECTED_V01)
39     {
40         LOG(" IPV4 WWAN is connected \n");
41     }
42     else if(wan_status_resp.conn_status == QCMAP_MSGR_WWAN_STATUS_DISCONNECTING_V01)
43     {
44         LOG(" IPV4 WWAN is Disconnecting \n");
45     }
46     else if(wan_status_resp.conn_status == QCMAP_MSGR_WWAN_STATUS_DISCONNECTED_V01)
47     {
48         LOG(" IPV4 WWAN is Disconnected \n");
49     }
50     }
51
52 #ifdef ENABLE_IPV6
53     memset(&wan_status_resp, 0, sizeof(qcmap_msgr_wwan_status_resp_msg_v01));
54     wan_status_req.mobile_ap_handle = self->mobile_ap_handle;
55     wan_status_req.call_type_valid = 1;
56     wan_status_req.call_type = QCMAP_MSGR_WWAN_CALL_TYPE_V6_V01;
57     qmi_error = qmi_client_send_msg_sync(self->qmi_qcmap_msgr_handle,
58                                         QMI_QCMAP_MSGR_WWAN_STATUS_REQ_V01,
59                                         &wan_status_req,
60                                         sizeof(qcmap_msgr_wwan_status_req_msg_v01),
61                                         (void*)&wan_status_resp,
62                                         sizeof(qcmap_msgr_wwan_status_resp_msg_v01),
63                                         QCMAP_MSGR_QMI_TIMEOUT_VALUE);
64
65     LOG("qmi_client_send_msg_sync(enable): error %d result %d",
66         qmi_error, wan_status_resp.resp.result);
67
68     if ( ( qmi_error == QMI_TIMEOUT_ERR ) ||
69         ( qmi_error != QMI_NO_ERR ) ||
70         ( wan_status_resp.resp.result != QMI_NO_ERR ) )
71     {
72         LOG("Can not get IPV6 WAN status %d : %d",
73             qmi_error, wan_status_resp.resp.error);
74         return FALSE;
75     }
76     if(wan_status_resp.conn_status_valid == 1)
77     {
78     *v6_status=wan_status_resp.conn_status;
79     if(wan_status_resp.conn_status == QCMAP_MSGR_WWAN_STATUS_IPV6_CONNECTING_V01)
80     {
81         LOG(" IPV6 WWAN is Connecting \n");
82     }
83     else if(wan_status_resp.conn_status == QCMAP_MSGR_WWAN_STATUS_IPV6_CONNECTED_V01)
84     {
85         LOG(" IPV6 WWAN is connected \n");
86     }
87     else if(wan_status_resp.conn_status == QCMAP_MSGR_WWAN_STATUS_IPV6_DISCONNECTING_V01)
88     {
89         LOG(" IPV6 WWAN is Disconnecting \n");
90     }
91     else if(wan_status_resp.conn_status == QCMAP_MSGR_WWAN_STATUS_IPV6_DISCONNECTED_V01)
92     {
93         LOG(" IPV6 WWAN is Disconnected \n");
94     }
95     }
96 #endif
97
98     return TRUE;
99 }

综上,基本用到的就这些接口了,比起直接使用高通提供的QCMAP_Client类接口,本文实现更原生、灵活,经过验证可以在国内多家9X07模块上正确稳定的执行。

3 其他组件服务功能

请自行研究实现,不做赘述了。

作者:LittleFat
链接:https://www.jianshu.com/p/82a8177b8299
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

原文地址:https://www.cnblogs.com/ricks/p/9968888.html

时间: 2024-11-05 23:26:58

高通9X07模块QMI架构使用入门的相关文章

高通要做ARM架构服务器芯片:进军服务器

高通作为世界最大的移动芯片制造商,不甘心在一个领域里当“独孤求败”,他们计划生产ARM架构的服务器芯片进军服务器芯片领域. 据eWeek报道,11月19日,高通CEO Steve Mollenkopf于纽约对外透露,公司的工程师们正在研究服务器芯片技术,他说:现在我们要带着一个重量级产品进军服务器领域. 除此之外,Mollenkopf并没有透露这个项目的时间进程和技术细节. 在进军服务器芯片领域的路上,高通一定会遇到劲敌英特尔,立博娱乐城而英特尔已经占领了这个市场总额的90%.另外,ARM架构的

【转】高通平台android 环境配置编译及开发经验总结

原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通开发板上烧录文件系统 建立高通平台开发环境 高通平台,android和 modem 编译流程分析 高通平台 7620 启动流程分析 qcril 流程分析,设置sim卡锁 python scons 语法学习 Python 语言之 scons 工具流程分析: 1.2 搭建高通平台环境开发环境 高通and

高通camera基本代码架构【转】

本文转载自:http://blog.sina.com.cn/s/blog_c0de2be70102vyn1.html 1  camera基本代码架构 高通平台对于camera的代码组织,大体上还是遵循Android的框架:即上层应用和HAL层交互,高通平台在HAL层里面实现自己的一套管理策略:在kernel中实现sensor的底层驱动.但是,对于最核心的sensor端的底层设置.ISP效果相关等代码则是单独进行了抽离,放在了一个 daemon进程中进行管理: 图1 Qualcomm平台camer

ARM Cortex-A7架构,高通210系列-MSM8909

核心板特性 A7架构 4核(4*1.1GHz(A7)) 产品尺寸小,便于客户集成,减少产品体积: 支持4G LTE超高速上网,单板兼容移动/联通/电信2G/3G/4G: 支持2+32存储器,Micro SD支持32G: 尺寸小.集成度高.大板布板灵活; 支持全网通.wifi.蓝牙.GPS; 支持 HD(1280*720) 接口丰富,可扩展性强 Sim 卡*2/MicroSD 卡*1/IIC*4/串口*2/USB(OTG)*1/3.5mm 耳机*1/GPIO *20/ADC*2/PWM*1 高通骁

2017最新技术java高级架构、千万高并发、分布式集群、架构师入门到精通视频教程

* { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战视频教程 视频课程包含: 高级Java架构师包含:Spring boot.Spring  cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat

高通QMI协议

QMI(Qualcomm MSM Interface,官方名称应该是Qualcomm Message Interface)是高通用来替代OneRPC/DM的协议,用来与modem通信. QMI协议定义了多个服务: DMS(设备管理Device Management) 提供载入 设备信息的功能 NAS(网络访问Network Access)提供欧冠你注册网络的动作 WDS(数据连接) PDS(GPS定位报告) UIM(管理User Identity Module) CTL(控制服务:用户发起其他服

高通平台MSM8916LCM模块移植(一)-bootloader部分【转】

本文转载自:http://www.mobile-open.com/2016/970947.html 高通平台中的bootloader叫做LK(Little Kernel,对于LCM来说LK部分相当重要,它不仅要负责开机部分的LCD显示任务,还要负责传参给kernel的LCM驱动,指导kernel选择合适的LCM参数. 1.LK中LCM启动流程 注:read_panel_id()和read_panel_id_ddr3()为私有添加,非高通库上代码. 在这个流程图中,需要着重了解的有oem_pane

浅谈编译高通android5.1源代码

为什么会编译高通5.1源代码,原因很简单,因为公司做高通平台的手机,所以有必要编译下 Linux基础学习篇 1.常用指令 ls 显示文件或目录 –l  列出文件详细信息 l(list)   –a   列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir 创建目录 -p 创建目录,若无父目录,则创建p(parent) cd 切换目录 touch 创建空文件 echo 创建带有内容的文件. cat 查看文件内容 cp 拷贝 mv 移动或重命名 rm 删除文件 -r 递归删除,可删除子目录

高通camera结构【转】

本文转载自:http://www.cnblogs.com/whw19818/p/5853407.html 摄像头基础介绍 一.摄像头结构和工作原理. 拍摄景物通过镜头,将生成的光学图像投射到传感器上,然后光学图像被转换成电信号,电信号再经过模数转换变为数字信号,数字信号经过DSP加工处理,再被送到电脑中进行处理,最终转换成手机屏幕上能够看到的图像. 数字信号处理芯片DSP(DIGITAL SIGNAL PROCESSING)功能:主要是通过一系列复杂的数学算法运算,对数字图像信号参数进行优化处理