Bonjour,

Je debute en Python et en objet donc si vous avez des conseils ou remarques sur mon code (qui n'est pas encore totalement mis au propre) en dehors de mon probleme n'hesitez pas.

Desole egalement pour l'absence d'accent, je suis en qwerty

Commencons par le module :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
import socket
import signal
 
from struct import pack
 
HEADER_MAGIC_NUMBER = 12321
ACK_TRANSFER_CODE = "transfer_ok"
ACK_STORAGE_CODE = "storage_ok"
TRANSFER_ABORTING_CODE = "abort_transfer"
NOK = 0
OK = 1
 
class ns_tcp:
	def __init__(self, ip="127.0.0.1", port=4224):
		self.ip = ip
		self.port = port
		self.state = "none"
		self.sock = socket.socket()
	def connect(self, timeout=20):
		try:
			self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			self.sock.connect((self.ip, self.port))
		except:
			print "Socket connection failed!!!"
			raise SystemExit(1)
	def close(self):
		self.sock.close()
	# data should be an array of bytes
	def send(self, data, type, timeout=150):
		print "Sending data (%d kB) to %s:%d" % (len(data.tostring())/1024, self.ip, self.port)
		self.state = "make_header"
		ns_header = self.__make_header(data, type)
		signal.alarm(timeout)
		self.state = "send_header"
		self.sock.send(ns_header, len(ns_header))
		self.state = "send_data"
		print self.state
		self.sock.sendall(data.tostring())
		# wait answer from board concerning the transfer
		self.state = "wait_transfer_ack"
		if not self.__wait_ack(ACK_TRANSFER_CODE):
			print "Bad transfer ack value"
			raise SystemExit(1)
		print "\tTransfert done"
		# wait answer from board concerning data storage
		self.state = "wait_storage_ack"
		if not self.__wait_ack(ACK_STORAGE_CODE):
			print "Bad storage ack value"
			raise SystemExit(1)
		print "\tStorage done"
		signal.alarm(0)
	# transfer could be aborted but storage can't
	def abort(self):
		if self.state == "wait_storage_ack":
			print "Transfert already done, operation can't be aborted"
		elif (self.state == "send_header") or (self.state == "send_data") or (self.state == "wait_transfer_ack"):
			print "Aborting transfert..."
			signal.alarm(15)
			self.sock.send(TRANSFER_ABORTING_CODE, len(TRANSFER_ABORTING_CODE))
			#TODO
			signal.alarm(0)
			self.sock.close()
	def set_ip(self, ip):
		self.ip = ip
	def set_port(self, port):
		self.port = port
	def get_state(self):
		return self.state
	def get_error(self):
		print self.state
		if self.state == "make_header": 
			return "Error while making tcp header"
		elif self.state == "send_header":
			return "Error or timeout while sending header"
		elif self.state == "send_data":
			return "Error or timeout while sending data"
		elif self.state == "wait_transfer_ack":
			return "Error or timeout while waiting transfer acknowledgement"
		elif self.state == "wait_storage_ack":
			return "Error or timeout while waiting storage acknowledgement"
		else:
			return "Unknown error"
	def __make_header(self, data, type):
		if type == "hw":
			ns_header = pack("=I", HEADER_MAGIC_NUMBER) + pack("=I", 5) + pack("=I", len(data.tostring()))
		elif type == "sw":
			ns_header = pack("=I", HEADER_MAGIC_NUMBER) + pack("=I", 6) + pack("=I", len(data.tostring()))
		else:
			print("Unknown type, must be hw or sw")
			raise SystemExit(1)
		return ns_header
	def __wait_ack(self, ack_code):
		ack = self.sock.recv(len(ack_code))
		if ack == ack_code:
			return OK
		else:
			return NOK
Puis le reste du code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
#!/usr/bin/env python
 
import re
import socket
import signal
import sys
from struct import pack
from array import array
from optparse import OptionParser
 
import ns_tcp
#import srec
 
HEADER_MAGIC_NUMBER = 12321
 
record_type = {	'0': 4,
		'1': 4, 
		'2': 6, 
		'3': 8, 
		'5': 4, 
		'7': 8, 
		'8': 6, 
		'9': 4 }
 
state = "none"
tcp_sock = ns_tcp.ns_tcp()
 
def sig_handler(signum, frame):
	global state
	if signum == signal.SIGINT:
		print "SIGINT received"
		sigint_process(state)
		sys.exit(0)
	if signum == signal.SIGALRM:
		print "Timeout"
		sigalarm_process(state)
		sys.exit(0)
 
def sigint_process(state):
	if state == "conversion":
		print "Conversion aborted!"
	if state == "sending":
		print "Sending aborted!"
		tcp_sock.abort()
		sys.exit(0)
 
def sigalarm_process(state):
	global tcp_sock
	print tcp_sock.get_error()
	tcp_sock.close()
 
def main():
	parser = OptionParser(usage="usage %prog [options]")
	parser.add_option(	"-i", "--ip", help="board ip", 
				action="store",	type="string", dest="boardIP")
	parser.add_option(	"-p", "--port", help="board tcp cmd port (optional, default value = 4224)", 
				action="store", type="int", dest="tcpPort", default="4224")
	parser.add_option(	"-f", "--file", help="srec file",
				action="store", type="string", dest="srecFile")
	parser.add_option(	"-t", "--type", help="hw/sw srec file", 
				action="store", type="string", dest="type")
	(options, args) = parser.parse_args()
 
	signal.signal(signal.SIGINT, sig_handler)
	signal.signal(signal.SIGALRM, sig_handler)
 
	global state
	state = "start"
 
	if options.srecFile == None:
		print("Please specify a srec file")
		parser.print_help()
		raise SystemExit(1)
	if options.boardIP == None:
		print("Please specify an ip address")
		parser.print_help()
		raise SystemExit(1)
 
	print "Read and convert srec file to binary data..."
	state = "conversion"
	srec_file = open (options.srecFile, 'r')
 
	lines = srec_file.readlines()
 
	data = array('B')
	for line in lines:
		#check first caracter
		if line[0] != 'S':
			print "line doesn't start with S"
			break
		if line[1] != '1':
			if line[1] != '2':
				if line[1] != '3':
					#print line[1]
					continue
		address_size = record_type[line[1]]
		record_size = int(line[2:4], 16)
		address = int(line[4:4+address_size], 16)
		#convert byte by byte
		i = 0
		while (record_size - address_size/2) > 1:
			start = 4+address_size+i*2
			#print line[start:start+2]
			data.append(int(line[start:start+2], 16))
			i = i + 1
			record_size = record_size - 1
	#print data
	print "Conversion done"
 
	state = "sending"
	tcp_sock.set_ip(options.boardIP)
	tcp_sock.set_port(options.tcpPort)
	tcp_sock.connect()
	tcp_sock.send(data, options.type, 150)
	tcp_sock.close()
 
 
if __name__ == "__main__":
	main()
Ce programme communique avec une carte contenant du soft embarque en C. Je souhaite securiser au maximum la connexion dans le sens ou une erreur ne doit pas bloquer la carte.

Mon test est de debrancher le cable ethernet lors du transfert. Pas de soucis cote carte, mon select timeout et je me remets dans un etat d'attente de nouvelle connexion. En revanche cote script petit soucis il semble que je reste bloque sur le sendall pourtant j'esperais que le signal sigalarm me permette de sortir de cet etat mais rien, je suis oblige de faire un ctrl+c qui est bien intercepte du coup le script est bien interrompu mais je ne comprends pas pourquoi je n'intercepte pas de signal sigalarm.

Le sigalarm marche dans le cas ou le transfert s'est passe correctement et que j'attends les acknowledges.

Merci de votre aide.