⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chan_skinny.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* time_t lastouttime; */			/* Unused */	int progress;	int ringing;	int onhold;	/* int lastout; */				/* Unused */	int cxmode;	int nat;	int outgoing;	int alreadygone;	struct skinny_subchannel *next;	struct skinny_line *parent;};struct skinny_line {	ast_mutex_t lock;	char name[80];	char label[24];					/* Label that shows next to the line buttons */	char accountcode[AST_MAX_ACCOUNT_CODE];	char exten[AST_MAX_EXTENSION];			/* Extension where to start */	char context[AST_MAX_CONTEXT];	char language[MAX_LANGUAGE];	char cid_num[AST_MAX_EXTENSION];		/* Caller*ID */	char cid_name[AST_MAX_EXTENSION];		/* Caller*ID */	char lastcallerid[AST_MAX_EXTENSION];		/* Last Caller*ID */	char call_forward[AST_MAX_EXTENSION];	char mailbox[AST_MAX_EXTENSION];	char mohinterpret[MAX_MUSICCLASS];	char mohsuggest[MAX_MUSICCLASS];	char lastnumberdialed[AST_MAX_EXTENSION];	/* Last number that was dialed - used for redial */	int curtone;					/* Current tone being played */	ast_group_t callgroup;	ast_group_t pickupgroup;	int callwaiting;	int transfer;	int threewaycalling;	int mwiblink;	int cancallforward;	int callreturn;	int dnd; /* How does this affect callwait?  Do we just deny a skinny_request if we're dnd? */	int hascallerid;	int hidecallerid;	int amaflags;	int type;	int instance;	int group;	int needdestroy;	int capability;	int nonCodecCapability;	int onhooktime;	int msgstate;					/* voicemail message state */	int immediate;	int hookstate;	int nat;	struct ast_codec_pref prefs;	struct skinny_subchannel *sub;	struct skinny_line *next;	struct skinny_device *parent;};struct skinny_speeddial {	ast_mutex_t lock;	char label[42];	char exten[AST_MAX_EXTENSION];	int instance;	struct skinny_speeddial *next;	struct skinny_device *parent;};struct skinny_addon {	ast_mutex_t lock;	char type[10];	struct skinny_addon *next;	struct skinny_device *parent;};static struct skinny_device {	/* A device containing one or more lines */	char name[80];	char id[16];	char version_id[16];	int type;	int registered;	int lastlineinstance;	int lastcallreference;	int capability;	int earlyrtp;	char exten[AST_MAX_EXTENSION];	struct sockaddr_in addr;	struct in_addr ourip;	struct skinny_line *lines;	struct skinny_speeddial *speeddials;	struct skinny_addon *addons;	struct ast_codec_pref prefs;	struct ast_ha *ha;	struct skinnysession *session;	struct skinny_device *next;} *devices = NULL;struct skinny_paging_device {	char name[80];	char id[16];	struct skinny_device ** devices;	struct skinny_paging_device *next;};static struct skinnysession {	pthread_t t;	ast_mutex_t lock;	struct sockaddr_in sin;	int fd;	char inbuf[SKINNY_MAX_PACKET];	char outbuf[SKINNY_MAX_PACKET];	struct skinny_device *device;	struct skinnysession *next;} *sessions = NULL;static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause);static int skinny_call(struct ast_channel *ast, char *dest, int timeout);static int skinny_hangup(struct ast_channel *ast);static int skinny_answer(struct ast_channel *ast);static struct ast_frame *skinny_read(struct ast_channel *ast);static int skinny_write(struct ast_channel *ast, struct ast_frame *frame);static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen);static int skinny_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);static int skinny_senddigit_begin(struct ast_channel *ast, char digit);static int skinny_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);static int handle_time_date_req_message(struct skinny_req *req, struct skinnysession *s);static const struct ast_channel_tech skinny_tech = {	.type = "Skinny",	.description = tdesc,	.capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,	.requester = skinny_request,	.call = skinny_call,	.hangup = skinny_hangup,	.answer = skinny_answer,	.read = skinny_read,	.write = skinny_write,	.indicate = skinny_indicate,	.fixup = skinny_fixup,	.send_digit_begin = skinny_senddigit_begin,	.send_digit_end = skinny_senddigit_end,/*	.bridge = ast_rtp_bridge, */};static void *get_button_template(struct skinnysession *s, struct button_definition_template *btn){	struct skinny_device *d = s->device;	struct skinny_addon *a = d->addons;	int i;	switch (d->type) {		case SKINNY_DEVICE_30SPPLUS:		case SKINNY_DEVICE_30VIP:			/* 13 rows, 2 columns */			for (i = 0; i < 4; i++)				(btn++)->buttonDefinition = BT_LINE;			(btn++)->buttonDefinition = BT_REDIAL;			(btn++)->buttonDefinition = BT_VOICEMAIL;			(btn++)->buttonDefinition = BT_CALLPARK;			(btn++)->buttonDefinition = BT_FORWARDALL;			(btn++)->buttonDefinition = BT_CONFERENCE;			for (i = 0; i < 4; i++)				(btn++)->buttonDefinition = BT_NONE;			for (i = 0; i < 13; i++)				(btn++)->buttonDefinition = BT_SPEEDDIAL;						break;		case SKINNY_DEVICE_12SPPLUS:		case SKINNY_DEVICE_12SP:		case SKINNY_DEVICE_12:			/* 6 rows, 2 columns */			for (i = 0; i < 2; i++)				(btn++)->buttonDefinition = BT_LINE;			(btn++)->buttonDefinition = BT_REDIAL;			for (i = 0; i < 3; i++)				(btn++)->buttonDefinition = BT_SPEEDDIAL;			(btn++)->buttonDefinition = BT_HOLD;			(btn++)->buttonDefinition = BT_TRANSFER;			(btn++)->buttonDefinition = BT_FORWARDALL;			(btn++)->buttonDefinition = BT_CALLPARK;			(btn++)->buttonDefinition = BT_VOICEMAIL;			(btn++)->buttonDefinition = BT_CONFERENCE;			break;		case SKINNY_DEVICE_7910:			(btn++)->buttonDefinition = BT_LINE;			(btn++)->buttonDefinition = BT_HOLD;			(btn++)->buttonDefinition = BT_TRANSFER;			(btn++)->buttonDefinition = BT_DISPLAY;			(btn++)->buttonDefinition = BT_VOICEMAIL;			(btn++)->buttonDefinition = BT_CONFERENCE;			(btn++)->buttonDefinition = BT_FORWARDALL;			for (i = 0; i < 2; i++)				(btn++)->buttonDefinition = BT_SPEEDDIAL;			(btn++)->buttonDefinition = BT_REDIAL;			break;		case SKINNY_DEVICE_7960:		case SKINNY_DEVICE_7961:		case SKINNY_DEVICE_7961GE:		case SKINNY_DEVICE_7962:		case SKINNY_DEVICE_7965:			for (i = 0; i < 6; i++)				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;			break;		case SKINNY_DEVICE_7940:		case SKINNY_DEVICE_7941:		case SKINNY_DEVICE_7941GE:		case SKINNY_DEVICE_7942:		case SKINNY_DEVICE_7945:			for (i = 0; i < 2; i++)				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;			break;		case SKINNY_DEVICE_7935:		case SKINNY_DEVICE_7936:			for (i = 0; i < 2; i++)				(btn++)->buttonDefinition = BT_LINE;			break;		case SKINNY_DEVICE_ATA186:			(btn++)->buttonDefinition = BT_LINE;			break;		case SKINNY_DEVICE_7970:		case SKINNY_DEVICE_7971:		case SKINNY_DEVICE_7975:		case SKINNY_DEVICE_CIPC:			for (i = 0; i < 8; i++)				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;			break;		case SKINNY_DEVICE_7985:			/* XXX I have no idea what the buttons look like on these. */			ast_log(LOG_WARNING, "Unsupported device type '%d (7985)' found.\n", d->type);			break;		case SKINNY_DEVICE_7912:		case SKINNY_DEVICE_7911:		case SKINNY_DEVICE_7905:			(btn++)->buttonDefinition = BT_LINE;			(btn++)->buttonDefinition = BT_HOLD;			break;		case SKINNY_DEVICE_7920:			/* XXX I don't know if this is right. */			for (i = 0; i < 4; i++)				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;			break;		case SKINNY_DEVICE_7921:			for (i = 0; i < 6; i++)				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;			break;		case SKINNY_DEVICE_7902:			ast_log(LOG_WARNING, "Unsupported device type '%d (7902)' found.\n", d->type);			break;		case SKINNY_DEVICE_7906:			ast_log(LOG_WARNING, "Unsupported device type '%d (7906)' found.\n", d->type);			break;		case SKINNY_DEVICE_7931:			ast_log(LOG_WARNING, "Unsupported device type '%d (7931)' found.\n", d->type);			break;		case SKINNY_DEVICE_7937:			ast_log(LOG_WARNING, "Unsupported device type '%d (7937)' found.\n", d->type);			break;		case SKINNY_DEVICE_7914:			ast_log(LOG_WARNING, "Unsupported device type '%d (7914)' found.  Expansion module registered by itself?\n", d->type);			break;		case SKINNY_DEVICE_SCCPGATEWAY_AN:		case SKINNY_DEVICE_SCCPGATEWAY_BRI:			ast_log(LOG_WARNING, "Unsupported device type '%d (SCCP gateway)' found.\n", d->type);			break;		default:			ast_log(LOG_WARNING, "Unknown device type '%d' found.\n", d->type);			break;	}	for (a = d->addons; a; a = a->next) {		if (!strcasecmp(a->type, "7914")) {			for (i = 0; i < 14; i++)				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;		} else {			ast_log(LOG_WARNING, "Unknown addon type '%s' found.  Skipping.\n", a->type);		}	}	return btn;}static struct skinny_req *req_alloc(size_t size, int response_message){	struct skinny_req *req;	if (!(req = ast_calloc(1, skinny_header_size + size + 4)))		return NULL;	req->len = htolel(size+4);	req->e = htolel(response_message);	return req;}static struct skinny_line *find_line_by_instance(struct skinny_device *d, int instance){	struct skinny_line *l;	if (!instance)		instance = 1;	for (l = d->lines; l; l = l->next) {		if (l->instance == instance)			break;	}	if (!l) {		ast_log(LOG_WARNING, "Could not find line with instance '%d' on device '%s'\n", instance, d->name);	}	return l;}static struct skinny_line *find_line_by_name(const char *dest){	struct skinny_line *l;	struct skinny_device *d;	char line[256];	char *at;	char *device;	ast_copy_string(line, dest, sizeof(line));	at = strchr(line, '@');	if (!at) {		ast_log(LOG_NOTICE, "Device '%s' has no @ (at) sign!\n", dest);		return NULL;	}	*at++ = '\0';	device = at;	ast_mutex_lock(&devicelock);	for (d = devices; d; d = d->next) {		if (!strcasecmp(d->name, device)) {			if (skinnydebug)				ast_verbose("Found device: %s\n", d->name);			/* Found the device */			for (l = d->lines; l; l = l->next) {				/* Search for the right line */				if (!strcasecmp(l->name, line)) {					ast_mutex_unlock(&devicelock);					return l;				}			}		}	}	/* Device not found */	ast_mutex_unlock(&devicelock);	return NULL;}/* It's quicker/easier to find the subchannel when we know the instance number too */static struct skinny_subchannel *find_subchannel_by_instance_reference(struct skinny_device *d, int instance, int reference){	struct skinny_line *l = find_line_by_instance(d, instance);	struct skinny_subchannel *sub;	if (!l) {		return NULL;	}	if (!reference)		sub = l->sub;	else {		for (sub = l->sub; sub; sub = sub->next) {			if (sub->callid == reference)				break;		}	}	if (!sub) {		ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s'\n", reference, d->name);	}	return sub;}/* Find the subchannel when we only have the callid - this shouldn't happen often */static struct skinny_subchannel *find_subchannel_by_reference(struct skinny_device *d, int reference){	struct skinny_line *l;	struct skinny_subchannel *sub = NULL;	for (l = d->lines; l; l = l->next) {		for (sub = l->sub; sub; sub = sub->next) {			if (sub->callid == reference)				break;		}		if (sub)			break;	}	if (!l) {		ast_log(LOG_WARNING, "Could not find any lines that contained a subchannel with reference '%d' on device '%s'\n", reference, d->name);	} else {		if (!sub) {			ast_log(LOG_WARNING, "Could not find subchannel with reference '%d' on '%s@%s'\n", reference, l->name, d->name);		}	}	return sub;}static struct skinny_speeddial *find_speeddial_by_instance(struct skinny_device *d, int instance){	struct skinny_speeddial *sd;	for (sd = d->speeddials; sd; sd = sd->next) {		if (sd->instance == instance)			break;	}	if (!sd) {		ast_log(LOG_WARNING, "Could not find speeddial with instance '%d' on device '%s'\n", instance, d->name);	}	return sd;}static int codec_skinny2ast(enum skinny_codecs skinnycodec){	switch (skinnycodec) {	case SKINNY_CODEC_ALAW:		return AST_FORMAT_ALAW;	case SKINNY_CODEC_ULAW:		return AST_FORMAT_ULAW;	case SKINNY_CODEC_G723_1:		return AST_FORMAT_G723_1;	case SKINNY_CODEC_G729A:		return AST_FORMAT_G729A;	case SKINNY_CODEC_G726_32:		return AST_FORMAT_G726_AAL2; /* XXX Is this right? */	case SKINNY_CODEC_H261:		return AST_FORMAT_H261;	case SKINNY_CODEC_H263:		return AST_FORMAT_H263;	default:		return 0;	}}static int codec_ast2skinny(int astcodec){	switch (astcodec) {	case AST_FORMAT_ALAW:		return SKINNY_CODEC_ALAW;	case AST_FORMAT_ULAW:		return SKINNY_CODEC_ULAW;	case AST_FORMAT_G723_1:		return SKINNY_CODEC_G723_1;	case AST_FORMAT_G729A:		return SKINNY_CODEC_G729A;	case AST_FORMAT_G726_AAL2: /* XXX Is this right? */		return SKINNY_CODEC_G726_32;	case AST_FORMAT_H261:		return SKINNY_CODEC_H261;	case AST_FORMAT_H263:		return SKINNY_CODEC_H263;	default:		return 0;	}}static int skinny_register(struct skinny_req *req, struct skinnysession *s){	struct skinny_device *d;	struct sockaddr_in sin;	socklen_t slen;	ast_mutex_lock(&devicelock);	for (d = devices; d; d = d->next) {		if (!strcasecmp(req->data.reg.name, d->id)				&& ast_apply_ha(d->ha, &(s->sin))) {			s->device = d;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -