Exemple #1
0
t_response *t_phone_user::create_options_response(t_request *r,
		bool in_dialog) const
{
	t_response *resp;

	// RFC 3261 11.2
	switch(phone->get_state()) {
	case PS_IDLE:
		if (!in_dialog && service->is_dnd_active()) {
			resp = r->create_response(R_480_TEMP_NOT_AVAILABLE);
		} else {
			resp = r->create_response(R_200_OK);
		}
		break;
	case PS_BUSY:
		if (in_dialog) {
			resp = r->create_response(R_200_OK);
		} else {
			resp = r->create_response(R_486_BUSY_HERE);
		}
		break;
	default:
		assert(false);
	}

	SET_HDR_ALLOW(resp->hdr_allow, user_config);
	SET_HDR_ACCEPT(resp->hdr_accept);
	SET_HDR_ACCEPT_ENCODING(resp->hdr_accept_encoding);
	SET_HDR_ACCEPT_LANGUAGE(resp->hdr_accept_language);
	SET_HDR_SUPPORTED(resp->hdr_supported, user_config);

	if (user_config->get_ext_100rel() != EXT_DISABLED) {
		resp->hdr_supported.add_feature(EXT_100REL);
	}

	// TODO: include SDP body if requested (optional)

	return resp;
}
void t_transaction_layer::recvd_request(t_request *r, t_tid tid,
		t_tid tid_cancel_target)
{
	bool fatal;
	string reason;
	t_response *resp;

	lock();

	// Return a 400 response if the SIP headers are wrong
	if (!r->is_valid(fatal, reason)) {
		resp = r->create_response(R_400_BAD_REQUEST, reason);
		send_response(resp, 0, tid);
		MEMMAN_DELETE(resp);
		delete resp;
		unlock();
		return;
	}

	// Return a 400 response if the SIP body contained a parse error
	if (r->body && r->body->invalid) {
		resp = r->create_response(R_400_BAD_REQUEST, "Invalid SIP body.");
		send_response(resp, 0, tid);
		MEMMAN_DELETE(resp);
		delete resp;
		unlock();
		return;
	}
	
	// If a message exceeded the maximum message size, than the body
	// is not parsed by the listener.
	if (r->hdr_content_length.is_populated() &&
	    r->hdr_content_length.length > 0 &&
	    !r->body)
	{
		resp = r->create_response(R_513_MESSAGE_TOO_LARGE);
		send_response(resp, 0, tid);
		MEMMAN_DELETE(resp);
		delete resp;
		unlock();
		return;
	}
	
	// RFC 3261 8.2.3
	// Return a 415 response if content encoding is not supported
	if (r->body && r->hdr_content_encoding.is_populated()) {
		for (list<t_coding>::iterator it = r->hdr_content_encoding.coding_list.begin();
		     it != r->hdr_content_encoding.coding_list.end(); ++it)
		{
			if (!CONTENT_ENCODING_SUPPORTED(it->content_coding)) {
				resp = r->create_response(R_415_UNSUPPORTED_MEDIA_TYPE);
				SET_HDR_ACCEPT_ENCODING(resp->hdr_accept_encoding);
				send_response(resp, 0, tid);
				MEMMAN_DELETE(resp);
				delete resp;
				unlock();
				return;
			}		
		}
	}

	// Check if URI scheme is supported
	if (r->uri.get_scheme() != "sip") {
		resp = r->create_response(R_416_UNSUPPORTED_URI_SCHEME);
		send_response(resp, 0, tid);
		MEMMAN_DELETE(resp);
		delete resp;
		unlock();
		return;
	}

	switch(r->method) {
	case INVITE:
		recvd_invite(r, tid);
		break;
	case ACK:
		recvd_ack(r, tid);
		break;
	case CANCEL:
		recvd_cancel(r, tid, tid_cancel_target);
		break;
	case BYE:
		recvd_bye(r, tid);
		break;
	case OPTIONS:
		recvd_options(r, tid);
		break;
	case REGISTER:
		recvd_register(r, tid);
		break;
	case PRACK:
		recvd_prack(r, tid);
		break;
	case SUBSCRIBE:
		recvd_subscribe(r, tid);
		break;
	case NOTIFY:
		recvd_notify(r, tid);
		break;
	case REFER:
		recvd_refer(r, tid);
		break;
	case INFO:
		recvd_info(r, tid);
		break;
	case MESSAGE:
		recvd_message(r, tid);
		break;
	default:
		resp = r->create_response(R_501_NOT_IMPLEMENTED);
		send_response(resp, 0, tid);
		MEMMAN_DELETE(resp);
		delete resp;
		break;
	}
	
	post_process_request(r, tid, tid_cancel_target);

	unlock();
}