blob: 497494bf3935a2f9edc15f148963ec69209a941b [file] [log] [blame]
Wentao Shangbd63e462012-12-03 16:19:33 -08001/**
Jeff Thompson17a9da82012-11-12 01:11:01 -08002 * @author: Jeff Thompson
3 * See COPYING for copyright and distribution information.
4 * Implement getAsync and putAsync used by NDN using nsISocketTransportService.
5 * This is used inside Firefox XPCOM modules.
6 */
7
8// Assume already imported the following:
9// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
10// Components.utils.import("resource://gre/modules/NetUtil.jsm");
11
Jeff Thompson3b6bf982013-01-13 20:00:03 -080012var XpcomTransport = function XpcomTransport() {
13 this.ndn = null;
14 this.socket = null; // nsISocketTransport
15 this.outStream = null;
16 this.connectedHost = null;
17 this.connectedPort = null;
18
Jeff Thompson3fa84152012-12-16 17:11:42 -080019 this.defaultGetHostAndPort = NDN.makeShuffledGetHostAndPort
20 (["A.hub.ndn.ucla.edu", "B.hub.ndn.ucla.edu", "C.hub.ndn.ucla.edu", "D.hub.ndn.ucla.edu",
21 "E.hub.ndn.ucla.edu", "F.hub.ndn.ucla.edu", "G.hub.ndn.ucla.edu", "H.hub.ndn.ucla.edu"],
22 9695);
Jeff Thompson17a9da82012-11-12 01:11:01 -080023};
24
Jeff Thompson3b6bf982013-01-13 20:00:03 -080025/*
26 * Connect to the host and port in ndn. This replaces a previous connection.
Jeff Thompson07f15fb2013-01-20 20:32:29 -080027 * Listen on the port to read an entire binary XML encoded element and call
Jeff Thompson24189e52013-01-20 23:29:51 -080028 * elementListener.onReceivedElement(element) where element is Uint8Array.
Jeff Thompson3b6bf982013-01-13 20:00:03 -080029 */
Jeff Thompson24189e52013-01-20 23:29:51 -080030XpcomTransport.prototype.connect = function(ndn, elementListener) {
Jeff Thompson3b6bf982013-01-13 20:00:03 -080031 if (this.socket != null) {
32 try {
33 this.socket.close(0);
34 } catch (ex) {
35 console.log("XpcomTransport socket.close exception: " + ex);
36 }
37 this.socket = null;
38 }
39 this.ndn = ndn;
40
41 var transportService = Components.classes["@mozilla.org/network/socket-transport-service;1"].getService
42 (Components.interfaces.nsISocketTransportService);
43 var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance
44 (Components.interfaces.nsIInputStreamPump);
45 this.socket = transportService.createTransport(null, 0, ndn.host, ndn.port, null);
46 this.connectedHost = ndn.host;
47 this.connectedPort = ndn.port;
48 this.outStream = this.socket.openOutputStream(1, 0, 0);
49
50 var inStream = this.socket.openInputStream(0, 0, 0);
51 var dataListener = {
Jeff Thompson24189e52013-01-20 23:29:51 -080052 elementReader: new BinaryXmlElementReader(elementListener),
Jeff Thompson3b6bf982013-01-13 20:00:03 -080053
54 onStartRequest: function (request, context) {
55 },
56 onStopRequest: function (request, context, status) {
57 },
58 onDataAvailable: function (request, context, _inputStream, offset, count) {
59 try {
60 // Use readInputStreamToString to handle binary data.
61 // TODO: Can we go directly from the stream to Uint8Array?
Jeff Thompson24189e52013-01-20 23:29:51 -080062 this.elementReader.onReceivedData(DataUtils.toNumbersFromString
63 (NetUtil.readInputStreamToString(inStream, count)));
Jeff Thompson3b6bf982013-01-13 20:00:03 -080064 } catch (ex) {
Jeff Thompson24189e52013-01-20 23:29:51 -080065 console.log("XpcomTransport.onDataAvailable exception: " + ex + "\n" + ex.stack);
Jeff Thompson3b6bf982013-01-13 20:00:03 -080066 }
67 }
68 };
69
70 pump.init(inStream, -1, -1, 0, 0, true);
71 pump.asyncRead(dataListener, null);
72};
73
74/*
75 * Send the data over the connection created by connect.
76 */
77XpcomTransport.prototype.send = function(/* Uint8Array */ data) {
78 if (this.socket == null) {
79 console.log("XpcomTransport connection is not established.");
80 return;
81 }
Jeff Thompson17a9da82012-11-12 01:11:01 -080082
Jeff Thompson3b6bf982013-01-13 20:00:03 -080083 var rawDataString = DataUtils.toString(data);
84 this.outStream.write(rawDataString, rawDataString.length);
85 this.outStream.flush();
86};
87
88XpcomTransport.prototype.expressInterest = function(ndn, interest, closure) {
Jeff Thompsona5668d52013-01-26 16:23:27 -080089 console.log("expressInterest " + interest.name.to_uri());
Jeff Thompson3b6bf982013-01-13 20:00:03 -080090 var thisXpcomTransport = this;
91
92 if (this.socket == null || this.connectedHost != ndn.host || this.connectedPort != ndn.port) {
Jeff Thompson24189e52013-01-20 23:29:51 -080093 var elementListener = {
Jeff Thompson275133e2013-01-20 21:33:07 -080094 onReceivedElement : function(element) {
95 var decoder = new BinaryXMLDecoder(element);
96 if (decoder.peekStartElement(CCNProtocolDTags.Interest)) {
Jeff Thompson24189e52013-01-20 23:29:51 -080097 // TODO: handle interest properly.
Jeff Thompson275133e2013-01-20 21:33:07 -080098 }
99 else if (decoder.peekStartElement(CCNProtocolDTags.ContentObject)) {
100 var co = new ContentObject();
101 co.from_ccnb(decoder);
Jeff Thompson17a9da82012-11-12 01:11:01 -0800102
Jeff Thompson275133e2013-01-20 21:33:07 -0800103 var pitEntry = NDN.getEntryForExpressedInterest(co.name);
104 if (pitEntry != null) {
105 // Remove PIT entry from NDN.PITTable.
106 // TODO: This needs to be a single thread-safe transaction.
107 var index = NDN.PITTable.indexOf(pitEntry);
108 if (index >= 0)
109 NDN.PITTable.splice(index, 1);
110 }
111 if (pitEntry != null) {
112 var currentClosure = pitEntry.closure;
Jeff Thompson3b6bf982013-01-13 20:00:03 -0800113
Jeff Thompson24189e52013-01-20 23:29:51 -0800114 // Cancel interest timer
115 clearTimeout(pitEntry.timerID);
116
Jeff Thompson275133e2013-01-20 21:33:07 -0800117 // TODO: verify the content object and set kind to UPCALL_CONTENT.
118 var result = currentClosure.upcall(Closure.UPCALL_CONTENT_UNVERIFIED,
119 new UpcallInfo(thisXpcomTransport.ndn, null, 0, co));
120 if (result == Closure.RESULT_OK) {
121 // success
122 }
123 else if (result == Closure.RESULT_ERR)
124 console.log("XpcomTransport: upcall returned RESULT_ERR.");
125 else if (result == Closure.RESULT_REEXPRESS) {
126 // TODO: Handl re-express interest.
127 }
128 else if (result == Closure.RESULT_VERIFY) {
129 // TODO: force verification of content.
130 }
131 else if (result == Closure.RESULT_FETCHKEY) {
132 // TODO: get the key in the key locator and re-call the interest
133 // with the key available in the local storage.
Jeff Thompson3fa84152012-12-16 17:11:42 -0800134 }
Jeff Thompson17a9da82012-11-12 01:11:01 -0800135 }
Jeff Thompson275133e2013-01-20 21:33:07 -0800136 }
137 else
138 console.log('Incoming packet is not Interest or ContentObject. Discard now.');
Jeff Thompson17a9da82012-11-12 01:11:01 -0800139 }
Jeff Thompson3b6bf982013-01-13 20:00:03 -0800140 }
141
Jeff Thompson24189e52013-01-20 23:29:51 -0800142 this.connect(ndn, elementListener);
Jeff Thompsona5668d52013-01-26 16:23:27 -0800143// DEBUG this.connect(ndn, ndn);
Jeff Thompson3b6bf982013-01-13 20:00:03 -0800144 }
Jeff Thompson17a9da82012-11-12 01:11:01 -0800145
Jeff Thompson24189e52013-01-20 23:29:51 -0800146 //TODO: check local content store first
147 if (closure != null) {
148 var pitEntry = new PITEntry(interest, closure);
149 // TODO: This needs to be a single thread-safe transaction on a global object.
150 NDN.PITTable.push(pitEntry);
151 closure.pitEntry = pitEntry;
152 }
Jeff Thompson3b6bf982013-01-13 20:00:03 -0800153
Jeff Thompson24189e52013-01-20 23:29:51 -0800154 // Set interest timer
155 if (closure != null) {
156 pitEntry.timerID = setTimeout(function() {
157 if (LOG > 3) console.log("Interest time out.");
158
159 // Remove PIT entry from NDN.PITTable.
160 // TODO: Make this a thread-safe operation on the global PITTable.
161 var index = NDN.PITTable.indexOf(pitEntry);
162 //console.log(NDN.PITTable);
163 if (index >= 0)
164 NDN.PITTable.splice(index, 1);
165 //console.log(NDN.PITTable);
166 //console.log(pitEntry.interest.name.getName());
167
168 // Raise closure callback
169 closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, new UpcallInfo(ndn, interest, 0, null));
170 }, interest.interestLifetime); // interestLifetime is in milliseconds.
171 //console.log(closure.timerID);
172 }
173
174 this.send(encodeToBinaryInterest(interest));
Jeff Thompson17a9da82012-11-12 01:11:01 -0800175};
Jeff Thompson24189e52013-01-20 23:29:51 -0800176