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

📄 bthandler.c

📁 linux下bluetooth后台服务程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/wait.h>#include "btdefines.h"#include "bthandler.h"#include "btutils.h"//PLEASECHECK (Victor): should be included from btutils.h#include "gotype.h"#ifdef ENABLE_DEBUG_LOG#define STATE2STR(state) state2str(state)#define ERROR2STR(error) error2str(error)#define UPDATE_STATE(state, newstate) {DEBUG_LOG2("state %s -> %s", STATE2STR(state), STATE2STR(newstate)); state = newstate;}/* Debug buffer */#define BT_DBGBUF_LEN 4096static char dbgbuf[BT_DBGBUF_LEN];#else //ENABLE_DEBUG_LOG#define STATE2STR(state) "DEBUG DISABLED"#define ERROR2STR(error) "DEBUG DISABLED"#define UPDATE_STATE(state, newstate) {state = newstate;}#endif //ENABLE_DEBUG_LOG#define INIT_LISTEN_TIMER(c, t) {BTSetTimer(&c->listentotaltr, t);BTSetTimer(&c->listenretrytr, 0);}#define INIT_CONNECT_TIMER(c, t) {BTSetTimer(&c->connecttotaltr, t);BTSetTimer(&c->connectretrytr, 0);}int BTHandlerCompare(cBTConnection con, const char *bdaddr, int chan, int profile, int *res){	int res1, res2;		if (!con || !bdaddr || !res)		return BT_ERR_ARGUMENT;	res1 = BTSocketCompare(con->sock, bdaddr, chan, &res2);	if (res1 != BT_ERR_NONE)		return res1;	res1 = (con->profile == profile) ? BT_TRUE : BT_FALSE;	if (res1 == BT_TRUE && res2 == BT_TRUE)		*res = BT_TRUE;	else		*res = BT_FALSE;	DEBUG_LOG4("%s, %d, %d: res=%d", bdaddr, chan, profile, *res);	return BT_ERR_NONE;}int BTHandlerCreate(BTConnection *con, const char *bdaddr, int chan, int profile, int flags, const char *pin){	DEBUG_LOG5("addr=[%s], chan=%d, prof=%d, flags=%d pin=[%s]", bdaddr, chan, profile, flags, pin);	BTConnection c;	if (!con || chan < 0 || chan > 30 || !bdaddr || !pin)		return BT_ERR_ARGUMENT;	if (strlen(bdaddr) > (BT_BDADDR_LEN - 1) || strlen(pin) > (BT_PIN_LEN - 1))		return BT_ERR_ARGUMENT;	c = (BTConnection)malloc(sizeof(struct sBTConnection));	if (!c)		return BT_ERR_NOMEMORY;	if (BTSocketCreate(&c->sock, bdaddr, chan) != BT_ERR_NONE) {		DEBUG_LOG("creating socket failed");		free(c);		return BT_ERR_FAILED;	}	c->state = BT_STATE_UNINITIALIZED;	c->ppp.state = BT_PPP_STATE_UNINITIALIZED;	c->profile = profile;	c->flags = flags;	strcpy(c->pin, pin);	c->sendbuf = NULL;	c->sendbuflen = 0;	c->error = BT_ERR_NONE;	if (flags & BT_FLAG_LISTEN) {		INIT_LISTEN_TIMER(c, BT_TO_LISTEN_TOTAL);		UPDATE_STATE(c->state, BT_STATE_START_LISTENING);	} else if (flags & BT_FLAG_OPEN) {		INIT_CONNECT_TIMER(c, BT_TO_CONNECT_TOTAL);		UPDATE_STATE(c->state, BT_STATE_START_CONNECTING);	} else		UPDATE_STATE(c->state, BT_STATE_INITIALIZED);	UPDATE_STATE(c->ppp.state, BT_PPP_STATE_UNINITIALIZED);	c->ppp.refcount = 0;	c->ppp.pid = -1;	c->reconnecting = 0;		*con = c;	return BT_ERR_NONE;}int BTHandlerDestroy(BTConnection con){	DEBUG_LOG1("state: %s", STATE2STR(con->state));	int res;		if (!con)		return BT_ERR_ARGUMENT;	res = BTHandlerClose(con);	free(con);		return res;}int BTHandlerStartApp(BTConnection con, const char *param){	DEBUG_LOG5("profile=%d, param=[%s], state=%s, refcount=%d, flags=0x%x", con->profile, param, STATE2STR(con->state), con->ppp.refcount, con->flags);	if (con->profile != BT_PROFILE_DUN)		return BT_ERR_NONE;	if (!con || !param)		return BT_ERR_ARGUMENT;	if (strlen(param) > (BT_PPP_PARAM_LEN - 1))		return BT_ERR_ARGUMENT;	if (con->state != BT_STATE_INITIALIZED && con->state != BT_STATE_APP_START && con->state != BT_STATE_APP_READY)		return BT_ERR_STATE;	con->ppp.refcount++;	if(con->ppp.refcount > 1 && con->state != BT_STATE_INITIALIZED)		return BT_ERR_NONE;	else if (con->ppp.refcount == 1)		strcpy(con->ppp.param, param);	UPDATE_STATE(con->state, BT_STATE_APP_START);	UPDATE_STATE(con->ppp.state, BT_PPP_STATE_INIT);		return BT_ERR_NONE;}int BTHandlerStopApp(BTConnection con){	int pid;	DEBUG_LOG3("profile=%d, state=%s, refcount=%d", con->profile, STATE2STR(con->state), con->ppp.refcount);	if (!con)		return BT_ERR_ARGUMENT;	if (con->profile != BT_PROFILE_DUN)		return BT_ERR_NONE;	if (con->state != BT_STATE_APP_START && con->state != BT_STATE_APP_READY && con->state != BT_STATE_INITIALIZED)		return BT_ERR_STATE;	if (con->ppp.refcount)		con->ppp.refcount--;	if (con->ppp.refcount || con->state == BT_STATE_INITIALIZED)		return BT_ERR_NONE;	if (con->state == BT_STATE_APP_START && (con->ppp.state == BT_PPP_STATE_CHECKTTY || con->ppp.state == BT_PPP_STATE_START || con->ppp.state == BT_PPP_STATE_CHECKREADY) )		BTSocketReleaseTTY(con->sock);	pid = BTGetFileInt(BT_PPP_PIDFILE);	if (pid > 0) {		DEBUG_LOG1("terminating %d", pid);		kill(pid, SIGTERM);	}	BTSetTimer(&con->ppp.removetr, BT_TO_APPREMOVE);	UPDATE_STATE(con->state, BT_STATE_APP_CLOSING);		return BT_ERR_NONE;}int BTHandlerSend(BTConnection con, const char *buf, int len, int *sent){#ifdef ENABLE_DEBUG_LOG	if (len <= BT_DBGBUF_LEN) {		if (buf && len)			strncpy(dbgbuf, buf, len);		dbgbuf[len - 1] = '\0';		DEBUG_LOG3("buf=[%s], len=%d, state=%s", dbgbuf, len, STATE2STR(con->state));	} else {		DEBUG_LOG("debug buffer is too small!");	}#endif //ENABLE_DEBUG_LOG	char *tmpbuf;		if (!con || !buf || !sent)		return BT_ERR_ARGUMENT;	if (con->state == BT_STATE_APP_START || con->state == BT_STATE_APP_READY || con->state == BT_STATE_APP_CLOSING)		return BT_ERR_STATE;	if (con->state != BT_STATE_CONNECTED || con->sendbuf) {		if (!con->sendbuf) {			con->sendbuf = (char*)malloc(len);			if (!con->sendbuf)				return BT_ERR_NOMEMORY;		} else {			tmpbuf = (char*)realloc(con->sendbuf, con->sendbuflen + len);			if (!tmpbuf)				return BT_ERR_NOMEMORY;			con->sendbuf = tmpbuf;		}		memcpy(con->sendbuf + con->sendbuflen, buf, len);		DEBUG_LOG2("send buffer grown %d -> %d", con->sendbuflen, con->sendbuflen + len);		con->sendbuflen += len;		if (con->state == BT_STATE_START_CONNECTING || con->state == BT_STATE_CONNECTING || con->state == BT_STATE_CONNECTED)			return BT_ERR_NONE;		if (con->state == BT_STATE_START_LISTENING || con->state == BT_STATE_LISTENING)			BTSocketStopListen(con->sock);		con->reconnecting = 0;		INIT_CONNECT_TIMER(con, BT_TO_CONNECT_TOTAL);		UPDATE_STATE(con->state, BT_STATE_START_CONNECTING);	} else {		if (BTSocketSend(con->sock, buf, len , sent, BT_TO_NONE) != BT_ERR_NONE) {			BTSocketClose(con->sock);			DEBUG_LOG1("direct send failed, reconnecting %s", strerror(errno));			INIT_CONNECT_TIMER(con, BT_TO_RECONNECT_TOTAL);			UPDATE_STATE(con->state, BT_STATE_START_CONNECTING);			return BT_ERR_CONNECTION;		}	}	return BT_ERR_NONE;}int BTHandlerReceive(BTConnection con, char *buf, int len, int *received){	int res;	if (!con || !buf || !received)		return BT_ERR_ARGUMENT;	if (con->state != BT_STATE_CONNECTED)		return BT_ERR_STATE;	res = BTSocketReceive(con->sock, buf, len, received, BT_TO_NONE);	switch (res) {	case BT_ERR_TIMEOUT:		*received = 0;		res = BT_ERR_NONE;		break;	case BT_ERR_NONE:#ifdef ENABLE_DEBUG_LOG		if (*received <= BT_DBGBUF_LEN) {			if (*received)				strncpy(dbgbuf, buf, *received);			buf[*received] = '\0';			DEBUG_LOG3("buf=[%s], len=%d, received=%d", buf, len, *received);		} else {			DEBUG_LOG("debug buffer is too small!");		}#endif //ENABLE_DEBUG_LOG		res = BT_ERR_NONE;		break;	case BT_ERR_FAILED:		DEBUG_LOG1("receive failed, reconnecting: %s", strerror(errno));		BTSocketClose(con->sock);		con->reconnecting = 1;		INIT_CONNECT_TIMER(con, BT_TO_RECONNECT_TOTAL);		UPDATE_STATE(con->state, BT_STATE_START_CONNECTING);		*received = 0;		res = BT_ERR_CONNECTION;		break;	default:		DEBUG_LOG("UNHANDLED ERROR!!!");		res = BT_ERR_FAILED;		*received = 0;		break;	}	return res;}int BTHandlerRelease(BTConnection con){	DEBUG_LOG1("state=%s", STATE2STR(con->state));	if (!con)		return BT_ERR_ARGUMENT;	if (con->state != BT_STATE_START_CONNECTING && con->state != BT_STATE_CONNECTING && con->state != BT_STATE_CONNECTED && con->state != BT_STATE_REMOVE_CONNECTION)		return BT_ERR_STATE;	BTSocketClose(con->sock);	if (con->sendbuf)		free(con->sendbuf);	con->sendbuf = NULL;	con->sendbuflen = 0;	if (con->flags & BT_FLAG_LISTEN) {		DEBUG_LOG("release to listening");		INIT_LISTEN_TIMER(con, BT_TO_LISTEN_TOTAL);		UPDATE_STATE(con->state, BT_STATE_START_LISTENING);	} else {		DEBUG_LOG("release to initialized");		UPDATE_STATE(con->state, BT_STATE_INITIALIZED);	}		return BT_ERR_NONE;}int BTHandlerClose(BTConnection con){	int pid;	DEBUG_LOG1("state=%s", STATE2STR(con->state));	if (!con)		return BT_ERR_ARGUMENT;	if (con->state == BT_STATE_APP_START || con->state == BT_STATE_APP_READY || con->state == BT_STATE_APP_CLOSING) {		if (con->state != BT_STATE_APP_CLOSING) {			pid = BTGetFileInt(BT_PPP_PIDFILE);			if (pid > 0) {				DEBUG_LOG1("terminating %d", pid);				kill(pid, SIGTERM);			}		}		BTSetTimer(&con->ppp.removetr, BT_TO_APPREMOVE);		UPDATE_STATE(con->state, BT_STATE_CLOSING);		UPDATE_STATE(con->ppp.state, BT_PPP_STATE_CLOSING);	} else if (con->state != BT_STATE_CLOSING) {		BTSocketClose(con->sock);		if (con->sendbuf)			free(con->sendbuf);		con->sendbuf = NULL;		con->sendbuflen = 0;		UPDATE_STATE(con->state, BT_STATE_CLOSING);		UPDATE_STATE(con->ppp.state, BT_PPP_STATE_UNINITIALIZED);	}	return BT_ERR_NONE;}int BTHandlerGetState(cBTConnection con, int *state){	if (!con || !state)		return BT_ERR_ARGUMENT;//	DEBUG_LOG1("state=%s", STATE2STR(con->state));	*state = con->state;		return BT_ERR_NONE;}int BTHandlerGetError(cBTConnection con, int *error){	if (!con || !error)		return BT_ERR_ARGUMENT;	DEBUG_LOG1("error=%s", ERROR2STR(con->error));	*error = con->error;		return BT_ERR_NONE;}int BTHandlerSetFlags(BTConnection con, int flags){	DEBUG_LOG3("flags=0x%X -> 0x%X, state=%s", con->flags, flags, STATE2STR(con->state));	if (!con)		return BT_ERR_ARGUMENT;	if (!(con->flags & BT_FLAG_LISTEN) && (flags & BT_FLAG_LISTEN) && con->state == BT_STATE_INITIALIZED) {		INIT_LISTEN_TIMER(con, BT_TO_LISTEN_TOTAL);		UPDATE_STATE(con->state, BT_STATE_START_LISTENING);	}	else if (!(con->flags & BT_FLAG_OPEN) && (flags & BT_FLAG_OPEN) && (con->state == BT_STATE_START_LISTENING || con->state == BT_STATE_LISTENING || con->state == BT_STATE_INITIALIZED) && !(con->flags & BT_FLAG_DONOTRECONNECT)) {		if (con->state == BT_STATE_START_LISTENING || con->state == BT_STATE_LISTENING)			BTSocketStopListen(con->sock);		con->reconnecting = 0;		INIT_CONNECT_TIMER(con, BT_TO_CONNECT_TOTAL);		UPDATE_STATE(con->state, BT_STATE_START_CONNECTING);	}	con->flags = flags;	return BT_ERR_NONE;}int BTHandlerGetFlags(cBTConnection con, int *flags){	if (!con || !flags)		return BT_ERR_ARGUMENT;	*flags = con->flags;		DEBUG_LOG2("flags=0x%X, state=%s", *flags, STATE2STR(con->state));	return BT_ERR_NONE;}int BTHandlerIsProfileActive(cBTConnection con, int profile, int *res){	if (!con || !profile)		return BT_ERR_ARGUMENT;	if (con->profile == profile && (con->state == BT_STATE_CONNECTED || con->state == BT_STATE_APP_READY))		*res = BT_TRUE;	else		*res = BT_FALSE;	return BT_ERR_NONE;}int BTHandlerNeedPair(cBTConnection con, int *res){	if (con->state == BT_STATE_START_LISTENING || con->state == BT_STATE_LISTENING ||	    con ->state == BT_STATE_START_CONNECTING || con->state == BT_STATE_CONNECTING ||	    con->state == BT_STATE_APP_START)		*res = BT_TRUE;	else		*res = BT_FALSE;	return BT_ERR_NONE;}int BTHandlerRun(BTConnection con){	int i, res, sent, pid;

⌨️ 快捷键说明

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