📄 sip_sock.c
字号:
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <osipparser2/osip_parser.h>
#include "nsrsbc.h"
/* socket used for sending SIP datagrams */
int sip_udp_socket = 0;
/*
* binds to SIP UDP socket for listening to incoming packets
*
* RETURNS
* STS_SUCCESS on success
* STS_FAILURE on error
*/
int sipsock_listen (void) {
struct in_addr ipaddr;
/* Set IP address to INADDR_ANY, so the socket will recevie
* all packets from both eth0 and eht1.
*/
memset(&ipaddr, 0, sizeof(ipaddr));
ipaddr.s_addr = htonl(INADDR_ANY);
sip_udp_socket = sockbind(ipaddr, SIP_LISTENING_PORT);
if (sip_udp_socket == 0) return STS_FAILURE;
return STS_SUCCESS;
}
/*
* Wait for incoming SIP message. After a 2 sec timeout
* this function returns with sts=0
*
* RETURNS >0 if data received, =0 if nothing received /T/O), -1 on error
*
*/
int sipsock_wait(void) {
int sts;
fd_set fdset;
struct timeval timeout;
timeout.tv_sec=2;
timeout.tv_usec=0;
FD_ZERO(&fdset);
FD_SET (sip_udp_socket, &fdset);
sts = select (sip_udp_socket+1, &fdset, NULL, NULL, &timeout);
/* WARN on failures */
if (sts < 0) {
/* WARN on failure, except if it is an "interrupted system call"
* as it will result by SIGINT, SIGTERM
*/
if (errno != 4) {
printf("sipsock: select() returned error [%i:%s]\n",errno, strerror(errno));
} else {
printf("sipsock: select() returned error [%i:%s]\n", errno, strerror(errno));
}
}
return sts;
}
/*
* Read a message from SIP listen socket (UDP datagram)
*
* RETURNS number of bytes read
* from is modified to return the sockaddr_in of the sender
*
*/
int sipsock_read(void *buf, size_t bufsize, struct sockaddr_in *from, int *protocol) {
int count;
socklen_t fromlen;
fromlen = sizeof(struct sockaddr_in);
*protocol = PROTO_UDP; /* up to now, unly UDP, TCP later */
count = recvfrom(sip_udp_socket, buf, bufsize, 0, (struct sockaddr *)from, &fromlen);
if (count<0) {
printf("sipsock: recvfrom() returned error [%s]\n",strerror(errno));
*protocol = PROTO_UNKN;
}
printf("sipsock: received UDP packet from %s, count=%i\n", inet_ntoa(from->sin_addr), count);
return count;
}
/*
* Sends an UDP datagram to the specified destination
*
* RETURNS
* STS_SUCCESS on success
* STS_FAILURE on error
*
*/
int sipsock_send(struct in_addr addr, int port, int protocol, char *buffer, size_t size) {
struct sockaddr_in dst_addr;
int sts;
/* first time: allocate a socket for sending */
if (sip_udp_socket == 0) {
printf("sipsock: SIP socket not allocated!\n");
return STS_FAILURE;
}
if (buffer == NULL) {
printf("sipsock: sipsock_send got NULL buffer!\n");
return STS_FAILURE;
}
if (protocol != PROTO_UDP) {
printf("sipsock: sipsock_send: only UDP supported by now!\n");
return STS_FAILURE;
}
dst_addr.sin_family = AF_INET;
memcpy(&dst_addr.sin_addr.s_addr, &addr, sizeof(struct in_addr));
dst_addr.sin_port= htons(port);
sts = sendto(sip_udp_socket, buffer, size, 0, (const struct sockaddr *)&dst_addr, (socklen_t)sizeof(dst_addr));
if (sts == -1) {
if (errno != ECONNREFUSED) {
printf("sipsock: sendto() [%s:%i size=%ld] call failed: %s\n", inet_ntoa(addr), port, (long)size, strerror(errno));
return STS_FAILURE;
}
printf("sipsock: sendto() [%s:%i] call failed: %s\n", inet_ntoa(addr), port, strerror(errno));
}
return STS_SUCCESS;
}
/*
* generic routine to allocate and bind a socket to a specified
* local address and port (UDP)
*
* RETURNS
* socket fd number on success
* zero on failure
*
*/
int sockbind(struct in_addr ipaddr, int localport) {
struct sockaddr_in my_addr;
int sts, on=1;
int sock;
int flags;
//printf("sock bind start!\n");
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
memcpy(&my_addr.sin_addr.s_addr, &ipaddr, sizeof(struct in_addr));
my_addr.sin_port = htons(localport);
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock < 0) {
printf("sipsock: socket call failed: %s\n",strerror(errno));
return 0;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on , sizeof(on)) < 0) {
printf("sipsock: setsockopt returned error [%i:%s]\n",errno, strerror(errno));
return 0;
}
sts = bind(sock, (struct sockaddr *)&my_addr, sizeof(my_addr));
if (sts != 0) {
printf("sipsock: bind failed: %s\n",strerror(errno));
close(sock);
return 0;
}
flags = fcntl(sock, F_GETFL);
if (flags < 0) {
printf("sipsock: fcntl(F_SETFL) failed: %s\n",strerror(errno));
close(sock);
return 0;
}
if (fcntl(sock, F_SETFL, (long) flags | O_NONBLOCK) < 0) {
printf("sipsock: fcntl(F_SETFL) failed: %s\n",strerror(errno));
close(sock);
return 0;
}
return sock;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -