...
SIP звонки на устройствах iOS возможны как из браузера, так и с использованием iOS SDKОписание.
Схема работы
1: SIP-сервер как прокси-сервер для передачи вызовов и RTP медиа
...
- два SIP-аккаунта;
- приложение Phone для совершения звонка;
- программный телефон для ответа на звонок.
...
6. Для завершения звонка нажмите кнопку Hangup в приложении, либо кнопку завершения звонка в программном телефоне.
Прием входящего звонка с SIP-устройства на
...
iOS
1. Для тестирования используем:
- два SIP-аккаунта;
- программный телефон для совершения звонка;
- приложение Phone для ответа на звонок.
2. Установите на AndroidiOS-устройство приложение Phoneприложение Phone. Запустите приложение, введите URL WCS-сервера для подключения к нему по Secure Websocket и данные SIP-аккаунта, принимающего звонок:
3. Запустите программный телефон, введите данные звонящего SIP-аккаунта:
...
5. Примите звонок в приложении, нажав Answer:
6. В программном телефоне убедитесь, что звонок начался:
...
Ниже описана последовательность вызовов при использовании примера Phone-min для создания звонка
PhoneMinActivity.javaКласс для основного вида приложения: ViewController (заголовочный файл ViewController.h; файл имплементации ViewController.m)
1. Создание звонка:
session.FPWCSApi2Session createCall(), call.call() code, FPWCSApi2Call call code
При создании звонка в метод createCall передаются параметры:
- имя вызываемого SIP-аккаунта
- дополнительные параметры SIP INVITE запроса, введенные пользователем
Code Block | ||||
---|---|---|---|---|
| ||||
- (FPWCSApi2Call *)call { CallOptions callOptions = new CallOptions(mCalleeView.getText().toString())FPWCSApi2Session *session = [FPWCSApi2 getSessions][0]; FPWCSApi2CallOptions *options = [[FPWCSApi2CallOptions alloc] init]; NSString AudioConstraints audioConstraints = callOptions.getConstraints().getAudioConstraints()*parameters = _inviteParameters.input.text; if (parameters && [parameters length] > 0) { NSError* MediaConstraintserr mediaConstraints = audioConstraints.getMediaConstraints()nil; parameters = [parameters stringByReplacingOccurrencesOfString:@""" withString:@"\""]; ... NSMutableDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:[parameters dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&err]; if (err) { call = session.createCall(callOptions); NSLog(@"Error converting JSON Invite parameters to dictionary %@, JSON %@", call.on(callStatusEventerr, parameters); } else { /** options.inviteParameters = dictionary; } } options.callee * Make the outgoing call= _callee.input.text; //used for only recv audio // options.localConstraints = [[FPWCSApi2MediaConstraints alloc] */ initWithAudio:NO video:NO]; // options.remoteConstraints = [[FPWCSApi2MediaConstraints alloc] initWithAudio:YES video:NO]; call.call()NSError *error; call = [session createCall:options error:&error]; ... [call call]; Log.i(TAG, "Permission has been granted by user"); return call; } |
2. Установка соединения с SIP-сервером
...
7. Стороны звонка обмениваются аудио- и видеопотоками
8. Завершение звонка
call.hangup() FPWCSApi2Call hangup code
Code Block | ||||
---|---|---|---|---|
| ||||
- (void)callButton:(UIButton *)button { [self changeViewState:button enabled:NO]; if (mCallButton.getTag() == null || Integer.valueOf(R.string.action_call).equals(mCallButton.getTag())) { [button.titleLabel.text isEqualToString:@"HANGUP"]) { if ("".equals(mCalleeView.getText().toString()))[FPWCSApi2 getSessions].count) { return; } ... [call hangup]; } else { mCallButton.setEnabled(false)[self toCallState]; } call.hangup();... call = null; } } |
9. Отправка команды на SIP-сервер
...