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

📄 chan_skinny.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
			d->type = letohl(req->data.reg.type);			if (ast_strlen_zero(d->version_id)) {				ast_copy_string(d->version_id, version_id, sizeof(d->version_id));			}			d->registered = 1;			d->session = s;			slen = sizeof(sin);			if (getsockname(s->fd, (struct sockaddr *)&sin, &slen)) {				ast_log(LOG_WARNING, "Cannot get socket name\n");				sin.sin_addr = __ourip;			}			d->ourip = sin.sin_addr;			break;		}	}	ast_mutex_unlock(&devicelock);	if (!d) {		return 0;	}	return 1;}static int skinny_unregister(struct skinny_req *req, struct skinnysession *s){	struct skinny_device *d;	d = s->device;	if (d) {		d->session = NULL;		d->registered = 0;	}	return -1; /* main loop will destroy the session */}static int transmit_response(struct skinnysession *s, struct skinny_req *req){	int res = 0;	if (!s) {		ast_log(LOG_WARNING, "Asked to transmit to a non-existant session!\n");		return -1;	}	ast_mutex_lock(&s->lock);	if (skinnydebug)		ast_log(LOG_VERBOSE, "writing packet type %04X (%d bytes) to socket %d\n", letohl(req->e), letohl(req->len)+8, s->fd);	if (letohl(req->len > SKINNY_MAX_PACKET) || letohl(req->len < 0)) {		ast_log(LOG_WARNING, "transmit_response: the length of the request is out of bounds\n");		ast_mutex_unlock(&s->lock);		return -1;	}	memset(s->outbuf,0,sizeof(s->outbuf));	memcpy(s->outbuf, req, skinny_header_size);	memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len));	res = write(s->fd, s->outbuf, letohl(req->len)+8);	if (res != letohl(req->len)+8) {		ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno));		if (res == -1) {			if (skinnydebug)				ast_log(LOG_WARNING, "Transmit: Skinny Client was lost, unregistering\n");			skinny_unregister(NULL, s);		}			}		ast_mutex_unlock(&s->lock);	return 1;}static void transmit_speaker_mode(struct skinnysession *s, int mode){	struct skinny_req *req;	if (!(req = req_alloc(sizeof(struct set_speaker_message), SET_SPEAKER_MESSAGE)))		return;	req->data.setspeaker.mode = htolel(mode);	transmit_response(s, req);}/*static void transmit_microphone_mode(struct skinnysession *s, int mode){	struct skinny_req *req;	if (!(req = req_alloc(sizeof(struct set_microphone_message), SET_MICROPHONE_MESSAGE)))		return;	req->data.setmicrophone.mode = htolel(mode);	transmit_response(s, req);}*/static void transmit_callinfo(struct skinnysession *s, const char *fromname, const char *fromnum, const char *toname, const char *tonum, int instance, int callid, int calltype){	struct skinny_req *req;	if (!(req = req_alloc(sizeof(struct call_info_message), CALL_INFO_MESSAGE)))		return;	if (skinnydebug)			ast_verbose("Setting Callinfo to %s(%s) from %s(%s) on %s(%d)\n", fromname, fromnum, toname, tonum, s->device->name, instance);	if (fromname) {		ast_copy_string(req->data.callinfo.callingPartyName, fromname, sizeof(req->data.callinfo.callingPartyName));	}	if (fromnum) {		ast_copy_string(req->data.callinfo.callingParty, fromnum, sizeof(req->data.callinfo.callingParty));	}	if (toname) {		ast_copy_string(req->data.callinfo.calledPartyName, toname, sizeof(req->data.callinfo.calledPartyName));	}	if (tonum) {		ast_copy_string(req->data.callinfo.calledParty, tonum, sizeof(req->data.callinfo.calledParty));	}	req->data.callinfo.instance = htolel(instance);	req->data.callinfo.reference = htolel(callid);	req->data.callinfo.type = htolel(calltype);	transmit_response(s, req);}static void transmit_connect(struct skinnysession *s, struct skinny_subchannel *sub){	struct skinny_req *req;	struct skinny_line *l = sub->parent;	struct ast_format_list fmt;	if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE)))		return;	fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));	req->data.openreceivechannel.conferenceId = htolel(sub->callid);	req->data.openreceivechannel.partyId = htolel(sub->callid);	req->data.openreceivechannel.packets = htolel(fmt.cur_ms);	req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));	req->data.openreceivechannel.echo = htolel(0);	req->data.openreceivechannel.bitrate = htolel(0);	transmit_response(s, req);}static void transmit_tone(struct skinnysession *s, int tone, int instance, int reference){	struct skinny_req *req;	if (tone == SKINNY_NOTONE) {		/* This is bad, mmm'kay? */		return;	}	if (tone > 0) {		if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE)))			return;		req->data.starttone.tone = htolel(tone);		req->data.starttone.instance = htolel(instance);		req->data.starttone.reference = htolel(reference);	} else {		if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE)))			return;		req->data.stoptone.instance = htolel(instance);		req->data.stoptone.reference = htolel(reference);	}	if (tone > 0) {		req->data.starttone.tone = htolel(tone);	}	transmit_response(s, req);}static void transmit_selectsoftkeys(struct skinnysession *s, int instance, int callid, int softkey){	struct skinny_req *req;	if (!(req = req_alloc(sizeof(struct select_soft_keys_message), SELECT_SOFT_KEYS_MESSAGE)))		return;	req->data.selectsoftkey.instance = htolel(instance);	req->data.selectsoftkey.reference = htolel(callid);	req->data.selectsoftkey.softKeySetIndex = htolel(softkey);	req->data.selectsoftkey.validKeyMask = htolel(0xFFFFFFFF);	transmit_response(s, req);}static void transmit_lamp_indication(struct skinnysession *s, int stimulus, int instance, int indication){	struct skinny_req *req;	if (!(req = req_alloc(sizeof(struct set_lamp_message), SET_LAMP_MESSAGE)))		return;	req->data.setlamp.stimulus = htolel(stimulus);	req->data.setlamp.stimulusInstance = htolel(instance);	req->data.setlamp.deviceStimulus = htolel(indication);	transmit_response(s, req);}static void transmit_ringer_mode(struct skinnysession *s, int mode){	struct skinny_req *req;	if (skinnydebug)		ast_verbose("Setting ringer mode to '%d'.\n", mode);	if (!(req = req_alloc(sizeof(struct set_ringer_message), SET_RINGER_MESSAGE)))		return;	req->data.setringer.ringerMode = htolel(mode);	/* XXX okay, I don't quite know what this is, but here's what happens (on a 7960).	   Note: The phone will always show as ringing on the display.	   1: phone will audibly ring over and over	   2: phone will audibly ring only once	   any other value, will NOT cause the phone to audibly ring	*/	req->data.setringer.unknown1 = htolel(1);	/* XXX the value here doesn't seem to change anything.  Must be higher than 0.	   Perhaps a packet capture can shed some light on this. */	req->data.setringer.unknown2 = htolel(1);	transmit_response(s, req);}static void transmit_displaymessage(struct skinnysession *s, const char *text, int instance, int reference){	struct skinny_req *req;	if (text == 0) {		if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE)))			return;		req->data.clearpromptstatus.lineInstance = instance;		req->data.clearpromptstatus.callReference = reference;		if (skinnydebug)			ast_verbose("Clearing Display\n");	} else {		if (!(req = req_alloc(sizeof(struct displaytext_message), DISPLAYTEXT_MESSAGE)))			return;		ast_copy_string(req->data.displaytext.text, text, sizeof(req->data.displaytext.text));		if (skinnydebug)			ast_verbose("Displaying message '%s'\n", req->data.displaytext.text);	}	transmit_response(s, req);}static void transmit_displaynotify(struct skinnysession *s, const char *text, int t){	struct skinny_req *req;	if (!(req = req_alloc(sizeof(struct display_notify_message), DISPLAY_NOTIFY_MESSAGE)))		return;	ast_copy_string(req->data.displaynotify.displayMessage, text, sizeof(req->data.displaynotify.displayMessage));	req->data.displaynotify.displayTimeout = htolel(t);	if (skinnydebug)		ast_verbose("Displaying notify '%s'\n", text);	transmit_response(s, req);}static void transmit_displaypromptstatus(struct skinnysession *s, const char *text, int t, int instance, int callid){	struct skinny_req *req;	if (text == 0) {		if (!(req = req_alloc(sizeof(struct clear_prompt_message), CLEAR_PROMPT_MESSAGE)))			return;		req->data.clearpromptstatus.lineInstance = htolel(instance);		req->data.clearpromptstatus.callReference = htolel(callid);		if (skinnydebug)			ast_verbose("Clearing Prompt\n");	} else {		if (!(req = req_alloc(sizeof(struct display_prompt_status_message), DISPLAY_PROMPT_STATUS_MESSAGE)))			return;		ast_copy_string(req->data.displaypromptstatus.promptMessage, text, sizeof(req->data.displaypromptstatus.promptMessage));		req->data.displaypromptstatus.messageTimeout = htolel(t);		req->data.displaypromptstatus.lineInstance = htolel(instance);		req->data.displaypromptstatus.callReference = htolel(callid);		if (skinnydebug)			ast_verbose("Displaying Prompt Status '%s'\n", text);	}	transmit_response(s, req);}static void transmit_dialednumber(struct skinnysession *s, const char *text, int instance, int callid){	struct skinny_req *req;	if (!(req = req_alloc(sizeof(struct dialed_number_message), DIALED_NUMBER_MESSAGE)))		return;	ast_copy_string(req->data.dialednumber.dialedNumber, text, sizeof(req->data.dialednumber.dialedNumber));	req->data.dialednumber.lineInstance = htolel(instance);	req->data.dialednumber.callReference = htolel(callid);	transmit_response(s, req);}static void transmit_callstate(struct skinnysession *s, int instance, int state, unsigned callid){	struct skinny_req *req;	if (state == SKINNY_ONHOOK) {		if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))			return;		req->data.closereceivechannel.conferenceId = htolel(callid);		req->data.closereceivechannel.partyId = htolel(callid);		transmit_response(s, req);		if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))			return;		req->data.stopmedia.conferenceId = htolel(callid);		req->data.stopmedia.passThruPartyId = htolel(callid);		transmit_response(s, req);		transmit_speaker_mode(s, SKINNY_SPEAKEROFF);		transmit_displaypromptstatus(s, NULL, 0, instance, callid);	}	if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))		return;	req->data.callstate.callState = htolel(state);	req->data.callstate.lineInstance = htolel(instance);	req->data.callstate.callReference = htolel(callid);	transmit_response(s, req);	if (state == SKINNY_ONHOOK) {		transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);	}	if (state == SKINNY_OFFHOOK || state == SKINNY_ONHOOK) {		if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))			return;		req->data.activatecallplane.lineInstance = htolel(instance);		transmit_response(s, req);	}}/*static int has_voicemail(struct skinny_line *l){	return ast_app_has_voicemail(l->mailbox, NULL);}*/static void do_housekeeping(struct skinnysession *s){/*	int new;	int old;	struct skinny_device *d = s->device;	struct skinny_line *l;*/	/* Update time on device */	handle_time_date_req_message(NULL, s);/*	for (l = d->lines; l; l = l->next) {		if (has_voicemail(l)) {			if (skinnydebug)				ast_verbose("Checking for voicemail Skinny %s@%s\n", l->name, d->name);			ast_app_inboxcount(l->mailbox, &new, &old);			if (skinnydebug)				ast_verbose("Skinny %s@%s has voicemail!\n", l->name, d->name);			transmit_lamp_indication(s, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON);		} else {			transmit_lamp_indication(s, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF);		}	}*/}/* I do not believe skinny can deal with video.   Anyone know differently? *//* Yes, it can.  Currently 7985 and Cisco VT Advantage do video. */static enum ast_rtp_get_result skinny_get_vrtp_peer(struct ast_channel *c, struct ast_rtp **rtp){	struct skinny_subchannel *sub = NULL;	if (!(sub = c->tech_pvt) || !(sub->vrtp))		return AST_RTP_GET_FAILED;	*rtp = sub->vrtp;	return AST_RTP_TRY_NATIVE;}static enum ast_rtp_get_result skinny_get_rtp_peer(struct ast_channel *c, struct ast_rtp **rtp){	struct skinny_subchannel *sub = NULL;	if (!(sub = c->tech_pvt) || !(sub->rtp))		return AST_RTP_GET_FAILED;	*rtp = sub->rtp;	return AST_RTP_TRY_NATIVE;}static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active){	struct skinny_subchannel *sub;	sub = c->tech_pvt;	if (sub) {		/* transmit_modify_with_sdp(sub, rtp); @@FIXME@@ if needed */		return 0;	}	return -1;}static struct ast_rtp_protocol skinny_rtp = {	.type = "Skinny",	.get_rtp_info = skinny_get_rtp_peer,	.get_vrtp_info = skinny_get_vrtp_peer,	.set_rtp_peer = skinny_set_rtp_peer,};static int skinny_do_debug(int fd, int argc, char *argv[]){	if (argc != 3) {		return RESULT_SHOWUSAGE;	}	skinnydebug = 1;	ast_cli(fd, "Skinny Debugging Enabled\n");	return RESULT_SUCCESS;}static int skinny_no_debug(int fd, int argc, char *argv[]){	if (argc != 4) {		return RESULT_SHOWUSAGE;	}	skinnydebug = 0;	ast_cli(fd, "Skinny Debugging Disabled\n");	return RESULT_SUCCESS;}static char *complete_skinny_reset(const char *line, const char *word, int pos, int state){	struct skinny_device *d;	char *result = NULL;	int wordlen = strlen(word);	int which = 0;	if (pos == 2) {		for (d = devices; d && !result; d = d->next) {			if (!strncasecmp(word, d->id, wordlen) && ++which > state)				result = ast_strdup(d->id);		}	}	return result;}

⌨️ 快捷键说明

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