Admin
Администратор
Сканер LTE/UMTS/GSM
Что это такое?Компактный прибор, позволяющий получать информацию о ближайших базовых станциях сотовой связи:
- частота и канал связи (arfcn)
- идентификаторы базовой станции - CellId, Location AreaCode, PCI,...
- служебную информацию - CellReselection Offset, Hysteresis, RXlam,...
- в 2G - списки соседних станций (neighbour cell list)
Зачем это нужно?
"Белое" применение:
- исследование покрытия сотовой сети. Выявление "проблемных" зон с низким уровнем сигнала или "перекрывающимися" секторами сот. Бюджетный аналог систем ROMES, TEMS, NEMO и др.
- определение соты и оператора с наиболее сильным сигналом - для монтажа "сотового интернета на даче", выбора правильного тарифного плана, определение направления на ближайшую базовую станцию
- измерение уровня сигнала при наведении/юстировки антенны модема (см предыдущий пункт)
- Обнаружение IMSI-Catcher'ов. Поиск "мест обитания" стационарных IMSI-Catcher'ов
- Если Вы обнаруживаете IMSI Catcher рядом со своим домом или местом работы - знайте, что за вами следят или хотят подставить, и это совсем уже не параноя
- Радио-разведка, построение актуальной карты расположения вышек сотовой сети для последующего использования данной информации в целях геолокации при подавлении GPS
- выдача частот для настройки редиректора LTE->2G
- выдача частот, коэффициентов и "цветов" БС для настройки 2G BTS
- выдача частот для работы пассивного комплекса перехвата моб.связи
- CatchInRide - непрерывное сканирование сети и перестройка параметров IMSI Cather'а "на ходу" для возможности работы в движении
Конечно, существуют специальные модифицированные (как программно, так и иногда-аппаратно) телефоны, позволяющие показывать списки сот. Нельзя сказать что лучше или хуже.
| Телефон + Компактность. Можно носить всегда с собой. + Не привлекает внимание + Цена "железа", доступность | ДЕВАЙС + Работает на всех частотных диапазонах. Легко добавить нужные Band'ы при необходимости. + Простота управления внешними устройствами, большой набор интерфейсов + opensource, позволяющий модернизировать функционал |
Реализованные функции на данный момент времени
- скан LTE сети в диапазонах B1/B2/B3/B5/B7/B8/B20/B28A/B38/B40/B41
- скан 3G в диапазонах B1/B2/B5/B8
- запись полученных данных в JSON лог
- отображает статус сканирования на LCD индикаторе
Записываемые параметры по каждой из обнаруженных сот:
- тип соты 3g/4g, MCC, MNC, ARFCN, TAC, PCI, RSSI, LAC, CID, PSC, RSCP, ECIO
Планы на ближайший месяц. Над чем работаю сейчас:
- парсинг и запись GPS координаты точки измерения.
- интерфейс для визуализации измерений
- "железо" модуля измерения параметров 2G сети
- программный модуль скана 2g сети
- интерактивное меню-управление с кнопочек на передней панели
Как помочь проекту?
- Морально. Распространите ссылку на статью по знакомым и медиа-ресурсам. Энтузиазм победить нельзя, но в рф он сам погаснет! Поэтому приоритет на зарубежные площадки. Кто есть на ру-ресурсах типа vrtp, фрикера и так далее - да будет спам! ) Репост + ссылка на эту тему.
- Материально. Все средства зачисленные на BTC адрес пойдут только на этот проект.
Если желающие поддержать не только словом, но и делом - найдутся - с меня отчет в этой теме, в формате хеш транзакции - на что конкретно была потрачена. Скидывайте ник и хеш транзакции, добавлю в список соучастников проекта! )
BTC кошелек проекта: bc1qrj2mk5m5jaxzee8vq625ec8tdusettpzrevk3q
- Технически. Приветствуются любые дополнения и участие в проекте - пишем код вместе и улучшаем возможности девайса. Код-ревью и "причесывание" исходников. Основной язык проекта - C. Обновления и дополнения обсуждаем в этой теме. Хорошие правки, дополнения - будут внесены в основной код с указанием авторов, после проверки мною "в железе". Можете делать свои "форки" сколько угодно, перезаливы на гитхаб - приветствуются с обязательным указанием ссылки на эту тему.
Лицензии и копирайты
Автор идеи проекта и первоначального кода - я.
Железо - Opensource, на стандартных общедоступных модулях.
Софт - Opensource, загружается в устройство самостоятельно
Ограничения на распространение и применение - отсутствуют. Обязательная ссылка на " xss.pro " .
Техподдержка - на все вопросы Вам обязательно ответит ChatGPT.
Платформа - одноплатный ПК Orange PI RK3399.
Для сканирования LTE используются 2 модема - Quectel EC25-EUX и Huawei ME909s-120
Huawei подключен в m2 разъем, Quectel - через usb-to-m2 адаптер.
Дисплей - знакосинтезирующий, фирмы Мелт, 20 символов 2 строки
Питание хуавея и дисплея - через отдельный dc/dc преобразователь с выходом 5 вольт
Enable преобразователя заведен на GPIO для возможности аппаратного ресета Quectel'а
Питание - LiPo авиамодельный аккумулятор 3S емкостью 3300мА/ч
Для сканирования LTE используются 2 модема - Quectel EC25-EUX и Huawei ME909s-120
Huawei подключен в m2 разъем, Quectel - через usb-to-m2 адаптер.
Дисплей - знакосинтезирующий, фирмы Мелт, 20 символов 2 строки
Питание хуавея и дисплея - через отдельный dc/dc преобразователь с выходом 5 вольт
Enable преобразователя заведен на GPIO для возможности аппаратного ресета Quectel'а
Питание - LiPo авиамодельный аккумулятор 3S емкостью 3300мА/ч
Определи геолокацию с точностью до улицы, на которой был записан этот лог - и получи кучу лайков )
JSON:
{
"cell": [
{
"type":"4G",
"MCC":"250",
"MNC":"20",
"ARFCN":"100",
"TAC":"195",
"PCI":"0",
"RSSI":"-44"
},
{
"type":"4G",
"MCC":"250",
"MNC":"01",
"ARFCN":"1802",
"TAC":"18A",
"PCI":"0",
"RSSI":"-41"
},
{
"type":"4G",
"MCC":"250",
"MNC":"01",
"ARFCN":"3200",
"TAC":"67",
"PCI":"0",
"RSSI":"-40"
},
{
"type":"4G",
"MCC":"250",
"MNC":"02",
"ARFCN":"6350",
"TAC":"13D",
"PCI":"0",
"RSSI":"-24"
},
{
"type":"4G",
"MCC":"250",
"MNC":"01",
"ARFCN":"38100",
"TAC":"108",
"PCI":"0",
"RSSI":"-74"
},
{
"type":"4G",
"MCC":"250",
"MNC":"20",
"ARFCN":"38950",
"TAC":"1D9",
"PCI":"0",
"RSSI":"-41"
},
{
"type":"4G",
"MCC":"250",
"MNC":"01",
"ARFCN":"40740",
"TAC":"108",
"PCI":"0",
"RSSI":"-70"
},
{
"type":"4G",
"MCC":"250",
"MNC":"20",
"ARFCN":"3400",
"TAC":"9D",
"PCI":"0",
"RSSI":"-48"
},
{
"type":"4G",
"MCC":"250",
"MNC":"99",
"ARFCN":"1301",
"TAC":"4C",
"PCI":"0",
"RSSI":"-41"
},
{
"type":"4G",
"MCC":"250",
"MNC":"01",
"ARFCN":"375",
"TAC":"DC",
"PCI":"0",
"RSSI":"-43"
},
{
"type":"4G",
"MCC":"250",
"MNC":"99",
"ARFCN":"3300",
"TAC":"B1",
"PCI":"0",
"RSSI":"-43"
},
{
"type":"4G",
"MCC":"250",
"MNC":"20",
"ARFCN":"39550",
"TAC":"8C",
"PCI":"0",
"RSSI":"-47"
},
{
"type":"4G",
"MCC":"250",
"MNC":"02",
"ARFCN":"2850",
"TAC":"2",
"PCI":"0",
"RSSI":"-51"
},
{
"type":"4G",
"MCC":"250",
"MNC":"02",
"ARFCN":"1602",
"TAC":"22",
"PCI":"0",
"RSSI":"-62"
},
{
"type":"4G",
"MCC":"250",
"MNC":"99",
"ARFCN":"6413",
"TAC":"177",
"PCI":"0",
"RSSI":"-65"
},
{
"type":"4G",
"MCC":"250",
"MNC":"99",
"ARFCN":"525",
"TAC":"F2",
"PCI":"0",
"RSSI":"-57"
},
{
"type":"4G",
"MCC":"250",
"MNC":"20",
"ARFCN":"75",
"TAC":"E3",
"PCI":"0",
"RSSI":"-36"
},
{
"type":"4G",
"MCC":"250",
"MNC":"20",
"ARFCN":"6200",
"TAC":"6CAD",
"PCI":"188",
"RSSI":"-58"
},
{
"type":"4G",
"MCC":"250",
"MNC":"02",
"ARFCN":"3048",
"TAC":"2606",
"PCI":"34",
"RSSI":"-75"
},
{
"type":"4G",
"MCC":"250",
"MNC":"02",
"ARFCN":"6338",
"TAC":"1E35",
"PCI":"54",
"RSSI":"-87"
},
{
"type":"3G",
"MCC":"250",
"MNC":"02",
"ARFCN":"10687",
"LAC":"25F4",
"CID":"A1B44C",
"PSC":"405",
"RSCP":"0",
"ECIO":"0"
},
{
"type":"3G",
"MCC":"250",
"MNC":"02",
"ARFCN":"2938",
"LAC":"25F4",
"CID":"A1B421",
"PSC":"12",
"RSCP":"-53",
"ECIO":"-3"
},
{
"type":"3G",
"MCC":"250",
"MNC":"20",
"ARFCN":"10563",
"LAC":"6CAD",
"CID":"742E89",
"PSC":"326",
"RSCP":"-56",
"ECIO":"-12"
},
{
"type":"3G",
"MCC":"250",
"MNC":"02",
"ARFCN":"10662",
"LAC":"25F4",
"CID":"A1B44E",
"PSC":"405",
"RSCP":"-58",
"ECIO":"-11"
},
{
"type":"3G",
"MCC":"250",
"MNC":"99",
"ARFCN":"3036",
"LAC":"7005",
"CID":"1F390A1",
"PSC":"378",
"RSCP":"-54",
"ECIO":"0"
},
{
"type":"3G",
"MCC":"250",
"MNC":"01",
"ARFCN":"2987",
"LAC":"18BA",
"CID":"330D101",
"PSC":"411",
"RSCP":"-71",
"ECIO":"0"
},
{
"type":"3G",
"MCC":"250",
"MNC":"02",
"ARFCN":"10638",
"LAC":"25F4",
"CID":"A19C99",
"PSC":"217",
"RSCP":"-93",
"ECIO":"0"
},
{
"type":"3G",
"MCC":"250",
"MNC":"01",
"ARFCN":"10762",
"LAC":"18D8",
"CID":"3306CC2",
"PSC":"421",
"RSCP":"-76",
"ECIO":"0"
}]
}
main.c
header.h
Код:
#include "header.h"
#include <pthread.h>
char dir_name[150]={};
int max_dir=0;
char file_name[150]={};
FILE *fp = NULL;
long lcd_start_time =0;
long lcd_cur_time =0;
long lcd_delta_time=0;
time_t lcd_seconds;
extern char umts_count;
extern char lte_count;
extern char umts_count_huawei;
extern char lte_count_huawei;
extern LTE_Cell lte_list[];
extern LTE_Cell lte_list_huawei[];
extern UMTS_Cell umts_list_huawei[];
extern UMTS_Cell umts_list[];
char umts_count_old =0;//for detecting new cells
char lte_count_old=0;//for detecting new cells
extern char umts_count_huawei_old=0;
extern char lte_count_huawei_old=0;
int plmn_arr[MAX_CELL][MAX_CELL] = {};
char buffer[1256]={};
char tx_string[256]={};
int fd;
void quectel_reset()
{
char in_c=0;
quectel_close();
sleep(5);
pinMode (19,OUTPUT);
digitalWrite(19,1);
sleep(10);
pinMode (19,OUTPUT);
digitalWrite(19,0);
lcdClear(fd);
lcdPosition(fd,0,0);
lcdPuts(fd,"BASEBAND RESET");
lcdPosition(fd,0,1);
lcdPuts(fd,"PLEASE WAIT...");
printf("bb reset \n");
sleep(20);
in_c = quectel_start();
qualcom_imei();
sleep(5);
}
void huawei_reset(){
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT+CFUN=0 \r");
huawei_println(tx_string, sizeof(tx_string));
memset(buffer,0,sizeof(buffer));
while (1)
{
huawei_readln(buffer);
if (strstr(buffer, "OK") ){
printf("huawei power off ok %s \n",buffer);
break;
}
if (strstr(buffer, "ERROR") ){
printf("at command error,retry \n");
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT+CFUN=0 \r");
huawei_println(tx_string, sizeof(tx_string));
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT+CFUN=1 \r");
huawei_println(tx_string, sizeof(tx_string));
while (1)
{
huawei_readln(buffer);
if (strstr(buffer, "OK") ){
printf("huawei power on ok %s \n",buffer);
break;
}
if (strstr(buffer, "ERROR") ){
printf("at command error,retry \n");
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT+CFUN=1 \r");
huawei_println(tx_string, sizeof(tx_string));
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT^CURC=0 \r");
huawei_println(tx_string, sizeof(tx_string));
while (1)
{
huawei_readln(buffer);
if (strstr(buffer, "OK") ){
break;
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
}
void merge_arrays()
{
int mcc = 0;
int mnc=0;
int lcd_merge_4g=0;
int lcd_merge_3g=0;
int merge_cnt=0;
int merge1_cnt=0;
int merge2_cnt=0;
for (merge_cnt=0;merge_cnt<MAX_CELL;merge_cnt++)
{
if (lte_list[merge_cnt].arfcn !=0 )
{
for (merge1_cnt=0;merge1_cnt<MAX_CELL;merge1_cnt++)
{
if ( (lte_list_huawei[merge1_cnt].arfcn == lte_list[merge_cnt].arfcn) &&(lte_list_huawei[merge1_cnt].plmn != lte_list[merge_cnt].plmn) )
{
merge2_cnt = 0;
while (merge2_cnt<MAX_CELL)
{
if ((plmn_arr[merge2_cnt][0]==lte_list[merge_cnt].plmn )||(plmn_arr[merge2_cnt][0]==0)) break;
merge2_cnt++;
}
if (plmn_arr[merge2_cnt][0]!=lte_list[merge_cnt].plmn){
plmn_arr[merge2_cnt][0]=lte_list[merge_cnt].plmn;
plmn_arr[merge2_cnt][1]=lte_list_huawei[merge1_cnt].plmn;
}
}
}
}
}
for (merge_cnt=0;merge_cnt<MAX_CELL;merge_cnt++)
{
if (plmn_arr[merge_cnt][0] !=0)
{
for (merge1_cnt=0;merge1_cnt<MAX_CELL;merge1_cnt++)
{
if (plmn_arr[merge_cnt][0] == lte_list[merge1_cnt].plmn) lte_list[merge1_cnt].plmn =plmn_arr[merge_cnt][1];
}
}
}
for (merge2_cnt=0;merge2_cnt<MAX_CELL;merge2_cnt++){
merge_cnt=0;
while (merge_cnt<MAX_CELL){
if (lte_list[merge_cnt].arfcn == 0 || (lte_list[merge_cnt].arfcn == lte_list_huawei[merge2_cnt].arfcn )) break;
merge_cnt++;
}
if (lte_list[merge_cnt].arfcn != lte_list_huawei[merge2_cnt].arfcn)
{
lte_list[merge_cnt].arfcn = lte_list_huawei[merge2_cnt].arfcn;
lte_list[merge_cnt].plmn = lte_list_huawei[merge2_cnt].plmn;
lte_list[merge_cnt].pci = lte_list_huawei[merge2_cnt].pci;
memcpy(lte_list[merge_cnt].tac, lte_list_huawei[merge2_cnt].tac, sizeof lte_list_huawei[merge2_cnt].tac);
lte_list[merge_cnt].rssi = lte_list_huawei[merge2_cnt].rssi;
}
}
printf("################## LTE CELL LIST ################## \n");
char firstrun=1;
for (merge_cnt=0;merge_cnt<MAX_CELL;merge_cnt++)
{
if (lte_list[merge_cnt].arfcn !=0)
{
printf ("plmn = %d arfcn = %d channel = %s tac=%s pci= %d rssi=%d \n",lte_list[merge_cnt].plmn, lte_list[merge_cnt].arfcn, lte_list[merge_cnt].channel,lte_list[merge_cnt].tac,lte_list[merge_cnt].pci,lte_list[merge_cnt].rssi);
lcd_merge_4g ++;
mcc = lte_list[merge_cnt].plmn / 100;
mnc =lte_list[merge_cnt].plmn %100;
if(firstrun)
{
firstrun=0;
}else
{
fprintf(fp,",\n");
}
fprintf(fp,"{\n");
fprintf(fp," \"type\":\"4G\",\n");
fprintf(fp," \"MCC\":\"%d\",\n",mcc);
fprintf(fp," \"MNC\":\"%02d\",\n",mnc);
fprintf(fp," \"ARFCN\":\"%d\",\n",lte_list[merge_cnt].arfcn);
fprintf(fp," \"TAC\":\"%s\",\n",lte_list[merge_cnt].tac);
fprintf(fp," \"PCI\":\"%d\",\n",lte_list[merge_cnt].pci);
fprintf(fp," \"RSSI\":\"%d\"\n",lte_list[merge_cnt].rssi);
fprintf(fp,"}");
fflush(fp);
}
}
////////////////////////////////////////////////
for (merge2_cnt=0;merge2_cnt<MAX_CELL;merge2_cnt++){
merge_cnt=0;
while (merge_cnt<MAX_CELL){
if (umts_list[merge_cnt].arfcn == 0 || (umts_list[merge_cnt].arfcn == umts_list_huawei[merge2_cnt].arfcn )) break;
merge_cnt++;
}
if (umts_list[merge_cnt].arfcn != umts_list_huawei[merge2_cnt].arfcn)
{
umts_list[merge_cnt].arfcn = umts_list_huawei[merge2_cnt].arfcn;
umts_list[merge_cnt].plmn = umts_list_huawei[merge2_cnt].plmn;
memcpy(umts_list[merge_cnt].lac, umts_list_huawei[merge2_cnt].lac, sizeof umts_list_huawei[merge2_cnt].lac);
memcpy(umts_list[merge_cnt].cid, umts_list_huawei[merge2_cnt].cid, sizeof umts_list_huawei[merge2_cnt].cid);
umts_list[merge_cnt].psc = umts_list_huawei[merge2_cnt].psc;
umts_list[merge_cnt].rscp = umts_list_huawei[merge2_cnt].rscp;
umts_list[merge_cnt].ecio = umts_list_huawei[merge2_cnt].ecio;
}
}
printf("################## UMTS CELL LIST ################## \n");
for (merge_cnt=0;merge_cnt<MAX_CELL;merge_cnt++)
{
if (umts_list[merge_cnt].arfcn !=0)
{
printf ("plmn = %d arfcn = %d lac=%s cid=%s psc=%d rscp= %d ecio=%d \n",umts_list[merge_cnt].plmn, umts_list[merge_cnt].arfcn,umts_list[merge_cnt].lac,umts_list[merge_cnt].cid,umts_list[merge_cnt].psc,umts_list[merge_cnt].rscp,umts_list[merge_cnt].ecio);
lcd_merge_3g ++;
mcc = umts_list[merge_cnt].plmn / 100;
mnc =umts_list[merge_cnt].plmn %100;
fprintf(fp,",\n{\n");
fprintf(fp," \"type\":\"3G\",\n");
fprintf(fp," \"MCC\":\"%d\",\n",mcc);
fprintf(fp," \"MNC\":\"%02d\",\n",mnc);
fprintf(fp," \"ARFCN\":\"%d\",\n",umts_list[merge_cnt].arfcn);
fprintf(fp," \"LAC\":\"%s\",\n",umts_list[merge_cnt].lac);
fprintf(fp," \"CID\":\"%s\",\n",umts_list[merge_cnt].cid);
fprintf(fp," \"PSC\":\"%d\",\n",umts_list[merge_cnt].psc);
fprintf(fp," \"RSCP\":\"%d\",\n",umts_list[merge_cnt].rscp);
fprintf(fp," \"ECIO\":\"%d\"\n",umts_list[merge_cnt].ecio);
fprintf(fp,"}");
fflush(fp);
}
}
printf("################## END ################## \n");
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"3G BTS=%d SCAN #%d",lcd_merge_3g,max_dir+1);
lcdPosition(fd,0,1);
lcdPrintf(fd,"4G BTS=%d",lcd_merge_4g);
lcdPosition(fd,5,0);
lcdCursorBlink(fd,0);
}
int scan_lte(void){
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"at+qcops=4,1,1,5\r");
quectel_println(tx_string, sizeof(tx_string));
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count+1, umts_count+1,lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei);
lcdPosition(fd,5,0);
lcdCursorBlink(fd,1);
while (1)
{
if(quectel_readln(buffer)<1){
printf("timeout reset");
memset(buffer,0,sizeof(buffer));
return -1;
}
if (strstr(buffer, "OK") ){
break;
}
if (strstr(buffer, "ERROR") ){
printf("at command error,retry \n");
quectel_reset();
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count+1, umts_count+1,lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei);
lcdPosition(fd,5,0);
lcdCursorBlink(fd,1);
sleep(10);
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"at+qcops=4,1,1,5\r");
quectel_println(tx_string, sizeof(tx_string));
}
if (strstr(buffer,"\"4G\"")){
lteparse(buffer);
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
return 1;
}
int huawei_imei(void)
{
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT^CURC=0 \r");
huawei_println(tx_string, sizeof(tx_string));
while (1)
{
if(huawei_readln(buffer)<1){
printf("timeout reset");
memset(buffer,0,sizeof(buffer));
return -1;
}
if (strstr(buffer, "OK") ){
break;
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT+CGSN \r");
huawei_println(tx_string, sizeof(tx_string));
while (1)
{
if(huawei_readln(buffer)<1){
printf("timeout reset");
memset(buffer,0,sizeof(buffer));
return -1;
}
if (strstr(buffer, "OK") ){
memset(buffer,0,sizeof(buffer));
break;
}
printf("%s \n",buffer);
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
return 1;
}
int qualcom_imei(void)
{
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT+CGSN \r");
quectel_println(tx_string, sizeof(tx_string));
while (1)
{
if(quectel_readln(buffer)<1){
printf("timeout reset");
memset(buffer,0,sizeof(buffer));
return -1;
}
if (strstr(buffer, "OK") ){
break;
memset(buffer,0,sizeof(buffer));
}
printf("%s \n",buffer);
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
return 1;
}
int scan_umts(void){
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"at+qcops=2,1,1,5\r");
quectel_println(tx_string, sizeof(tx_string));
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count, umts_count+1, lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei);
lcdPosition(fd,10,0);
lcdCursorBlink(fd,1);
while (1)
{
if(quectel_readln(buffer)<1){
printf("timeout reset");
memset(buffer,0,sizeof(buffer));
return -1;
}
if (strstr(buffer, "OK") ){
printf("received OK \n");
break;
}
if (strstr(buffer, "ERROR") ){
printf("at command error,retry \n");
quectel_reset();
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count, umts_count+1, lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei);
lcdPosition(fd,10,0);
lcdCursorBlink(fd,1);
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"at+qcops=2,1,1,5\r");
quectel_println(tx_string, sizeof(tx_string));
}
if (strstr(buffer,"\"3G\"")){
umtsparse(buffer);
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
return 1;
}
int huawei_scan_umts(void){
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT^SYSCFGEX=\"02\",3FFFFFFF,1,2,7FFFFFFFFFFFFFFF,, \r");
huawei_println(tx_string, sizeof(tx_string));
memset(buffer,0,sizeof(buffer));
while (1)
{
huawei_readln(buffer);
if (strstr(buffer, "OK") ){
printf("huawei switched to umts %s \n",buffer);
memset(buffer,0,sizeof(buffer));
break;
}
if (strstr(buffer, "ERROR") ){
printf("at command error,retry \n");
sprintf(tx_string,"AT^SYSCFGEX=\"02\",3FFFFFFF,1,2,7FFFFFFFFFFFFFFF,, \r");
huawei_println(tx_string, sizeof(tx_string));
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT^NETSCAN=20,-110,1\r");
huawei_println(tx_string, sizeof(tx_string));
while (1)
{
if(huawei_readln(buffer)<1){
printf("timeout reset");
memset(buffer,0,sizeof(buffer));
return -1;
}
if (strstr(buffer, "OK") ){
break;
}
if (strstr(buffer, "ERROR") ){
printf("at command error,retry \n");
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT^NETSCAN=20,-110,1\r");
huawei_println(tx_string, sizeof(tx_string));
}
if (strstr(buffer, "^NETSCAN: ") ){
huawei_umtsparse(buffer);
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
return 1;
}
int huawei_scan_lte(void){
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT^SYSCFGEX=\"03\",3FFFFFFF,1,2,7FFFFFFFFFFFFFFF,, \r");
huawei_println(tx_string, sizeof(tx_string));
memset(buffer,0,sizeof(buffer));
while (1)
{
if(huawei_readln(buffer)<1){
printf("timeout reset");
memset(buffer,0,sizeof(buffer));
return -1;
}
if (strstr(buffer, "OK") ||strstr(buffer, "ECCLIST") ){
printf("huawei switched to LTE %s \n",buffer);
memset(buffer,0,sizeof(buffer));
break;
}
if (strstr(buffer, "ERROR") ){
printf("at command error,retry \n");
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT^SYSCFGEX=\"03\",3FFFFFFF,1,2,7FFFFFFFFFFFFFFF,, \r");
huawei_println(tx_string, sizeof(tx_string));
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT^NETSCAN=20,-110,3\r");
huawei_println(tx_string, sizeof(tx_string));
while (1)
{
if(huawei_readln(buffer)<1){
printf("timeout reset");
memset(buffer,0,sizeof(buffer));
return -1;
}
if (strstr(buffer, "OK") ){
break;
}
if (strstr(buffer, "ERROR") ){
printf("at command error,retry \n");
memset(tx_string,0,sizeof(tx_string));
sprintf(tx_string,"AT^NETSCAN=20,-110,3\r");
huawei_println(tx_string, sizeof(tx_string));
}
if (strstr(buffer, "^NETSCAN: ") ){
huawei_lteparse(buffer);
}
memset(buffer,0,sizeof(buffer));
}
memset(buffer,0,sizeof(buffer));
return 1;
}
void huawei_scan(){
/////////////////////3G UMTS SCAN////////////////////
printf("new HUAWEI UMTS scan started \n");
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count+1, umts_count+1,lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei);
lcdPosition(fd,10,1);
lcdCursorBlink(fd,1);
while(1){
if ( huawei_scan_umts()<1)
{
huawei_reset();
}
else
{
break;
}
}
while (umts_count_huawei!=umts_count_huawei_old) //rescan while modem founds new cells in each round
{
printf("HUAWEI UMTS rescan started. UMTS cell count = %d \n",umts_count_huawei+1);
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count+1, umts_count+1, lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei+1);
lcdPosition(fd,10,1);
lcdCursorBlink(fd,1);
umts_count_huawei_old = umts_count_huawei;
while(1){
if ( huawei_scan_umts()<1)
{
huawei_reset();
}
else
{
break;
}
}
}
printf("HUAWEI UMTS scan completed. Total 3G cell count = %d \n",umts_count_huawei+1);
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count+1, umts_count+1,lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei+1);
lcdPosition(fd,5,1);
lcdCursorBlink(fd,1);
/////////////////////LTE SCAN////////////////////
printf("new HUAWEI LTE scan started \n");
while(1){
if ( huawei_scan_lte()<1)
{
huawei_reset();
}
else
{
break;
}
}
while (lte_count_huawei!=lte_count_huawei_old) //rescan while modem founds new cells in each round
{
printf("HUAWEI LTE rescan started. LTE cell count = %d \n",lte_count_huawei+1);
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count+1, umts_count+1,lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei+1, umts_count_huawei+1);
lcdPosition(fd,5,1);
lcdCursorBlink(fd,1);
lte_count_huawei_old = lte_count_huawei;
while(1){
if ( huawei_scan_lte()<1)
{
huawei_reset();
}
else
{
break;
}
}
}
printf("HUAWEI LTE scan completed. Total 4G cell count = %d \n",lte_count_huawei+1);
}
void qualcom_scan(){
/////////////////////3G UMTS SCAN////////////////////
printf("new UMTS scan started \n");
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count, umts_count,lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei);
lcdPosition(fd,10,0);
lcdCursorBlink(fd,1);
while(1){
if ( scan_umts()<1)
{
sleep(1);
quectel_reset();
}
else
{
break;
}
}
while (umts_count!=umts_count_old) //rescan while modem founds new cells in each round
{
printf("UMTS rescan started. UMTS cell count = %d \n",umts_count+1);
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count, umts_count+1, lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei);
lcdPosition(fd,10,0);
lcdCursorBlink(fd,1);
umts_count_old = umts_count;
while(1){
if ( scan_umts()<1)
{
sleep(1);
quectel_reset();
}
else
{
break;
}
}
}
printf("UMTS scan completed. Total 3G cell count = %d \n",umts_count+1);
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count, umts_count+1,lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei);
lcdPosition(fd,5,0);
lcdCursorBlink(fd,1);
/////////////////////SCAN 4G LTE//////////////////////
printf("New LTE scan started \n");
while(1){
if ( scan_lte()<1)
{
sleep(1);
quectel_reset();
}
else
{
break;
}
}
while (lte_count!=lte_count_old) //rescan while modem founds new cells in each round
{
printf("LTE rescan started. LTE cell count = %d \n",lte_count+1);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdClear(fd);
lcd_seconds = time(NULL);
lcd_cur_time = lcd_seconds;
lcd_delta_time = lcd_cur_time-lcd_start_time;
lcdPosition(fd,0,0);
lcdPrintf(fd,"#1 4G=%d 3G=%d %d",lte_count+1, umts_count+1,lcd_delta_time);
lcdPosition(fd,0,1);
lcdPrintf(fd,"#2 4G=%d 3G=%d",lte_count_huawei, umts_count_huawei);
lcdPosition(fd,5,0);
lcdCursorBlink(fd,1);
lte_count_old = lte_count;
while(1){
if ( scan_lte()<1)
{
sleep(1);
quectel_reset();
}
else
{
break;
}
}
}
printf("LTE scan completed. Total 4G cell count = %d \n",lte_count+1);
}
int main(void){
int code = wiringPiSetup();
if (code !=0){
printf("wiring init error");
}
pinMode (19,OUTPUT);
digitalWrite(19,1);
sleep(5);
pinMode (19,OUTPUT);
digitalWrite(19,0);
/* pinMode (BUTTON4, INPUT) ;
while (1){
sleep(1);
printf("button = %d \n",digitalRead (BUTTON4));
}
*/
fd = lcdInit(2,20,4,LCD_RS,LCD_E,LCD_D4,LCD_D5,LCD_D6,LCD_D7,0,0,0,0);
lcdCursorBlink(fd,0);
lcdClear(fd);
lcdPosition(fd,0,0);
lcdPuts(fd,"BASEBAND STARTING");
lcdPosition(fd,0,1);
lcdPuts(fd,"SCAN VIEW GPS ...");
printf("start quectel modem init \n");
sleep(20);
lcd_seconds = time(NULL);
lcd_start_time = lcd_seconds;
////////////////////////////////////////////////
struct stat st = {0};
DIR *d;
struct dirent *dir;
d = opendir(LOG_DIR);
if (d) {
while ((dir = readdir(d)) != NULL ) {
if ((dir->d_type==4)&&!(strstr(dir->d_name, ".") ))
{
if (atoi(dir->d_name) > max_dir )max_dir =atoi(dir->d_name);
printf("%s %d\n", dir->d_name, dir->d_type);
}
}
closedir(d);
}
printf("max dir = %d \n",max_dir);
sprintf(dir_name,"%s%d",LOG_DIR,max_dir+1);
if (stat(dir_name, &st) == -1) {
mkdir(dir_name, 0777);
}
sprintf(file_name,"%s/lte_cells.json",dir_name);
fp = fopen(file_name ,"a");
fprintf(fp,"{\n");
fprintf(fp,"\"cell\": [\n");
fflush(fp);
if (quectel_start()){
qualcom_imei(); // extract and print qualcomm ec-25 modem imei
qualcom_scan(); //complete and iterative network scan using qualcomm modem
}
if (huawei_start())
{
printf("huawei started ok - next \n");
huawei_reset();
huawei_imei();
huawei_scan();
}
merge_arrays();
fprintf(fp,"]\n");
fprintf(fp,"}\n");
fflush(fp);
fclose(fp);
}
Код:
#ifndef HEADER_H_
#define HEADER_H_
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
#include <math.h>
#include <inttypes.h>
#include <string.h>
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include "/usr/local/include/wiringPi.h"
#include "/usr/local/include/lcd.h"
#include "serial.h"
#define LOG_DIR "/home/linaro/bts_logs/"
#define LCD_RS 25
#define LCD_E 24
#define LCD_D4 23
#define LCD_D5 22
#define LCD_D6 21
#define LCD_D7 20
#define BUTTON1 2
#define BUTTON2 6
#define BUTTON3 9
#define BUTTON4 10
int quectel_start(void);
void lteparse(char *);
void umtsparse(char *);
void huawei_umtsparse(char *umtsstring);
void huawei_lteparse(char *ltestring);
int scan_lte(void);
int scan_umts(void);
void huawei_reset(void);
int huawei_scan_umts(void);
int huawei_scan_lte(void);
int huawei_start(void);
void huawei_scan(void);
void qualcom_scan(void);
int qualcom_imei(void);
void merge_arrays(void);
#define MAX_CELL 40
struct UMTS_CellData{
int plmn;
int arfcn;
char lac[50];
char cid[50];
int psc;
int rscp;
int ecio;
};
typedef struct UMTS_CellData UMTS_Cell;
struct LTE_CellData{
int plmn;
int arfcn;
char channel[50];
int pci;
char tac[50];
int rssi;
};
typedef struct LTE_CellData LTE_Cell;
#endif /* HEADER_H_ */