EMANE  1.2.1
build/lib/emane/ota/otapublisher.py
Go to the documentation of this file.
1 #
2 # Copyright (c) 2014,2017 - Adjacent Link LLC, Bridgewater, New Jersey
3 # All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
8 #
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in
13 # the documentation and/or other materials provided with the
14 # distribution.
15 # * Neither the name of Adjacent Link LLC nor the names of its
16 # contributors may be used to endorse or promote products derived
17 # from this software without specific prior written permission.
18 #
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 # POSSIBILITY OF SUCH DAMAGE.
31 #
32 
33 from . import OTAMessage
34 from . import OTAPublisherException
35 import os
36 import socket
37 import fcntl
38 import uuid
39 import struct
40 import sys
41 
42 def get_ip_address(ifname):
43  # http://code.activestate.com/recipes/439094/
44  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
45  return socket.inet_ntoa(fcntl.ioctl(
46  s.fileno(),
47  0x8915, # SIOCGIFADDR
48  struct.pack('256s', ifname[:15].encode() if sys.version_info >= (3,0) else ifname[:15])
49  )[20:24])
50 
51 def init_multicast_socket(group,port,device):
52  try:
53  sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
54 
55  except socket.error as msg :
56  if sys.version_info >= (3,3):
57  raise OTAPublisherException("ota socket failure %s" % str(msg),True)
58  else:
59  raise OTAPublisherException("ota socket failure %s %s" % (str(msg[0]), msg[1]),True)
60 
61  try:
62  sock.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL,32)
63  except socket.error as msg :
64  if sys.version_info >= (3,3):
65  raise OTAPublisherException("ota socket option failure %s" % str(msg),True)
66  else:
67  raise OTAPublisherException("ota socket option failure %s %s" % (str(msg[0]), msg[1]),True)
68 
69  try:
70  sock.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_LOOP,1)
71  except socket.error as msg :
72  if sys.version_info >= (3,3):
73  raise OTAPublisherException("ota socket option failure %s" % str(msg),True)
74  else:
75  raise OTAPublisherException("ota socket option failure %s %s" % (str(msg[0]), msg[1]),True)
76 
77  try:
78  sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
79  except socket.error as msg :
80  if sys.version_info >= (3,3):
81  raise OTAPublisherException("ota socket option failure %s" % str(msg),True)
82  else:
83  raise OTAPublisherException("ota socket option failure %s %s" % (str(msg[0]), msg[1]),True)
84 
85  try:
86  sock.bind((group,port))
87  except socket.error as msg:
88  if sys.version_info >= (3,3):
89  raise OTAPublisherException("bind failure %s" % str(msg),True)
90  else:
91  raise OTAPublisherException("bind failure %s %s" % (str(msg[0]), msg[1]),True)
92 
93 
94  try:
95  if device:
96  devAddress = socket.inet_aton(get_ip_address(device))
97  else:
98  devAddress = socket.inet_aton("0.0.0.0")
99 
100  sock.setsockopt(socket.SOL_IP,
101  socket.IP_ADD_MEMBERSHIP,
102  socket.inet_aton(group) +
103  devAddress)
104 
105  sock.setsockopt(socket.SOL_IP,
106  socket.IP_MULTICAST_IF,
107  devAddress)
108 
109  except socket.error as msg:
110  if sys.version_info >= (3,3):
111  raise OTAPublisherException("mulicast add membership failure %s" % str(msg),True)
112  else:
113  raise OTAPublisherException("mulicast add membership failure %s %s" % (str(msg[0]), msg[1]),True)
114 
115  except IOError:
116  raise OTAPublisherException("unknown device %s" % device,True)
117 
118  return sock
119 
120 
122  def __init__(self,otachannel):
123  (self._multicastGroup,self._port,_) = otachannel
124  self._socket = None
125  self._uuid = uuid.uuid4()
126  self._sequenceNumber = 0
127 
128  self._socket = init_multicast_socket(*otachannel)
129 
130 
131  def publish(self,otaMessage,txTimeMicroseconds):
132  self._socket.sendto(otaMessage.generate(txTimeMicroseconds,
133  self._sequenceNumber,
134  self._uuid)
135  ,(self._multicastGroup,self._port))
def publish(self, otaMessage, txTimeMicroseconds)
def init_multicast_socket(group, port, device)