⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atbus.c

📁 NOKIA手机开发包
💻 C
字号:
/*  $Id: atbus.c,v 1.38 2003/10/28 00:03:40 bozo Exp $  G N O K I I  A Linux/Unix toolset and driver for mobile phones.  This file is part of gnokii.  Gnokii is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.  Gnokii is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with gnokii; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  Copyright 2001 Manfred Jonsson <manfred.jonsson@gmx.de>*//* System header files */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <errno.h>#ifdef HAVE_BLUETOOTH#  include <bluetooth/bluetooth.h>#endif/* Various header file */#include "config.h"#include "compat.h"#include "misc.h"#include "links/atbus.h"#include "links/utils.h"#include "gnokii-internal.h"#include "gnokii.h"#include "device.h"/*  * FIXME - when sending an AT command while another one is still in progress, * the old command is aborted and the new ignored. the result is _one_ error * message from the phone. */static int xwrite(unsigned char *d, int len, struct gn_statemachine *sm){	int res;	at_dprintf("write: ", d, len);	while (len) {		res = device_write(d, len, sm);		if (res == -1) {			if (errno != EAGAIN) {				perror("gnokii I/O error ");				return -1;			}		} else {			d += res;			len -= res;		}	}	return 0;}static bool atbus_serial_open(int mode, char *device, struct gn_statemachine *sm){	int result = device_open(device, false, false, mode, GN_CT_Serial, sm);	if (!result) {		perror(_("Couldn't open ATBUS device"));		return false;	}	if (mode) {		/* 		 * make 7110 with dlr-3 happy. the nokia dlr-3 cable provides		 * hardware handshake lines but is, at least at initialization,		 * slow. to be properly detected, state changes must be longer		 * than 700 ms. if the timing is too fast all commands after dtr		 * high will be ignored by the phone until dtr is toggled again.		 * to reset the phone and set a sane state, dtr must pulled low.		 * when irda is turned on in the phone, dtr must pulled high to		 * switch on the serial line of the phone (this will switch off		 * irda). only set it high after serial line initialization		 * (when it probably was low before) is not enough. so we do		 * high, low and high again, always with one second apply time.		 * also wait one second before sending commands or init will		 * fail.		 */		device_setdtrrts(1, 1, sm);		sleep(1);		device_setdtrrts(0, 1, sm);		sleep(1);		device_setdtrrts(1, 1, sm);		sleep(1);	} else {		device_setdtrrts(1, 1, sm);	}	return true;}static gn_error at_send_message(unsigned int message_length, unsigned char message_type, unsigned char *msg, struct gn_statemachine *sm){	usleep(10000);	sm_incoming_acknowledge(sm);	return xwrite(msg, message_length, sm) ? GN_ERR_UNKNOWN : GN_ERR_NONE;}char *findcrlfbw(unsigned char *str, int len){	while ((*str != '\n') && (*str-1 != '\r') && len--)		str--;	return len ? str+1 : NULL;}/*  * rx state machine for receive handling. called once for each character * received from the phone.  */static void atbus_rx_statemachine(unsigned char rx_char, struct gn_statemachine *sm){	int error;	atbus_instance *bi = AT_BUSINST(sm);		bi->rbuf[bi->rbuf_pos++] = rx_char;	bi->rbuf[bi->rbuf_pos] = '\0';	if (bi->rbuf_pos < bi->binlen)		return;	bi->rbuf[0] = GN_AT_NONE;	/* first check if <cr><lf> is found at end of reply_buf.	 * none: the needed length is greater 4 because we don't	 * need to enter if no result/error will be found. */	if (bi->rbuf_pos > 4 && !strncmp(bi->rbuf + bi->rbuf_pos - 2, "\r\n", 2)) {		/* try to find previous <cr><lf> */		char *start = findcrlfbw(bi->rbuf + bi->rbuf_pos - 2, bi->rbuf_pos - 1);		/* if not found, start at buffer beginning */		if (!start)			start = bi->rbuf+1;		/* there are certainly more that 2 chars in buffer */		if (!strncmp(start, "OK", 2))			bi->rbuf[0] = GN_AT_OK;		else if (bi->rbuf_pos > 7 && !strncmp(start, "ERROR", 5))			bi->rbuf[0] = GN_AT_ERROR;		/* FIXME: use error codes some useful way */		else if (sscanf(start, "+CMS ERROR: %d", &error) == 1)			bi->rbuf[0] = GN_AT_ERROR;		else if (sscanf(start, "+CME ERROR: %d", &error) == 1)			bi->rbuf[0] = GN_AT_ERROR;	}	/* check if SMS prompt is found */	if (bi->rbuf_pos > 4 && !strncmp(bi->rbuf + bi->rbuf_pos - 4, "\r\n> ", 4))		bi->rbuf[0] = GN_AT_PROMPT;	if (bi->rbuf[0] != GN_AT_NONE) {		at_dprintf("read : ", bi->rbuf + 1, bi->rbuf_pos - 1);		sm_incoming_function(sm->last_msg_type, bi->rbuf, bi->rbuf_pos - 1, sm);		bi->rbuf_pos = 1;		bi->binlen = 1;		return;	}#if 0	/* needed for binary date etc */	TODO: correct reading of variable length integers	if (reply_buf_pos == 12) {		if (!strncmp(reply_buf + 3, "ABC", 3) {			binlength = atoi(reply_buf + 8);		}	}#endif}static gn_error atbus_loop(struct timeval *timeout, struct gn_statemachine *sm){	unsigned char buffer[255];	int count, res;	res = device_select(timeout, sm);	if (res > 0) {		res = device_read(buffer, 255, sm);		for (count = 0; count < res; count++)			atbus_rx_statemachine(buffer[count], sm);	} else		return GN_ERR_TIMEOUT;	/* This traps errors from device_read */	if (res > 0)		return GN_ERR_NONE;	else		return GN_ERR_INTERNALERROR;}/* Initialise variables and start the link *//* Fixme we allow serial and irda for connection to reduce *//* bug reports. this is pretty silly for /dev/ttyS?. */gn_error atbus_initialise(int mode, struct gn_statemachine *state){	gn_error error = GN_ERR_NONE;	atbus_instance *businst;	if (!(businst = malloc(sizeof(atbus_instance))))		return GN_ERR_FAILED;	/* Fill in the link functions */	state->link.loop = &atbus_loop;	state->link.send_message = &at_send_message;	businst->rbuf_pos = 1;	businst->binlen = 1;	AT_BUSINST(state) = businst;	switch (state->config.connection_type) {	case GN_CT_Serial:	case GN_CT_Irda:	case GN_CT_TCP:		if (!atbus_serial_open(mode, state->config.port_device, state)) {			error = GN_ERR_FAILED;			goto err;		}		break;#ifdef HAVE_BLUETOOTH	case GN_CT_Bluetooth:		if (!device_open(state->config.port_device, false, false, false, state->config.connection_type, state)) {			error = GN_ERR_FAILED;			goto err;		}		break;#endif	default:		dprintf("Device not supported by AT bus\n");		error = GN_ERR_FAILED;		goto err;	}	goto out;err:	dprintf("AT bus initialization failed (%d)\n", error);	free(AT_BUSINST(state));	AT_BUSINST(state) = NULL;out:	return error;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -