| /** |
| * \file mbtk_bs_position.c |
| * \brief A Documented file. |
| * |
| * Detailed description |
| * \Author: Sniper <js.wang@mobiletek.cn> |
| * \Version: 1.0.0 |
| * \Date: 2022-03-17 |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <strings.h> |
| #include <stdlib.h> |
| #include <errno.h> |
| #include <termios.h> |
| #include <unistd.h> |
| #include <fcntl.h> |
| #include <signal.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| #include <pthread.h> |
| #include <termios.h> |
| #include <sys/ioctl.h> |
| #include "mbtk_type.h" |
| #include <telephony/ril.h> |
| #include <telephony/ril_ext.h> |
| #include "rilutil.h" |
| #include "mbtk_log.h" |
| |
| #define RIL_UBUS_REQ "ril_request" |
| #define RIL_UBUS_ID "ril" |
| #define IMSI_SIZE 15 |
| |
| // #define DEBUG 1 |
| |
| #ifdef DEBUG |
| #define bs_log(...) printf(__VA_ARGS__) |
| #else |
| #define bs_log(...) |
| #endif |
| |
| struct bs_ril_cellinfo { |
| int type; |
| int mcc; |
| int mnc; |
| int lac; |
| int cid; |
| int reg_state; |
| }; |
| |
| struct mbtk_bs_ubus_t |
| { |
| struct ubus_context *ctx; |
| |
| /* RIL */ |
| struct ubus_subscriber ril_ind_event; |
| uint32_t ril_subscriber_id; |
| uint32_t ril_request_id; |
| pthread_t call_status_pthread; |
| struct bs_ril_cellinfo cellinfo; |
| }; |
| struct mbtk_bs_ubus_t *mbtk_bs_ubus = NULL; |
| static struct blob_buf b; |
| |
| static inline int radio_tech_2_act(int radio_tech) |
| { |
| switch(radio_tech) |
| { |
| case RADIO_TECH_GPRS: return 0; /* ACT could have been either 1 or 0 !! */ |
| case RADIO_TECH_UMTS: return 2; |
| case RADIO_TECH_EDGE: return 3; |
| case RADIO_TECH_HSDPA: return 4; |
| case RADIO_TECH_HSUPA: return 5; |
| case RADIO_TECH_HSPA: return 6; |
| case RADIO_TECH_LTE: return 7; |
| case RADIO_TECH_LTEP: return 7; /* temporary set it to 7, in future we may need to set to a number for 4G+ */ |
| case RADIO_TECH_HSPAP: return 8; |
| case RADIO_TECH_UNKNOWN: |
| default: break; |
| } |
| |
| return 0; |
| } |
| static void cellid_cb(void *response) |
| { |
| rilutilstrings *resp = NULL; |
| |
| resp = (rilutilstrings *) response; |
| bs_log("response num : %d\n", resp->num); |
| |
| sscanf(resp->str[0], "%d", &mbtk_bs_ubus->cellinfo.reg_state); |
| sscanf(resp->str[1], "%x", &mbtk_bs_ubus->cellinfo.lac); |
| sscanf(resp->str[2], "%x", &mbtk_bs_ubus->cellinfo.cid); |
| sscanf(resp->str[3], "%d", &mbtk_bs_ubus->cellinfo.type); /* converted ACT value */ |
| bs_log("cellinfo (%p): reg_state before=%d", |
| &mbtk_bs_ubus->cellinfo, |
| mbtk_bs_ubus->cellinfo.reg_state); |
| bs_log("lac:%x, cid:%x\n", |
| mbtk_bs_ubus->cellinfo.lac, |
| mbtk_bs_ubus->cellinfo.cid); |
| bs_log("reg_state:%d, lac:%d, cid:%d, type:%d\n", |
| mbtk_bs_ubus->cellinfo.reg_state, mbtk_bs_ubus->cellinfo.lac, |
| mbtk_bs_ubus->cellinfo.cid, mbtk_bs_ubus->cellinfo.type); |
| mbtk_bs_ubus->cellinfo.type = radio_tech_2_act(mbtk_bs_ubus->cellinfo.type); |
| // bs_log("mcc:%d, mnc:%d, type:%d\n", |
| // mbtk_bs_ubus->cellinfo.mcc, mbtk_bs_ubus->cellinfo.mnc, mbtk_bs_ubus->cellinfo.type); |
| bs_log("cellinfo (%p): reg_state=%d, lac=%d, cid=%d, type=%d, mcc=%d, mnc=%d\n", |
| &mbtk_bs_ubus->cellinfo, |
| mbtk_bs_ubus->cellinfo.reg_state, mbtk_bs_ubus->cellinfo.lac, mbtk_bs_ubus->cellinfo.cid, |
| mbtk_bs_ubus->cellinfo.type, mbtk_bs_ubus->cellinfo.mcc, mbtk_bs_ubus->cellinfo.mnc); |
| } |
| |
| |
| static void setid_cb(char *resp) |
| { |
| char mcc[4] = { 0 }, mnc[4] = { 0}; |
| char *imsi = NULL; |
| |
| imsi = malloc(IMSI_SIZE + 1); |
| if (!imsi) { |
| printf("Memory allocation failed\n"); |
| return; |
| } |
| memset(imsi, 0, IMSI_SIZE + 1); |
| /* update imsi and cellinfo mcc & mnc */ |
| strncpy(imsi, resp, IMSI_SIZE); |
| bs_log("imsi: %s\n", imsi); |
| memcpy(mcc, imsi, 3); |
| memcpy(mnc, (char *)imsi + 3, 2); |
| mbtk_bs_ubus->cellinfo.mcc = atoi(mcc); |
| mbtk_bs_ubus->cellinfo.mnc = atoi(mnc); |
| |
| bs_log("reg_stat, mcc:%d, mnc:%d, \n", |
| mbtk_bs_ubus->cellinfo.mcc, mbtk_bs_ubus->cellinfo.mnc); |
| free(imsi); |
| } |
| |
| static void bs_complete_cb(struct ubus_request *req, int ret) |
| { |
| bs_log("ubus_request = %08X\n", req); |
| free(req); |
| } |
| |
| static void bs_requset_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| unsigned int requestid = 0; |
| unsigned int rilerrno; |
| void *response = NULL; |
| int responselen = 0; |
| int ret = 0; |
| |
| ret = rilutil_parseResponse(msg, &requestid, &rilerrno, &response, &responselen); |
| if(ret) |
| { |
| fprintf(stderr, "parse blob error\n"); |
| goto done; |
| } |
| |
| if(rilerrno) |
| { |
| fprintf(stderr, "unsolicited id %d, error code %d\n", requestid, rilerrno); |
| goto done; |
| } |
| bs_log("requestid : %d\n", requestid); |
| if(requestid == RIL_REQUEST_GET_IMSI) |
| { |
| setid_cb((char *)response); |
| } |
| else if(requestid == RIL_REQUEST_DATA_REGISTRATION_STATE) |
| { |
| cellid_cb(response); |
| } |
| done: |
| if(response) |
| rilutil_freeResponseData(requestid, response, responselen); |
| |
| return; |
| } |
| |
| |
| int bs_get_cell_info(struct mbtk_bs_ubus_t *bs) |
| { |
| int ret_val; |
| struct ubus_request *req = NULL; |
| |
| if(!bs) { |
| printf("ril module not running\n"); |
| return 0; |
| } |
| blob_buf_init(&b, 0); |
| |
| rilutil_makeRequestBlob(&b, RIL_REQUEST_DATA_REGISTRATION_STATE, NULL, 0); |
| |
| req = (struct ubus_request *)malloc(sizeof(struct ubus_request)); |
| |
| if ((ret_val = |
| ubus_invoke_async(bs->ctx, bs->ril_request_id, RIL_UBUS_REQ, b.head, req)) != UBUS_STATUS_OK) { |
| printf("mubus_invoke_async failed\n"); |
| free(req); |
| return -1; |
| } else { |
| req->data_cb = bs_requset_cb; |
| req->complete_cb = bs_complete_cb; |
| ubus_complete_request_async(bs->ctx, req); |
| } |
| return 0; |
| } |
| |
| int bs_get_setid_info(struct mbtk_bs_ubus_t *bs) |
| { |
| int ret_val; |
| struct ubus_request *req = NULL; |
| |
| if(!bs) { |
| printf("ril module not running\n"); |
| return 0; |
| } |
| blob_buf_init(&b, 0); |
| |
| rilutil_makeRequestBlob(&b, RIL_REQUEST_GET_IMSI, NULL, 0); |
| |
| req = (struct ubus_request *)malloc(sizeof(struct ubus_request)); |
| |
| if ((ret_val = |
| ubus_invoke_async(bs->ctx, bs->ril_request_id, RIL_UBUS_REQ, b.head, req)) != UBUS_STATUS_OK) { |
| printf("mubus_invoke_async failed\n"); |
| free(req); |
| return -1; |
| } else { |
| req->data_cb = bs_requset_cb; |
| req->complete_cb = bs_complete_cb; |
| ubus_complete_request_async(bs->ctx, req); |
| } |
| return 0; |
| } |
| |
| static void bs_register_ril(void* hdl) |
| { |
| pthread_detach(pthread_self()); |
| uloop_run(); |
| bs_log("%s uloop_run!\n", __FUNCTION__); |
| pthread_exit(NULL); |
| } |
| |
| struct mbtk_bs_ubus_t *bs_ril_init(struct mbtk_bs_ubus_t *bs) |
| { |
| int ret; |
| |
| mbtk_bs_ubus = malloc(sizeof(struct mbtk_bs_ubus_t)); |
| if (!mbtk_bs_ubus) { |
| printf("memory allocation failed\n"); |
| return NULL; |
| } |
| |
| memset(mbtk_bs_ubus, 0, sizeof(*mbtk_bs_ubus)); |
| uloop_init(); |
| mbtk_bs_ubus->ctx = ubus_connect(NULL); |
| if(!mbtk_bs_ubus->ctx) |
| { |
| LOGE("Failed to connect to ubus"); |
| goto out_error; |
| } |
| |
| ubus_add_uloop(mbtk_bs_ubus->ctx); |
| if (ubus_lookup_id(mbtk_bs_ubus->ctx, RIL_UBUS_ID, &mbtk_bs_ubus->ril_request_id)) { |
| fprintf(stderr, "%s, Failed to look up test object\n", __FUNCTION__); |
| goto out_error; |
| } |
| |
| pthread_create(&mbtk_bs_ubus->call_status_pthread, NULL, (void *)bs_register_ril, NULL); |
| |
| return mbtk_bs_ubus; |
| |
| out_error: |
| free(mbtk_bs_ubus); |
| return NULL; |
| } |
| |
| int bs_ril_exit(struct mbtk_bs_ubus_t *bs) |
| { |
| int ret; |
| |
| if(!bs) { |
| printf("ril module not running\n"); |
| return 0; |
| } |
| |
| ret = pthread_cancel(bs->call_status_pthread); |
| pthread_join(bs->call_status_pthread, NULL); |
| do{ |
| ret = pthread_kill(bs->call_status_pthread, 0); |
| bs_log("kill pthread: %d \n", ret); |
| if(ret == ESRCH) |
| bs_log("The specified thread does not exist or has terminated\n"); |
| else if(ret == EINVAL) |
| printf("Useless signal\n"); |
| else |
| printf("The thread exists\n"); |
| usleep(100000); |
| }while(0 == ret); |
| |
| free(bs); |
| return 0; |
| } |
| int mbtk_bs_position(void) |
| { |
| struct mbtk_bs_ubus_t *bs_hdl; |
| bs_hdl = bs_ril_init(NULL); |
| bs_get_setid_info(bs_hdl); |
| bs_get_cell_info(bs_hdl); |
| |
| sleep(1); |
| bs_ril_exit(bs_hdl); |
| |
| return 0; |
| } |