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

📄 fbus.c

📁 NOKIA手机开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
					/* Add data to the relevant Message buffer */					/* having checked the sequence number */					m = &FBUSINST(state)->messages[i->message_type];					frm_num = i->message_buffer[i->frame_length - 2];					seq_num = i->message_buffer[i->frame_length - 1];					/* 0x40 in the sequence number indicates first frame of a message */					if ((seq_num & 0x40) == 0x40) {						/* Fiddle around and malloc some memory */						m->message_length = 0;						m->frames_to_go = frm_num;						if (m->malloced != 0) {							free(m->message_buffer);							m->malloced = 0;							m->message_buffer = NULL;						}						m->malloced = frm_num * m->message_length;						m->message_buffer = (char *) malloc(m->malloced);					} else if (m->frames_to_go != frm_num) {						dprintf("Missed a frame in a multiframe message.\n");						/* FIXME - we should make sure we don't ack the rest etc */					}					if (m->malloced < m->message_length + i->frame_length) {						m->malloced = m->message_length + i->frame_length;						m->message_buffer = (char *) realloc(m->message_buffer, m->malloced);					}					memcpy(m->message_buffer + m->message_length, i->message_buffer,					       i->frame_length - 2);					m->message_length += i->frame_length - 2;					m->frames_to_go--;					/* Send an ack (for all for now) */					fbus_tx_send_ack(i->message_type, seq_num & 0x0f, state);					/* Finally dispatch if ready */					if (m->frames_to_go == 0) {						message_buffer = m->message_buffer;						m->message_buffer = NULL;						m->malloced = 0;						sm_incoming_function(i->message_type, message_buffer,								     m->message_length, state);						free(message_buffer);					}				}			} else {				dprintf("Bad checksum!\n");			}		}		break;	}}/* This is the main loop function which must be called regularly *//* timeout can be used to make it 'busy' or not */static gn_error fbus_loop(struct timeval *timeout, struct gn_statemachine *state){	unsigned char buffer[255];	int count, res;	res = device_select(timeout, state);	if (res > 0) {		res = device_read(buffer, 255, state);		for (count = 0; count < res; count++)			fbus_rx_statemachine(buffer[count], state);	} else		return GN_ERR_TIMEOUT;	/* This traps errors from device_read */	if (res > 0)		return GN_ERR_NONE;	else		return GN_ERR_INTERNALERROR;}/* Prepares the message header and sends it, prepends the message start byte	   (0x1e) and other values according the value specified when called.	   Calculates checksum and then sends the lot down the pipe... */int fbus_tx_send_frame(u8 message_length, u8 message_type, u8 *buffer, struct gn_statemachine *state){	u8 out_buffer[FBUS_TRANSMIT_MAX_LENGTH + 5];	int count, current = 0;	unsigned char checksum;	/* FIXME - we should check for the message length ... */	/* Now construct the message header. */	if (IR_MODE(state))		out_buffer[current++] = FBUS_IR_FRAME_ID;	/* Start of the IR frame indicator */	else			/* connection_type == GN_CT_Serial */		out_buffer[current++] = FBUS_FRAME_ID;		/* Start of the frame indicator */	out_buffer[current++] = FBUS_DEVICE_PHONE;		/* Destination */	out_buffer[current++] = FBUS_DEVICE_PC;			/* Source */	out_buffer[current++] = message_type;			/* Type */	out_buffer[current++] = 0;				/* Length */	out_buffer[current++] = message_length;			/* Length */	/* Copy in data if any. */	if (message_length != 0) {		memcpy(out_buffer + current, buffer, message_length);		current += message_length;	}	/* If the message length is odd we should add pad byte 0x00 */	if (message_length % 2)		out_buffer[current++] = 0x00;	/* Now calculate checksums over entire message and append to message. */	/* Odd bytes */	checksum = 0;	for (count = 0; count < current; count += 2)		checksum ^= out_buffer[count];	out_buffer[current++] = checksum;	/* Even bytes */	checksum = 0;	for (count = 1; count < current; count += 2)		checksum ^= out_buffer[count];	out_buffer[current++] = checksum;	/* Send it out... */	if (device_write(out_buffer, current, state) != current)		return false;	return true;}/* Main function to send an fbus message *//* Splits up the message into frames if necessary */static gn_error fbus_send_message(unsigned int messagesize, unsigned char messagetype, unsigned char *message, struct gn_statemachine *state){	u8 seqnum, frame_buffer[FBUS_CONTENT_MAX_LENGTH + 2];	u8 nom, lml;		/* number of messages, last message len */	int i;	seqnum = 0x40 + FBUSINST(state)->request_sequence_number;	FBUSINST(state)->request_sequence_number =	    (FBUSINST(state)->request_sequence_number + 1) & 0x07;	if (messagesize > FBUS_CONTENT_MAX_LENGTH) {		nom = (messagesize + FBUS_CONTENT_MAX_LENGTH - 1)		    / FBUS_CONTENT_MAX_LENGTH;		lml = messagesize - ((nom - 1) * FBUS_CONTENT_MAX_LENGTH);		for (i = 0; i < nom - 1; i++) {			memcpy(frame_buffer, message + (i * FBUS_CONTENT_MAX_LENGTH),			       FBUS_CONTENT_MAX_LENGTH);			frame_buffer[FBUS_CONTENT_MAX_LENGTH] = nom - i;			frame_buffer[FBUS_CONTENT_MAX_LENGTH + 1] = seqnum;			fbus_tx_send_frame(FBUS_CONTENT_MAX_LENGTH + 2,					  messagetype, frame_buffer, state);			seqnum = FBUSINST(state)->request_sequence_number;			FBUSINST(state)->request_sequence_number = (FBUSINST(state)->request_sequence_number + 1) & 0x07;		}		memcpy(frame_buffer, message + ((nom - 1) * FBUS_CONTENT_MAX_LENGTH), lml);		frame_buffer[lml] = 0x01;		frame_buffer[lml + 1] = seqnum;		fbus_tx_send_frame(lml + 2, messagetype, frame_buffer, state);	} else {		memcpy(frame_buffer, message, messagesize);		frame_buffer[messagesize] = 0x01;		frame_buffer[messagesize + 1] = seqnum;		fbus_tx_send_frame(messagesize + 2, messagetype,				  frame_buffer, state);	}	return GN_ERR_NONE;}static int fbus_tx_send_ack(u8 message_type, u8 message_seq, struct gn_statemachine *state){	unsigned char request[2];	request[0] = message_type;	request[1] = message_seq;	dprintf("[Sending Ack of type %02x, seq: %x]\n",message_type, message_seq);	return fbus_tx_send_frame(2, 0x7f, request, state);}/* Initialise variables and start the link *//* state is only passed around to allow for muliple state machines (one day...) */gn_error fbus_initialise(int attempt, struct gn_statemachine *state){	unsigned char init_char = 0x55;	int count;	bool connection = false;	/* Fill in the link functions */	state->link.loop = &fbus_loop;	state->link.send_message = &fbus_send_message;	/* Check for a valid init length */	if (state->config.init_length == 0)		state->config.init_length = 250;	/* Start up the link */	if ((FBUSINST(state) = calloc(1, sizeof(fbus_link))) == NULL)		return GN_ERR_MEMORYFULL;	FBUSINST(state)->request_sequence_number = 0;	switch (state->config.connection_type) {	case GN_CT_Infrared:	case GN_CT_Tekram:		connection = fbus_ir_open(state);		break;	case GN_CT_Serial:	case GN_CT_TCP:		switch (attempt) {		case 0:		case 1:			connection = fbus_serial_open(1 - attempt, state);			break;		case 2:			connection = at2fbus_serial_open(state, state->config.connection_type);			break;		default:			break;		}		break;	case GN_CT_DAU9P:		connection = fbus_serial_open(0, state);		break;	case GN_CT_DLR3P:		switch (attempt) {		case 0:			connection = at2fbus_serial_open(state, GN_CT_Serial);			break;		case 1:			connection = fbus_serial_open(1, state);			break;		default:			break;		}		break;#ifdef HAVE_BLUETOOTH	case GN_CT_Bluetooth:		connection = at2fbus_serial_open(state, state->config.connection_type);		break;#endif	default:		break;	}	if (!connection) {		free(FBUSINST(state));		FBUSINST(state) = NULL;		return GN_ERR_FAILED;	}	/* Send init string to phone, this is a bunch of 0x55 characters. Timing is	   empirical. */	/* I believe that we need/can do this for any phone to get the UART synced */	if (state->config.connection_type != GN_CT_Bluetooth && state->config.connection_type != GN_CT_TCP) {		for (count = 0; count < state->config.init_length; count++) {			usleep(100);			device_write(&init_char, 1, state);		}	}	/* Init variables */	FBUSINST(state)->i.state = FBUS_RX_Sync;	FBUSINST(state)->i.buffer_count = 0;	for (count = 0; count < FBUS_MESSAGE_MAX_TYPES; count++) {		FBUSINST(state)->messages[count].malloced = 0;		FBUSINST(state)->messages[count].frames_to_go = 0;		FBUSINST(state)->messages[count].message_length = 0;		FBUSINST(state)->messages[count].message_buffer = NULL;	}	return GN_ERR_NONE;}

⌨️ 快捷键说明

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