WML (or light weight XHTML) version

1 view
Skip to first unread message

Chris Swan

unread,
Jan 4, 2008, 6:08:28 AM1/4/08
to BTMojo
One of my use cases for this tool is to initiate a call from my
BlackBerry (or other mobile device with a free/cheap data tarrif), so
it would be nice to have a lighter GUI (and maybe pages customised to
achieving one thing well).

Robert Clutton

unread,
Jan 4, 2008, 6:14:55 AM1/4/08
to btm...@googlegroups.com
Hi Chris,

Would the following pages be of use?:

http://mojo.bt.com/messages/new
http://mojo.bt.com/calls/new

I'm assuming you can get past the OpenID login process OK on the blackberry?

Robbie

Chris Swan

unread,
Jan 4, 2008, 6:27:48 AM1/4/08
to BTMojo
Thanks Robbie,

That answers the point on having pages customised to achieving one
thing well.

OpenID wasn't a problem on the BlackBerry (though it was a pain to dig
out my password, as I've gotten used to using CardSpace with
myopenid), so I guess what I'm mostly asking for here is a user agent
sensitive GUI diet (so that when GPRS is having a bad day I don't have
to wait tooo long for the form to paint).

I spotted a little problem with calls/new, as it prepopulates the from
field with:

"./script/../config/../vendor/rails/actionpack/lib/action_view/helpers/
form_helper.rb:356:in `value_before_type_cast'./script/../config/../
vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb:344:in
`value_before_type_cast'./script/../config/../vendor/rails/actionpack/
lib/action_view/helpers/form_helper.rb:259:in `to_input_field_tag'./
script/../config/../vendor/rails/actionpack/lib/action_view/helpers/
form_helper.rb:162:in `text_field'./script/../config/../vendor/rails/
actionpack/lib/action_view/helpers/form_helper.rb:430:in `send'./
script/../config/../vendor/rails/actionpack/lib/action_view/helpers/
form_helper.rb:430:in `text_field'./script/../config/../app/views//
calls/_call.rhtml:9:in `_run_rhtml_47app47views47calls47_call46rhtml'./
script/../config/../vendor/rails/actionpack/lib/action_view/helpers/
form_helper.rb:151:in `fields_for'./script/../config/../vendor/rails/
actionpack/lib/action_view/helpers/form_helper.rb:127:in `form_for'./
script/../config/../app/views//calls/_call.rhtml:4:in
`_run_rhtml_47app47views47calls47_call46rhtml'./script/../config/../
vendor/rails/actionpack/lib/action_view/base.rb:326:in `send'./
script/../config/../vendor/rails/actionpack/lib/action_view/base.rb:
326:in `compile_and_render_template'./script/../config/../vendor/rails/
actionpack/lib/action_view/base.rb:301:in `render_template'./script/../
config/../vendor/rails/actionpack/lib/action_view/base.rb:260:in
`render_file'./script/../config/../vendor/rails/actionpack/lib/
action_view/base.rb:275:in `render'./script/../config/../vendor/rails/
actionpack/lib/action_view/partials.rb:59:in `render_partial'./
script/../config/../vendor/rails/actionpack/lib/action_controller/
benchmarking.rb:30:in `benchmark'./script/../config/../vendor/rails/
actionpack/lib/action_view/partials.rb:58:in `render_partial'./
script/../config/../vendor/rails/actionpack/lib/action_view/base.rb:
287:in `render'./script/../config/../app/views/calls/new.rhtml:1:in
`_run_rhtml_47app47views47calls47new46rhtml'./script/../config/../
vendor/rails/actionpack/lib/action_view/base.rb:326:in `send'./
script/../config/../vendor/rails/actionpack/lib/action_view/base.rb:
326:in `compile_and_render_template'./script/../config/../vendor/rails/
actionpack/lib/action_view/base.rb:301:in `render_template'./script/../
config/../vendor/rails/actionpack/lib/action_view/base.rb:260:in
`render_file'./script/../config/../vendor/rails/actionpack/lib/
action_controller/base.rb:806:in `render_file'./script/../config/../
vendor/rails/actionpack/lib/action_controller/base.rb:711:in
`render_with_no_layout'./script/../config/../vendor/rails/actionpack/
lib/action_controller/layout.rb:247:in `render_without_benchmark'./
script/../config/../vendor/rails/actionpack/lib/action_controller/
benchmarking.rb:50:in `render'c:/ruby/lib/ruby/1.8/benchmark.rb:293:in
`measure'./script/../config/../vendor/rails/actionpack/lib/
action_controller/benchmarking.rb:50:in `render'./script/../config/../
vendor/rails/actionpack/lib/action_controller/base.rb:1096:in
`perform_action_without_filters'./script/../config/../vendor/rails/
actionpack/lib/action_controller/filters.rb:632:in `call_filter'./
script/../config/../vendor/rails/actionpack/lib/action_controller/
filters.rb:638:in `call_filter'./script/../config/../vendor/rails/
actionpack/lib/action_controller/filters.rb:438:in `call'./script/../
config/../vendor/rails/actionpack/lib/action_controller/filters.rb:
637:in `call_filter'./script/../config/../vendor/rails/actionpack/lib/
action_controller/filters.rb:638:in `call_filter'./script/../config/../
vendor/rails/actionpack/lib/action_controller/filters.rb:438:in
`call'./script/../config/../vendor/rails/actionpack/lib/
action_controller/filters.rb:637:in `call_filter'./script/../config/../
vendor/rails/actionpack/lib/action_controller/filters.rb:619:in
`perform_action_without_benchmark'./script/../config/../vendor/rails/
actionpack/lib/action_controller/benchmarking.rb:66:in
`perform_action_without_rescue'c:/ruby/lib/ruby/1.8/benchmark.rb:
293:in `measure'./script/../config/../vendor/rails/actionpack/lib/
action_controller/benchmarking.rb:66:in
`perform_action_without_rescue'./script/../config/../vendor/rails/
actionpack/lib/action_controller/rescue.rb:83:in `perform_action'./
script/../config/../vendor/rails/actionpack/lib/action_controller/
base.rb:430:in `send'./script/../config/../vendor/rails/actionpack/lib/
action_controller/base.rb:430:in `process_without_filters'./script/../
config/../vendor/rails/actionpack/lib/action_controller/filters.rb:
624:in `process_without_session_management_support'./script/../
config/../vendor/rails/actionpack/lib/action_controller/
session_management.rb:114:in `process'./script/../config/../vendor/
rails/actionpack/lib/action_controller/base.rb:330:in `process'./
script/../config/../vendor/rails/railties/lib/dispatcher.rb:41:in
`dispatch'c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/
mongrel/rails.rb:78:in `process'c:/ruby/lib/ruby/1.8/thread.rb:135:in
`synchronize'c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/
mongrel/rails.rb:76:in `process'c:/ruby/lib/ruby/gems/1.8/gems/
mongrel-1.0.1-mswin32/lib/mongrel.rb:618:in `process_client'c:/ruby/
lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:617:in
`each'c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/
mongrel.rb:617:in `process_client'c:/ruby/lib/ruby/gems/1.8/gems/
mongrel-1.0.1-mswin32/lib/mongrel.rb:736:in `run'c:/ruby/lib/ruby/gems/
1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:736:in `initialize'c:/
ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:
736:in `new'c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/
mongrel.rb:736:in `run'c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-
mswin32/lib/mongrel.rb:720:in `initialize'c:/ruby/lib/ruby/gems/1.8/
gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:720:in `new'c:/ruby/lib/ruby/
gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel.rb:720:in `run'c:/ruby/
lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/
configurator.rb:271:in `run'c:/ruby/lib/ruby/gems/1.8/gems/
mongrel-1.0.1-mswin32/lib/mongrel/configurator.rb:270:in `each'c:/ruby/
lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/
configurator.rb:270:in `run'c:/ruby/lib/ruby/gems/1.8/gems/
mongrel-1.0.1-mswin32/bin/mongrel_rails:127:in `run'c:/ruby/lib/ruby/
gems/1.8/gems/mongrel-1.0.1-mswin32/lib/mongrel/command.rb:211:in
`run'c:/ruby/lib/ruby/gems/1.8/gems/mongrel-1.0.1-mswin32/bin/
mongrel_rails:243./script/../config/../vendor/rails/activesupport/lib/
active_support/dependencies.rb:488:in `load'./script/../config/../
vendor/rails/activesupport/lib/active_support/dependencies.rb:488:in
`load'./script/../config/../vendor/rails/activesupport/lib/
active_support/dependencies.rb:342:in `new_constants_in'./script/../
config/../vendor/rails/activesupport/lib/active_support/
dependencies.rb:488:in `load'./script/../config/../vendor/rails/
railties/lib/commands/servers/mongrel.rb:60c:/ruby/lib/ruby/site_ruby/
1.8/rubygems/custom_require.rb:27:in `gem_original_require'c:/ruby/lib/
ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'./
script/../config/../vendor/rails/activesupport/lib/active_support/
dependencies.rb:495:in `require'./script/../config/../vendor/rails/
activesupport/lib/active_support/dependencies.rb:342:in
`new_constants_in'./script/../config/../vendor/rails/activesupport/lib/
active_support/dependencies.rb:495:in `require'./script/../config/../
vendor/rails/railties/lib/commands/server.rb:39c:/ruby/lib/ruby/
site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'c:/ruby/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:27:in `require'script/server:3"

On Jan 4, 11:14 am, "Robert Clutton" <robert.clut...@gmail.com> wrote:
> Hi Chris,
>
> Would the following pages be of use?:
>
> http://mojo.bt.com/messages/newhttp://mojo.bt.com/calls/new
>
> I'm assuming you can get past the OpenID login process OK on the blackberry?
>
> Robbie
>
> On 04/01/2008, Chris Swan <cps...@gmail.com> wrote:
>
>
>
> > One of my use cases for this tool is to initiate a call from my
> > BlackBerry (or other mobile device with a free/cheap data tarrif), so
> > it would be nice to have a lighter GUI (and maybe pages customised to
> > achieving one thing well).
>
> --
> -----------------------------http://blog.iclutton.comhttp://twitter.com/robb1ehttp://flickr.com/photos/robbieshttp://pownce.com/robb1e/http://www.dopplr.com/traveller/robbiehttp://robb1e.onaswarm.com

Robert Clutton

unread,
Jan 4, 2008, 7:08:57 AM1/4/08
to btm...@googlegroups.com
Thanks for the bug.

The other alternative is using the API, (more reading on that here:http://mojo.bt.com/howtos).  Using this you could build a widget/gadget that runs on your blackberry and remembers stuff like your username/password and can get most recent calls (partially in answer to your other question). 

Robbie

Paul Downey

unread,
Jan 4, 2008, 7:59:00 AM1/4/08
to btm...@googlegroups.com
Hey Chris,

> That answers the point on having pages customised to achieving one
> thing well.
>

one of the reasons for giving out alpha users is to see what
folks build with it. If it's good, then we'll consider
rolling the changes into mojo. The ethos so far has
been to keep mojo as small and simple as possible.

I'd suggest you put together a small mobile web friendly web
site which does what you want then blogging / pointing us at it.

Have fun!

Paul (psd)
--
http://blog.whatfettle.com


Paul (psd)
--
http://blog.whatfettle.com

Chris Swan

unread,
Jan 5, 2008, 6:26:02 AM1/5/08
to BTMojo
So, here was my first effort, using just client side stuff (which
didn't work as I discovered that my BlackBerry doesn't do JavaScript).
It's much like the example in the HowTo, though maybe even more paired
down. If it had worked then a remaining issue is that the response is
quite verbose:

<html>
<head>
<title>BlackBerry calls</title>
<script type="text/javascript" src="uuid.js"></script>
<script type="text/javascript" src="sha1.js"></script>
<script language="JavaScript">
function calcDigestandName(form) {
form.name.value = new UUID();
var digestString =
form.username.value + ":"+
form.gadgetkey.value + ":"+
form.name.value + ":***mysecretkey***";
form.digest.value = hex_sha1(digestString);
document.send.submit();
}
</script>
</head>
<body>
<h1>Make Call</h1>
<form name="send" action="http://mojo.bt.com/calls" method="POST">
<input type="hidden" name="name" />
<input type="hidden" name="caller" value="+4477***myBBnumber***"/>
<label for="callee">To</label>
<input type="text" name="callee" size="14" />
<input type="hidden" name="username" value="cpswan" />
<input type="hidden" name="gadgetkey"
value="af4ed11eef026853df9b0d581e3441508bd00efc" />
<input type="hidden" name="digest" />
<input type="button" name="call" value="call"
onClick="calcDigestandName(this.form);"/>
</form>
</body>
</html>

Chris Swan

unread,
Jan 5, 2008, 6:32:09 AM1/5/08
to BTMojo
Without any JavaScript support I needed to do something server side,
which if it's going to be subsequently used in my corporate
environment meant .Net or Java (both of which I knew would be a pain).
The coin landed on .Net (2.0) and here's what came out. It's ugly and
needs some serious refactoring, but it works :) I'm presently running
it on my workstation using Cassini 2.0:

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://
www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="Callee" runat="server"></asp:TextBox>
<asp:Button ID="Call" runat="server" OnClick="Call_Click"
Text="Call" /></div>
</form>
</body>
</html>




Default.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Security.Cryptography;
using System.Net;
using System.IO;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void Call_Click(object sender, EventArgs e)
{
string callee = "%2B" + Callee.Text;
string caller = "%2B44***myBBnumber***";
string user = "cpswan";
string gadgetkey =
"af4ed11eef026853df9b0d581e3441508bd00efc";
string name = System.Guid.NewGuid().ToString();
string predigest = user + ":" + gadgetkey + ":" + name +
":***mySecretKey***";
ASCIIEncoding enc = new ASCIIEncoding();
byte[] buffer = enc.GetBytes(predigest);
SHA1CryptoServiceProvider cryptoTransformSHA1 = new
SHA1CryptoServiceProvider();
string digest =
BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-",
"");
WebRequest call = WebRequest.Create("http://mojo.bt.com/
calls");
call.Method = "POST";
call.ContentType = "application/x-www-form-urlencoded";
// some proxy stuff needed here for corporate environment
string stuff = "name=" + name + "&caller=" + caller +
"&callee=" + callee + "&gadgetkey=" + gadgetkey + "&username=" + user
+ "&digest=" + digest;
byte[] postdata = enc.GetBytes(stuff);
Stream os = null;
try{ //send the POST
call.ContentLength = postdata.Length; // Count bytes
to send
os = call.GetRequestStream();
os.Write (postdata, 0, postdata.Length); // Send it
}
catch (WebException ex)
{
Callee.Text = ex.Message.ToString();
}
finally
{
if (os != null)
{
os.Close();
}
}

try
{ //get the response
WebResponse rep = call.GetResponse();
Callee.Text = rep.GetResponseStream().ToString();
}
catch (WebException ex)
{
Callee.Text = ex.Message.ToString();
}

}
}


Robert Clutton

unread,
Jan 5, 2008, 10:41:32 AM1/5/08
to btm...@googlegroups.com
Nice work, shame you couldn't get it to work client side on the black berry.  Is there any language support on the device?  As you can see from the howtos, any language that can cope with SHA1 and HTTP can use Mojo.

Saying that, if you wanted to put some basic security around that page it'd do everything you probably want =)

Robbie
--
-----------------------------
http://blog.iclutton.com

Chris Swan

unread,
Jan 7, 2008, 10:41:40 AM1/7/08
to BTMojo
Robbie,

I fear that the point you raise over 'basic security' will quickly
take us into something of an identity management tar pit.

Mojo does a pretty good job of decoupling things that have been
traditionaly quite intertwined:

1) Who pays for the call (Mojits [secret key])
2) Whose number the call is coming from (callee)
3) Who is the originator of the call (user)

Clearly there is a need to establish some sort of relationship between
these 3 activities, which needs to be balanced against flexibility. My
understaning of the present gadget model is that I could now give
something that works to my colleagues, but the use of my secret key
implies the use of my Mojits (and they won't last long if I let loads
of other people use them).

I don't see how this can be fixed without doing federated identity
stuff, which is what Mojo gets by using OpenID. At the moment though
that depends on BT people being trust anchors (in order to create
accounts, hand out Mojits etc.).

PS BlackBerry supports Java applications, but my corporate environment
doesn't allow me to put new apps onto a BlackBerry without jumping
through a LOT of hoops, so a simple web form was always going to be
preferable to a standalone app(let).

Robert Clutton

unread,
Jan 7, 2008, 11:07:39 AM1/7/08
to btm...@googlegroups.com
Chris,

I mentioned basic security after briefly looking over your code which seemed very open.  Of course, as you stated it's completely upto you as developer/product owner to choose any models surrounding your application.  It's a dicussion we've had lots of times here.  You may also find the services behind Mojo interesting for what your doing, http://web21c.bt.com.  The reason I mention this is that what Mojo has tried to do is create a more user friendly way of doing things like placing calls and sending messages (more to come too).  The difference here is with the Web21C SDK the developer/application pays for the consumtion, leading to questions about security and identity for the applications users.  With Mojo, as you've indentifed with the secret key, you could quite happily give away a client based application safe in the knowledge that the users would have to go to Mojo to buy 'mojits' at no cost to yourself.  This is what I was thinking when you developed a server side application to call Mojo as this was what we had to do when using the Web21C SDK many times over. 

With the ID management, it's as I've suggested above, you don't give away your secret key, but instead you get others to get their own.  There is discussion of an API to create users, make a payment, create groups to administer and fund centrally which could give you the potential to run an app somewhere that administrates a team where everyone has their own secret key but doesn't pay for their consumption.  Our thoughts in this area are still a bit wolly round the edges so we'd welcome any thoughts into how you think you could use (or not use) any of these features, or if there is anything we're missing.

Hope you're enjoying using Mojo, keep the thoughts coming.

Robbie

Reply all
Reply to author
Forward
0 new messages