📄 btd.c
字号:
void init_stack(int spd){ printf("Init stack\n"); #ifdef BTD_USERSTACK /* Direct function calls instead of ioctls... */ init_read_thread(); /* Initialise all layers in the bluetooth stack */ DSYS("Initialising Bluetooth Stack\n"); hci_init(); l2cap_init(); rfcomm_init(); sdp_init(role); tcs_init(); test_init(); btmem_init(); bt_stat.bytes_received = 0; bt_stat.bytes_sent = 0; bt_initdone = 1;#else /* Kernel mode stack */ /* FIXME -- add ioctls for all hci functions */ if (ioctl(bt_cfd, BTINITSTACK)<0) { perror("Init stack"); exit(1); }#endif /* FIXME: Maybe we should read this parameters from somwhere... */ bt_set_classofdevice(bt_cfd, 0x10, 0x3, 0x0, 0x0);#ifndef __CRIS__ set_local_name(local_name); #endif if (hw_init) init_hw(spd);}void shutdown_stack(void){ syslog(LOG_INFO, "Shutting down bluetooth stack\n");#ifndef BTD_USERSTACK if (bt_cfd != -1 && (ioctl(bt_cfd, BTSHUTDOWN) < 0)) { syslog(LOG_ERR, "Shutting down stack failed (bt_cfd = %d)", bt_cfd); }#else if (bt_initdone) { rfcomm_close(); sdp_shutdown(); tcs_shutdown(); l2cap_shutdown(); btmem_shutdown(); bt_initdone = 0; }#endif btd_killchilds();}int open_device(char* dev, int flags, int role){ int fd;#ifdef BTD_USERSTACK /* if opening bt dev or control dev simply discard and return fake fd */ if ((strcmp(dev, btdev) == 0) || (strcmp(dev, BT_CTRL_TTY) == 0)) return 0xb055e; if (use_local_socket) return open_socket(dev, role); else if (use_tcp_socket) return open_tcpsocket(dev, role);#endif syslog(LOG_INFO, "Opening dev %s\n", dev); if ((fd = open(dev, flags | O_NOCTTY)) < 0) { perror("open_device"); exit(1); } tcflush(fd, TCIOFLUSH); return fd;}void close_device(int fd){ syslog(LOG_INFO, "close_device"); #ifdef BTD_USERSTACK /* if fake fd is used, ignore close since there are no open fd */ if (fd != 0xb055e) close(fd);#else if (fd != -1) close(fd);#endif}//#define PALM_FIX #ifdef PALM_FIXint search_str(char *data, const char *searchstr) { int cur = 0; int len = strlen(data); if (len < 0) return 0; while (cur < (len-strlen(searchstr))) { if(!strncasecmp(data+cur, searchstr, strlen(searchstr))) { /* found searchstr */ //printf("search_str : found %s!\n", (char*)search_str); return 1; } cur++; } return 0;}#endifint parse_modem_data(char *databuf, int len, int bt_fd){ int i; syslog(LOG_INFO, "parse_modem_data : %d chars", len); databuf[len] = 0; syslog(LOG_INFO, "data : %s", databuf); if (len <= 0) { if (btd_shuttingdown) return SHUTDOWN; else return RESTART; } /* Check if data is a ppp frame, if so start pppd right away and hope we catch a retransmission */ for (i = 0; i < len; i++) { if (databuf[i] == PPP_DELIMITER) { /* fixme<3> -- check prot field + LCP code for conf req aswell we are also depening on a non-fragmented ppp frame i.e the delimiter comes in the same chunk as the rest... */ if ((len - i) >= 7) { if (((databuf[i+7]^0x20) == PPP_TERM_REQ)) { syslog(LOG_INFO, "Found PPP Terminate don't start pppd"); return RESTART; } } return DO_PPP; } } if(!strncasecmp(databuf, "ATD", 3)) /* windows standard modem */ { syslog(LOG_INFO, "got ATD"); return CONNECT; } else if(!strncasecmp(databuf, "CLIENT", 6)) /* windows null modem */ { syslog(LOG_INFO, "got CLIENT"); return NULLCONNECT; }#ifdef PALM_FIX else if (search_str(databuf, "DT")) /* palm */ { syslog(LOG_INFO, "found DT"); return CONNECT; }#endif else if (!strncasecmp(databuf, "HELLO", 5)) /* windows null modem */ { syslog(LOG_INFO, "got HELLO"); return HELLOCONNECT; } else if (!strncasecmp(databuf, "AT", 2)) /* AT command */ { return SEND_OK; } else return SEND_OK;}void modem_emulator(int bt_fd, char *data, int len){ int done = 0; /* FIXME -- adjust this to real speed */ char *connect = "CONNECT 115200\r\n"; char *client_server = "CLIENTSERVER\r\n"; char *ok = "OK\r\n"; char *hello = "HELLO\r\n";#ifdef BTD_USERSTACK if ((bt_fd == 0xb055e) && (len > 0)) { data[len] = 0; done = parse_modem_data(data, len, bt_fd); if (done == CONNECT) {#ifdef PALM_FIX sleep(2); /* wait for client */#endif syslog(LOG_INFO, "Write : %s", connect); bt_write_top(connect, strlen(connect), 0); syslog(LOG_INFO, "Modem connected !"); modem_connected = 1; } else if (done == NULLCONNECT) { bt_write_top(client_server, strlen(client_server),0); syslog(LOG_INFO, "Nullmodem connected !"); modem_connected = 1; } else if (done == RESTART) { /* If we got a SIGHUP from kernel reopen btdev */ syslog(LOG_INFO, "Restart modem emulator..."); close_device(bt_fd); bt_fd = open_device(btdev, O_RDWR, 0); done = 0; } else if (done == HELLOCONNECT) { bt_write_top(hello, strlen(hello), 0); syslog(LOG_INFO, "Hellomodem connected !"); modem_connected = 1; } else if (done == DO_PPP) { syslog(LOG_INFO, "LAN Access no CLIENT - CLIENTSERVER"); modem_connected = 1; } else if (done == SEND_OK) { syslog(LOG_INFO, "Modem emulator replies %s", ok); bt_write_top(ok, strlen(ok), 0); } else { syslog(LOG_INFO, "LAN Access no CLIENT - CLIENTSERVER"); modem_connected = 0; } } /* return and possibly wait for new modem data (is fed from bt_receive_top) */ return; #else /* BTD_USERSTACK */ fd_set rfd; char databuf[128]; while (!modem_connected) { FD_ZERO(&rfd); FD_SET(bt_fd, &rfd); select(FD_SETSIZE, &rfd, NULL, NULL, NULL); if (FD_ISSET(bt_fd, &rfd)) { int len = read(bt_fd, &databuf, 128); databuf[len] = 0; done = parse_modem_data(databuf, len, bt_fd); if (done == CONNECT) {#ifdef PALM_FIX sleep(2); /* wait for client */#endif syslog(LOG_INFO, "Write : %s", connect); write(bt_fd, connect, strlen(connect)); syslog(LOG_INFO, "Modem connected !"); modem_connected = 1; } else if (done == NULLCONNECT) { write(bt_fd, client_server, strlen(client_server)); syslog(LOG_INFO, "Nullmodem connected !"); modem_connected = 1; } else if (done == RESTART) { /* If we got a SIGHUP from kernel reopen btdev */ syslog(LOG_INFO, "Restart modem emulator..."); close_device(bt_fd); bt_fd = open_device(btdev, O_RDWR, 0); done = 0; } else if (done == SHUTDOWN) { syslog(LOG_INFO, "Shutting down modem emulator\n"); return; } else if (done == HELLOCONNECT) { write(bt_fd, hello, strlen(hello)); syslog(LOG_INFO, "Hellomodem connected !"); modem_connected = 1; } else if (done == DO_PPP) { syslog(LOG_INFO, "LAN Access no CLIENT - CLIENTSERVER"); modem_connected = 1; } else if (done == SEND_OK) { syslog(LOG_INFO, "Modem emulator replies %s", ok); write(bt_fd, ok, strlen(ok)); } else { syslog(LOG_INFO, "Modem emulator replies OK"); write(bt_fd, ok, strlen(ok)); } } }#endif}static voidbtd_cleanup(void){ btd_killchilds(); shutdown_stack(); if (bt_fd != -1) { close_device(bt_fd); bt_fd = -1; } if (bt_cfd != -1) { close_device(bt_cfd); bt_cfd = -1; } /* now close phys device */ if (phys_fd != -1) { tcflush(phys_fd, TCIOFLUSH); close_device(phys_fd); phys_fd = -1; } /* pid_fd is set if we created the pid file when we started */ if (pid_fd != -1) { unlink(PID_FILE); }}static voidbtd_killchilds(void){ if (sdpsrv_pid > 0 && role == SERVER) { syslog(LOG_INFO, "Killing SDP server\n"); kill(sdpsrv_pid, SIGTERM); if (waitpid(sdpsrv_pid, NULL, 0) < 0) perror("waitpid sdp server"); sdpsrv_pid = 0; } if (pppd_pid > 0) { syslog(LOG_INFO, "Killing pppd\n"); kill(pppd_pid, SIGTERM); if (waitpid(pppd_pid, NULL, 0) < 0) perror("waitpid pppd"); pppd_pid = 0; }}const char* signame(int sig){ switch (sig) { case SIGHUP: return "SIGHUP"; break; case SIGINT: return "SIGINT"; break; case SIGCHLD: return "SIGCHLD"; break; case SIGQUIT: return "SIGQUIT"; break; case SIGTERM: return "SIGTERM"; break; default : return "Unknown signal"; }}static voidbtd_sighandler(int sig){#ifdef __CRIS__ if (sig == SIGUSR1) {#ifdef RESTART_ENABLED printf("resetting hw to activate bd change\n"); btd_killchilds(); shutdown_stack(); close_device(bt_fd); close_device(bt_cfd); close_device(phys_fd); bt_fd = -1; bt_cfd = -1; phys_fd = -1; reset_hw(); siglongjmp(jmpbuffer, 1);#else printf("reset HW to activate bd change\n"); return;#endif }#endif /* __CRIS__ */ if (btd_shuttingdown) { syslog(LOG_INFO, "Why are we getting more than one signal here ?\n"); return; } btd_shuttingdown = 1; exit(0);}static voidinit_sighandler(void){ struct sigaction act; syslog(LOG_INFO, "Initiating signal handler\n"); act.sa_handler = btd_sighandler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGHUP, &act, 0); sigaction(SIGINT, &act, 0); sigaction(SIGQUIT, &act, 0); sigaction(SIGTERM, &act, 0);#ifdef __CRIS__ sigaction(SIGUSR1, &act, 0);#endif}#ifdef BTD_USERSTACK/* * USER STACK FUNCTIONS (instead of bluetooth.c) */int init_read_thread(void){ printf("Initiating read thread\n"); if (pthread_create(&read_thread, NULL, (void*)hci_receive_thread, NULL)!=0) perror("pthread_create"); return 0;}void hci_receive_thread(void){ fd_set rfd; char databuf[4096]; while (1) { FD_ZERO(&rfd); FD_SET(phys_fd, &rfd); select(phys_fd+1, &rfd, NULL, NULL, NULL); if (FD_ISSET(phys_fd, &rfd)) { int len = read(phys_fd, &databuf, 4096); if (len > 0) { BT_DATA("-->|X| %3d\n", len); PRINTPKT("data rec : ", databuf, len); hci_receive_data(databuf, len); } } }}/* * Allocate a pty master-slave pair. */int open_pty(void){ struct termios settings; int result; printf("Open pty.\n"); result = openpty(&pty_master_fd, &pty_slave_fd, ptydev, NULL, NULL); if (result < 0) { perror("openpty"); return result; } /* modify pty settinges -> turn off echo - mfuchs */ result = tcgetattr(pty_master_fd, &settings); if (result < 0) { perror("tcgetattr"); return result; } cfmakeraw(&settings); settings.c_lflag &= ~ECHO; result = tcsetattr(pty_master_fd, TCSANOW, &settings); if (result < 0) { perror("tcsetattr"); return result; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -