📄 a2dpd_ipc.c
字号:
/*** A2DPD - Bluetooth A2DP daemon for Linux** Copyright (C) 2006 Frédéric DALLEAU <frederic.dalleau@palmsource.com>** This program 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.** This program 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 this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/#include "a2dpd_ipc.h"#include <unistd.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <syslog.h>#include <errno.h>#include <signal.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/poll.h>#include <sys/un.h>#include <sys/stat.h> #include <sys/wait.h> #include <netinet/in.h>#include <arpa/inet.h>#include "a2dpd_protocol.h"#define DEFAULTIP "127.0.0.1"#define DEFAULTPORT 21453#define BROADCASTIP "127.0.0.255"#define ABSTRACT_SOCKET#ifdef ABSTRACT_SOCKET#define AFUNIX_PATH "\0/tmp/a2dpd"#else#define AFUNIX_PATH "/tmp/a2dpd"#endifstatic int enable_internet_socket = 0;void close_socket(int *sockfd){ if(*sockfd>0) { DBG("Closing %d", *sockfd); (void)shutdown(*sockfd, SHUT_RDWR); (void)close(*sockfd); } *sockfd = -1;}static int g_server_socket = -1;void close_server_socket_on_fork(){ DBG("Closing server socket %d", g_server_socket); if(g_server_socket>0) { if(enable_internet_socket) { (void)close(g_server_socket); } else { (void)close(g_server_socket); } }}void close_server_socket(int *sockfd){ if(*sockfd>0) { if(enable_internet_socket) { (void)shutdown(*sockfd, SHUT_RDWR); (void)close(*sockfd); } else { (void)shutdown(*sockfd, SHUT_RDWR); (void)close(*sockfd);#ifndef ABSTRACT_SOCKET (void)unlink(AFUNIX_PATH);#endif } } *sockfd = -1; g_server_socket = -1;}int make_udp_socket(){ int sockfd = socket(PF_INET, SOCK_DGRAM, 0); if(sockfd>0) { int broadcast=1; if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, (int)sizeof(broadcast)) == 0) { struct sockaddr_in peer_addr; peer_addr.sin_family = AF_INET; peer_addr.sin_port = htons(DEFAULTPORT); peer_addr.sin_addr.s_addr = inet_addr(BROADCASTIP); // Connect on a datagram socket simulate recvfrom with the address specified (void)bind(sockfd, (struct sockaddr *)&peer_addr, (int)sizeof(peer_addr)); if(connect(sockfd, (struct sockaddr*)&peer_addr, (int)sizeof(peer_addr)) == 0) { } else { (void)close(sockfd); sockfd=-1; } } else { (void)close(sockfd); sockfd=-1; } } return sockfd;}int make_client_socket(){ int sockfd = -1; if(enable_internet_socket) { sockfd = socket(PF_INET, SOCK_STREAM, 0); if(sockfd>0) { struct sockaddr_in peer_addr; peer_addr.sin_family = AF_INET; peer_addr.sin_port = htons(DEFAULTPORT); peer_addr.sin_addr.s_addr = inet_addr(DEFAULTIP); (void)connect(sockfd, (struct sockaddr*)&peer_addr, (int)sizeof(peer_addr)); } } else { sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if(sockfd>0) { struct sockaddr_un peer_addr; int peer_addr_size = (int)(sizeof(peer_addr.sun_family)+sizeof(AFUNIX_PATH));#ifdef ABSTRACT_SOCKET peer_addr_size--;#endif memset(&peer_addr, 0, sizeof(peer_addr)); peer_addr.sun_family = AF_UNIX; memcpy(peer_addr.sun_path, AFUNIX_PATH, sizeof(AFUNIX_PATH)); (void)connect(sockfd, (struct sockaddr*)&peer_addr, peer_addr_size); } } return sockfd;}int make_server_socket(){ int sockfd = -1; DBG(""); if(enable_internet_socket) { struct sockaddr_in my_addr; sockfd = socket(PF_INET, SOCK_STREAM, 0); memset(&my_addr, 0, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(DEFAULTPORT); my_addr.sin_addr.s_addr = INADDR_ANY; if(sockfd>0) { int on = 1; (void)setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, (int)sizeof(on)); if(bind(sockfd, (struct sockaddr *)&my_addr, (int)sizeof(struct sockaddr))==0) { if(listen(sockfd, 0)==0) { // No error } else { (void)close(sockfd); sockfd = -3; } } else { (void)close(sockfd); sockfd = -2; } } } else { struct sockaddr_un my_addr; int my_addr_size = (int)(sizeof(my_addr.sun_family)+sizeof(AFUNIX_PATH));#ifdef ABSTRACT_SOCKET my_addr_size --;#else (void)unlink(AFUNIX_PATH);#endif sockfd = socket(AF_UNIX, SOCK_STREAM, 0); memset(&my_addr, 0, sizeof(my_addr)); my_addr.sun_family = AF_UNIX; memcpy(my_addr.sun_path, AFUNIX_PATH, sizeof(AFUNIX_PATH)); if(sockfd>0) { int on = 1; (void)setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, (int)sizeof(on)); if(bind(sockfd, (struct sockaddr *)&my_addr, my_addr_size)==0) { if(listen(sockfd, 0)==0) {#ifndef ABSTRACT_SOCKET (void)chmod(AFUNIX_PATH, 0777);#endif // No error } else { (void)close(sockfd); sockfd = -3; } } else { (void)close(sockfd); sockfd = -2; } } } g_server_socket = sockfd; return sockfd;}int poll_accept(int sockfd, int timeout){ int result = 0; int ipoll = -1; struct pollfd pollfds[1]; memset(pollfds, 0, sizeof(pollfds)); // Poll pollfds[0].fd = sockfd; pollfds[0].events = POLLIN | POLLERR | POLLHUP; pollfds[0].revents = 0; //DBG("Polling %d", sockfd); ipoll = poll(pollfds, (nfds_t)ARRAY_SIZE(pollfds), timeout); // if(pollfds[0].revents) // DBG("Polled %d = %d %08X", sockfd, ipoll, pollfds[0].revents); if((ipoll>0) && (pollfds[0].revents & POLLIN)) { result = 1; } else if(ipoll==0) { errno = EAGAIN; } return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -