FreeCalypso > hg > themwi-system-sw
view sip-out/mncc_sock.c @ 178:b259e2722485
README: update for current status
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 09 Mar 2023 13:08:31 -0800 |
parents | e54b0a9e322f |
children |
line wrap: on
line source
/* * 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); }