Current directory :
Root directory

Tree directory :
ilya.muromec@jabber.ru
  Filter :
  Language :  
 
/* 
   bton - tell tapisrv to turn on Bluetooth chip.
 
   Copyright (C) Ho Ming Shun      cyph
                                    at	
                               cyph.ath.cx
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2 as
   published by the Free Software Foundation;
 
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
   SOFTWARE IS DISCLAIMED.
*/
 
/*
 * Apparently, ezx_bt tells tapisrv to enable the bluetooth chip when it starts up through
 * some kind of binary RPC protocol. tapisrv will use an AT command (AT+EBTP=1) to powerup 
 * bluetooth!! (what the hell does bluetooth got to do with the GSM module??)
 *
 * This program is created by running strace output through a Vim macro :)
 *
 * Based on observations of other users, it seems tapisrv returns the BD_ADDR to be programmed
 * into the bluetooth chip. bton will take this BD_ADDR and write it into /tmp/bd_addr
 * in the format that dload expects.
*/
 
/*
 *  Modificado por Fábio Belavenuto <belavenuto@gmail> para funcionar no A1200
 */
 
//#define DEBUG 1
 
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <asm/ioctls.h>
 
#define END 0
#define WRITE 1
#define READ 2
#define OPENTTY 3
#define BDADDR 4
#define MAX_DATA 12
 
struct rw_op {
	char op;
	unsigned char data[MAX_DATA];
	int len;
 
};
 
struct rw_op tapi_ops_on[] =
{
	{ WRITE, {0x02, 0x81, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00}, 8 },
	{ WRITE, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, 12 },
	{ READ, {0x02, 0x81, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, 8 },
	{ READ, {0x00, 0x00, 0x00, 0x00}, 4 },
	{ WRITE, {0x11, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 8 },
	{ READ, {0x11, 0x86, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}, 8 },
	{ BDADDR, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 10 },
	{ WRITE, {0x13, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 8 },
	{ READ, {0x13, 0x86, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}, 8 },
	{ READ, {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff}, 8 },
	{ END },
};
 
struct rw_op tapi_ops_off[] =
{
	{ WRITE, {0x02, 0x81, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00}, 8 },
	{ WRITE, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 12 },
	{ READ, {0x02, 0x81, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, 8 },
	{ READ, {0x00, 0x00, 0x00, 0x00}, 4 },
	{ END },
};
 
char bdaddr[13];
void read_write(int fd, struct rw_op ops[]);
void read_bdaddr(int fd);
void dump(unsigned char *start, int len);
 
int main(int argc, char **argv)
{
	int tapisock;
	int startchip=1;
	struct sockaddr_un tapiaddr;
	unsigned short pid;
	char cmdline[255];
 
	/* shutdown */
	if (argc > 1 && strcmp(argv[1], "-s") == 0)
	{
		startchip=0;
	}
 
	if((tapisock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
	{
		perror("cannot create socket");
		exit(1);
	}
 
	tapiaddr.sun_family = AF_UNIX;
	strcpy(tapiaddr.sun_path, "/tmp/tapisock");
 
	if(connect(tapisock, (struct sockaddr*)&tapiaddr, sizeof(tapiaddr.sun_family) + strlen(tapiaddr.sun_path)))
	{
		perror("cannot connect");
		//exit(1);
	}
#ifdef DEBUG
	printf("Connected. Starting read/write\n");
#endif
	pid = getpid();
	tapi_ops_on[1].data[0] = (char)(pid & 0xFF);
	tapi_ops_on[1].data[1] = (char)((pid >> 8) & 0xFF);
	tapi_ops_off[1].data[0] = (char)((pid) & 0xFF);
	tapi_ops_off[1].data[1] = (char)(((pid) >> 8) & 0xFF);
	if (startchip)
	{
		//read_write(tapisock, tapi_ops_on);
                unsigned short state;
                int ret, fd;
                fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY);
 
                ret = ioctl(fd, TIOC_BT_VOLTAGE_OFF, &state);
                printf("OFF: %d, %d\n",ret, state);
                usleep(200000);
                ioctl(fd, TIOC_BT_VOLTAGE_ON,  &state);
                printf("ON:  %d, %d\n", ret, state);
 
                close(fd);
 
		sprintf(cmdline, "/usr/SYSbt/mbtdload /dev/ttyS1 1 921600 0009DD502319 1 0 -1", bdaddr);
#ifdef DEBUG
		printf("Executando %s\n", cmdline);
#endif
		system(cmdline);
	}
	else
		read_write(tapisock, tapi_ops_off);
	close(tapisock);
	return 0;
}
 
void read_write(int fd, struct rw_op ops[])
{
	struct rw_op *curr = ops;
	char buf[MAX_DATA];
	int readlen;
 
	while(curr->op != END)
	{
		switch(curr->op)
		{
			case WRITE:
#ifdef DEBUG
				printf("Writing %02d bytes: ", curr->len);
				dump(curr->data, curr->len);
				printf("\n");
#endif
				if(write(fd, curr->data, curr->len) < 0)
				{
					perror("write failed");
					exit(1);
				}
			break;
 
			case READ:
#ifdef DEBUG
				printf("Reading %02d bytes: \n", curr->len);
#endif
				readlen = 0;
				while(readlen != curr->len)
				{
					if((readlen += read(fd, buf + readlen, curr->len - readlen)) < 0)
					{
						perror("read failed");
					}
				}
#ifdef DEBUG
				printf("Read      : ");
				dump(buf, curr->len);
				printf("\n");
 
				printf("Expecting : ");
				dump(curr->data, curr->len);
				printf("\n");
#endif
				if(memcmp(curr->data, buf, curr->len)) 
				{
					perror("read wrong");
				}
 
			break;
 
			case BDADDR:
#ifdef DEBUG
				printf("Reading BD ADDR:\n");
#endif
				readlen = 0;
				while(readlen != curr->len)
				{
					if((readlen += read(fd, buf + readlen, curr->len - readlen)) < 0)
					{
						perror("read failed");
					}
				}
#ifdef DEBUG
				printf("Read      : ");
				dump(buf, curr->len);
				printf("\n");
#endif
				sprintf(bdaddr, "%02x%02x%02x%02x%02x%02x", buf[4], buf[5], buf[6], buf[7], buf[8], buf[9]);
			break;
		}
		curr++;
	}
}
#ifdef DEBUG
void dump(unsigned char *start, int len)
{
	int i;
 
	for(i = 0; i < len; i++) {
		printf("%02x ", (unsigned int)start[i]);
	}
}
#endif
 
VIP: No | Used: 83M/101M | 0.076 sec / GZIP-2