FreeCalypso > hg > themwi-system-sw
diff sip-out/mncc_sock.c @ 154:e54b0a9e322f
beginning of themwi-sip-out
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2022 23:04:01 -0800 |
parents | mncc/mtsock.c@db7ed6a55ba4 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sip-out/mncc_sock.c Tue Oct 11 23:04:01 2022 -0800 @@ -0,0 +1,153 @@ +/* + * In this module we implement the MNCC socket interface to themwi-sip-out. + * We have an outcall socket on which we accept connections, and each + * accepted connection becomes a struct mncc_conn for us. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <syslog.h> +#include <unistd.h> +#include "../include/mncc.h" +#include "../include/out_routes.h" +#include "call.h" + +static char outcall_socket_pathname[] = "/var/gsm/outcall_socket"; + +int mncc_listener; +struct mncc_conn *mncc_conn_list; + +create_outcall_socket() +{ + struct sockaddr_un sa; + unsigned sa_len; + int rc; + + mncc_listener = socket(AF_UNIX, SOCK_SEQPACKET, 0); + if (mncc_listener < 0) { + syslog(LOG_CRIT, "socket(AF_UNIX, SOCK_SEQPACKET, 0): %m"); + return(-1); + } + unlink(outcall_socket_pathname); + fill_sockaddr_un(outcall_socket_pathname, &sa, &sa_len); + rc = bind(mncc_listener, (struct sockaddr *) &sa, sa_len); + if (rc < 0) { + syslog(LOG_ERR, "bind to %s: %m", outcall_socket_pathname); + return(-1); + } + rc = listen(mncc_listener, 3); + if (rc < 0) { + syslog(LOG_CRIT, "listen on UNIX socket: %m"); + return(-1); + } + chmod(outcall_socket_pathname, 0775); + update_max_fd(mncc_listener); + return(0); +} + +void +mncc_listener_select() +{ + struct sockaddr_un sa; + socklen_t sa_len; + int fd; + struct mncc_conn *conn; + + sa_len = sizeof sa; + fd = accept(mncc_listener, (struct sockaddr *) &sa, &sa_len); + if (fd < 0) { + syslog(LOG_CRIT, "accept on UNIX socket: %m"); + exit(1); + } + conn = malloc(sizeof(struct mncc_conn)); + if (!conn) { + syslog(LOG_CRIT, "malloc for outcall socket conn: %m"); + close(fd); + return; + } + syslog(LOG_INFO, "new outcall socket connection"); + conn->fd = fd; + conn->next = mncc_conn_list; + mncc_conn_list = conn; + update_max_fd(fd); +} + +static void +dispatch_mncc_msg(mncc, msg, msglen) + struct mncc_conn *mncc; + union mncc_msg *msg; + unsigned msglen; +{ + switch (msg->msg_type) { + case MNCC_SETUP_IND: + handle_setup_ind(mncc, msg, msglen); + return; + case MNCC_SETUP_COMPL_IND: + case MNCC_NOTIFY_IND: + case MNCC_DISC_IND: + case MNCC_FACILITY_IND: + case MNCC_START_DTMF_IND: + case MNCC_STOP_DTMF_IND: + case MNCC_MODIFY_IND: + case MNCC_HOLD_IND: + case MNCC_RETRIEVE_IND: + case MNCC_USERINFO_IND: + case MNCC_REL_IND: + case MNCC_REL_CNF: + handle_mncc_signal(mncc, msg, msglen); + return; + case MNCC_RTP_CREATE: + handle_rtp_create(mncc, msg, msglen); + return; + case MNCC_RTP_CONNECT: + syslog(LOG_ERR, "MNCC_RTP_CONNECT error from OsmoMSC"); + return; + case MNCC_RTP_FREE: + syslog(LOG_ERR, "MNCC_RTP_FREE bogon from OsmoMSC"); + return; + default: + syslog(LOG_CRIT, + "FATAL: received unexpected MNCC message type 0x%x", + msg->msg_type); + exit(1); + } +} + +void +mncc_socket_select(conn) + struct mncc_conn *conn; +{ + union mncc_msg msg; + int rc; + + rc = recv(conn->fd, &msg, sizeof msg, 0); + if (rc <= 0) { + syslog(LOG_ERR, "outcall socket disconnected"); + close(conn->fd); + conn->fd = -1; + shutdown_mncc_socket(conn); + return; + } + if (rc < 4) { + syslog(LOG_CRIT, "short read from MNCC socket: %d bytes", rc); + exit(1); + } + dispatch_mncc_msg(conn, &msg, rc); +} + +send_mncc_to_sock(mncc, msg, msglen) + struct mncc_conn *mncc; + union mncc_msg *msg; + unsigned msglen; +{ + return send(mncc->fd, msg, msglen, 0); +}