blob: 99a3d07937b409cb39415dbeda0c289cd5ae3fbc [file] [log] [blame]
Alexander Afanasyev39f53162013-07-18 16:24:31 -07001## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -07002#
Alexander Afanasyev39f53162013-07-18 16:24:31 -07003# Copyright (c) 2011-2013, Regents of the University of California
4# Alexander Afanasyev
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -07005#
Alexander Afanasyev39f53162013-07-18 16:24:31 -07006# GNU 3.0 license, See the LICENSE file for more information
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -07007#
Alexander Afanasyev39f53162013-07-18 16:24:31 -07008# Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -07009#
Alexander Afanasyev39f53162013-07-18 16:24:31 -070010
11#
12# Based on PyCCN code, copyrighted and licensed as follows
13#
14# Copyright (c) 2011-2013, Regents of the University of California
15# BSD license, See the COPYING file for more information
16# Written by: Derek Kulinski <takeda@takeda.tk>
17# Jeff Burke <jburke@ucla.edu>
18#
19
20import ns.ndnSIM
21from Name import Name
22
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -070023class DataError (Exception):
24 pass
25
Alexander Afanasyev39f53162013-07-18 16:24:31 -070026class Data (object):
27 _data = None
28
29 def __init__(self,
30 name = None, content = None, signed_info = None,
31 data = None):
32 if data:
33 if type (data) is Data:
34 self._data = data._data
35 elif type (data) is ns.ndnSIM.ndn.ContentObject:
36 self._data = data
37 else:
38 raise TypeError ("Invalid type supplied for 'data' parameter [%s]" % type (data))
39 else:
40 self._data = ns.ndnSIM.ndn.ContentObject ()
41
42 self.name = name
43 self.content = content
44 self.signedInfo = signed_info or SignedInfo ()
45
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -070046 @staticmethod
47 def fromWire (wire):
48 data = Data (data = ns.ndnSIM.ndn.Wire.ToData (wire))
49 # timestamp
50 data.signedInfo.freshnessSeconds = data._data.GetFreshness ()
51 if data._data.GetKeyLocator ():
52 data.keyLocator = Name (_name = data._data.GetKeyLocator ())
53
Alexander Afanasyev39f53162013-07-18 16:24:31 -070054 def sign (self, key):
55 """There is no actual signing in ndnSIM for now, but we will assign signature bits based on key"""
56 self._data.SetSignature (key.fakeKey)
57
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -070058 def toWire (self):
59 if self._data.GetSignature () == 0:
60 raise DataError ("Data packet has not been signed, cannot create wire format")
61
62 return ns.ndnSIM.ndn.Wire.FromData (self._data)
63
Alexander Afanasyev39f53162013-07-18 16:24:31 -070064 def verify_signature (self, key):
65 """There is no actual signing in ndnSIM for now, but we will check if signature matches the key"""
66 return self._data.GetSignature () == key.fakeKey
67
68 def __getattr__ (self, name):
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -070069 if name == "_data":
70 return object.__getattr__ (self, name)
71
72 elif name == "signedInfo":
Alexander Afanasyev39f53162013-07-18 16:24:31 -070073 return object.__getattr__ (self, name)
74 elif name == "name":
75 return Name (self._data.GetName ())
76 elif name == "scope":
77 return self._data.GetScope ()
78 elif name == "interestLifetime":
79 return self._data.GetInterestLifetime ().ToDouble (ns.core.Time.S)
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -070080 elif name == "content":
81 pkt = self._data.GetContent ()
82 return ns.ndnSIM.ndn.PacketToBuffer (pkt)
Alexander Afanasyev39f53162013-07-18 16:24:31 -070083 else:
84 return self._data.__getattribute__ (name)
85
86 def __setattr__(self, name, value):
87 if name == "_data":
88 return object.__setattr__ (self, name, value)
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -070089
Alexander Afanasyev39f53162013-07-18 16:24:31 -070090 elif name == 'signedInfo':
91 if not value:
92 return
93 if type (value) is SignedInfo:
94 object.__setattr__ (self, name, value)
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -070095
Alexander Afanasyev39f53162013-07-18 16:24:31 -070096 if value.timestamp:
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -070097 # ?
Alexander Afanasyev39f53162013-07-18 16:24:31 -070098 pass
99 if value.freshnessSeconds:
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -0700100 self._data.SetFreshness (ns.core.Seconds (value))
Alexander Afanasyev39f53162013-07-18 16:24:31 -0700101 if value.keyLocator:
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -0700102 self._data.SetKeyLocator (value._name)
Alexander Afanasyev39f53162013-07-18 16:24:31 -0700103 else:
104 raise TypeError ("signedInfo can be assigned either None or SignedInfo object, [%s] supplied" % type (value))
105 elif name == "name":
106 if not value:
107 return self._data.SetName (ns.ndnSIM.ndn.Name ())
108 elif type (value) is Name:
109 return self._data.SetName (value._name)
110 elif type (value) is ns.ndnSIM.ndn.Name:
111 return self._data.SetName (value)
112 elif type (value) is str:
113 return self._data.SetName (ns.ndnSIM.ndn.Name (value))
114 else:
115 raise ValueError ("Invalid name parameter")
116 elif name == "content":
117 if not value:
118 pkt = ns.network.Packet ()
119 self._data.SetPayload (pkt)
120 else:
Alexander Afanasyevf6f9ef22013-07-26 11:34:00 -0700121 pkt = ns.ndnSIM.ndn.BufferToPacket (bytes (value))
Alexander Afanasyev39f53162013-07-18 16:24:31 -0700122 self._data.SetPayload (pkt)
123 else:
124 raise NameError ("Unknown attribute [%s]" % name)
125
126 def __repr__(self):
127 return "ndn.Data(%s)" % str (self._data)
128
129class SignedInfo (object):
130 def __init__(self, keyLocator = None, freshness = None, timestamp = None):
131
132 self.timestamp = timestamp
133 self.freshnessSeconds = freshness
134 self.keyLocator = keyLocator
135
136 def __repr__(self):
137 args = []
138
139 if self.keyLocator is not None:
140 args += ["keyLocator=%r" % self.keyLocator]
141 if self.freshnessSeconds is not None:
142 args += ["freshness=%r" % self.freshnessSeconds]
143 if self.timeStamp is not None:
144 args += ["timestamp=%r" % self.timestamp]
145
146 return "ndn.SignedInfo(%s)" % ", ".join(args)
147
148class ContentObject (Data):
149 """For backwards compatibility"""
150 pass
151