cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1264
Views
0
Helpful
8
Replies

OpenGL crash at REM iOS client SDK official demo

carson002
Level 1
Level 1

Crash if the REM client receive incoming call in background


Steps:

  • Init and start the ACBUC session in multithreading mode.
  • Log in REM client -> put in background
  • Waiting for the incoming call, and do not do anything on callee side.
  • End the call from caller side.


Result:

App crash

Expected:

App should not crash

Workaround:

Re-launch REM client app

Config:

REM server version: REM-10.6.1.10000-8

REM client SDK version: 2.1.31.1.1

Finesse version: 10.5.1

REM client iOS: 9.1

User impact:

After app crash, the session is disconnect and can not receive call.


Attach the crash log.

1 Accepted Solution

Accepted Solutions

rdoyle001
Level 1
Level 1

Hi Carson,

Sorry for the delay in responding.

We have not been able to reproduce this issue but in the steps to reproduce you mentioned:

  • Init and start the ACBUC session in multithreading mode.

Did you modify the sample code?

And if so can you provide a code snippet?

Thanks,

Rob

View solution in original post

8 Replies 8

sarapaul
Cisco Employee
Cisco Employee

Thanks for the report. I've passed it back to the development team to investigate.

Thanks for the quick reply.

rdoyle001
Level 1
Level 1

Hi Carson,

Sorry for the delay in responding.

We have not been able to reproduce this issue but in the steps to reproduce you mentioned:

  • Init and start the ACBUC session in multithreading mode.

Did you modify the sample code?

And if so can you provide a code snippet?

Thanks,

Rob

Hi Rob,

     You are welcome.

     That's indeed to modify the sample code for reproducing this issue, just do not init the UC session on the main thread, the issue is 100% reproducible.

     We can do just enough to reproduce this issue:


  • In ConnectivityManager.m , do not init the UC session on main thread, add some code in Bold:


-(void)dataLoaded:(NSData *)nsData

{

    // nsData will be empty on logout.

    if (nsData.length > 0)

    {

        NSError *error = nil;

        NSDictionary *response = [NSJSONSerialization JSONObjectWithData:nsData options:0 error:&error];

        if (error != nil)

        {

            NSLog(@"Error decoding JSON response from REST login API: %@", [error localizedDescription]);

            // TODO display error

            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Login/Logout failed!" message:[NSString stringWithFormat:@"Failed to log in/out. %@", [error localizedDescription]] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];

            [alert show];

            [self hider:NO];

        }

        else

        {

            configuration = [response objectForKey:@"sessionid"];

            NSLog(@"Got session : %@", configuration);

           

            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

                // The following line of code creates a UC object using the configuration retrieved from the gateway

                _uc = [ACBUC ucWithConfiguration:configuration delegate:self];

               

                // The following code can be used instead if STUN is required

               

                // NSArray* stunServers = [NSArray arrayWithObject:@"stun:stun.l.google.com:19302"];

                // _uc = [ACBUC ucWithConfiguration:configuration stunServers:stunServers delegate:self];

               

                [self registerForReachabilityCallback];

                BOOL acceptUntrustedCertificates = [[[NSUserDefaults standardUserDefaults] objectForKey:@"acceptUntrustedCertificates"] boolValue];

                [_uc acceptAnyCertificate:acceptUntrustedCertificates];

               

                NSNumber *useCookiesNumber = [[NSUserDefaults standardUserDefaults] objectForKey:@"useCookies"];

                _uc.useCookies = [useCookiesNumber boolValue];

               

                [_uc startSession];

               

                // _uc.phone is available, but please wait for ucDidStartSession before making a call.

               CFRunLoopRun();

            });

        }

    }

}


  • After UC session started, we can get the incoming call signal, so we can remove all call back logic for eliminating interference,      add code like these:

- (void) ucDidStartSession:(ACBUC *)uc

{

        return;

        [self hider:NO];

        ImSampleAppDelegate *appDelegate = (ImSampleAppDelegate *)[UIApplication sharedApplication].delegate;

        UITabBarItem *accountTab = appDelegate.tabbedViewController.tabBar.items.lastObject;

        accountTab.badgeValue = nil;

       

        automaticLoginReattempts = 0;

        LoginViewController *loginViewController = appDelegate.loginViewController;

        loginViewController.uc = _uc;

        loginViewController.configuration = configuration;

        // TODO - not to perform the segue if the user logged out manually, or in other words perform it only after a non-repeated login from the Login view controller. This is not causing a problem, anyway, as the segue doesn't seem to operate if the login form is not on top.

        [loginViewController performSegueWithIdentifier:@"loginSegue" sender:self];

}

        Do the same on all method of ACBUCDelegate and ACBClientCallDelegate and ACBClientPhoneDelegate that implement in ConnectivityManager.m and DialPadViewController.m :

- (void) phone:(ACBClientPhone*)phone didReceiveCall:(ACBClientCall*)call

{

    return;

     .......................

}

- (void) call:(ACBClientCall*)call didChangeStatus:(ACBClientCallStatus)status

{

    return;

     ..........................

}

              

..............

    

  • Now we can rebuild the sample code and run on iPad to reproduce the issue.
  • Log in REM client -> put in background
  • Waiting for the incoming call, and do not do anything on callee side.
  • End the call from caller side.
  • Then crash on callee side.

If there is any question on the reproduce step, let me know.

Thanks,

Carson

Thanks for the detailed response Carson I've passed it on to the dev team, Rob

Thanks

Hi Carson,

It has been pointed out to me that all method invocations on the SDK, even to access read-only properties, must be made from the same thread.

This can be any thread, and not necessarily the main thread. Internally, the SDK can use other threads to increase responsiveness, but any delegate callbacks are made on this same thread that is used to invoke to the SDK.

Regards,

Rob

Hi Rob,

Yes, just according to this developing guide:

          "This can be any thread, and not necessarily the main thread"


Only in this way can reproduce this bug.

As the code I showed before:

     firstly, according to "This can be any thread, and not necessarily the main thread", so we DO NOT init ACBUC object and start UC session on the main thread.

     secondly, according to "any delegate callbacks are made on this same thread that is used to invoke to the SDK", so we add "return" for all delegate callbacks for eliminating interference, that means we don't handle any logic and don't invoke any method and don't access any properties of the REM SDK while it callback.

     Finally, following the steps I showed before, keep monitor on the console log, we can reproduce this bug:

  • Use other threads to increase responsiveness for the REM SDK
  • Now we can rebuild the sample code and run on iPad to reproduce the issue.
  • Log in REM client -> put in background
  • Waiting for the incoming call, and do anything on callee side.
  • End the call from caller side.
  • Then crash on callee side.

Thanks,

Carson

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: