blob: 0b1d6e35ee2a1f253d8f624f7e5875aa53e8bf0f [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001/**
2 * \file mbtk_bs_position.c
3 * \brief A Documented file.
4 *
5 * Detailed description
6 * \Author: Sniper <js.wang@mobiletek.cn>
7 * \Version: 1.0.0
8 * \Date: 2022-03-17
9 */
10
11#include <stdio.h>
12#include <string.h>
13#include <strings.h>
14#include <stdlib.h>
15#include <errno.h>
16#include <termios.h>
17#include <unistd.h>
18#include <fcntl.h>
19#include <signal.h>
20#include <sys/types.h>
21#include <unistd.h>
22#include <pthread.h>
23#include <termios.h>
24#include <sys/ioctl.h>
25#include "mbtk_type.h"
26#include <telephony/ril.h>
27#include <telephony/ril_ext.h>
28#include "rilutil.h"
29#include "mbtk_log.h"
30
31#define RIL_UBUS_REQ "ril_request"
32#define RIL_UBUS_ID "ril"
33#define IMSI_SIZE 15
34
35// #define DEBUG 1
36
37#ifdef DEBUG
38 #define bs_log(...) printf(__VA_ARGS__)
39#else
40 #define bs_log(...)
41#endif
42
43struct bs_ril_cellinfo {
44 int type;
45 int mcc;
46 int mnc;
47 int lac;
48 int cid;
49 int reg_state;
50};
51
52struct mbtk_bs_ubus_t
53{
54 struct ubus_context *ctx;
55
56 /* RIL */
57 struct ubus_subscriber ril_ind_event;
58 uint32_t ril_subscriber_id;
59 uint32_t ril_request_id;
60 pthread_t call_status_pthread;
61 struct bs_ril_cellinfo cellinfo;
62};
63struct mbtk_bs_ubus_t *mbtk_bs_ubus = NULL;
64static struct blob_buf b;
65
66static inline int radio_tech_2_act(int radio_tech)
67{
68 switch(radio_tech)
69 {
70 case RADIO_TECH_GPRS: return 0; /* ACT could have been either 1 or 0 !! */
71 case RADIO_TECH_UMTS: return 2;
72 case RADIO_TECH_EDGE: return 3;
73 case RADIO_TECH_HSDPA: return 4;
74 case RADIO_TECH_HSUPA: return 5;
75 case RADIO_TECH_HSPA: return 6;
76 case RADIO_TECH_LTE: return 7;
77 case RADIO_TECH_LTEP: return 7; /* temporary set it to 7, in future we may need to set to a number for 4G+ */
78 case RADIO_TECH_HSPAP: return 8;
79 case RADIO_TECH_UNKNOWN:
80 default: break;
81 }
82
83 return 0;
84}
85static void cellid_cb(void *response)
86{
87 rilutilstrings *resp = NULL;
88
89 resp = (rilutilstrings *) response;
90 bs_log("response num : %d\n", resp->num);
91
92 sscanf(resp->str[0], "%d", &mbtk_bs_ubus->cellinfo.reg_state);
93 sscanf(resp->str[1], "%x", &mbtk_bs_ubus->cellinfo.lac);
94 sscanf(resp->str[2], "%x", &mbtk_bs_ubus->cellinfo.cid);
95 sscanf(resp->str[3], "%d", &mbtk_bs_ubus->cellinfo.type); /* converted ACT value */
96 bs_log("cellinfo (%p): reg_state before=%d",
97 &mbtk_bs_ubus->cellinfo,
98 mbtk_bs_ubus->cellinfo.reg_state);
99 bs_log("lac:%x, cid:%x\n",
100 mbtk_bs_ubus->cellinfo.lac,
101 mbtk_bs_ubus->cellinfo.cid);
102 bs_log("reg_state:%d, lac:%d, cid:%d, type:%d\n",
103 mbtk_bs_ubus->cellinfo.reg_state, mbtk_bs_ubus->cellinfo.lac,
104 mbtk_bs_ubus->cellinfo.cid, mbtk_bs_ubus->cellinfo.type);
105 mbtk_bs_ubus->cellinfo.type = radio_tech_2_act(mbtk_bs_ubus->cellinfo.type);
106 // bs_log("mcc:%d, mnc:%d, type:%d\n",
107 // mbtk_bs_ubus->cellinfo.mcc, mbtk_bs_ubus->cellinfo.mnc, mbtk_bs_ubus->cellinfo.type);
108 bs_log("cellinfo (%p): reg_state=%d, lac=%d, cid=%d, type=%d, mcc=%d, mnc=%d\n",
109 &mbtk_bs_ubus->cellinfo,
110 mbtk_bs_ubus->cellinfo.reg_state, mbtk_bs_ubus->cellinfo.lac, mbtk_bs_ubus->cellinfo.cid,
111 mbtk_bs_ubus->cellinfo.type, mbtk_bs_ubus->cellinfo.mcc, mbtk_bs_ubus->cellinfo.mnc);
112}
113
114
115static void setid_cb(char *resp)
116{
117 char mcc[4] = { 0 }, mnc[4] = { 0};
118 char *imsi = NULL;
119
120 imsi = malloc(IMSI_SIZE + 1);
121 if (!imsi) {
122 printf("Memory allocation failed\n");
123 return;
124 }
125 memset(imsi, 0, IMSI_SIZE + 1);
126 /* update imsi and cellinfo mcc & mnc */
127 strncpy(imsi, resp, IMSI_SIZE);
128 bs_log("imsi: %s\n", imsi);
129 memcpy(mcc, imsi, 3);
130 memcpy(mnc, (char *)imsi + 3, 2);
131 mbtk_bs_ubus->cellinfo.mcc = atoi(mcc);
132 mbtk_bs_ubus->cellinfo.mnc = atoi(mnc);
133
134 bs_log("reg_stat, mcc:%d, mnc:%d, \n",
135 mbtk_bs_ubus->cellinfo.mcc, mbtk_bs_ubus->cellinfo.mnc);
136 free(imsi);
137}
138
139static void bs_complete_cb(struct ubus_request *req, int ret)
140{
141 bs_log("ubus_request = %08X\n", req);
142 free(req);
143}
144
145static void bs_requset_cb(struct ubus_request *req, int type, struct blob_attr *msg)
146{
147 unsigned int requestid = 0;
148 unsigned int rilerrno;
149 void *response = NULL;
150 int responselen = 0;
151 int ret = 0;
152
153 ret = rilutil_parseResponse(msg, &requestid, &rilerrno, &response, &responselen);
154 if(ret)
155 {
156 fprintf(stderr, "parse blob error\n");
157 goto done;
158 }
159
160 if(rilerrno)
161 {
162 fprintf(stderr, "unsolicited id %d, error code %d\n", requestid, rilerrno);
163 goto done;
164 }
165 bs_log("requestid : %d\n", requestid);
166 if(requestid == RIL_REQUEST_GET_IMSI)
167 {
168 setid_cb((char *)response);
169 }
170 else if(requestid == RIL_REQUEST_DATA_REGISTRATION_STATE)
171 {
172 cellid_cb(response);
173 }
174done:
175 if(response)
176 rilutil_freeResponseData(requestid, response, responselen);
177
178 return;
179}
180
181
182int bs_get_cell_info(struct mbtk_bs_ubus_t *bs)
183{
184 int ret_val;
185 struct ubus_request *req = NULL;
186
187 if(!bs) {
188 printf("ril module not running\n");
189 return 0;
190 }
191 blob_buf_init(&b, 0);
192
193 rilutil_makeRequestBlob(&b, RIL_REQUEST_DATA_REGISTRATION_STATE, NULL, 0);
194
195 req = (struct ubus_request *)malloc(sizeof(struct ubus_request));
196
197 if ((ret_val =
198 ubus_invoke_async(bs->ctx, bs->ril_request_id, RIL_UBUS_REQ, b.head, req)) != UBUS_STATUS_OK) {
199 printf("mubus_invoke_async failed\n");
200 free(req);
201 return -1;
202 } else {
203 req->data_cb = bs_requset_cb;
204 req->complete_cb = bs_complete_cb;
205 ubus_complete_request_async(bs->ctx, req);
206 }
207 return 0;
208}
209
210int bs_get_setid_info(struct mbtk_bs_ubus_t *bs)
211{
212 int ret_val;
213 struct ubus_request *req = NULL;
214
215 if(!bs) {
216 printf("ril module not running\n");
217 return 0;
218 }
219 blob_buf_init(&b, 0);
220
221 rilutil_makeRequestBlob(&b, RIL_REQUEST_GET_IMSI, NULL, 0);
222
223 req = (struct ubus_request *)malloc(sizeof(struct ubus_request));
224
225 if ((ret_val =
226 ubus_invoke_async(bs->ctx, bs->ril_request_id, RIL_UBUS_REQ, b.head, req)) != UBUS_STATUS_OK) {
227 printf("mubus_invoke_async failed\n");
228 free(req);
229 return -1;
230 } else {
231 req->data_cb = bs_requset_cb;
232 req->complete_cb = bs_complete_cb;
233 ubus_complete_request_async(bs->ctx, req);
234 }
235 return 0;
236}
237
238static void bs_register_ril(void* hdl)
239{
240 pthread_detach(pthread_self());
241 uloop_run();
242 bs_log("%s uloop_run!\n", __FUNCTION__);
243 pthread_exit(NULL);
244}
245
246struct mbtk_bs_ubus_t *bs_ril_init(struct mbtk_bs_ubus_t *bs)
247{
liubin281ac462023-07-19 14:22:54 +0800248
249 mbtk_bs_ubus = malloc(sizeof(struct mbtk_bs_ubus_t));
250 if (!mbtk_bs_ubus) {
251 printf("memory allocation failed\n");
252 return NULL;
253 }
254
255 memset(mbtk_bs_ubus, 0, sizeof(*mbtk_bs_ubus));
256 uloop_init();
257 mbtk_bs_ubus->ctx = ubus_connect(NULL);
258 if(!mbtk_bs_ubus->ctx)
259 {
260 LOGE("Failed to connect to ubus");
261 goto out_error;
262 }
263
264 ubus_add_uloop(mbtk_bs_ubus->ctx);
265 if (ubus_lookup_id(mbtk_bs_ubus->ctx, RIL_UBUS_ID, &mbtk_bs_ubus->ril_request_id)) {
266 fprintf(stderr, "%s, Failed to look up test object\n", __FUNCTION__);
267 goto out_error;
268 }
269
270 pthread_create(&mbtk_bs_ubus->call_status_pthread, NULL, (void *)bs_register_ril, NULL);
271
272 return mbtk_bs_ubus;
273
274out_error:
275 free(mbtk_bs_ubus);
276 return NULL;
277}
278
279int bs_ril_exit(struct mbtk_bs_ubus_t *bs)
280{
281 int ret;
282
283 if(!bs) {
284 printf("ril module not running\n");
285 return 0;
286 }
287
288 ret = pthread_cancel(bs->call_status_pthread);
289 pthread_join(bs->call_status_pthread, NULL);
290 do{
291 ret = pthread_kill(bs->call_status_pthread, 0);
292 bs_log("kill pthread: %d \n", ret);
293 if(ret == ESRCH)
294 bs_log("The specified thread does not exist or has terminated\n");
295 else if(ret == EINVAL)
296 printf("Useless signal\n");
297 else
298 printf("The thread exists\n");
299 usleep(100000);
300 }while(0 == ret);
301
302 free(bs);
303 return 0;
304}
305int mbtk_bs_position(void)
306{
307 struct mbtk_bs_ubus_t *bs_hdl;
308 bs_hdl = bs_ril_init(NULL);
309 bs_get_setid_info(bs_hdl);
310 bs_get_cell_info(bs_hdl);
311
312 sleep(1);
313 bs_ril_exit(bs_hdl);
314
315 return 0;
316}