imsdroid 是全功能的SIP / IMS的客户端,它基于doubango框架开发的app,doubango是目前世界上最好的3GPP IMS/RCS 嵌入式桌面系统框架,该框架提供了一套独特的功能,包括音频/视频通话、内容共享、消息、会议、通讯录等。
官网地址:http://code.google.com/p/imsdroid/
1、Boghe
IMS/ RCS Windows客户端
2、IMSDroid
IMS/ RCS Android客户端(使用NGN堆栈)
3、iDoubs
IMS/ RCS iOS客户端(iPhone,iPad和iPod Touch)
4、OpenVCS
开源视频会议服务器,用于管理多点控制单元(MCU),每个MCU可以处理多达64人参与
5、Flash2IMS
使用Adobe Flash 的SIP/ IMS网关
1、SIP ( RFC 3261 3GPP TS 24.229 REL- 9 )
2、 IPv4 IPv6 TCP UDP
3、信号编码 SigComp (RFC 3320 、3485、 4077 、4464 、4465、4896、5049、5112、1951)
4、通讯录
5、GSMA 通信
6、 语音(GSMA VoLTE)
7、GSMA RCS and GSMA VoLTE
8 、IMS 登陆 MD5加密
9、3GPP
10、服务路由探索
11、注册事件监听(注册事件、拨打事件、来电事件、消息事件。。。)
12、3GPP IP ( 3GPP TS 23.038 、24.040 、 24.011、 24.341、24.451短信)
13、语音呼叫( G729AB1 、 AMR - NB 、iLBC、 GSM 、 PCMA 、 PCMU、 Speex NB )
14、视频通话( H264、MP4V - ES 、Theora、 H.263 、 H.263 -1998 、H.261 )
15、双音多频DTMF ( RFC 4733 )
16、解决网络延迟和阻塞技术QoS negotiation using Preconditions (RFC 3312, 4032 and 5027)
17、SIP会话定时器( RFC 4028 )
18、临时响应( PRACK )
19、通信保持(3GPP TS 24.610 )
20、消息等待指示( 3GPP TS 24.606 )
21、E.164号码呼叫通过使用ENUM协议( RFC 3761 )
22、NAT穿越
23、一对一和群组聊天
如何注册一个SIP / IMS服务器?如下:
final String realm = "sip:doubango.org"; final String privateIdentity = "001"; final String publicIdentity = "sip:[email protected]"; final String password = "my secret"; final String proxyHost = "192.168.0.1"; RegistrationSession registrationSession; // Sip Callback final SipCallback callback = new SipCallback(){ @Override public int OnDialogEvent(DialogEvent e) { final SipSession sipSession = e.getBaseSession(); final long sipSessionId = sipSession.getId(); final short code = e.getCode(); switch (code){ case tinyWRAPConstants.tsip_event_code_dialog_connecting: if(registrationSession != null && registrationSession.getId() == sipSessionId){ // Registration in progress } break; case tinyWRAPConstants.tsip_event_code_dialog_connected: if(registrationSession != null && registrationSession.getId() == sipSessionId){ // You are registered } break; case tinyWRAPConstants.tsip_event_code_dialog_terminating: if(registrationSession != null && registrationSession.getId() == sipSessionId){ // You are unregistering } break; case tinyWRAPConstants.tsip_event_code_dialog_terminated: if(registrationSession != null && registrationSession.getId() == sipSessionId){ // You are unregistered } break; } return 0; } @Override public int OnRegistrationEvent(RegistrationEvent e) { // low level events return 0; } }; // Create the SipStack SipStack sipStack = new SipStack(callback, realm, privateIdentity, publicIdentity); // Set Proxy Host and port sipStack.setProxyCSCF(proxyHost, 5060, "UDP", "IPv4"); // Set password sipStack.setPassword(password); if(sipStack.isValid()){ if(sipStack.start()){ registrationSession = new RegistrationSession(sipStack); registrationSession.setFromUri(publicIdentity); // Send SIP register request registrationSession.register_(); } }
final NgnEngine mEngine = NgnEngine.getInstance();获取配置服务:
INgnConfigurationService mConfigurationService = mEngine.getConfigurationService();获取SIP / IMS服务:
INgnSipService mSipService = mEngine.getSipService();启动/停止引擎:
// Starts the engine mEngine.start(); // Stops the engine mEngine.stop();Contact Service
HTTP/HTTPS Service
HTTP / HTTPS服务用来发送和检索数据到/从远程服务器使用HTTP / HTTPS协议
Network Service
网络服务是用来管理WiFi和3G/4G网络连接
Sound Service
铃声,彩铃业务,警报
//获取和NGN引擎实例 NgnEngine mEngine = NgnEngine.getInstance(); //播放铃音 mEngine.getSoundService().startRingBackTone(); //停止铃音 mEngine.getSoundService().stopRingBackTone();Storage Service
final INgnConfigurationService mConfigurationService = NgnEngine.getInstance().getConfigurationService();
final INgnHistoryService mHistoryService = NgnEngine.getInstance().getHistoryService();
final INgnSipService mSipService = NgnEngine.getInstance().getSipService();
final String remoteUri = "+33600000000"; final String validUri = NgnUriUtils.makeValidSipUri(remoteUri); // sip:+33600000000"@doubango.org NgnAVSession avSession = NgnAVSession.createOutgoingSession(mSipService.getSipStack(), NgnMediaType.Audio); if(avSession.makeCall(validUri)){ Log.d(TAG,"all is ok"); } else{ Log.e(TAG,"Failed to place the call"); }
final String remoteUri = "+33600000000"; final String validUri = NgnUriUtils.makeValidSipUri(remoteUri); // sip:+33600000000"@doubango.org NgnAVSession avSession = NgnAVSession.createOutgoingSession(mSipService.getSipStack(), NgnMediaType.AudioVideo); if(avSession.makeCall(validUri)){ Log.d(TAG,"all is ok"); } else{ Log.e(TAG,"Failed to place the call"); }
final String SMSC = "sip:[email protected]"; // SMS Center final String remotePartyUri = "sip:[email protected]"; // remote party final String textToSend = "hello world!"; final NgnMessagingSession imSession = NgnMessagingSession.createOutgoingSession(mSipService.getSipStack(), remotePartyUri); if(!imSession.SendBinaryMessage(textToSend,SMSC)){ Log.e(TAG,"Failed to send"); } else{ Log.d(TAG,"Message sent"); } // release session NgnMessagingSession.releaseSession(imSession);
final String textToSend = "hello world!"; final String remotePartyUri = "sip:[email protected]"; // remote party final NgnMessagingSession imSession = NgnMessagingSession.createOutgoingSession(mSipService.getSipStack(), remotePartyUri); if(!imSession.sendTextMessage(textToSend)){ Log.e(TAG,"Failed to send"); } else{ Log.d(TAG,"Message sent"); } // release session NgnMessagingSession.releaseSession(imSession);
监听事件
SIP/IMS服务负责对SIP协议相关的所有任务(登记,音频/视频电话,寻呼机模式IM…)等都有监听,所有的通知都是异步方式。
final TextView mTvInfo = (TextView)findViewById(R.id.textViewInfo); final BroadcastReceiver mSipBroadCastRecv = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); // Registration Event if(NgnRegistrationEventArgs.ACTION_REGISTRATION_EVENT.equals (action)){ NgnRegistrationEventArgs args = intent.getParcelableExtra(NgnEventArgs.EXTRA_EMBEDDED); if(args == null){ Log.e(TAG, "Invalid event args"); return; } switch(args.getEventType()){ case REGISTRATION_NOK: mTvInfo.setText("Failed to register :("); break; case UNREGISTRATION_OK: mTvInfo.setText("You are now unregistered :)"); break; case REGISTRATION_OK: mTvInfo.setText("You are now registered :)"); break; case REGISTRATION_INPROGRESS: mTvInfo.setText("Trying to register..."); break; case UNREGISTRATION_INPROGRESS: mTvInfo.setText("Trying to unregister..."); break; case UNREGISTRATION_NOK: mTvInfo.setText("Failed to unregister :("); break; } } } }; final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(NgnRegistrationEventArgs.ACTION_REGISTRATION_EVENT); registerReceiver(mSipBroadCastRecv, intentFilter); Listening for audio/video call state change You can listen to the audio/video call state change in order to get notified when the call state change (incoming, incall, outgoing, terminated, ...). final BroadcastReceiver mSipBroadCastRecv = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { InviteState state; final String action = intent.getAction(); if(NgnInviteEventArgs.ACTION_INVITE_EVENT.equals(action)){ NgnInviteEventArgs args = intent.getParcelableExtra (NgnEventArgs.EXTRA_EMBEDDED); if(args == null){ Log.e(TAG, "Invalid event args"); return; } Log.d(TAG, "This is an event for session number "+args.getSessionId()); // Retrieve the session from the store NgnAVSession avSession = NgnAVSession.getSession (args.getSessionId()); if(avSession == null){ Log.e(TAG, "Cannot find session"); return; } switch((state = avSession.getState())){ case NONE: default: break; case INCOMING: Log.i(TAG, "Incoming call"); break; case INPROGRESS: Log.i(TAG, "Call in progress"); break; case REMOTE_RINGING: Log.i(TAG, "Remote party is ringing"); break; case EARLY_MEDIA: Log.i(TAG, "Early media started"); break; case INCALL: Log.i(TAG, "Call connected"); break; case TERMINATING: Log.i(TAG, "Call terminating"); break; case TERMINATED: Log.i(TAG, "Call terminated"); break; } } } };
final String myRealm = "sip:doubango.org"; final boolean bSaveNow = true; mConfigurationService(ConfigurationEntry.NETWORK_REALM, myRealm, bSaveNow);