blob: 0b1d6e35ee2a1f253d8f624f7e5875aa53e8bf0f [file] [log] [blame]
/**
* \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)
{
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;
}