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

📄 chan_skinny.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
static int skinny_reset_device(int fd, int argc, char *argv[]){	struct skinny_device *d;	struct skinny_req *req;	if (argc < 3 || argc > 4) {		return RESULT_SHOWUSAGE;	}	ast_mutex_lock(&devicelock);	for (d = devices; d; d = d->next) {		int fullrestart = 0;		if (!strcasecmp(argv[2], d->id) || !strcasecmp(argv[2], "all")) {			if (!(d->session))				continue;			if (!(req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE)))				continue;			if (argc == 4 && !strcasecmp(argv[3], "restart"))				fullrestart = 1;			if (fullrestart)				req->data.reset.resetType = 2;			else				req->data.reset.resetType = 1;			if (option_verbose > 2)				ast_verbose(VERBOSE_PREFIX_3 "%s device %s.\n", (fullrestart) ? "Restarting" : "Resetting", d->id);			transmit_response(d->session, req);		}	}	ast_mutex_unlock(&devicelock);	return RESULT_SUCCESS;}static char *device2str(int type){	char *tmp;	switch (type) {	case SKINNY_DEVICE_NONE:		return "No Device";	case SKINNY_DEVICE_30SPPLUS:		return "30SP Plus";	case SKINNY_DEVICE_12SPPLUS:		return "12SP Plus";	case SKINNY_DEVICE_12SP:		return "12SP";	case SKINNY_DEVICE_12:		return "12";	case SKINNY_DEVICE_30VIP:		return "30VIP";	case SKINNY_DEVICE_7910:		return "7910";	case SKINNY_DEVICE_7960:		return "7960";	case SKINNY_DEVICE_7940:		return "7940";	case SKINNY_DEVICE_7935:		return "7935";	case SKINNY_DEVICE_ATA186:		return "ATA186";	case SKINNY_DEVICE_7941:		return "7941";	case SKINNY_DEVICE_7971:		return "7971";	case SKINNY_DEVICE_7914:		return "7914";	case SKINNY_DEVICE_7985:		return "7985";	case SKINNY_DEVICE_7911:		return "7911";	case SKINNY_DEVICE_7961GE:		return "7961GE";	case SKINNY_DEVICE_7941GE:		return "7941GE";	case SKINNY_DEVICE_7931:		return "7931";	case SKINNY_DEVICE_7921:		return "7921";	case SKINNY_DEVICE_7906:		return "7906";	case SKINNY_DEVICE_7962:		return "7962";	case SKINNY_DEVICE_7937:		return "7937";	case SKINNY_DEVICE_7942:		return "7942";	case SKINNY_DEVICE_7945:		return "7945";	case SKINNY_DEVICE_7965:		return "7965";	case SKINNY_DEVICE_7975:		return "7975";	case SKINNY_DEVICE_7905:		return "7905";	case SKINNY_DEVICE_7920:		return "7920";	case SKINNY_DEVICE_7970:		return "7970";	case SKINNY_DEVICE_7912:		return "7912";	case SKINNY_DEVICE_7902:		return "7902";	case SKINNY_DEVICE_CIPC:		return "IP Communicator";	case SKINNY_DEVICE_7961:		return "7961";	case SKINNY_DEVICE_7936:		return "7936";	case SKINNY_DEVICE_SCCPGATEWAY_AN:		return "SCCPGATEWAY_AN";	case SKINNY_DEVICE_SCCPGATEWAY_BRI:		return "SCCPGATEWAY_BRI";	case SKINNY_DEVICE_UNKNOWN:		return "Unknown";	default:		if (!(tmp = ast_threadstorage_get(&device2str_threadbuf, DEVICE2STR_BUFSIZE)))			return "Unknown";		snprintf(tmp, DEVICE2STR_BUFSIZE, "UNKNOWN-%d", type);		return tmp;	}}static int skinny_show_devices(int fd, int argc, char *argv[]){	struct skinny_device *d;	struct skinny_line *l;	int numlines = 0;	if (argc != 3) {		return RESULT_SHOWUSAGE;	}	ast_mutex_lock(&devicelock);	ast_cli(fd, "Name                 DeviceId         IP              Type            R NL\n");	ast_cli(fd, "-------------------- ---------------- --------------- --------------- - --\n");	for (d = devices; d; d = d->next) {		numlines = 0;		for (l = d->lines; l; l = l->next) {			numlines++;		}		ast_cli(fd, "%-20s %-16s %-15s %-15s %c %2d\n",				d->name,				d->id,				d->session?ast_inet_ntoa(d->session->sin.sin_addr):"",				device2str(d->type),				d->registered?'Y':'N',				numlines);	}	ast_mutex_unlock(&devicelock);	return RESULT_SUCCESS;}static int skinny_show_lines(int fd, int argc, char *argv[]){	struct skinny_device *d;	struct skinny_line *l;	if (argc != 3) {		return RESULT_SHOWUSAGE;	}	ast_mutex_lock(&devicelock);	ast_cli(fd, "Device Name          Instance Name                 Label               \n");	ast_cli(fd, "-------------------- -------- -------------------- --------------------\n");	for (d = devices; d; d = d->next) {		for (l = d->lines; l; l = l->next) {			ast_cli(fd, "%-20s %8d %-20s %-20s\n",				d->name,				l->instance,				l->name,				l->label);		}	}	ast_mutex_unlock(&devicelock);	return RESULT_SUCCESS;}static char show_devices_usage[] ="Usage: skinny show devices\n""       Lists all devices known to the Skinny subsystem.\n";static char show_lines_usage[] ="Usage: skinny show lines\n""       Lists all lines known to the Skinny subsystem.\n";static char debug_usage[] ="Usage: skinny set debug\n""       Enables dumping of Skinny packets for debugging purposes\n";static char no_debug_usage[] ="Usage: skinny set debug off\n""       Disables dumping of Skinny packets for debugging purposes\n";static char reset_usage[] ="Usage: skinny reset <DeviceId|all> [restart]\n""       Causes a Skinny device to reset itself, optionally with a full restart\n";static struct ast_cli_entry cli_skinny[] = {	{ { "skinny", "show", "devices", NULL },	skinny_show_devices, "List defined Skinny devices",	show_devices_usage },	{ { "skinny", "show", "lines", NULL },	skinny_show_lines, "List defined Skinny lines per device",	show_lines_usage },	{ { "skinny", "set", "debug", NULL },	skinny_do_debug, "Enable Skinny debugging",	debug_usage },	{ { "skinny", "set", "debug", "off", NULL },	skinny_no_debug, "Disable Skinny debugging",	no_debug_usage },	{ { "skinny", "reset", NULL },	skinny_reset_device, "Reset Skinny device(s)",	reset_usage, complete_skinny_reset },};#if 0static struct skinny_paging_device *build_paging_device(const char *cat, struct ast_variable *v){	return NULL;}#endifstatic struct skinny_device *build_device(const char *cat, struct ast_variable *v){	struct skinny_device *d;	struct skinny_line *l;	struct skinny_speeddial *sd;	struct skinny_addon *a;	int lineInstance = 1;	int speeddialInstance = 1;	int y = 0;	if (!(d = ast_calloc(1, sizeof(struct skinny_device)))) {		return NULL;	} else {		ast_copy_string(d->name, cat, sizeof(d->name));		d->lastlineinstance = 1;		d->capability = default_capability;		d->prefs = default_prefs;		d->earlyrtp = 1;		while(v) {			if (!strcasecmp(v->name, "host")) {				if (ast_get_ip(&d->addr, v->value)) {					free(d);					return NULL;				}			} else if (!strcasecmp(v->name, "port")) {				d->addr.sin_port = htons(atoi(v->value));			} else if (!strcasecmp(v->name, "device")) {				ast_copy_string(d->id, v->value, sizeof(d->id));			} else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {				d->ha = ast_append_ha(v->name, v->value, d->ha);			} else if (!strcasecmp(v->name, "context")) {				ast_copy_string(context, v->value, sizeof(context));			} else if (!strcasecmp(v->name, "allow")) {				ast_parse_allow_disallow(&d->prefs, &d->capability, v->value, 1);			} else if (!strcasecmp(v->name, "disallow")) {				ast_parse_allow_disallow(&d->prefs, &d->capability, v->value, 0);			} else if (!strcasecmp(v->name, "version")) {				ast_copy_string(d->version_id, v->value, sizeof(d->version_id));			} else if (!strcasecmp(v->name, "earlyrtp")) {				d->earlyrtp = ast_true(v->value);			} else if (!strcasecmp(v->name, "nat")) {				nat = ast_true(v->value);			} else if (!strcasecmp(v->name, "callerid")) {				if (!strcasecmp(v->value, "asreceived")) {					cid_num[0] = '\0';					cid_name[0] = '\0';				} else {					ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));				}			} else if (!strcasecmp(v->name, "language")) {				ast_copy_string(language, v->value, sizeof(language));			} else if (!strcasecmp(v->name, "accountcode")) {				ast_copy_string(accountcode, v->value, sizeof(accountcode));			} else if (!strcasecmp(v->name, "amaflags")) {				y = ast_cdr_amaflags2int(v->value);				if (y < 0) {					ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);				} else {					amaflags = y;				}			} else if (!strcasecmp(v->name, "mohinterpret") || !strcasecmp(v->name, "musiconhold")) {				ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));			} else if (!strcasecmp(v->name, "mohsuggest")) {				ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));			} else if (!strcasecmp(v->name, "callgroup")) {				cur_callergroup = ast_get_group(v->value);			} else if (!strcasecmp(v->name, "pickupgroup")) {				cur_pickupgroup = ast_get_group(v->value);			} else if (!strcasecmp(v->name, "immediate")) {				immediate = ast_true(v->value);			} else if (!strcasecmp(v->name, "cancallforward")) {				cancallforward = ast_true(v->value);			} else if (!strcasecmp(v->name, "mailbox")) {				ast_copy_string(mailbox, v->value, sizeof(mailbox));			} else if (!strcasecmp(v->name, "hasvoicemail")) {				if (ast_true(v->value) && ast_strlen_zero(mailbox)) {					ast_copy_string(mailbox, cat, sizeof(mailbox));				}			} else if (!strcasecmp(v->name, "callreturn")) {				callreturn = ast_true(v->value);			} else if (!strcasecmp(v->name, "callwaiting")) {				callwaiting = ast_true(v->value);			} else if (!strcasecmp(v->name, "transfer")) {				transfer = ast_true(v->value);			} else if (!strcasecmp(v->name, "threewaycalling")) {				threewaycalling = ast_true(v->value);			} else if (!strcasecmp(v->name, "mwiblink")) {				mwiblink = ast_true(v->value);			} else if (!strcasecmp(v->name, "linelabel")) {				ast_copy_string(linelabel, v->value, sizeof(linelabel));			} else if (!strcasecmp(v->name, "speeddial")) {				if (!(sd = ast_calloc(1, sizeof(struct skinny_speeddial)))) {					return NULL;				} else {					char *stringp, *exten, *label;					stringp = v->value;					exten = strsep(&stringp, ",");					label = strsep(&stringp, ",");					ast_mutex_init(&sd->lock);					ast_copy_string(sd->exten, exten, sizeof(sd->exten));					if (label)						ast_copy_string(sd->label, label, sizeof(sd->label));					else						ast_copy_string(sd->label, exten, sizeof(sd->label));					sd->instance = speeddialInstance++;					sd->parent = d;					sd->next = d->speeddials;					d->speeddials = sd;				}			} else if (!strcasecmp(v->name, "addon")) {				if (!(a = ast_calloc(1, sizeof(struct skinny_addon)))) {					return NULL;				} else {					ast_mutex_init(&a->lock);					ast_copy_string(a->type, v->value, sizeof(a->type));					a->next = d->addons;					d->addons = a;				}			} else if (!strcasecmp(v->name, "trunk") || !strcasecmp(v->name, "line")) {				if (!(l = ast_calloc(1, sizeof(struct skinny_line)))) {					return NULL;				} else {					ast_mutex_init(&l->lock);					ast_copy_string(l->name, v->value, sizeof(l->name));					/* XXX Should we check for uniqueness?? XXX */					ast_copy_string(l->context, context, sizeof(l->context));					ast_copy_string(l->cid_num, cid_num, sizeof(l->cid_num));					ast_copy_string(l->cid_name, cid_name, sizeof(l->cid_name));					ast_copy_string(l->label, linelabel, sizeof(l->label));					ast_copy_string(l->language, language, sizeof(l->language));					ast_copy_string(l->mohinterpret, mohinterpret, sizeof(l->mohinterpret));					ast_copy_string(l->mohsuggest, mohsuggest, sizeof(l->mohsuggest));					ast_copy_string(l->mailbox, mailbox, sizeof(l->mailbox));					if (!ast_strlen_zero(mailbox)) {						if (option_verbose > 2)							ast_verbose(VERBOSE_PREFIX_3 "Setting mailbox '%s' on %s@%s\n", mailbox, d->name, l->name);					}					l->msgstate = -1;					l->capability = d->capability;					l->prefs = d->prefs;					l->parent = d;					if (!strcasecmp(v->name, "trunk")) {						l->type = TYPE_TRUNK;					} else {						l->type = TYPE_LINE;					}					l->immediate = immediate;					l->callgroup = cur_callergroup;					l->pickupgroup = cur_pickupgroup;					l->callreturn = callreturn;					l->cancallforward = cancallforward;					l->callwaiting = callwaiting;					l->transfer = transfer;					l->threewaycalling = threewaycalling;					l->mwiblink = mwiblink;					l->onhooktime = time(NULL);					l->instance = lineInstance++;					/* ASSUME we're onhook at this point */					l->hookstate = SKINNY_ONHOOK;					l->nat = nat;					l->next = d->lines;					d->lines = l;				}			} else {				ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno);			}			v = v->next;	 	}	 	if (!d->lines) {			ast_log(LOG_ERROR, "A Skinny device must have at least one line!\n");			return NULL;		}		if (/*d->addr.sin_addr.s_addr && */!ntohs(d->addr.sin_port)) {			d->addr.sin_port = htons(DEFAULT_SKINNY_PORT);		}#if 0		/* I don't think we need this anymore at all, since d->ourip is set in skinny_register now */		if (d->addr.sin_addr.s_addr) {			/* XXX See note above, in 'host' option. */			if (ast_ouraddrfor(&d->addr.sin_addr, &d->ourip)) {				d->ourip = __ourip;			}		} else {			d->ourip = __ourip;		}#endif	}	return d;}static void start_rtp(struct skinny_subchannel *sub){	struct skinny_line *l = sub->parent;	struct skinny_device *d = l->parent;	int hasvideo = 0;	ast_mutex_lock(&sub->lock);	/* Allocate the RTP */	sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);	if (hasvideo)		sub->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);		if (sub->rtp && sub->owner) {		sub->owner->fds[0] = ast_rtp_fd(sub->rtp);		sub->owner->fds[1] = ast_rtcp_fd(sub->rtp);	}	if (hasvideo && sub->vrtp && sub->owner) {		sub->owner->fds[2] = ast_rtp_fd(sub->vrtp);		sub->owner->fds[3] = ast_rtcp_fd(sub->vrtp);	}	if (sub->rtp) {		ast_rtp_setnat(sub->rtp, l->nat);	}	if (sub->vrtp) {		ast_rtp_setnat(sub->vrtp, l->nat);	}	/* Set Frame packetization */	if (sub->rtp)		ast_rtp_codec_setpref(sub->rtp, &l->prefs);	/* Create the RTP connection */	transmit_connect(d->session, sub); 	ast_mutex_unlock(&sub->lock);}static void *skinny_newcall(void *data){	struct ast_channel *c = data;	struct skinny_subchannel *sub = c->tech_pvt;	struct skinny_line *l = sub->parent;	struct skinny_device *d = l->parent;	struct skinnysession *s = d->session;	int res = 0;	ast_copy_string(l->lastnumberdialed, c->exten, sizeof(l->lastnumberdialed));	ast_set_callerid(

⌨️ 快捷键说明

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