Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1534952
  • 博文数量: 114
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 1357
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-19 18:13
文章分类
文章存档

2010年(8)

2009年(9)

2008年(27)

2007年(62)

2006年(8)

我的朋友

分类: LINUX

2007-08-23 22:35:47

北京理工大学 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
下载: 下载
阅读(4665) | 评论(8) | 转发(0) |
给主人留下些什么吧!~~