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(); }