Changeset 4275 for pjproject/trunk
- Timestamp:
- Oct 4, 2012 6:11:58 AM (12 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip/sip_endpoint.h
r4154 r4275 214 214 pjsip_module *module ); 215 215 216 /** 217 * This describes additional parameters to pjsip_endpt_process_rx_data() 218 * function. Application MUST call pjsip_process_rdata_param_default() to 219 * initialize this structure. 220 */ 221 typedef struct pjsip_process_rdata_param 222 { 223 /** 224 * Specify the minimum priority number of the modules that are allowed 225 * to process the message. Default is zero to allow all modules to 226 * process the message. 227 */ 228 unsigned start_prio; 229 230 /** 231 * Specify the pointer of the module where processing will start. 232 * The default is NULL, meaning processing will start from the start 233 * of the module list. 234 */ 235 void *start_mod; 236 237 /** 238 * Set to N, then processing will start at Nth module after start 239 * module (where start module can be an explicit module as specified 240 * by \a start_mod or the start of module list when \a start_mod is 241 * NULL). For example, if set to 1, then processing will start from 242 * the next module after start module. Default is zero. 243 */ 244 unsigned idx_after_start; 245 246 /** 247 * Print nothing to log. Default is PJ_FALSE. 248 */ 249 pj_bool_t silent; 250 251 } pjsip_process_rdata_param; 252 253 /** 254 * Initialize with default. 255 * 256 * @param p The param. 257 */ 258 PJ_DECL(void) pjsip_process_rdata_param_default(pjsip_process_rdata_param *p); 259 260 /** 261 * Manually distribute the specified pjsip_rx_data to registered modules. 262 * Normally application does not need to call this function because received 263 * messages will be given to endpoint automatically by transports. 264 * 265 * Application can use this function when it has postponed the processing of 266 * an incoming message, for example to perform long operations such as 267 * database operation or to consult other servers to decide what to do with 268 * the message. In this case, application clones the original rdata, return 269 * from the callback, and perform the long operation. Upon completing the 270 * long operation, it resumes pjsip's module processing by calling this 271 * function, and then free the cloned rdata. 272 * 273 * @param endpt The endpoint instance. 274 * @param rdata The rdata to be distributed. 275 * @param p Optional pointer to param to specify from which module 276 * the processing should start. 277 * @param p_handled Optional pointer to receive last return value of 278 * module's \a on_rx_request() or \a on_rx_response() 279 * callback. 280 * 281 * @return PJ_SUCCESS on success. 282 */ 283 PJ_DECL(pj_status_t) pjsip_endpt_process_rx_data(pjsip_endpoint *endpt, 284 pjsip_rx_data *rdata, 285 pjsip_process_rdata_param *p, 286 pj_bool_t *p_handled); 216 287 217 288 /** -
pjproject/trunk/pjsip/include/pjsip/sip_transport.h
r4218 r4275 427 427 */ 428 428 PJ_DECL(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata); 429 430 /** 431 * Clone pjsip_rx_data. This will duplicate the contents of 432 * pjsip_rx_data and add reference count to the transport. 433 * Once application has finished using the cloned pjsip_rx_data, 434 * it must release it by calling #pjsip_rx_data_free_cloned(). 435 * 436 * By default (if flags is set to zero), this function copies the 437 * transport pointer in \a tp_info, duplicates the \a pkt_info, 438 * perform deep clone of the \a msg_info parts of the rdata, and 439 * fills the \a endpt_info (i.e. the \a mod_data) with zeros. 440 * 441 * @param src The source to be cloned. 442 * @param flags Optional flags. Must be zero for now. 443 * @param p_rdata Pointer to receive the cloned rdata. 444 * 445 * @return PJ_SUCCESS on success or the appropriate error. 446 */ 447 PJ_DECL(pj_status_t) pjsip_rx_data_clone(const pjsip_rx_data *src, 448 unsigned flags, 449 pjsip_rx_data **p_rdata); 450 451 /** 452 * Free cloned pjsip_rx_data. This function must be and must only 453 * be called for a cloned pjsip_rx_data. Specifically, it must NOT 454 * be called for the original pjsip_rx_data that is returned by 455 * transports. 456 * 457 * This function will free the memory used by the pjsip_rx_data and 458 * decrement the transport reference counter. 459 * 460 * @param rdata The receive data buffer. 461 * 462 * @return PJ_SUCCESS on success or the appropriate error. 463 */ 464 PJ_DECL(pj_status_t) pjsip_rx_data_free_cloned(pjsip_rx_data *rdata); 429 465 430 466 -
pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c
r4154 r4275 813 813 } 814 814 815 /* Init with default */ 816 PJ_DEF(void) pjsip_process_rdata_param_default(pjsip_process_rdata_param *p) 817 { 818 pj_bzero(p, sizeof(*p)); 819 } 820 821 /* Distribute rdata */ 822 PJ_DEF(pj_status_t) pjsip_endpt_process_rx_data( pjsip_endpoint *endpt, 823 pjsip_rx_data *rdata, 824 pjsip_process_rdata_param *p, 825 pj_bool_t *p_handled) 826 { 827 pjsip_msg *msg; 828 pjsip_process_rdata_param def_prm; 829 pjsip_module *mod; 830 pj_bool_t handled = PJ_FALSE; 831 unsigned i; 832 pj_status_t status; 833 834 PJ_ASSERT_RETURN(endpt && rdata, PJ_EINVAL); 835 836 if (p==NULL) { 837 p = &def_prm; 838 pjsip_process_rdata_param_default(p); 839 } 840 841 msg = rdata->msg_info.msg; 842 843 if (p_handled) 844 *p_handled = PJ_FALSE; 845 846 if (!p->silent) { 847 PJ_LOG(5, (THIS_FILE, "Distributing rdata to modules: %s", 848 pjsip_rx_data_get_info(rdata))); 849 pj_log_push_indent(); 850 } 851 852 LOCK_MODULE_ACCESS(endpt); 853 854 /* Find start module */ 855 if (p->start_mod) { 856 mod = pj_list_find_node(&endpt->module_list, p->start_mod); 857 if (!mod) { 858 status = PJ_ENOTFOUND; 859 goto on_return; 860 } 861 } else { 862 mod = endpt->module_list.next; 863 } 864 865 /* Start after the specified index */ 866 for (i=0; i < p->idx_after_start && mod != &endpt->module_list; ++i) { 867 mod = mod->next; 868 } 869 870 /* Start with the specified priority */ 871 while (mod != &endpt->module_list && mod->priority < p->start_prio) { 872 mod = mod->next; 873 } 874 875 if (mod == &endpt->module_list) { 876 status = PJ_ENOTFOUND; 877 goto on_return; 878 } 879 880 /* Distribute */ 881 if (msg->type == PJSIP_REQUEST_MSG) { 882 do { 883 if (mod->on_rx_request) 884 handled = (*mod->on_rx_request)(rdata); 885 if (handled) 886 break; 887 mod = mod->next; 888 } while (mod != &endpt->module_list); 889 } else { 890 do { 891 if (mod->on_rx_response) 892 handled = (*mod->on_rx_response)(rdata); 893 if (handled) 894 break; 895 mod = mod->next; 896 } while (mod != &endpt->module_list); 897 } 898 899 status = PJ_SUCCESS; 900 901 on_return: 902 if (p_handled) 903 *p_handled = handled; 904 905 UNLOCK_MODULE_ACCESS(endpt); 906 if (!p->silent) { 907 pj_log_pop_indent(); 908 } 909 return status; 910 } 911 815 912 /* 816 913 * This is the callback that is called by the transport manager when it … … 821 918 pjsip_rx_data *rdata ) 822 919 { 823 pjsip_msg *msg = rdata->msg_info.msg; 920 pjsip_process_rdata_param proc_prm; 921 pj_bool_t handled = PJ_FALSE; 824 922 825 923 if (status != PJ_SUCCESS) { … … 928 1026 #endif 929 1027 930 931 /* Distribute to modules, starting from modules with highest priority */ 932 LOCK_MODULE_ACCESS(endpt); 933 934 if (msg->type == PJSIP_REQUEST_MSG) { 935 pjsip_module *mod; 936 pj_bool_t handled = PJ_FALSE; 937 938 mod = endpt->module_list.next; 939 while (mod != &endpt->module_list) { 940 if (mod->on_rx_request) 941 handled = (*mod->on_rx_request)(rdata); 942 if (handled) 943 break; 944 mod = mod->next; 945 } 946 947 /* No module is able to handle the request. */ 948 if (!handled) { 949 PJ_TODO(ENDPT_RESPOND_UNHANDLED_REQUEST); 950 PJ_LOG(4,(THIS_FILE, "Message %s from %s:%d was dropped/unhandled by" 951 " any modules", 952 pjsip_rx_data_get_info(rdata), 953 rdata->pkt_info.src_name, 954 rdata->pkt_info.src_port)); 955 } 956 957 } else { 958 pjsip_module *mod; 959 pj_bool_t handled = PJ_FALSE; 960 961 mod = endpt->module_list.next; 962 while (mod != &endpt->module_list) { 963 if (mod->on_rx_response) 964 handled = (*mod->on_rx_response)(rdata); 965 if (handled) 966 break; 967 mod = mod->next; 968 } 969 970 if (!handled) { 971 PJ_LOG(4,(THIS_FILE, "Message %s from %s:%d was dropped/unhandled" 972 " by any modules", 973 pjsip_rx_data_get_info(rdata), 974 rdata->pkt_info.src_name, 975 rdata->pkt_info.src_port)); 976 } 977 } 978 979 UNLOCK_MODULE_ACCESS(endpt); 1028 pjsip_process_rdata_param_default(&proc_prm); 1029 proc_prm.silent = PJ_TRUE; 1030 1031 pjsip_endpt_process_rx_data(endpt, rdata, &proc_prm, &handled); 1032 1033 /* No module is able to handle the message */ 1034 if (!handled) { 1035 PJ_LOG(4,(THIS_FILE, "%s from %s:%d was dropped/unhandled by" 1036 " any modules", 1037 pjsip_rx_data_get_info(rdata), 1038 rdata->pkt_info.src_name, 1039 rdata->pkt_info.src_port)); 1040 } 980 1041 981 1042 /* Must clear mod_data before returning rdata to transport, since -
pjproject/trunk/pjsip/src/pjsip/sip_transport.c
r4262 r4275 603 603 } 604 604 605 /* Clone pjsip_rx_data. */ 606 PJ_DEF(pj_status_t) pjsip_rx_data_clone( const pjsip_rx_data *src, 607 unsigned flags, 608 pjsip_rx_data **p_rdata) 609 { 610 pj_pool_t *pool; 611 pjsip_rx_data *dst; 612 pjsip_hdr *hdr; 613 614 PJ_ASSERT_RETURN(src && flags==0 && p_rdata, PJ_EINVAL); 615 616 pool = pj_pool_create(src->tp_info.pool->factory, 617 "rtd%p", 618 PJSIP_POOL_RDATA_LEN, 619 PJSIP_POOL_RDATA_INC, 620 NULL); 621 if (!pool) 622 return PJ_ENOMEM; 623 624 dst = PJ_POOL_ZALLOC_T(pool, pjsip_rx_data); 625 626 /* Parts of tp_info */ 627 dst->tp_info.pool = pool; 628 dst->tp_info.transport = (pjsip_transport*)src->tp_info.transport; 629 630 /* pkt_info can be memcopied */ 631 pj_memcpy(&dst->pkt_info, &src->pkt_info, sizeof(src->pkt_info)); 632 633 /* msg_info needs deep clone */ 634 dst->msg_info.msg_buf = dst->pkt_info.packet; 635 dst->msg_info.len = src->msg_info.len; 636 dst->msg_info.msg = pjsip_msg_clone(pool, src->msg_info.msg); 637 pj_list_init(&dst->msg_info.parse_err); 638 639 #define GET_MSG_HDR2(TYPE, type, var) \ 640 case PJSIP_H_##TYPE: \ 641 dst->msg_info.var = (pjsip_##type##_hdr*)hdr; \ 642 break 643 #define GET_MSG_HDR(TYPE, var_type) GET_MSG_HDR2(TYPE, var_type, var_type) 644 645 hdr = dst->msg_info.msg->hdr.next; 646 while (hdr != &dst->msg_info.msg->hdr) { 647 switch (hdr->type) { 648 GET_MSG_HDR(CALL_ID, cid); 649 GET_MSG_HDR(FROM, from); 650 GET_MSG_HDR(TO, to); 651 GET_MSG_HDR(VIA, via); 652 GET_MSG_HDR(CSEQ, cseq); 653 GET_MSG_HDR(MAX_FORWARDS, max_fwd); 654 GET_MSG_HDR(ROUTE, route); 655 GET_MSG_HDR2(RECORD_ROUTE, rr, record_route); 656 GET_MSG_HDR(CONTENT_TYPE, ctype); 657 GET_MSG_HDR(CONTENT_LENGTH, clen); 658 GET_MSG_HDR(REQUIRE, require); 659 GET_MSG_HDR(SUPPORTED, supported); 660 default: 661 break; 662 } 663 hdr = hdr->next; 664 } 665 666 #undef GET_MSG_HDR 667 #undef GET_MSG_HDR2 668 669 *p_rdata = dst; 670 671 /* Finally add transport ref */ 672 return pjsip_transport_add_ref(dst->tp_info.transport); 673 } 674 675 /* Free previously cloned pjsip_rx_data. */ 676 PJ_DEF(pj_status_t) pjsip_rx_data_free_cloned(pjsip_rx_data *rdata) 677 { 678 PJ_ASSERT_RETURN(rdata, PJ_EINVAL); 679 680 pjsip_transport_dec_ref(rdata->tp_info.transport); 681 pj_pool_release(rdata->tp_info.pool); 682 683 return PJ_SUCCESS; 684 } 685 605 686 /***************************************************************************** 606 687 *
Note: See TracChangeset
for help on using the changeset viewer.