@ -31,6 +31,7 @@
# include <pjsip_simple.h>
# include <pjlib.h>
# include "asterisk/app.h"
# include "asterisk/res_pjsip_pubsub.h"
# include "asterisk/module.h"
# include "asterisk/linkedlists.h"
@ -3402,12 +3403,144 @@ end:
return res ;
}
struct simple_message_summary {
int messages_waiting ;
int voice_messages_new ;
int voice_messages_old ;
int voice_messages_urgent_new ;
int voice_messages_urgent_old ;
char message_account [ PJSIP_MAX_URL_SIZE ] ;
} ;
static int parse_simple_message_summary ( char * body ,
struct simple_message_summary * summary )
{
char * line ;
char * buffer ;
int found_counts = 0 ;
if ( ast_strlen_zero ( body ) | | ! summary ) {
return - 1 ;
}
buffer = ast_strdupa ( body ) ;
memset ( summary , 0 , sizeof ( * summary ) ) ;
while ( ( line = ast_read_line_from_buffer ( & buffer ) ) ) {
line = ast_str_to_lower ( line ) ;
if ( sscanf ( line , " voice-message: %d/%d (%d/%d) " ,
& summary - > voice_messages_new , & summary - > voice_messages_old ,
& summary - > voice_messages_urgent_new , & summary - > voice_messages_urgent_old ) ) {
found_counts = 1 ;
} else {
sscanf ( line , " message-account: %s " , summary - > message_account ) ;
}
}
return ! found_counts ;
}
static pj_bool_t pubsub_on_rx_mwi_notify_request ( pjsip_rx_data * rdata )
{
RAII_VAR ( struct ast_sip_endpoint * , endpoint , NULL , ao2_cleanup ) ;
struct simple_message_summary summary ;
const char * endpoint_name ;
char * atsign ;
char * context ;
char * body ;
char * mailbox ;
int rc ;
endpoint = ast_pjsip_rdata_get_endpoint ( rdata ) ;
if ( ! endpoint ) {
ast_debug ( 1 , " Incoming MWI: Endpoint not found in rdata (%p) \n " , rdata ) ;
rc = 404 ;
goto error ;
}
endpoint_name = ast_sorcery_object_get_id ( endpoint ) ;
ast_debug ( 1 , " Incoming MWI: Found endpoint: %s \n " , endpoint_name ) ;
if ( ast_strlen_zero ( endpoint - > incoming_mwi_mailbox ) ) {
ast_debug ( 1 , " Incoming MWI: No incoming mailbox specified for endpoint '%s' \n " , endpoint_name ) ;
ast_test_suite_event_notify ( " PUBSUB_NO_INCOMING_MWI_MAILBOX " ,
" Endpoint: %s " , endpoint_name ) ;
rc = 404 ;
goto error ;
}
mailbox = ast_strdupa ( endpoint - > incoming_mwi_mailbox ) ;
atsign = strchr ( mailbox , ' @ ' ) ;
if ( ! atsign ) {
ast_debug ( 1 , " Incoming MWI: No '@' found in endpoint %s's incoming mailbox '%s'. Can't parse context \n " ,
endpoint_name , endpoint - > incoming_mwi_mailbox ) ;
rc = 404 ;
goto error ;
}
* atsign = ' \0 ' ;
context = atsign + 1 ;
body = ast_alloca ( rdata - > msg_info . msg - > body - > len + 1 ) ;
rdata - > msg_info . msg - > body - > print_body ( rdata - > msg_info . msg - > body , body ,
rdata - > msg_info . msg - > body - > len + 1 ) ;
if ( parse_simple_message_summary ( body , & summary ) ! = 0 ) {
ast_debug ( 1 , " Incoming MWI: Endpoint: '%s' There was an issue getting message info from body '%s' \n " ,
ast_sorcery_object_get_id ( endpoint ) , body ) ;
rc = 404 ;
goto error ;
}
if ( ast_publish_mwi_state ( mailbox , context ,
summary . voice_messages_new , summary . voice_messages_old ) ) {
ast_log ( LOG_ERROR , " Incoming MWI: Endpoint: '%s' Could not publish MWI to stasis. "
" Mailbox: %s Message-Account: %s Voice-Messages: %d/%d (%d/%d) \n " ,
endpoint_name , endpoint - > incoming_mwi_mailbox , summary . message_account ,
summary . voice_messages_new , summary . voice_messages_old ,
summary . voice_messages_urgent_new , summary . voice_messages_urgent_old ) ;
rc = 404 ;
} else {
ast_debug ( 1 , " Incoming MWI: Endpoint: '%s' Mailbox: %s Message-Account: %s Voice-Messages: %d/%d (%d/%d) \n " ,
endpoint_name , endpoint - > incoming_mwi_mailbox , summary . message_account ,
summary . voice_messages_new , summary . voice_messages_old ,
summary . voice_messages_urgent_new , summary . voice_messages_urgent_old ) ;
ast_test_suite_event_notify ( " PUBSUB_INCOMING_MWI_PUBLISH " ,
" Endpoint: %s \r \n "
" Mailbox: %s \r \n "
" MessageAccount: %s \r \n "
" VoiceMessagesNew: %d \r \n "
" VoiceMessagesOld: %d \r \n "
" VoiceMessagesUrgentNew: %d \r \n "
" VoiceMessagesUrgentOld: %d " ,
endpoint_name , endpoint - > incoming_mwi_mailbox , summary . message_account ,
summary . voice_messages_new , summary . voice_messages_old ,
summary . voice_messages_urgent_new , summary . voice_messages_urgent_old ) ;
rc = 200 ;
}
error :
pjsip_endpt_respond_stateless ( ast_sip_get_pjsip_endpoint ( ) , rdata , rc , NULL , NULL , NULL ) ;
return PJ_TRUE ;
}
static pj_bool_t pubsub_on_rx_notify_request ( pjsip_rx_data * rdata )
{
if ( pj_stricmp2 ( & rdata - > msg_info . msg - > body - > content_type . type , " application " ) = = 0 & &
pj_stricmp2 ( & rdata - > msg_info . msg - > body - > content_type . subtype , " simple-message-summary " ) = = 0 ) {
return pubsub_on_rx_mwi_notify_request ( rdata ) ;
}
return PJ_FALSE ;
}
static pj_bool_t pubsub_on_rx_request ( pjsip_rx_data * rdata )
{
if ( ! pjsip_method_cmp ( & rdata - > msg_info . msg - > line . req . method , pjsip_get_subscribe_method ( ) ) ) {
return pubsub_on_rx_subscribe_request ( rdata ) ;
} else if ( ! pjsip_method_cmp ( & rdata - > msg_info . msg - > line . req . method , & pjsip_publish_method ) ) {
return pubsub_on_rx_publish_request ( rdata ) ;
} else if ( ! pjsip_method_cmp ( & rdata - > msg_info . msg - > line . req . method , & pjsip_notify_method ) ) {
return pubsub_on_rx_notify_request ( rdata ) ;
}
return PJ_FALSE ;