1 #ifndef __QMI_THREAD_H__ 2 #define __QMI_THREAD_H__ 3 4 #define CONFIG_GOBINET 5 #define CONFIG_QMIWWAN 6 #define CONFIG_SIM 7 #define CONFIG_APN 8 #define CONFIG_VERSION 9 // #define CONFIG_SIGNALINFO 10 #define CONFIG_DEFAULT_PDP 1 11 //#define CONFIG_IMSI_ICCID 12 #define QUECTEL_UL_DATA_AGG 13 //#define QUECTEL_QMI_MERGE 14 15 #include <stdio.h> 16 #include <string.h> 17 #include <termios.h> 18 #include <stdio.h> 19 #include <ctype.h> 20 #include <time.h> 21 #include <fcntl.h> 22 #include <signal.h> 23 #include <errno.h> 24 #include <string.h> 25 #include <stdlib.h> 26 #include <unistd.h> 27 #include <errno.h> 28 #include <pthread.h> 29 #include <sys/types.h> 30 #include <sys/stat.h> 31 #include <sys/epoll.h> 32 #include <poll.h> 33 #include <sys/ioctl.h> 34 #include <sys/socket.h> 35 #include <stddef.h> 36 37 #include "MPQMI.h" 38 #include "MPQCTL.h" 39 #include "MPQMUX.h" 40 #include "util.h" 41 42 #define DEVICE_CLASS_UNKNOWN 0 43 #define DEVICE_CLASS_CDMA 1 44 #define DEVICE_CLASS_GSM 2 45 46 #define WWAN_DATA_CLASS_NONE 0x00000000 47 #define WWAN_DATA_CLASS_GPRS 0x00000001 48 #define WWAN_DATA_CLASS_EDGE 0x00000002 /* EGPRS */ 49 #define WWAN_DATA_CLASS_UMTS 0x00000004 50 #define WWAN_DATA_CLASS_HSDPA 0x00000008 51 #define WWAN_DATA_CLASS_HSUPA 0x00000010 52 #define WWAN_DATA_CLASS_LTE 0x00000020 53 #define WWAN_DATA_CLASS_5G_NSA 0x00000040 54 #define WWAN_DATA_CLASS_5G_SA 0x00000080 55 #define WWAN_DATA_CLASS_1XRTT 0x00010000 56 #define WWAN_DATA_CLASS_1XEVDO 0x00020000 57 #define WWAN_DATA_CLASS_1XEVDO_REVA 0x00040000 58 #define WWAN_DATA_CLASS_1XEVDV 0x00080000 59 #define WWAN_DATA_CLASS_3XRTT 0x00100000 60 #define WWAN_DATA_CLASS_1XEVDO_REVB 0x00200000 /* for future use */ 61 #define WWAN_DATA_CLASS_UMB 0x00400000 62 #define WWAN_DATA_CLASS_CUSTOM 0x80000000 63 64 struct wwan_data_class_str { 65 ULONG class; 66 CHAR *str; 67 }; 68 69 #pragma pack(push, 1) 70 71 typedef struct _QCQMIMSG { 72 QCQMI_HDR QMIHdr; 73 union { 74 QMICTL_MSG CTLMsg; 75 QMUX_MSG MUXMsg; 76 }; 77 } __attribute__ ((packed)) QCQMIMSG, *PQCQMIMSG; 78 79 typedef struct __IPV4 { 80 uint32_t Address; 81 uint32_t Gateway; 82 uint32_t SubnetMask; 83 uint32_t DnsPrimary; 84 uint32_t DnsSecondary; 85 uint32_t Mtu; 86 } IPV4_T; 87 88 typedef struct __IPV6 { 89 UCHAR Address[16]; 90 UCHAR Gateway[16]; 91 UCHAR SubnetMask[16]; 92 UCHAR DnsPrimary[16]; 93 UCHAR DnsSecondary[16]; 94 UCHAR PrefixLengthIPAddr; 95 UCHAR PrefixLengthGateway; 96 ULONG Mtu; 97 } IPV6_T; 98 99 typedef struct { 100 UINT size; 101 UINT rx_urb_size; 102 UINT ep_type; 103 UINT iface_id; 104 UINT MuxId; 105 UINT ul_data_aggregation_max_datagrams; //0x17 106 UINT ul_data_aggregation_max_size ;//0x18 107 UINT dl_minimum_padding; //0x1A 108 } QMAP_SETTING; 109 110 //Configured downlink data aggregationprotocol 111 #define WDA_DL_DATA_AGG_DISABLED (0x00) //DL data aggregation is disabled (default) 112 #define WDA_DL_DATA_AGG_TLP_ENABLED (0x01) // DL TLP is enabled 113 #define WDA_DL_DATA_AGG_QC_NCM_ENABLED (0x02) // DL QC_NCM isenabled 114 #define WDA_DL_DATA_AGG_MBIM_ENABLED (0x03) // DL MBIM isenabled 115 #define WDA_DL_DATA_AGG_RNDIS_ENABLED (0x04) // DL RNDIS is enabled 116 #define WDA_DL_DATA_AGG_QMAP_ENABLED (0x05) // DL QMAP isenabled 117 #define WDA_DL_DATA_AGG_QMAP_V2_ENABLED (0x06) // DL QMAP V2 is enabled 118 #define WDA_DL_DATA_AGG_QMAP_V3_ENABLED (0x07) // DL QMAP V3 is enabled 119 #define WDA_DL_DATA_AGG_QMAP_V4_ENABLED (0x08) // DL QMAP V4 is enabled 120 #define WDA_DL_DATA_AGG_QMAP_V5_ENABLED (0x09) // DL QMAP V5 is enabled 121 122 typedef struct { 123 unsigned int size; 124 unsigned int rx_urb_size; 125 unsigned int ep_type; 126 unsigned int iface_id; 127 unsigned int qmap_mode; 128 unsigned int qmap_version; 129 unsigned int dl_minimum_padding; 130 char ifname[8][16]; 131 unsigned char mux_id[8]; 132 } RMNET_INFO; 133 134 #define IpFamilyV4 (0x04) 135 #define IpFamilyV6 (0x06) 136 137 struct __PROFILE; 138 struct qmi_device_ops { 139 int (*init)(struct __PROFILE *profile); 140 int (*deinit)(void); 141 int (*send)(PQCQMIMSG pRequest); 142 void* (*read)(void *pData); 143 }; 144 extern const struct qmi_device_ops gobi_qmidev_ops; 145 extern const struct qmi_device_ops qmiwwan_qmidev_ops; 146 extern const struct qmi_device_ops mbim_dev_ops; 147 extern const struct qmi_device_ops atc_dev_ops; 148 extern int (*qmidev_send)(PQCQMIMSG pRequest); 149 150 struct usb_device_info { 151 int idVendor; 152 int idProduct; 153 int busnum; 154 int devnum; 155 int bNumInterfaces; 156 }; 157 158 struct usb_interface_info { 159 int bNumEndpoints; 160 int bInterfaceClass; 161 int bInterfaceSubClass; 162 int bInterfaceProtocol; 163 char driver[32]; 164 }; 165 166 #define LIBQMI_PROXY "qmi-proxy" //src/libqmi-glib/qmi-proxy.h 167 #define LIBMBIM_PROXY "mbim-proxy" 168 #define QUECTEL_QMI_PROXY "quectel-qmi-proxy" 169 #define QUECTEL_MBIM_PROXY "quectel-mbim-proxy" 170 171 #ifndef bool 172 #define bool uint8_t 173 #endif 174 struct request_ops; 175 typedef struct __PROFILE { 176 char qmichannel[32]; 177 char usbnet_adapter[32]; 178 char qmapnet_adapter[32]; 179 char driver_name[32]; 180 int qmap_mode; 181 int qmap_size; 182 int qmap_version; 183 const char *apn; 184 const char *user; 185 const char *password; 186 const char *pincode; 187 char proxy[32]; 188 int auth; 189 int pdp; 190 int curIpFamily; 191 int rawIP; 192 int muxid; 193 int enable_bridge; 194 int wda_client; 195 IPV4_T ipv4; 196 IPV6_T ipv6; 197 UINT PCSCFIpv4Addr1; 198 UINT PCSCFIpv4Addr2; 199 UCHAR PCSCFIpv6Addr1[16]; 200 UCHAR PCSCFIpv6Addr2[16]; 201 bool enable_ipv4; 202 bool enable_ipv6; 203 int apntype; 204 bool reattach_flag; 205 int hardware_interface; 206 int software_interface; 207 208 struct usb_device_info usb_dev; 209 struct usb_interface_info usb_intf; 210 211 int usbmon_fd; 212 FILE *usbmon_logfile_fp; 213 bool loopback_state; 214 int replication_factor; 215 216 char BaseBandVersion[64]; 217 218 const struct qmi_device_ops *qmi_ops; 219 const struct request_ops *request_ops; 220 RMNET_INFO rmnet_info; 221 } PROFILE_T; 222 223 #ifdef QUECTEL_QMI_MERGE 224 #define MERGE_PACKET_IDENTITY 0x2c7c 225 #define MERGE_PACKET_VERSION 0x0001 226 #define MERGE_PACKET_MAX_PAYLOAD_SIZE 56 227 typedef struct __QMI_MSG_HEADER { 228 uint16_t idenity; 229 uint16_t version; 230 uint16_t cur_len; 231 uint16_t total_len; 232 } QMI_MSG_HEADER; 233 234 typedef struct __QMI_MSG_PACKET { 235 QMI_MSG_HEADER header; 236 uint16_t len; 237 char buf[4096]; 238 } QMI_MSG_PACKET; 239 #endif 240 241 typedef enum { 242 SIM_ABSENT = 0, 243 SIM_NOT_READY = 1, 244 SIM_READY = 2, /* SIM_READY means the radio state is RADIO_STATE_SIM_READY */ 245 SIM_PIN = 3, 246 SIM_PUK = 4, 247 SIM_NETWORK_PERSONALIZATION = 5, 248 SIM_BAD = 6, 249 } SIM_Status; 250 251 #pragma pack(pop) 252 253 #define WDM_DEFAULT_BUFSIZE 256 254 #define RIL_REQUEST_QUIT 0x1000 255 #define RIL_INDICATE_DEVICE_CONNECTED 0x1002 256 #define RIL_INDICATE_DEVICE_DISCONNECTED 0x1003 257 #define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 0x1004 258 #define RIL_UNSOL_DATA_CALL_LIST_CHANGED 0x1005 259 #define MODEM_REPORT_RESET_EVENT 0x1006 260 #define RIL_UNSOL_LOOPBACK_CONFIG_IND 0x1007 261 262 extern pthread_mutex_t cm_command_mutex; 263 extern pthread_cond_t cm_command_cond; 264 extern unsigned int cm_recv_buf[1024]; 265 extern int cm_open_dev(const char *dev); 266 extern int cm_open_proxy(const char *name); 267 extern int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t * mutex, unsigned msecs); 268 extern int QmiThreadSendQMITimeout(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse, unsigned msecs, const char *funcname); 269 #define QmiThreadSendQMI(pRequest, ppResponse) QmiThreadSendQMITimeout(pRequest, ppResponse, 30 * 1000, __func__) 270 extern void QmiThreadRecvQMI(PQCQMIMSG pResponse); 271 extern void udhcpc_start(PROFILE_T *profile); 272 extern void udhcpc_stop(PROFILE_T *profile); 273 extern void ql_set_driver_link_state(PROFILE_T *profile, int link_state); 274 extern void ql_set_driver_qmap_setting(PROFILE_T *profile, QMAP_SETTING *qmap_settings); 275 extern void ql_get_driver_rmnet_info(PROFILE_T *profile, RMNET_INFO *rmnet_info); 276 extern void dump_qmi(void *dataBuffer, int dataLen); 277 extern void qmidevice_send_event_to_main(int triger_event); 278 extern void qmidevice_send_event_to_main_ext(int triger_event, void *data, unsigned len); 279 280 struct request_ops { 281 int (*requestBaseBandVersion)(PROFILE_T *profile); 282 int (*requestSetEthMode)(PROFILE_T *profile); 283 int (*requestSetLoopBackState)(UCHAR loopback_state, ULONG replication_factor); 284 int (*requestGetSIMStatus)(SIM_Status *pSIMStatus); 285 int (*requestEnterSimPin)(const CHAR *pPinCode); 286 int (*requestSetProfile)(PROFILE_T *profile) ; 287 int (*requestGetProfile)(PROFILE_T *profile); 288 int (*requestRegistrationState)(UCHAR *pPSAttachedState); 289 int (*requestSetupDataCall)(PROFILE_T *profile, int curIpFamily); 290 int (*requestQueryDataCall)(UCHAR *pConnectionStatus, int curIpFamily); 291 int (*requestDeactivateDefaultPDP)(PROFILE_T *profile, int curIpFamily); 292 int (*requestGetIPAddress)(PROFILE_T *profile, int curIpFamily); 293 int (*requestGetSignalInfo)(void); 294 int (*requestGetICCID)(void); 295 int (*requestGetIMSI)(void); 296 }; 297 extern const struct request_ops qmi_request_ops; 298 extern const struct request_ops mbim_request_ops; 299 extern const struct request_ops atc_request_ops; 300 301 extern int get_driver_type(PROFILE_T *profile); 302 extern BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize, PROFILE_T *profile); 303 int mhidevice_detect(char *qmichannel, char *usbnet_adapter, PROFILE_T *profile); 304 extern int ql_bridge_mode_detect(PROFILE_T *profile); 305 extern int ql_enable_qmi_wwan_rawip_mode(PROFILE_T *profile); 306 extern int ql_qmap_mode_detect(PROFILE_T *profile); 307 308 #define qmidev_is_gobinet(_qmichannel) (strncmp(_qmichannel, "/dev/qcqmi", strlen("/dev/qcqmi")) == 0) 309 #define qmidev_is_qmiwwan(_qmichannel) (strncmp(_qmichannel, "/dev/cdc-wdm", strlen("/dev/cdc-wdm")) == 0) 310 #define qmidev_is_pciemhi(_qmichannel) (strncmp(_qmichannel, "/dev/mhi_", strlen("/dev/mhi_")) == 0) 311 312 #define driver_is_qmi(_drv_name) (strncasecmp(_drv_name, "qmi_wwan", strlen("qmi_wwan")) == 0) 313 #define driver_is_mbim(_drv_name) (strncasecmp(_drv_name, "cdc_mbim", strlen("cdc_mbim")) == 0) 314 315 extern FILE *logfilefp; 316 extern int debug_qmi; 317 extern int qmidevice_control_fd[2]; 318 extern USHORT le16_to_cpu(USHORT v16); 319 extern UINT le32_to_cpu (UINT v32); 320 extern UINT ql_swap32(UINT v32); 321 extern USHORT cpu_to_le16(USHORT v16); 322 extern UINT cpu_to_le32(UINT v32); 323 extern void update_resolv_conf(int iptype, const char *ifname, const char *dns1, const char *dns2); 324 void update_ipv4_address(const char *ifname, const char *ip, const char *gw, unsigned prefix); 325 void update_ipv6_address(const char *ifname, const char *ip, const char *gw, unsigned prefix); 326 int reattach_driver(PROFILE_T *profile); 327 328 enum 329 { 330 DRV_INVALID, 331 SOFTWARE_QMI, 332 SOFTWARE_MBIM, 333 SOFTWARE_ECM_RNDIS_NCM, 334 HARDWARE_PCIE, 335 HARDWARE_USB, 336 }; 337 338 enum 339 { 340 SIG_EVENT_START, 341 SIG_EVENT_CHECK, 342 SIG_EVENT_STOP, 343 }; 344 345 #ifdef CM_DEBUG 346 #define dbg_time(fmt, args...) do { \ 347 fprintf(stdout, "[%15s-%04d: %s] " fmt "\n", __FILE__, __LINE__, get_time(), ##args); \ 348 if (logfilefp) fprintf(logfilefp, "[%s-%04d: %s] " fmt "\n", __FILE__, __LINE__, get_time(), ##args); \ 349 } while(0) 350 #else 351 #define dbg_time(fmt, args...) do { \ 352 fprintf(stdout, "[%s] " fmt "\n", get_time(), ##args); \ 353 if (logfilefp) fprintf(logfilefp, "[%s] " fmt "\n", get_time(), ##args); \ 354 } while(0) 355 #endif 356 #endif 357