forked from PDXostc/rvi_sota_demo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sota_server.py
184 lines (143 loc) · 5.29 KB
/
sota_server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/usr/bin/python
#
# Copyright (C) 2014, Jaguar Land Rover
#
# This program is licensed under the terms and conditions of the
# Mozilla Public License, version 2.0. The full text of the
# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/
#
#
# Simple SOTA Client
#
import sys
from rvilib import RVI
import jsonrpclib
import random
import time
import threading
import os
import base64
import struct
import SocketServer
from base64 import b64encode
from hashlib import sha1
from mimetools import Message
from StringIO import StringIO
import json
import Queue
transaction_id = 0
package_queue = Queue.Queue()
def package_pusher():
global package_queue
global transaction_id
while True:
[package, destination] = package_queue.get()
print "Package pushed will push",package,"to",destination
try:
f = open(package)
except Err:
print "Could not open",file_name,":", Err
return
chunk_size = 128*1024
f_stat = os.stat(package)
transaction_id += 1
rvi_server.message(service_name = destination + "/start",
timeout = int(time.time())+60,
parameters = [{ u'package': package,
u'chunk_size': chunk_size,
u'total_size': f_stat.st_size
}])
index = 0
while True:
offset = f.tell()
msg = f.read(chunk_size)
if msg == "":
break
print "Sending package:", package, " chunk:", index, " offset:", offset, " message size: ", len(msg)
transaction_id+=1
rvi_server.message(service_name = destination + "/chunk",
timeout = int(time.time())+60,
parameters = [
{ u'index': index },
{ u'msg': base64.b64encode(msg) }])
index += 1
f.close()
print "Finishing package:", package
time.sleep(1.0)
transaction_id+=1
rvi_server.message(service_name = destination + "/finish",
timeout = int(time.time())+60,
parameters = [ { u'dummy': 0}])
def usage():
print "Usage:", sys.argv[0], "<rvi_url>"
print " <rvi_url> URL of Service Edge on a local RVI node"
print
print "The RVI Service Edge URL can be found in"
print "[backend,vehicle].config as"
print "env -> rvi -> components -> service_edge -> url"
print
print "The Service Edge URL is also logged as a notice when the"
print "RVI node is started."
sys.exit(255)
def initiate_download(package, retry, destination):
print "Will push packet", package, " transaction id", retry, " to",destination
package_queue.put([package, destination])
return {u'status': 0}
def cancel_download(retry):
print "transaction", retry, "was cancelled by device."
return {u'status': 0}
def download_complete(status, retry):
print "Download transaction",retry," completed with:",status
return {u'status': 0}
#
# Check that we have the correct arguments
#
if len(sys.argv) != 2:
usage()
# Grab the URL to use
[ progname, rvi_url ] = sys.argv
# Setup an outbound JSON-RPC connection to the RVI Service Edge.
rvi_server = RVI(rvi_url)
rvi_server.start_serve_thread()
#
# Regsiter callbacks for incoming JSON-RPC calls delivered to
# the SOTA server from the vehicle RVI node's Service Edge.
#
full_initiate_download_service_name = rvi_server.register_service("/sota/initiate_download", initiate_download )
full_cancel_download_service_name = rvi_server.register_service("/sota/cancel_download", cancel_download )
full_download_complete_service_name = rvi_server.register_service("/sota/download_complete", download_complete )
print "Vehicle RVI node URL: ", rvi_url
print "Full initiate download service name : ", full_initiate_download_service_name
print "Full download complete service name : ", full_download_complete_service_name
print "Full cancel download service name : ", full_cancel_download_service_name
chunk_size = 1024*64
#
# Start the queue dispatcher thread
#
package_pusher_thr = threading.Thread(target=package_pusher)
package_pusher_thr.start()
while True:
transaction_id += 1
line = raw_input('Enter <vin> <file_name> or "q" for quit: ')
if line == 'q':
rvi_server.shutdown()
sys.exit(0)
# Read a line and split it into a key val pair
lst = line.split(' ')
if len(lst) != 2:
print "Nope", len(lst), lst
continue
[vin, file_name] = line.split(' ')
dst = 'jlr.com/vin/'+vin+'/sota'
try:
f = open(file_name)
except Err:
print "Could not open",file_name,":", Err
continue
rvi_server.message(service_name = dst + "/notify",
timeout = int(time.time())+60,
parameters = [{ u'package': file_name,
u'retry': transaction_id }])
print "Queueing package ", file_name, " to ", dst
package_queue.put([file_name, dst])
print('Package {} sent to {}'. format(file_name, dst))