Thursday, April 30, 2015

Bar code reading in iOS


With iOS 7.0 Apple introduced ability to detect the bar code and QR codes using the AV foundation framework. The supported types are UPC-A, UPC-E, Code 39, Code 39 Mode 43, Cdoe 93, Code 128, EAN 8, EAN 13, Aztec, PDF 417, QR 

Detecting bar code programmatically is simple. The below are the main steps involved 

1. Create a CaptureDeviceInput With AVCaptureSession as media type video
2. Create a AVVideoCatptureOutput and set the delegate 
3. Create a AVCapturePReview layer so that viewpoint on the screen 

_session = [[AVCaptureSession alloc] init];
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;

_input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error];
if (_input) {
    [_session addInput:_input];
} else {
    NSLog(@"Error: %@", error);
}

_output = [[AVCaptureMetadataOutput alloc] init];
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[_session addOutput:_output];

_output.metadataObjectTypes = [_output availableMetadataObjectTypes];

_prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_prevLayer.frame = self.view.bounds;
_prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:_prevLayer];

[_session startRunning];

Now, when the call back happens, transform the preview layer data to the machine readable code transformed value 

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    CGRect highlightViewRect = CGRectZero;
    AVMetadataMachineReadableCodeObject *barCodeObject;
    NSString *detectionString = nil;
    NSArray *barCodeTypes = @[AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code,
                              AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code,
                              AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];
    
    for (AVMetadataObject *metadata in metadataObjects) {
        for (NSString *type in barCodeTypes) {
            if ([metadata.type isEqualToString:type])
            {
                barCodeObject = (AVMetadataMachineReadableCodeObject *)[_prevLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata];
                highlightViewRect = barCodeObject.bounds;
                detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
                break;
            }
        }
        
        if (detectionString != nil)
        {
            _label.text = detectionString;
            break;
        }
        else
            _label.text = @"(none)";
    }
    
    _highlightView.frame = highlightViewRect;
}


References:



Installing and Running SIPp tool on MAC

The whole procedure was quite easy i felt until i attempted to do this. Below are the main steps like in any other installation 

- Clone the project from git. git clone https://github.com/SIPp/sipp.git 
- Now run the ./build.sh which will do the below things
1. Checkout the gtest submodule
2. generate autotools files
3. runs configure 
4. builds and runs the test suite 
5. builds SIPp. 

If we want to build with SSL, PCAP and SCTP, then below command to be given 

./build.sh —-with-pcap —with-sctp —-with-openssl 


once the build is successful, below command can be used for running the SIPp as user agent server is like below 

./sipp -sn uas 

the below window was shown



references:

SIPp tool for SIP Testing a brief overview

SIPp is an open source test tool/ traffic generator. 

It includes a few basic SipStone user agent scenarios (UAC and UAS) and establishes and releases multiple calls with the INVITE and BYE methods. it can also read customXML files to generate simple and complex scenarios. It features dynamic display of running tests as well. 

There are advanced features such as IPV6 support, TLS, SCTP, SIP Authentication, conditional scenarios, UDP retransmissions, error robustness (call timeouts, protocol defences) 

SIPp can also send media RTP traffic through RTP echo and RTP/pcap replay. Media can be audio or video. 

SIPp can be used to test various real SIP equipments like SIP Proxies, B2BUAs, SIP media servers, SIP/x gateways, SIP PBX, it is also useful to emulate thousands of user agent calling the SIP system. 

References: 

Tuesday, April 28, 2015

Android playing Youtube video

Below is the launch scheme to launch the native Android You tube player 

Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:VIDEO_ID"));
startActivity(i);

Now, we can also check whether this launch scheme is supported by the below code and decide to show an error message or laugh a web view and pass the link 

Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:" + videoID));
List list = getPackageManager().queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() == 0) {
    // default youtube app not present or doesn't conform to the standard we know
    // use our own activity
    i = new Intent(getApplicationContext(), YouTube.class);
    i.putExtra("VIDEO_ID", videoID);
}
startActivity(i);


If want to launch in wbeview, just give the URL for the web view as the youtube link such as https://www.youtube.com/watch?v=6SRQQ1jdBJw 

References:

WebRTC vs WebSocket

WebRTC is designed for high performance, high quality communication of video, audio and arbitrary data. This mechanism needs a service via which it can exchange network and media data which is called signalling Once the signalling has taken place, audio/video/data is streamed directly between clients avoiding the performance cost of streaming via an intermediary server. 

WebSocket is designed to provide bi-directional communication between client and server. It is possible to stream audio and video over web sockets, but this technology is not inheratly designed for streaming unlike WebRTC. 

Web sockets are supported in most of the modern browsers. This uses HTTP compatible handshaking and default ports making it much easier to use with existing firewall, proxy and web server infrastructure. 
this has simpler web APIs. a class and a few call backs 

Only supports reliable, in-order transport because it is built on TCP. This means that packet drops can delay all subsequent packets. 

WebRTC: 
This is mostly supported by only Chrome and Firefox. this mechanism is P2P , but even might require a signalling. Transport layer is configurable with application to choose if connection is in-order and/or reliable. The APIs are complex, The JS libs provide simpler API, but these are constantly evolving. 

references:

Monday, April 27, 2015

Back to Back User Agents

A B2BUA is a logical network element in SIP applications. A B2BUA operates between both ends of a phone call or communications session and divides the communication channel into two call legs and mediates all SIP signalling between both ends of the call, from call establishment to termination. This mechanism help service provider to implement metering for the calls and may also provide value added services during the call. 

In the originating call leg, B2BUA acts as a user agent server (UAS) and processes the request as user agent client (UAC) to the destination end, handling the signalling between end points back to back. A B2BUA maintains the complete state for the calls it handles. Each side of the B2BUA operates as standard SIP network element as specified in RFC 3261. 

Often B2BUA are implemented in Media gateways to also bridge the media streams for full control over the session. 

A Signalling gateway, implemented as part of the Session Border Controller is example of B2BUA. 


References:

Sunday, April 26, 2015

Google Scatter Chart Example

Below is a scatter chart code. The intention is to plot the frequency of request in Y axis and the clock time on the X axis.

JSFiddler out put is below



 google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Time', 'Interval'],
          [ .30,      30],
          [ 1.00,      27],
          [ 1.30,     29],
          [ 2.00,      35],
          [ 3.00,      60],
          [ 3.30,    30]
        ]);

        var options = {
          title: 'Request Frequency scatter chart',
          hAxis: {title: 'Time', minValue: 0, maxValue: 2},
          vAxis: {title: 'Interval', minValue: 0, maxValue: 60},
          legend: 'none'
        };

        var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));

        chart.draw(data, options);
      }

References:
https://developers.google.com/chart/interactive/docs/gallery/scatterchart

Saturday, April 25, 2015

Android Music Player Intents

There are a good set of intents for Android default music player which allows application to control the Player behaviour without even having to launch the Music player

Some of them are below 

AudioManager mAudioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);

                        if (mAudioManager.isMusicActive()) {

                            Intent musicPlayerIntent = new Intent("com.android.music.musicservicecommand");

                            musicPlayerIntent.putExtra("command", "pause");
                            sendBroadcast(musicPlayerIntent);
                        }

  // pause
                        Intent i = new Intent("com.android.music.musicservicecommand");
                        i.putExtra("command", "pause");
                        sendBroadcast(i);

// play
                        Intent i = new Intent("com.android.music.musicservicecommand");
                        i.putExtra("command", "play");
                        sendBroadcast(i);

// next
                        Intent i = new Intent("com.android.music.musicservicecommand");
                        i.putExtra("command", "next");
                        sendBroadcast(i);

// previous
                        Intent i = new Intent("com.android.music.musicservicecommand");
                        i.putExtra("command", "previous");
                        sendBroadcast(i);

References:


Android Changing the Audio Focus

Ignored for app to get exclusive access to the device output sound card, first app needs to request the Audio service for focus change
The code is like below. 

AudioManager am = (AudioManager)(AppUtils.getAppContext()).getSystemService(Context.AUDIO_SERVICE);
                        int result = am.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener(){
                                                              @Override
                                                              public void onAudioFocusChange(int focusChange) {

                                                                  if (focusChange == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {

                                                                  }
                                                              }
                                                          },
                                // Use the music stream.
                                AudioManager.STREAM_MUSIC,
                                // Request permanent focus.
                                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

                        // Start playback.
                        Intent objIntent = new Intent(AppUtils.getAppContext(), AudioPlayerService.class);
                        AppUtils.getAppContext().startService(objIntent);

References:

Tuesday, April 21, 2015

Java Socket - Accepting multiple clients on single port

The concept is simple that after accepting the client on the socket, move that socket on to a separate thread and wait for next client to come to the same port. Code is below

public static void main(String args[]) {
            ServerSocket serverSocket = null;
            Socket socket = null;
            
            try {
                serverSocket = new ServerSocket(1234);
            } catch (IOException e) {
                e.printStackTrace();
                
            }
            while (true) {
                try {
                    socket = serverSocket.accept();
                } catch (IOException e) {
                    System.out.println("I/O error: " + e);
                }
              
                new ClientSocketProcessor(socket).start();
            }

        }


 public class ClientSocketProcessor extends Thread {
            protected Socket clientSocket;
            
            public ClientSocketProcessor(Socket socket) {
                this.clientSocket = socket;
            }
            
            public void run() {
System.out.println("accepted a client socket");
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
            System.out.println("created print writer out");
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            
            String inputLine, outputLine;
            
            StringBuffer requestBuffer = new StringBuffer();
            MSIPRequest request = new MSIPRequest();
            while ((inputLine = in.readLine()) != null) {
                System.out.println(inputLine);
}
            }
        }

References: 
https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html
http://stackoverflow.com/questions/10131377/socket-programming-multiple-client-to-one-server

Monday, April 20, 2015

iOS Identifying if the device is 64 bit Chipset programmatically

Part of my project, had to identify whether the device chipset is 64 bit architecture. Beginning from A7 chipset, Apple has  64 bit hardware architecture. Based on this chipset, the devices in market  as of now are

iPhone 5S,
iPad mini 2
iPad mini 3
iPad Air

Apple has introduced A8 chipset on their below models which are also desktop class 64 bit architecture.

iPhone 6
iPhone 6 Plus

To figure out programatically whether the device is running on 64 bit architecture, code at the given link can be used. Note that this is available on various stack over flow forums and i just colleged all into one.

http://goo.gl/PfqJwk

References:
http://en.wikipedia.org/wiki/List_of_iOS_devices
http://en.wikipedia.org/wiki/Apple_A7#Products_that_include_the_Apple_A7

Sunday, April 19, 2015

SIP Authentication response generation

Validating the “response” in an incoming SIP request is not so much complicated. the main part is recreating the 

public boolean isAuthorizationValid(String inputResponse, String method, String username,String plainPassword, String realm, String inputNonce, String inputCNonce, String uri) throws Exception
    {
        MD5 md5 = new MD5();
        String HA1 = md5.getMD5(username+":"+realm+":"+plainPassword);
        String HA2 = md5.getMD5(method.toUpperCase() + ":" + uri);
        
        String temp1 = HA1 + ":" + inputNonce;
        if (inputCNonce != null)
        {
            temp1 += ":" + inputCNonce;
        }
        temp1 += ":" + HA2;
        String recreatedResponse = md5.getMD5(temp1);
        System.out.println("recreated Response :"+recreatedResponse);
        return inputResponse.equals(recreatedResponse);
    }


Calling the method with the parameters like below reveal that the first parameter and the response created with the rest of the parameter are the same.  

 md5.isAuthorizationValid("375fdfc61c98416748e436f1960082a7", "REGISTER", "testusername","testpassword", "testrealm.example.com","62886a59552fb3f51S43f5f55577d8bb798d25e9e8aa93d75611b5","faaaa525","sip:testrealm.example.com");

References:


RFC 2067 MD5 response generation

MD5 is a one way hash algorithm. It is not possible to reverse code to the original string.
Typically use case would be to verify the user name and password. provided both client and server knows it. 
a simple digest based authentication would be of form below RFC 2067 

HA1 = MD5(username:realm:password)
HA2 = MD5(method:digestURI)
response=MD5(HA1:nonce:HA2)

For e.g. say user name is “user1” and password is “pass1” and realm is example.com

HA1 will be MD5 (user1:example.com:pass1) 
14f4a22e8a3c41f0a88822ce8b64e23a

Consider the client is trying to access the resource 

GET /dir/index.html HTTP/1.0 
Host : localhost 

HA2 will be MD5(GET:/dir/index.html)
39aff3a2bab6126f332b942af96d3366

Now assume the nonce came from server in the WWW-Authenticated header is dcd98b7102dd2f0e8b11d0f600bfb0c093 
then the response created will be 

response = MD5(14f4a22e8a3c41f0a88822ce8b64e23a:dcd98b7102dd2f0e8b11d0f600bfb0c093:39aff3a2bab6126f332b942af96d3366);

71def13957000653830c2054c39dc7fd

The MD5 can be generated using the code below. 

MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(inputStr.getBytes());
        
        byte byteData[] = md.digest();
        
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < byteData.length; i++)
            sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
        
        return sb.toString();

References:

Saturday, April 18, 2015

Digest Authentication

Digest authentication was originally specified by RFC 2069. This specifies a roughly traditional digest authentication scheme with security maintained by a server-generated nonce value. The authentication response is formed as follows (where HA1 and HA2 are names of string variables) 

HA1 = MD5(username:realm:password)
HA2 = MD5(method:digestURI)
response = MD5(HA1:nonce:HA2)

RFC 2069 is later replaced by RFC 2617 (HTTP authentication : Basic and Digest Access Authentication). RFC 2617 introduced a number of optional security enhancements to the digest authentication; “quality of protection” (qop), nonce counter incremented by the client, a client generated random nonce. 

If the Algorithm directive is “MD5” or unspecified, then HA1 is, 

HA1 = MD5(username:realm:password)

If the algorithm directive value is “MD5-sess” then HA1 is 

HA1 = MD5(MD5(username:realm:password):nonce:cnonce)

If the qop directive is “auth” or unspecified, then HA2 is 

HA2 = MD5(method:digestURI)

If the qop directive is “auth-int” then HA2 is 

HA2 = MD5(method:digestURI:MD5(entireBody)) 

If the qop is not specified then the response is computed as follows 

response = MD5(HA1:nonce:HA2)

if the qop is specified as “auth“ or “auth-int”, then the response is computed as follows 

response = MD5(HA1:nonce:nonceCount:clientNonce:qop:HA2) 

References: 

Java Generating Secure Random

SecureRandom class in Java provides cryptographically strong random number generator (RNG). A cryptographically strong random number minimally complies with the statistical random number generator tests specified in FIPS 140-2. The seed material passed to the random number must be unpredictable. 

A caller obtains a SecureRandom  via a no argument constructor or one of the getInstance methods. 

SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);

Many random number generators are in the form of pseudo - random number generator (PRNG), which means they use deterministic algorithm to produce a pseudo-random sequence from a true random seed. Other implementations may produce true random numbers, and yet others may use combination of these two techniques. 

Also, if the requirement is only to generate a unique identifier which is not securely strong, below approach can be used as well.  

 String uuid = UUID.randomUUID().toString();
 uuid = uuid.replaceAll("-", "z");
 return uuid;

References:

iOS Playing Youtube video.

Playing youtube video is easy and an application can play this using the help component that is provided. 
More details are at the links mentioned in References: 

The code to integrate this is as follows 

Firs of all, download the github repository files and take the YTPlayerView.h & YTPlayerView.m files
Also, take the asset folder that contains the HTML file that is loaded by this YTPlayerView class 
Make sure it is included in the bundle, otherwise, need to do a work around to load the file file resource instead of the build that the class by default looking for. 

Now, below are the steps to add the player and start playing it. 

#import “YTPlayerView.h”
@property(nonatomic, strong) IBOutlet YTPlayerView *playerView;

[self.playerView loadWithVideoId:@"M7lc1UVf-VE"];


There are a few delegates like below. 

@interface ViewController : UIViewController
- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
    switch (state) {
        case kYTPlayerStatePlaying:
            NSLog(@"Started playback");
            break;
        case kYTPlayerStatePaused:
            NSLog(@"Paused playback");
            break;
        default:
            break;
    }
}

- (void)playerViewDidBecomeReady:(YTPlayerView *)playerView;
- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state;
- (void)playerView:(YTPlayerView *)playerView didChangeToQuality:(YTPlaybackQuality)quality;
- (void)playerView:(YTPlayerView *)playerView receivedError:(YTPlayerError)error;


There are quite some bugs in this class it looks like. Did some modification in the class for few tests. 

References: 

iOS Launching Settings from iOS App

From iOS 8.0, it looks like application can launch the settings screen. Below code can do this


[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];

When tested with the sample app, below is the screenshot after running. In this case, the app had only requested for Notification permission. 


All the permissions for the appication will be listed in this screen. 

References: 

Thursday, April 16, 2015

CoAP

CoAP is a constrained Application protocol from CoRE (Constrained Resource Environment) IETF Group

Architecuture of CoAP 
Like HTTP, CoAP is a document transfer protocol. Unlike HTTP CoAP is designed for the needs of constrained devices. 
CoAP packets are much smaller than HTTP TCP flows. Bitfields and mappings from strings to integers are used extensively to save space. 
Packets are simple to generate and can be parsed without much RAM in constrained devices. 
CoAP runs over UDP, not TCP. Clients and servers communicate through connectionless datagrams. Retries and Recordings are implemented 
in the application stack. Removing the need of TCP may allow full IP networking in small micro controllers. CoAP alows UDP broadcast and multicast
to be used for addressing. 

CoAP follows a client server model, clients request to servers, servers send back responses. Clients may GET, PUT, POST and DELETE resources. 
CoAP is designed to interoperate with HTTP and the RESTful web at large through simple proxies. 
Because CoAP is datagram based, it may be used on top of SMS and other packet based communication protocols. 

Application Level QoS 
Requests and response message may be marked as confirmable or non confirmable. Confirmable messages must be acknowledged by the receiver with an ack packet. 

non confirmable messages are fire and forget 

Content Negotiation 
Like HTTP, CoAP supports Content negotiation. Client uses Accept option to express a preferred presentation of a resource and servers reply with a Content-Type option to tell clients what they are getting. As with HTTP, this allows client and server to evolve independently adding new representations without affecting each other. 

CoAP requests may use query strings in form ?a=b&c=d. These can be used to provide search, paging and other features to clients. 

Security. Because CoAP is built on top of UDP and not TCP, TLS/SSL is not possible for providing security. DTLS, Datagram Transport Layer Security provides the same assurance as TLS. Typically CoAP supported devices will support RSA and AES or ECC and AES. 

Observe: CoAP extends the HTTP request model with the ability to observe a resource. When the observe flag is set on a CoAP GET request, server might continue to reply after the initial document has been transferred. This allows servers to stream states as  they occur. 

Resource Discovery 
CoAP defines a standard mechanism for a resource discovery. Servers provides a list of their resource at a well known core. 

NAT issues: In CoAP, a sensor mode is typically a server, not a client (though it may be both). The sensor (or actuator) provides resources which can be accessed by clients to read or alter the state of the sensor. 

as CoAP sensors are servers, they must be able to to receive inbound packets. To function properly behind NAT, a device may first send a request out to the server, as done in LWM2M, allowing the router to associate the two. Although CoAP does not require IPv6, it is easiest used in IP environment where device are directly routable. 

References:

Wednesday, April 15, 2015

MQTT Protocol

MQTT is  a publish/subscribe messaging protocol designed for lightweight M2M communications.
This was originally developed by IBM and now it is a standard. 




MQTT is a client server protocol where every sensor is a client and it connects to a server, known as broker, over TCP. 

MQTT is message oriented, every message is a discrete chunk of data, opaque to the broker. 

Every message is published to an address, known as topic. Clients may subscribe to multiple topics. Every client subscribed to a topic receives every message published to the topic. 

Below is the concept exemplified with 3 clients and a broker. 


Client B, C subscribed for light on event. When A publishes light ON, Broker server sends that as Notify to B & C.

MQTT supports 3 application level QOS. Fire and Forget, devlivered at least once, delivered exactly once. 

MQTT clients can register a custom “lat will and testament” message to be sent by the broker when they disconnect. These messages can be 
used to signal to subscribers when a device disconnects. 

Persistence : MQTT has support for persistent messages stored on the Broker. When client publish, it can request broker to store the message when a client subscribe to a topic, any persisted message will be sent to the client. Unlike message queues, MQTT brokers do not allow persisted messages to be backed up inside the server. 

Security MQTT brokers may require username and password authentication from the client. To ensure privacy, TCP connection can be encrypted using SSL/TLS. 

MQTT-SN. Even though MQTT is designed to be light weight, it has two drawbacks for very constrained devices. 

1. Every MQTT client must support TCP and will typically hold a connection open to the broker a all the times. For some environments where packet loss is high or computing resources are scarce, this is a problem. 

2. MQTT topic names are often long strings which make them impractical for 802.15.4

Both of these shortcomings are addressed for MQTT-SN protocol. which defines UDP mapping of MQTT and adds broker support for indexing topic names.   

References:

Tuesday, April 14, 2015

SIP Authentication Procedure - Part I


SIP provides a stateless, challenge based mechanism for authentication that is based on authentication in HTTP. Any time that a proxy server or UA receive a request, it may challenge the originator to provide assurance of its identity. 

The framework for SIP authentication closely parallels the HTTP (RFC 2617) In particular, the BNF form for auth-scheme, auth-param, challenge, realm, realm-value, and credential is identical  (although the use of “Basic” as a scheme is not permitted) . In SIP, a UAS uses the 401 response to challenge the identify of a UAC. Additionally, registrars and redirect servers may make use of 401. The proxies must make use of 407 response code for the same. The requirements for inclusion of Proxy-Authenticate, Proxy-Authorisation, WWW-Authenticate, and Authorization in various messages are identical to those described in RFC 2617. 

Below are the rules for creating realm string for the operators of user agents or proxy servers. 

1. Realm string must be globally unique. It is recommended to have hostname or domain name. 
2. Realm string should present a human- readable identifier that can be rendered to a user. 

For e.g. 

INVITE sip: bob@biloxi.com SIP/2.0 
Authorisation : Digest realm=“biloxi.com”, <…>

generally SIP authentication is meaningful for a specific realm, a protection domain. Thus for a digest authentication, each such protection domain has its own username and password. If a server does not require authentication or password if may accept a default user name “anonymous”, which has no password (password of “”). Similarly UAC representing many users such as PSTN gateways may have their own device specific user name and password, rather than accounts for a particular users, for their realm. 

ACK and CANCEL are special request that does require special handling. 

UAC creating an ACK message will duplicate all of the authorisation and Proxy-Authorization header field value that appeared in the INVITE to which the ACK corresponds. Servers must not attempt to challenge ACK. 

When UAC receives a challenge, it SHOULD render it to the user the contents of the “realm” parameter in the challenge which appears either in the WWW-Authenticate or Proxy-Authenticate header header field. This is needed if the UAC does not already know the credential for the realm. 

References:



Monday, April 13, 2015

Android Shared Preferences

Saving values 

        Context ctx = AppUtils.getAppContext();
        if(ctx != null && prefKey != null && prefValue != null)
        {
            Log.v(LOG_TAG,"context value exists: "+ctx);
            this.sensorPreferenceStorage = ctx.getSharedPreferences(PREFERNCE_STORE,  AppUtils.getAppContext().MODE_PRIVATE);
            Log.v(LOG_TAG,"preference storage is :"+this.sensorPreferenceStorage);
            SharedPreferences.Editor editor = this.sensorPreferenceStorage.edit();
            editor.putString(prefKey,prefValue);
            editor.commit();
        }

Reading value 

        Context ctx = AppUtils.getAppContext();
        Log.v(LOG_TAG,"getting the Sensor preferece value for key:"+preferenceKey);
        if(ctx != null && preferenceKey != null)
        {
            this.sensorPreferenceStorage = ctx.getSharedPreferences(PREFERNCE_STORE,  AppUtils.getAppContext().MODE_PRIVATE);
            String strVal = this.sensorPreferenceStorage.getString(preferenceKey, null);
            Log.v(LOG_TAG,"value retrieved is:"+strVal);
            return strVal;
        }

References: 

Thursday, April 9, 2015

Java Using Reflection to Invoke method.

Below code is an example for it

import java.lang.reflect.Method;
import java.lang.reflect.Type;

public class MethodReflection {
    
    public static void main(String a[]) throws Exception
    {
        
        RuleEvaluator evaluator = new RuleEvaluator();
        Method[] allMethods = evaluator.getClass().getDeclaredMethods();
        for (Method m : allMethods) {
            String mname = m.getName();
            if(mname.startsWith("difference"))
            {
                Type[] pType = m.getGenericParameterTypes();
                for (int i = 0; i < pType.length; i++)
                {
                    System.out.println("pType is :"+pType[i]);
                }
                Object o = m.invoke(evaluator,1,2,3,4);
                System.out.println("difference is:"+(Integer)o);
            }
        }
    }
}

class RuleEvaluator
{
    public int difference(int srcLat, int srcLon, int dstLon, int dstLat)
    {
        System.out.println("--Invoking difference --");
        return srcLat - srcLon - dstLon - dstLon;
    }
    
    public int total(int one, int two)
    {
        return 10;
    }
    
    public int sumOf(int[] args)
    {
        return 10;
    }


}

References:
https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html

Sunday, April 5, 2015

A look at think app blog about apple watch

this tutorial basically walk through the Apple’s Sample App for Apple Watch, Watchkit Catalog. 

Watch kit acts a a conduit that connects to the watch kit extension which resides in the iPhone app and orchastrates the watch app interface. 
When the user interacts with the watch interface, WatchKit signals to the paired iPhone and Watchkit extension then creates the objects at runtime needed to manage 
the appropriate screens the user interacts with. 

The watch kit architecture is like below 



If one need to add a watch kit app to a project, below step can be followed 

file -> New > Target -> and then select Apple Watch. 

On this screen we can select whether we need glance or Notification. 

Notification can be two, static and dynamic.

Once we create glance or notification, we can run that by selecting the executable accordingly by creating a new target. 

References:

WatchKit FAQ Items


This is a summary of few main points got in to me about the watch kit after going through the article in reference. 

How many Apple watches can be paired with iPhone? 
one Apple watch at a time. 

Can one pair Apple watch with iPad? 
No. 

Can iPhone app wake up watch extension and watch app?
No. Only watch kit extension can request System to launch the iPhone app which happens in the background and not the other way around. 

Can third party app make phone calls from a watch app? 
No. There is no third party api that lets one to initiate a phone call directly from watch kit extension. Since the companion app cannot be brought to foreground either, all the calls to the openURL are ignored silently. 

Can a watch app access hardware sensors such as heartbeat sensors and other sensors on the watch from watch app? 
No, there is no API to access hardware sensors on the watch from Watch app at this time. 

What are the difference between Short-look, long-look, static and dynamic notifications? 
Short-Look : a short look notification is provided by the system. Similar to a notification that appears on the iPhone at the banner, user don’t have any control over this short look notification. A short look notification displays App icon, app name and the title string from the notifications payload. When the notification arrives, system displays the notification and if the user raise the wrist, it get converted to a long-look notification after a slight pause. 

Long-Look. A long look notification can be either static or dynamic. 

Static: A static notification includes a single label that is populated automatically using the notifications payload. One can create a static notification scene in the watch app’s storyboard, but can’t really customise it beyond changing the color of the label and title. 

Dynamic: Dynamic notification require one to subclass WKUserInterfaceController. It is instantiated from the storyboard, and one can provide own custom interface. Note that there is no guarantee that a dynamic notification interface will be displayed. For e.g. if the watch battery is low, system may decide to show a static notification interface instead of dynamic one in the interest to preserve the battery. 

To note, one cannot create and add subviews dynamically in the app watch app, it is possible to hide and show the ui elements those are already in the story board. 

Is there UIActivityIndicator or UIAlertViewController? 
No, but one can display WKInterfaceCotnroller modally. One can work around the activity indicator by providing a series of images that is necessary for creating animation. 

Can one use Coregraphics to generate image dynamically and then use them in a watch app? Can they be cached on the watch? 
YEs, but the composition of those images should be happening in the iPhone watch kit extension. Once we have rendered the core graphics drawing context into an image, one can cache that on to the watch app by calling addCachedImage() from WKInterfaceDevice 

Can one create Custom Views in the Apple Watch? Can the public interface be customised ? 
No. Once cannot customize any views. Watch kit only support certain native interface elements. 

How does the Apple watch communicate with the iPhone? 
The Apple watch leverage both bluetooth LE or Wifi technologies to communicate with its paired phone. The exact nature of communication and its implementation is opaque to both users and developers. 

Can one use Apple watch while in Airplane mode? 
Yes. If bluetooth and WiFi can be turned on while in airplane mode, Apple watch can communicate with the phone. 

What happens when watch app cannot communicate with the paired iPhone ? 
The app won’t run and if running already, it will be suspended. 

In the Watchkit extension, didDeactivate() method will be called to indicate the loss of connectivity. Also, a red icon will be displayed on the status bar on the watch to indicate the loss of connectivity. 

How can a watch app communicate with its companion iPhone app? 
There are various techniques for this, one being watch app writes the data in a shared container and notifies the iPhone app. 
Another technique is to pass the data into the iPhone app as a dictionary, but this can be only initiated by the watch app. There is a single API for the watch kit extension; call the parent Application openParentApplication(userInfo:reply) of WKInterfaceController, as shown in the following snippet. 

to receive this communication, the companion app must implement application(:handleWatchKitExtensionRequest:reply)
If the companion app is in the background, then it will be waken up to process this. Companion app can pass the data back as well allowing the watch app to be able to process the response. 

  
Referencnes:

Inspecting WatchKit Catalog app.

there seems to be main three components :

1. Apple Watch Settings App 
2. Apple Watch app on the device (Watchkit Catalog)
3. Apple watch app running on the watch  (Watchkit Catalog WatchKit App)
4. Apple watch app extension (Watchkit Catalog Watchkit Extension)

WatchKit Catalog WatchKit App doesn’t seem to be doing much of the things exccept that it defines the ui for the app running on the device. The watckit extension does the major tasks which get invoked as the user interact with the app ui on the watch device. 

The Watch app running on the device is having interface.storyboard which defines all of the ui for the app. 

1. Opening the Watch Settings app (“Apple Watch”) shown the app installed on the watch. User can select each app listed in this app and select whether to show up on the Apple Watch device or not. 

2. Apple Watch app on the device. 
This app did not have much code except the Main xib file that contained bit of information on how to use the app. 

The interface.storyboard gives much detail of all the screens present in the Apple watch app.  

Upon running the app, AAPLNotificationController willActivate get called.  

Many of the Ui components are similar to the ones in 

WKInterfaceTable, => Table 
WKInterfaceLabel  => Label 
WKInterfaceButton => Button 
WKInterfaceSwitch => Switch 
WKInterfaceSlider => slider
WKInterfaceImage => image
WKInterfaceMap => Map 
WKInterfaceDevice => Gets device details 


References: 

Contact Header in SIP Request

Contact header provides a meaning which depends on the type of request or response it is in. 
A contact header may provide a display name, a URI with URI parameters and header parameters 

the q and expires are parameters in the in the Contact header. These parameters are contained in a REGISTER request. It is upto the specification if it want to define additional parameters. 

When the header field contains a display name, the URI including all URI parameters are enclosed in “<“ and “>”. If no < and > is present, then all parameters after the URI are header parameters not uri parameters. The display name can be tokens or quoted string if a large character set is desired. 

For e.g. in the Contact header below, 

Contact: ;+sip.custom=“value”;+sip.9193023016-socktest3
tranport=tcp is a contact uri parameter, while + sip.custom =“value” is a contact parameter. 

Even if the display-name is empty, the “name-addr” form MUST be used if the “addr-spec“ contains comma or semicolon or question mark 

The rule for parsing display name, uri and uri parameters also applies to the headers To and From. 

The compact form of the Contact header is “m” (moved) 

Some of the samples are: 
Contact: "Mr. Watson"
         ;q=0.7; expires=3600,
         "Mr. Watson" ;q=0.1
      m: ;expires=60


References: