Anyone know any good examples on how to setup a pjsip client to receive messages. I can send messages from the client using:
pjsua_im_send(sip_acc_id, &to, NULL, &msgbody, NULL, NULL);
to any number.
But I have no idea what to do to receive messages into the already registered sip account.
Any info would be greatly appreciated.
Note: I can only use pjsip and no other library.
Edit: Some new stuff I found:
http://trac.pjsip.org/repos/ticket/1070
http://www.pjsip.org/release/0.5.4/PJSIP-Dev-Guide.pdf (however all this document says about incoming msgs is this:
16.1.2 Receiving MESSAGE
Incoming MESSAGE requests outside any dialogs will be received by application module. Incoming MESSAGE requests inside a dialog will be notified to dialog usage via on_tsx_state() callback of the dialog.
which still doesn't shine much light on how to handle incoming messages.
http://www.ietf.org/rfc/rfc3261.txt
http://trac.pjsip.org/repos/wiki/SIP_Message_Buffer_Event
Edit2: I've been told that on_pager function needs to be used for this functionality. So I tried but still no success unfortunately.
Here is what I did:
/* Initialize application callbacks */ app_config->cfg.cb.on_call_state = &on_call_state; app_config->cfg.cb.on_call_media_state = &on_call_media_state; app_config->cfg.cb.on_incoming_call = &on_incoming_call; app_config->cfg.cb.on_reg_state = &on_reg_state; app_config->cfg.cb.on_pager = &on_pager;
And the on_pager implementation:
static void on_pager(pjsua_call_id call_id, const pj_str_t *from, const pj_str_t *to, const pj_str_t *contact, const pj_str_t *mime_type, const pj_str_t *body) { NSLog(@"**************** on_pager called **********************"); AppDelegate *app = (AppDelegate *)[AppDelegate sharedApplication]; pjsua_call_info ci; pjsua_call_get_info(call_id, &ci); PJ_UNUSED_ARG(call_id); PJ_UNUSED_ARG(to); PJ_UNUSED_ARG(contact); PJ_UNUSED_ARG(mime_type); [app ring]; //PJ_LOG(3,(THIS_FILE, "MESSAGE from %.*s: %.*s (%.*s)", (int)from->slen, from->ptr, (int)text->slen, text->ptr, (int)mime_type->slen, mime_type->ptr)); postMessageStateNotification(call_id, &ci); }
I was expecting the application to call on_pager when a message is received but it didn't. on_incoming_call
however, does get called.
Turns out, what I did was correct, and it was just an issue with the server. Receiving msgs is now working!
To sum it up, basically:
when registering for sip:
app_config->cfg.cb.on_pager = &on_pager;
That will register for the on_pager() function to be called upon receiving an SMS. The rest is up to you what to do on inside that function.
This is the function header:
static void on_pager(pjsua_call_id call_id, const pj_str_t *from, const pj_str_t *to, const pj_str_t *contact, const pj_str_t *mime_type, const pj_str_t *body)
I think everything is self explanatory for the function parameters, etc. Thanks everyone anyways for trying!
And app_config is passed inside the pjsua_init() function.
Also, in sipStartup() we register the NSNotification functions for iOS.
/***** SIP ********/ /* */ - (BOOL)sipStartup { kSIPCallState = @"CallState"; kSIPRegState = @"RegState"; kSIPMwiInfo = @"MWIInfo"; if (_app_config.pool) return YES; self.networkActivityIndicatorVisible = YES; if (sip_startup(&_app_config) != PJ_SUCCESS) { self.networkActivityIndicatorVisible = NO; return NO; } self.networkActivityIndicatorVisible = NO; CTTelephonyNetworkInfo *phoneInfo = [[CTTelephonyNetworkInfo alloc] init]; CTCarrier *phoneCarrier = [phoneInfo subscriberCellularProvider]; NSLog(@"Carrier = %@", phoneCarrier); [self checkForConnection]; NSTimer *timer; receiveCallTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ }]; //timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(checkForConnection) userInfo:nil repeats:YES]; /** Call management **/ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processCallState:) name: kSIPCallState object:nil]; /** Registration management */ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processRegState:) name: kSIPRegState object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processMessageState:) name:kSIPMwiInfo object:nil]; return YES; }
and processMessageState: is below:
- (void)processMessageState:(NSNotification *)notification { NSLog(@"***** processMessageState is called *****"); NSNumber *value = [[ notification userInfo] objectForKey:@"CallID"]; pjsua_call_id callId = [value intValue]; int state = [[[ notification userInfo] objectForKey:@"Event"] intValue]; switch (state) { case PJSIP_EVENT_UNKNOWN: NSLog(@"unknown event"); break; case PJSIP_EVENT_TIMER: NSLog(@"timer event"); break; case PJSIP_EVENT_RX_MSG: NSLog(@"received --> rx_msg"); break; case PJSIP_EVENT_TX_MSG: NSLog(@"tx_msg"); break; case PJSIP_EVENT_TRANSPORT_ERROR: NSLog(@"msg transport error"); break; case PJSIP_EVENT_TSX_STATE: NSLog(@"event tsx state"); break; case PJSIP_EVENT_USER: NSLog(@"event user"); break; default: NSLog(@"processMessageState was called"); break; } }