📄 pkthandler.c
字号:
/* pkthandler.c -- Control packet handler for intercom Copyright (C) 2001-2003 Shane Wegner This file is part of Intercom. Intercom is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. Intercom 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 version 2 of the GNU General Public License along with Intercom; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA To contact the author, please send email to shane@cm.nu. *//* $Id: pkthandler.c,v 1.37 2003/02/13 20:22:49 shane Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <assert.h>#include <errno.h>#include <time.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/socket.h>#if defined(HAVE_SYS_SOUNDCARD_H)#include <sys/soundcard.h>#elif defined(HAVE_MACHINE_SOUNDCARD_H)#include <machine/soundcard.h>#else#include <soundcard.h>#endif#include <sys/ioctl.h>#include <netinet/in.h>#include <arpa/inet.h>#ifdef USE_GETTEXT#include <libintl.h>#define _(String) gettext(String)#define gettext_noop(String) (String)#define N_(String) gettext_noop(String)#else#define _(String) (String)#define N_(String) (String)#endif#include "intercom.h"#include "protocol.h"#include "iobuff.h"#include "console.h"#include "userdefs.h"#include "hooks.h"void handle_pkt_hello(struct pkt_hello *pkt){if (pkt->proto_version != INTERCOM_PROTOCOL_VERSION) {fprintf(stderr, _("Error: host %s protocol version %d and we speak version %d\n"),call.r_hostent->h_name, pkt->proto_version, INTERCOM_PROTOCOL_VERSION);send_errorpkt(&call.cssq, PKT_ERROR_PROTO_VERSION);closecall();}memcpy(&call.r_hellopkt, pkt, sizeof(call.r_hellopkt));call.r_hellopkt.username[sizeof(call.r_hellopkt.username) - 1] = 0;icsetenv("remote_username", call.r_hellopkt.username);SET_BIT(call.state, CALL_STATE_HELLO);/* The event is here because we send the call packet before we drop out and * * get the remote hello. Perhapse we aught not to do this but it doesn't hurt. */if (TEST_BIT(call.state, CALL_STATE_CALLING))hk_trigger(hk_call_outgoing);}void handle_pkt_call(struct pkt_call *pkt){if (!TEST_BIT(call.state, CALL_STATE_HELLO)) {send_errorpkt(&call.cssq, PKT_ERROR_PKTORDER);return;}#ifndef USE_CRYPTOif (pkt->cryptinfo.type != CALL_CRYPT_NONE) {send_errorpkt(&call.cssq, PKT_ERROR_NOCRYPT);return;}#endifif (pkt->cryptinfo.type == CALL_CRYPT_NONE)printf(_("Incoming call from %s@%s.\n"),call.r_hellopkt.username, call.r_hostent->h_name);elseprintf(_("Incoming encrypted call from %s@%s.\n"),call.r_hellopkt.username, call.r_hostent->h_name);memcpy(&call.rcv_aparams, &pkt->aparams, sizeof(pkt->aparams));#ifdef USE_CRYPTOmemcpy(&call.cryptinfo, &pkt->cryptinfo, sizeof(pkt->cryptinfo));#endifSET_BIT(call.state, CALL_STATE_WFRANSWER);puts(_("Use 'answer' to respond or 'hangup' to reject."));hk_trigger(hk_call_incoming);}void handle_pkt_callresponse(struct pkt_callresponse *pkt){struct pkt_audiostart audiopkt;struct sockaddr_in r_address;if (!TEST_BIT(call.state, CALL_STATE_HELLO) ||!TEST_BIT(call.state, CALL_STATE_CALLING)) {send_errorpkt(&call.cssq, PKT_ERROR_PKTORDER);return;}switch(pkt->responsecode) {case CALLRESPONSE_ACCEPT:printf(_("Call to %s@%s has been accepted.\n"), call.r_hellopkt.username, call.r_hostent->h_name);memcpy(&call.rcv_aparams, &pkt->aparams, sizeof(pkt->aparams));hk_trigger(hk_call_connect);CLEAR_BIT(call.state, CALL_STATE_CALLING);SET_BIT(call.state, CALL_STATE_INCALL);call.connstats.start_time = time(NULL);if ((call.dsock = setup_udpsock(&r_address)) == -1)return;if (*opt_get_str("snd_play_device")) {if ((call.pdsp = dsp_setup(opt_get_str("snd_play_device"),(opt_get_int("snd_singleopen")) ? O_RDWR : O_WRONLY, &call.rcv_aparams)) == -1)return;if (ioctl(call.pdsp, SNDCTL_DSP_GETBLKSIZE, &call.pdsp_blksize) == -1) {perror("ioctl(SND_DSP_GETBLKSIZE)");return;}call.pdsp_buff = malloc(call.pdsp_blksize);iob_setminbytes(&call.pdspq, call.pdsp_blksize * 4);}audiopkt.dport = r_address.sin_port;queuepacket(&call.cssq, PKT_TYPE_AUDIOSTART, (char *)&audiopkt, sizeof(audiopkt));SET_BIT(call.state, CALL_STATE_AUDIORCV);break;case CALLRESPONSE_DENY:printf(_("Call to %s was denied.\n"), call.r_hostent->h_name);closecall();break;default:fprintf(stderr, _("Received unknown response code (%u) in callresponse packet.\n"),pkt->responsecode);send_errorpkt(&call.cssq, PKT_ERROR_PKTUNKNOWN);};}void handle_pkt_audiostart(struct pkt_audiostart *pkt){struct sockaddr_in addr;char *rdevice;if (TEST_BIT(call.state, CALL_STATE_CALLING) ||TEST_BIT(call.state, CALL_STATE_WFRANSWER) ||call.dsock == -1) {send_errorpkt(&call.cssq, PKT_ERROR_PKTORDER);return;}/* Connect our UDP socket */addr.sin_family = AF_INET;addr.sin_addr.s_addr = call.r_address.sin_addr.s_addr;addr.sin_port = pkt->dport;if (connect(call.dsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {perror("connect");return;}rdevice = opt_get_str("snd_capture_device");if (opt_get_int("snd_loopback"))call.loopback = 1;else if (*rdevice) {if (!opt_get_int("snd_singleopen")) {if ((call.rdsp = dsp_setup(opt_get_str("snd_capture_device"), O_RDONLY, &call.snd_aparams)) == -1)return;if (ioctl(call.rdsp, SNDCTL_DSP_GETBLKSIZE, &call.rdsp_blksize) == -1) {perror("ioctl(SND_DSP_GETBLKSIZE)");return;}} else {call.rdsp = call.pdsp;call.rdsp_blksize = call.pdsp_blksize;}call.rdsp_buff = malloc(call.rdsp_blksize);iob_setminbytes(&call.rdspq, call.rdsp_blksize);/* Hack to make sure select actually returns as some audio drivers * * need an initial read(). It may fail but does that matter? */read(call.rdsp, call.rdsp_buff, call.rdsp_blksize);} elsereturn;switch(call.snd_aparams.compression) {case AUDIO_COMPRESSION_NONE:call.snd_datasize = 2;break;#ifdef HAVE_LIBGSMcase AUDIO_COMPRESSION_GSM:call.snd_datasize = 33;break;#endifcase AUDIO_COMPRESSION_G711U:case AUDIO_COMPRESSION_G711A:call.snd_datasize = 1;break;#ifdef HAVE_G72Xcase AUDIO_COMPRESSION_G721:call.snd_datasize = 1;break;case AUDIO_COMPRESSION_G723_24:call.snd_datasize = 3;break;case AUDIO_COMPRESSION_G723_40:call.snd_datasize = 5;break;#endifdefault:assert(0);}SET_BIT(call.state, CALL_STATE_AUDIOSND);}void handle_pkt_usrtext(char *msgdata, size_t msglen){size_t i;fputs(_("Text message from remote party: "), stdout);for (i = 0; i < msglen; i++) {if ((unsigned char)msgdata[i] >= 32 && (unsigned char)msgdata[i] <= 127)putchar(msgdata[i]);elseputchar('?');}putchar('\n');}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -