基带(Baseband)是手机的通讯模块,它负责移动网络的调制与解调工作,它与手机核心通讯功能息息相关。iPhone中也有一个基带,越狱用户可能会经常听到这个名词,有锁的iPhone,如果基带不进行破解是没办法进行操作的。下面来介绍一下用iPhone基带进行通讯,本文需要手机越狱并具备足够的系统权限,建议在命令行下以root权限运行。未来会继续介绍利用基带进行SIM卡联系人和短信数据的导入导出,以及发短信等知识,敬请关注。

##基带设备文件

与iPhone基带设备文件有好几个,目前发现比较方便可用的是/dev/dlci.spi-baseband.extra_0。如果是旧版本的iOS可能会是/dev/tty.debug。如果你是比较旧的iOS,可以尝试tty.debug。为了进行基带通讯,首先我们要打开基带设备文件,代码如下:

1
2
3
4
NSFileHandle *baseBand = [NSFileHandle fileHandleForUpdatingAtPath:@"/dev/dlci.spi-baseband.extra_0"];
if (baseBand == nil) {
NSLog(@"Can't open baseband.");
}

打开基带设备后,需要对基带进行一些配置,如串口速率,数据位,模式等。配置基带文件代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int fd = [baseBand fileDescriptor];
ioctl(fd, TIOCEXCL);
fcntl(fd, F_SETFL, 0);
static struct termios term;
tcgetattr(fd, &term);
cfmakeraw(&term);
cfsetspeed(&term, 115200);
term.c_cflag = CS8 | CLOCAL | CREAD;
term.c_iflag = 0;
term.c_oflag = 0;
term.c_lflag = 0;
term.c_cc[VMIN] = 0;
term.c_cc[VTIME] = 0;
tcsetattr(fd, TCSANOW, &term);

AT指令

基带是根据AT指令进行通讯,AT指令是GSM网络中非常常见的通讯指令,这里就不再详细说明,相关AT指令的东西和文档请自行Google,有很多手册。AT指令是以“AT”开头的一些字符串,可以发送给基带,用以设置、查询信息或条件测试。它包括查看SIM卡数据,打电话,发短信,查运营商,设置运营商等各种指令。与移动网络相关的大部分操作都要用AT指令来完成。最简单的AT指令就是发送“AT”,然后返回“AT\rOK\r\n”,用于测试联通性。每个AT命令以回车(\r)结束。

1
2
3
4
5
6
> AT\r
AT
OK

发送AT指令并接收结果

发送AT指令很简单,只需要向基带设备文件写入数据即可。处理结果也只是从基带设备文件中读入数据。由于AT命令往往是以“OK\r\n”或“ERROR\r\n”结束,所以我用此来判断AT命令结果输出结束,相关代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
NSString *sendATCommand(NSFileHandle *baseBand, NSString *atCommand){
NSLog(@"SEND AT: %@", atCommand);
[baseBand writeData:[atCommand dataUsingEncoding:NSASCIIStringEncoding]];
NSMutableString *result = [NSMutableString string];
NSData *resultData = [baseBand availableData];
while ([resultData length]) {
[result appendString:[[NSString alloc] initWithData:resultData encoding:NSASCIIStringEncoding]];
if ([result hasSuffix:@"OK\r\n"]||[result hasSuffix:@"ERROR\r\n"]) {
NSLog(@"RESULT: %@", result);
return [NSString stringWithString:result];
}
else{
resultData = [baseBand availableData];
}
}
return nil;
}

一些简单的AT命令测试

获取手机IMEI

1
NSString *result = sendATCommand(baseBand, @"AT+CGSN\r");

获取IMSI

1
result = sendATCommand(baseBand, @"AT+CIMI\r");

获取ICCID

1
result = sendATCommand(baseBand, @"AT+CCID\r");

拨打电话(在我的手机上可以看到拨打电话界面,但没有声音,可能还要结合其他接口才行。)

1
2
sendATCommand(baseBand, @"ATD10010\r");

全部代码:https://gist.github.com/shenqiliang/9183906