北京理工大学 20981 陈罡
今天偶然在ccmove上面看到OpenMoko的大侠——Daniel Willmann写的一段代码,
据说可以越过moto的tapi,通过直接读写/dev/mux*来向mobilinux手机发送at指令。
呵呵,我看了如获至宝,毕竟如果这一步走通了,整个linux手机,就全部open了,
其实有了frambuffer,显示应该不成问题,至于ezx是否开放已经无关紧要的,可以
装个opie或者open moko,在或者,就着现有的系统,移植一个gtke,或者sdl什么的,
ui什么的就都不成问题了。如果at命令这个通道能够走通,那么拨打电话、接听电话,
发送短信、接收短信,发送彩信,接收彩信,gprs拨号,电话本存取,等等,这些都
可以解决。
言归正转,Daniel Willmann大侠经过一段艰苦的按照他的话来说——“happy hack”
以后,编写了一个叫做opentapi的头文件,我对比了一下官方sdk里面的TAPI函数,
我可以很负责的说确实很不一样,opentapi是直接操作/dev/mux,而官方的接口则
封装什么drm之类的更多的东西,通过opentapi我们可以直接发送at指令,而官方的
封装,则需要与tapisvr这个后台服务程序交互,才有可能拨打电话,发送短信。
目前看openmoko上的讨论,可以知道Daniel Willmann大侠已经实现了拨打电话、
发送短信,不过接收短信还会造成damn crash。我把网上看到的代码整理一下发出来。
opentapi.h文件内容如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LOGFILENAME "/tmp/opentapi.log"
#define MUX_BASE "/dev/mux"
#define MUX_FILES_MAX 8
#define MUX_BUFFER_SIZE 1024
#ifdef __cplusplus
extern "C" {
#endif
struct mux_buf {
char buffer[MUX_BUFFER_SIZE];
int length;
};
fd_set read_set, write_set, master_read_set, master_write_set;
int max_fd, mux[MUX_FILES_MAX], con[MUX_FILES_MAX], serv[MUX_FILES_MAX], logfile;
int debug = 1;
struct mux_buf con_buffer[MUX_FILES_MAX];
struct mux_buf mux_buffer[MUX_FILES_MAX];
int open_files() ;
void init_mux_buffer(struct mux_buf *mb) ;
void remove_data(struct mux_buf *buf, int length) ;
void add_data(struct mux_buf *mbuf, char *buf, int length) ;
#ifdef __cplusplus
}
#endif
int open_files() {
int i ;
char filename[40];
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
for (i = 0; i < MUX_FILES_MAX; i++) {
snprintf(filename, 40, "%s%d", MUX_BASE, i);
printf("open %s\r\n",filename);
if ((mux[i] = open(filename, O_RDWR|O_NONBLOCK|O_NOCTTY)) == -1)
printf("Failed to open file %s", filename);
FD_SET(mux[i], &master_read_set);
FD_SET(mux[i], &master_write_set);
if (mux[i] > max_fd) max_fd = mux[i];
printf("Opened /dev/mux%d as filede SCRIPT or %d\n", i, mux[i]);
}
if ((logfile = open("/mmc/mmca1/log.txt", O_WRONLY | O_APPEND | O_CREAT))
== -1)
printf("Failed to open %s for appending", LOGFILENAME);
return 0 ;
}
void init_mux_buffer(struct mux_buf *mb) {
mb->length = 0;
}
void remove_data(struct mux_buf *buf, int length) {
memmove(&buf->buffer[0], &buf->buffer[length], length);
buf->length -= length;
}
void add_data(struct mux_buf *mbuf, char *buf, int length) {
if (length > MUX_BUFFER_SIZE) {
printf("%s: length too big(%i)!\n", __func__, length);
exit(1);
}
if (mbuf->length + length >= MUX_BUFFER_SIZE)
remove_data(mbuf, (mbuf->length + length) - MUX_BUFFER_SIZE);
memcpy(&mbuf->buffer[mbuf->length], buf, length);
mbuf->length += length;
}
调用opentapi的文件如下:
#include
#include
#include
#include "opentapi.h"
pthread_t thread;
void * read_route(void *pcon) {
struct timeval tv;
int result, i, length;
char buffer[1005];
while(1) {
memcpy(&read_set, &master_read_set, sizeof(master_read_set)) ;
tv.tv_sec = 5 ;
tv.tv_usec = 0 ;
result = select(max_fd, &read_set, NULL, NULL, &tv) ;
for (i = 0; (i < MUX_FILES_MAX) && (result > 0); i++) {
if (FD_ISSET(mux[i], &read_set)) {
if (debug) printf("Mux%d: read\n", i);
result--;
ioctl(mux[i], FIONREAD, &length);
memset(buffer,0,length);
length = read(mux[i], buffer, length);
buffer[length]=0;
if (debug) printf("Got %i bytes from /dev/mux%d %
s\n", length, i , buffer);
}
}
sleep(0) ;
}
}
int main (void) {
struct timeval tv;
int result, i, length;
char cmd[50];
FD_ZERO(&master_read_set);
FD_ZERO(&master_write_set);
max_fd = 0;
printf("open files\r\n");
open_files();
pthread_create(&thread, 0, read_route, 0);
while (1) {
memcpy(&read_set, &master_read_set, sizeof(master_read_set));
memcpy(&write_set, &master_write_set, sizeof(master_write_set));
tv.tv_sec = 5;
tv.tv_usec = 0;
result = select(max_fd, NULL, &write_set, NULL, &tv);
scanf("%s",cmd);
strcat(cmd,"\r");
for (i = 0; (i < MUX_FILES_MAX) && (result > 0); i++ ) {
if (FD_ISSET(mux[i], &write_set)) {
if (FD_ISSET(mux[i], &write_set)) {
if (debug) printf("Mux%d: ", i);
result--;
scanf("%s",cmd);
strcat(cmd,"\r");
length = write(mux[i], cmd, strlen(cmd));
}
}
}
sleep(0) ;
} // while
return 0 ;
}
具体的不解释了,代码很少,很容易理解,大体上是一个线程读取mux的输出,主线程负责
读取用户输入的内容,然后把用户输入的内容加入"\r",送入允许写入的mux文件中。
我摸索了一下,大家可以利用Motorola C18调制解调器的绝大多数AT命令。感兴趣的朋友
可以自己下载一下文档来看看。
AT+MODE=2:
打开拨号模式,看上去似乎发送短消息或者拨打电话之前都要先把mode设置为2,如果使用
AT+MODE?的话,可以看到默认的情况下a1200的mode是0。
ATH:挂断电话
AT+CGSN:获取手机imei
AT+CIMI:获取手机imsi
ATD15901261xxxx:拨打电话,可惜的是只能够拨通但是无法通话。
AT+CSCA="+8613800270500":设置短消息中心的命令
还有很多短信相关的指令,懒得敲了,大家自己查查吧。
主要有如下的指令:
+CNMI,+CMGD,+CMSS,+CSMS,+CPMS,+CMGF,+MEGA,+CSDH,+CMTI,
+CMGL,+MMGL,+CMGR,+MMGR,+MMAR,+CMGW,+CSCA
具体的指令操作参数请查阅相关资料。
最后把上面测试程序贴出来,可以使用eKonsole或者telnet到a1200上面运行一下试试。
|
文件: |
attst.rar |
大小: |
2KB |
下载: |
下载 | |