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 :
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 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
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.
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()
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.
Partager