예제 #1
0
    def connect(self, connectParams):

        if 'port' in connectParams:
            self.comPort = connectParams['port']
        else:
            output = "'port' entry required in connection parameters"
            log.warning(output)
            raise ConnectionError(output)

        if 'baudrate' in connectParams:
            baudrate = connectParams['baudrate']
        else:
            baudrate = self._BAUDRATE

        if 'errorQueue' in connectParams:
            self._ERRORQUEUE = connectParams['errorQueue']

        try:
            self.pyserialHandler = serial.Serial(self.comPort,
                                                 baudrate=baudrate)
            self.pyserialHandler.setRTS(False)
            self.pyserialHandler.setDTR(True)
        except serial.serialutil.SerialException as err:
            output = "could not open " + self.comPort + ", reason: " + str(err)
            log.warning(output)
            raise ConnectionError(output)
        else:
            log.info("opened port " + self.comPort)
            self._restart()
            self.connected = True
            self.connectcallback(self.connected)
            self.name = '{0}_HDLC'.format(self.comPort)
            self.start()
        return self
 def _ackIfNeeded(self, cmdId, isResponse):
     if ((not isResponse) and (self.shouldAck)):
         # send normal ACK (with RC=0)
         self._sendInternal(cmdId, True, [0])
         return True
     elif cmdId == self.HELLO_IDS['manager_hello'] and self.isConnect:
         raise ConnectionError("Unexpected manager_hello")
     return False
예제 #3
0
    def send(self, message):

        if not self.connected:
            output = 'not connected'
            log.error(output)
            raise ConnectionError(output)

        # calculate fcs
        packetToSend = {}
        packetToSend['payload'] = message
        packetToSend['fcs'] = self.crc.calculate(packetToSend['payload'])
        packetToSend['valid'] = True

        # assemble packet
        packetBytes = packetToSend['payload'] + packetToSend['fcs']

        # add HDLC escape characters
        index = 0
        while index < len(packetBytes):
            if packetBytes[index] == self._HDLC_FLAG or packetBytes[
                    index] == self._HDLC_ESCAPE:
                packetBytes.insert(index, self._HDLC_ESCAPE)
                index += 1
                packetBytes[index] = packetBytes[index] ^ self._HDLC_MASK
            index += 1

        # add HDLC flags
        packetBytes.insert(0, self._HDLC_FLAG)
        packetBytes.insert(len(packetBytes), self._HDLC_FLAG)

        # log
        if log.isEnabledFor(logging.DEBUG):
            output = []
            output += ['\npacketToSend:']
            output += self._formatFrame(packetToSend)
            log.debug('\n'.join(output))

        # reconstitute byteArray
        byteArray = ''.join([chr(byte) for byte in packetBytes])

        # send over serial port
        try:
            with self.busySending:
                numWritten = self.pyserialHandler.write(byteArray)
        except IOError, e:
            raise ConnectionError(str(e))
예제 #4
0
    def send(self, commandArray, fields):
        if not self.isConnected:
            output = "not connected"
            log.error(output)
            raise ConnectionError(output)

        # serialize the fields
        cmdId, serializedFields = self.api_def.serialize(commandArray, fields)

        return self._sendInternal(cmdId, False, serializedFields)
예제 #5
0
 def connect(self,comPort,baudrate=_BAUDRATE):
     self.comPort         = comPort
     try:
         self.pyserialHandler = serial.Serial(self.comPort,baudrate=baudrate)
         self.pyserialHandler.setRTS(False)
         self.pyserialHandler.setDTR(True)
     except serial.serialutil.SerialException as err:
         output = "could not open {0}@{1}baud, reason: {2}".format(self.comPort,baudrate,err)
         log.warning(output)
         raise ConnectionError(output)
     else:
         log.info("opened port {0}@{1}baud".format(self.comPort,baudrate))
         self._restart()
         self.connected = True
         self.connectcallback(self.connected)
         self.name      = '{0}_HDLC'.format(self.comPort)
         self.start()
     return self
예제 #6
0
    def _hdlcRxCb(self, frameRx):
        '''
        \brief called by HDLC when it's done receiving a complete frame.
        
        \note The frame received does not contain any of the HDLC-specific
              flags and espace characters
       
        \param frameRx The received frame, represented as a byteArray
        '''

        if len(frameRx) < 3:
            output = "received packet too short"
            log.error(output)
            raise ConnectionError(output)

        cmdId, length, isResponse, packetId, payload = self._parseRxHeader(
            frameRx)

        # log
        if log.isEnabledFor(logging.DEBUG):
            log.debug(
                "cmdId={0} length={1} isResponse={2} packetId={3} payload={4}".
                format(cmdId, length, isResponse, packetId, payload))

            if isResponse:
                log.debug(
                    "<--------- pcToMote ACK ({0}) after {1:.3f} --------".
                    format(packetId,
                           time.time() - self.tsDataSent))
            else:
                log.debug("<--------- moteToPc DATA ({0}) ----------".format(
                    packetId))
                self.tsDataReceived = time.time()

        # check packetId
        (wasValidPacketId, isRepeatId,
         updateRxPacketId) = self.isValidPacketId(cmdId, isResponse, packetId)

        # update RxPacketId
        self.paramLock.acquire()
        if isResponse == False and (not isRepeatId) and updateRxPacketId:
            self.RxPacketId = packetId
        self.paramLock.release()

        # send ACK if necessary
        try:
            ackSent = self._ackIfNeeded(cmdId, isResponse)
        except ConnectionError as ex:
            log.error("putting disconnect notification {0}".format(ex))
            self.putDisconnectNotification(str(ex))
            raise ex

        # log
        if log.isEnabledFor(logging.DEBUG):
            if ackSent:
                log.debug(
                    "---------- moteToPc ACK ({0}) after {1:.3f} ------->".
                    format(self.RxPacketId,
                           time.time() - self.tsDataReceived))
                log.debug("ack sent")
            else:
                log.debug("no ack needed")

        if isResponse or self.isHelloResponse(cmdId):

            # deserialize received packet
            try:
                nameArray, fields = self.api_def.deserialize(
                    ApiDefinition.ApiDefinition.COMMAND, cmdId, payload)
            except Exception as err:
                self.responseBuf = err
            else:
                # put received packet in local response buffer
                self.responseBuf = fields

            # release semaphore
            if self.waitForResp:
                self.waitForResp = False
                self.waitForRespEvent.set()
            else:
                output = "unexpected response"
                log.error(output)
                raise ConnectionError(output)

        else:
            if not isRepeatId:

                # deserialize received packet
                nameArray, fields = self.api_def.deserialize(
                    ApiDefinition.ApiDefinition.NOTIFICATION, cmdId, payload)

                # put received packet in notification buffer
                self.putNotification((nameArray, fields))

        # raise error if packet id is wrong
        if not wasValidPacketId:
            output = "wrong packetId"
            log.error(output)
            raise ConnectionError(output)
예제 #7
0
    def _sendInternal(self, cmdId, isResponse, serializedFields):

        try:
            if not isResponse:
                self.requestSendLock.acquire()

            # build packet to send
            packet = []
            packet += self._buildTxHeader(cmdId, isResponse, serializedFields)
            packet += serializedFields

            retry = 0

            # Prepare for reliable send
            if not isResponse:
                self.waitForResp = True
                self.waitForRespEvent.clear()

            while True:
                if log.isEnabledFor(logging.DEBUG):
                    log.debug(
                        "_sendInternal cmdId={0} retry={1} isResponse={2} serializedFields={3}"
                        .format(cmdId, retry, isResponse, serializedFields))

                if not isResponse:
                    if log.isEnabledFor(logging.DEBUG):
                        log.debug("---------- pcToMote DATA ({0}) ---------->".
                                  format(self.TxPacketId))
                        self.tsDataSent = time.time()

                # send packet through HDLC module
                with self.hdlcLock:
                    if not self.hdlc:
                        output = "no HDLC module, did I just disconnect?"
                        log.error(output)
                        raise ConnectionError(output)
                    self.hdlc.send(packet)

                if isResponse:
                    return None

                # wait for response. semaphore released by _hdlcRxCb()
                if self.waitForRespEvent.wait(RX_TIMEOUT):
                    break

                log.info("retry {0}".format(retry))

                # Timeout error
                if retry >= MAX_NUM_RETRY:
                    output = "retried {0} times, max allowed is {1}".format(
                        retry, MAX_NUM_RETRY)
                    log.error(output)
                    raise ConnectionError(output)
                retry = retry + 1

            if isinstance(self.responseBuf, Exception):
                log.error("responseBuf contains exception {0}".format(
                    self.responseBuf))
                raise self.responseBuf

            if  (
                    (ApiDefinition.ApiDefinition.RC in self.responseBuf) and
                    (
                        self.responseBuf[ApiDefinition.ApiDefinition.RC]!= \
                            ApiDefinition.ApiDefinition.RC_OK
                    )
                ):
                temp_name = self.api_def.idToName(
                    ApiDefinition.ApiDefinition.COMMAND, cmdId)
                temp_rc = self.responseBuf[ApiDefinition.ApiDefinition.RC]
                temp_desc = '({0})\n{1}'.format(
                    self.api_def.fieldValueToDesc(
                        ApiDefinition.ApiDefinition.COMMAND, [temp_name],
                        ApiDefinition.ApiDefinition.RC, temp_rc),
                    self.api_def.rcToDescription(
                        temp_rc,
                        [temp_name],
                    ),
                )
                if temp_rc not in [
                        11, 18
                ]:  # rc==11:RC_NOT_FOUND, rc==18:RC_END_OF_LIST
                    log.warning("received RC={0} for command {1}:\n{2}".format(
                        temp_rc, temp_name, temp_desc))
                raise APIError(temp_name, temp_rc, temp_desc)

            # return packet received
            return self.responseBuf

        finally:
            if not isResponse:
                self.requestSendLock.release()
예제 #8
0
    def send(self, commandArray, fields):
        if not self.isConnected:
            output = "not connected"
            log.error(output)
            raise ConnectionError(output)

        log.debug('send commandArray={0} fields={1}'.format(
            commandArray, fields))

        assert len(commandArray) == 1 or len(commandArray) == 2
        commandName = commandArray[0]
        if len(commandArray) == 2:
            subCommandName = commandArray[1]
        else:
            subCommandName = None

        apiCommand = None
        for c in IpMoteDefinition.IpMoteDefinition.commands:
            if c['name'] == commandName:

                if ('subCommands' in c) and subCommandName:
                    for sc in c['subCommands']:
                        if sc['name'] == subCommandName:
                            apiCommand = sc
                            break
                else:
                    apiCommand = c
                    break
        assert apiCommand

        #===== send command to manager

        # create params on the fly
        params = []
        varSizeParamLen = None

        for [paramname, type, length, _] in apiCommand['request']:
            thisparam = {}
            thisparam['name'] = paramname
            thisparam['C'] = _generateCParam(type, length, fields[paramname])

            params += [thisparam]

            if length == None:
                varSizeParamLen = len(fields[paramname])

        # create (dummy) buffer to hold reply
        reply = create_string_buffer(self.MAX_FRAME_LENGTH)

        # format params
        cparams = []
        cparams += [p['C'] for p in params]
        if varSizeParamLen != None:
            cparams += [varSizeParamLen]
        cparams += [byref(reply)]

        # log
        log.debug('C parameters: {0}'.format(pp.pformat(params)))

        # issue request
        if subCommandName:
            funcName = 'dn_ipmt_{0}_{1}'.format(commandName, subCommandName)
        else:
            funcName = 'dn_ipmt_{0}'.format(commandName)
        rcApi = getattr(self.smipmt, funcName)(*cparams)
        assert rcApi == DN_ERR_NONE

        #===== wait for response

        if self.waitForResponse.wait(self.RESPONSE_TIMEOUT):
            self.waitForResponse.clear()
        else:
            self.smipmt.dn_ipmt_cancelTx()
            raise ConnectionError("timeout response")

        #===== convert C response to Python dictionary

        # create returned fields on the fly
        theseFields = []
        theseFields += [('RC', _getResponseType(INT, 1))]
        for [name, type, length,
             validName] in apiCommand['response']['FIELDS']:
            theseFields += [(name, _getResponseType(type, length))]

        # Structure to hold the response
        class reply_t(Structure):
            _fields_ = theseFields

        # cast response to that structure
        notif = cast(reply, POINTER(reply_t))

        # convert structure to dictionary
        returnVal = {}
        for (f, _) in theseFields:
            rawVal = getattr(notif.contents, f)
            if isinstance(rawVal, int):
                returnVal[f] = rawVal
            elif isinstance(rawVal, long):
                returnVal[f] = int(rawVal)
            else:
                returnVal[f] = [int(b) for b in rawVal]

        return returnVal
예제 #9
0
    def connect(self, connectParams):
        log.debug("connect connectParams={0}".format(connectParams))

        if 'port' not in connectParams:
            output = "'port' entry required in connection parameters"
            log.error(output)
            raise ValueError(output)

        #==== connect to serial port

        self.comPort = connectParams['port']
        try:
            self.pyserialHandler = serial.Serial(self.comPort,
                                                 baudrate=self._BAUDRATE)
            self.pyserialHandler.setRTS(False)
            self.pyserialHandler.setDTR(True)
        except serial.serialutil.SerialException as err:
            output = "could not open " + self.comPort + ", reason: " + str(err)
            log.warning(output)
            raise ConnectionError(output)
        else:
            log.info("opened port " + self.comPort)

        #==== import and initialize the C library

        global uart_txByte
        global ipmt_notif
        global ipmt_reply
        global ipmt_status

        # local variables
        uart_txByte = uart_txByte_cbt(self._uart_txByte)
        ipmt_notif = ipmt_notif_cbt(self._ipmt_notif)
        ipmt_reply = ipmt_reply_cbt(self._ipmt_reply)
        ipmt_status = ipmt_status_cbt(self._ipmt_status)

        # configure the callback function
        self.notifBuf = create_string_buffer(self.MAX_FRAME_LENGTH)

        # open the library under test
        self.smipmt = CDLL(CLIB_PATH)
        self.smipmt.dn_ipmt_init(
            ipmt_notif,  # notifCb
            self.notifBuf,  # notifBuf
            len(self.notifBuf),  # notifBufLen
            ipmt_reply,  # replyCb
            ipmt_status,  # statusCb
        )

        # install callbacks
        self.smipmt.dn_uart_register_txByte(uart_txByte)

        # initial thread
        threading.Thread.__init__(self)
        self.name = 'IpMoteConnectorSerial'

        # start myself
        self.start()

        #==== connect administratively

        # connect the parent class
        ApiConnector.connect(self)
예제 #10
0
class Hdlc(threading.Thread):

    _BAUDRATE = 115200  # the default baudrate used by this module

    _HDLC_FLAG = 0x7e  # the HDLC flag at the beginning/end of a frame
    _HDLC_ESCAPE = 0x7d  # escape character when the HDLC flag in payload
    _HDLC_MASK = 0x20  # mask used to recover from escape characters

    _FCS_LENGTH = 2  # number of bytes in the FCS field

    def __init__(self, rxcallback, connectcallback):

        # log
        log.info('Creating object')

        # store params
        self.rxcallback = rxcallback
        self.connectcallback = connectcallback

        # initialize parent class
        threading.Thread.__init__(self)
        self.name = 'HDLC'
        self.daemon = True

        # local variables
        self.crc = Crc.Crc()
        self.connected = False
        self.comPort = ''
        self.pyserialHandler = ''
        self.busySending = threading.Lock()
        self.busyReceiving = False
        self.lastRxByte = self._HDLC_FLAG

        # initialize state
        self._restart()

    def run(self):

        # log
        log.info('thread started')

        try:

            while self.connected == True:
                try:

                    # received a byte
                    try:
                        rxByte = self.pyserialHandler.read(1)
                    except Exception as err:
                        # work-around for bug in pyserial
                        # https://sourceforge.net/tracker/?func=detail&aid=3591432&group_id=46487&atid=446302
                        raise serial.SerialException(str(err))
                    if not len(rxByte):
                        raise serial.SerialException()

                    # convert the received byte from a character to an int
                    rxByte = ord(rxByte)
                    if ((not self.busyReceiving)
                            and self.lastRxByte == self._HDLC_FLAG
                            and rxByte != self._HDLC_FLAG):
                        # start of frame

                        self.busyReceiving = True
                        self.receivedFrame = {}
                        self.receivedFrame['payload'] = [rxByte]

                    elif (self.busyReceiving and rxByte != self._HDLC_FLAG):
                        # middle of frame

                        if rxByte == self._HDLC_ESCAPE:
                            self._escape = True
                            # do not add this byte to the payload
                        else:
                            if self._escape == True:
                                self.receivedFrame['payload'].append(
                                    rxByte ^ self._HDLC_MASK)
                                self._escape = False
                            else:
                                self.receivedFrame['payload'].append(rxByte)

                    elif (self.busyReceiving and rxByte == self._HDLC_FLAG):
                        # end of frame

                        self.busyReceiving = False

                        # split payload and fcs
                        if len(self.receivedFrame['payload']
                               ) > self._FCS_LENGTH:
                            temp_payload = self.receivedFrame['payload']
                            self.receivedFrame['payload'] = temp_payload[:-2]
                            self.receivedFrame['fcs'] = temp_payload[-2:]

                            # check fcs, write 'valid' field
                            recalculatedCrc = self.crc.calculate(
                                self.receivedFrame['payload'])
                            if recalculatedCrc == self.receivedFrame['fcs']:
                                self.receivedFrame['valid'] = True
                            else:
                                self.receivedFrame['valid'] = False

                            # log
                            if log.isEnabledFor(logging.DEBUG):
                                output = []
                                output += ['\nreceivedFrame:']
                                output += self._formatFrame(self.receivedFrame)
                                log.debug('\n'.join(output))

                            # callback
                            if self.receivedFrame['valid'] == True:
                                try:
                                    self.rxcallback(
                                        self.receivedFrame['payload'])
                                except (ConnectionError, CommandError) as err:
                                    output = "@Hdlc: {0}".format(err)
                                    log.error(output)
                                    print output
                        else:
                            output = "@Hdlc: received hdlc frame too short"
                            log.error(output)
                            print output
                        self._restart()

                    # remember the last byte I received
                    self.lastRxByte = rxByte

                except serial.SerialException:
                    self.connected = False

        except Exception as err:
            output = []
            output += ['===== crash in thread {0} ====='.format(self.name)]
            output += ['\nerror:\n']
            output += [str(err)]
            output += ['\ncall stack:\n']
            output += [traceback.format_exc()]
            output = '\n'.join(output)
            print output  # critical error
            log.critical(output)
            raise

        del self.crc
        del self.pyserialHandler
        self.connectcallback(self.connected)

        # log
        log.info('thread ended')

    #======================== public ==========================================

    def connect(self, comPort, baudrate=_BAUDRATE):
        self.comPort = comPort
        try:
            self.pyserialHandler = serial.Serial(self.comPort,
                                                 baudrate=baudrate)
            self.pyserialHandler.setRTS(False)
            self.pyserialHandler.setDTR(True)
        except serial.serialutil.SerialException as err:
            output = "could not open {0}@{1}baud, reason: {2}".format(
                self.comPort, baudrate, err)
            log.warning(output)
            raise ConnectionError(output)
        else:
            log.info("opened port {0}@{1}baud".format(self.comPort, baudrate))
            self._restart()
            self.connected = True
            self.connectcallback(self.connected)
            self.name = '{0}_HDLC'.format(self.comPort)
            self.start()
        return self

    def send(self, message):

        if not self.connected:
            output = 'not connected'
            log.error(output)
            raise ConnectionError(output)

        # calculate fcs
        packetToSend = {}
        packetToSend['payload'] = message
        packetToSend['fcs'] = self.crc.calculate(packetToSend['payload'])
        packetToSend['valid'] = True

        # assemble packet
        packetBytes = packetToSend['payload'] + packetToSend['fcs']

        # add HDLC escape characters
        index = 0
        while index < len(packetBytes):
            if packetBytes[index] == self._HDLC_FLAG or packetBytes[
                    index] == self._HDLC_ESCAPE:
                packetBytes.insert(index, self._HDLC_ESCAPE)
                index += 1
                packetBytes[index] = packetBytes[index] ^ self._HDLC_MASK
            index += 1

        # add HDLC flags
        packetBytes.insert(0, self._HDLC_FLAG)
        packetBytes.insert(len(packetBytes), self._HDLC_FLAG)

        # log
        if log.isEnabledFor(logging.DEBUG):
            output = []
            output += ['\npacketToSend:']
            output += self._formatFrame(packetToSend)
            log.debug('\n'.join(output))

        # reconstitute byteArray
        byteArray = ''.join([chr(byte) for byte in packetBytes])

        # send over serial port
        try:
            with self.busySending:
                numWritten = self.pyserialHandler.write(byteArray)
        except IOError, e:
            raise ConnectionError(str(e))

        if numWritten != len(packetBytes):
            output = 'wrote ' + str(numWritten) + ' bytes, expected ' + str(
                len(packetBytes))
            log.error(output)
            raise ConnectionError(output)
예제 #11
0
 def connect(self,connectParams):
     '''
     \brief Connect to the LBR.
     '''
     
     # filter error
     if self.getStatus() not in [self.STATUS_DISCONNECTED]:
         self._abortConnectionWithError(connectParams,'is at wrong status to connect '+str(self.getStatus()))
     
     # record variables
     try:
         self.varLock.acquire()
         self.lbrAddr              = connectParams['lbrAddr']
         self.lbrPort              = connectParams['lbrPort']
         self.username             = connectParams['username']
         self.seclevel             = connectParams['seclevel']
         if   self.seclevel==LbrProtocol.SECLEVEL_PASSWORD:
             self.password         = connectParams['password']
         elif self.seclevel==LbrProtocol.SECLEVEL_SSL:
             self.clientprivatekey = connectParams['clientprivatekey']
             self.clientpublickey  = connectParams['clientpublickey']
             self.lbrpublickey     = connectParams['lbrpublickey']
     except KeyError as err:
         raise ConnectionError('Missing connection parameter: '+str(err))
     finally:
         self.varLock.release()
     
     # connect the parent
     ApiConnector.connect(self)
     
     # update status
     self._updateStatus(self.STATUS_INIT_CONNECTION)
     
     # create TCP socket to connect to LBR
     try:
         self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         self.socket.connect((self.lbrAddr,self.lbrPort))
     except socket.error:
         self._abortConnectionWithError(connectParams,'could not open socket to LBR@'+self.lbrAddr+':'+str(self.lbrPort)+'.')
     
     # listen for at most AUTHTIMEOUT seconds during connection
     self.socket.settimeout(AUTHTIMEOUT)
     
     #=== Step 1. Send my security capability to LBR
     self._updateStatus(self.STATUS_TX_SECURITY)
     try:
         self.socket.send(LbrProtocol.CMD_SECURITY+chr(self.seclevel))
     except socket.error:
         self._abortConnectionWithError(connectParams,'could not send security capability.')
     
     #=== Step 2. Receive security capabilities from LBR
     self._updateStatus(self.STATUS_RX_SECURITY)
     try:
         input = self.socket.recv(TCPRXBUFSIZE)
     except socket.timeout:
         self._abortConnectionWithError(connectParams,'waited too long for security reply.')
     if (     len(input)!=2   or
              input[0]  !=LbrProtocol.CMD_SECURITY or
          ord(input[1]) !=self.seclevel):
         self._abortConnectionWithError(connectParams,'received incorrect security reply.')
     
     #=== Step 3. Send username
     self._updateStatus(self.STATUS_TX_USERNAME)
     try:
         self.socket.send(LbrProtocol.CMD_USERNAME+self.username)
     except socket.error:
         self._abortConnectionWithError(connectParams,'could not send username.')
     
     #=== Step 4. Receive username
     self._updateStatus(self.STATUS_RX_USERNAME)
     try:
         input = self.socket.recv(TCPRXBUFSIZE)
     except socket.timeout:
         self._abortConnectionWithError(connectParams,'waited too long for username echo.')
     if (     len(input)<=1   or
              input[0]  !=LbrProtocol.CMD_USERNAME or
              input[1:] !=self.username):
         self._abortConnectionWithError(connectParams,'received incorrect echoed username.')
     
     #=== Step 5. Secure TCP session
     if   self.seclevel==LbrProtocol.SECLEVEL_NONE:
         log.debug('TCP session securing: none')
     elif self.seclevel==LbrProtocol.SECLEVEL_PASSWORD:
         log.debug('TCP session securing: password')
         self._updateStatus(self.STATUS_TX_PASSWORD)
         try:
             self.socket.send(LbrProtocol.CMD_PASSWORD+self.password)
         except socket.error:
             self._abortConnectionWithError(connectParams,'could not send password.')
     elif self.seclevel==LbrProtocol.SECLEVEL_SSL:
         log.debug('TCP session securing: SSL')
         self._updateStatus(self.STATUS_SLL_WRAPPING)
         try:
             clientPrivateKeyPem      = self._privatekeyToPem(self.clientprivatekey)
             clientPrivateKeyFileName = self.username+'.tempprivatekey'
             clientPrivateKeyFile     = open(clientPrivateKeyFileName,'w')
             clientPrivateKeyFile.write(clientPrivateKeyPem)
             clientPrivateKeyFile.close()
             
             clientPublicKeyPem       = self._publickeyToPem(self.clientpublickey)
             clientPublicKeyFileName  = self.username+'.temppublickey'
             clientPublicKeyFile      = open(clientPublicKeyFileName,'w')
             clientPublicKeyFile.write(clientPublicKeyPem)
             clientPublicKeyFile.close()
             
             lbrpublickeyPem       = self._publickeyToPem(self.lbrpublickey)
             lbrpublickeyFileName  = self.username+'.templbrpublickey'
             lbrpublickeyFile      = open(lbrpublickeyFileName,'w')
             lbrpublickeyFile.write(lbrpublickeyPem)
             lbrpublickeyFile.close()
             
             self.socket = ssl.wrap_socket(
                                 self.socket,
                                 keyfile=clientPrivateKeyFileName,     # client's private key
                                 certfile=clientPublicKeyFileName,     # client's public key
                                 ca_certs=lbrpublickeyFileName,     # server's public key
                                 cert_reqs=ssl.CERT_REQUIRED)
         except ssl.SSLError as err:
             self._abortConnectionWithError(connectParams,'SSL wrapping failed.')
         except Exception as err:
             print err
         else:
             output  = ''
             output += 'Peer validated:\n'
             output += '- name:        '+str(self.socket.getpeername())+'\n'
             output += '- cipher:      '+str(self.socket.cipher())+'\n'
             output += '- cartificate: '+str(self.socket.getpeercert())
             log.debug(output)
         finally:
             os.remove(clientPrivateKeyFileName)
             os.remove(clientPublicKeyFileName)
             os.remove(lbrpublickeyFileName)
     
     #=== Step 6. Receive assigned prefix from LBR
     self._updateStatus(self.STATUS_RX_PREFIX)
     try:
         input = self.socket.recv(TCPRXBUFSIZE)
     except (socket.timeout,ssl.SSLError):
         self._abortConnectionWithError(connectParams,'waited too long for prefix.')
     if (len(input)!=20 or
           input[0]!=LbrProtocol.CMD_PREFIX):
         self._abortConnectionWithError(connectParams,'received malformatted prefix.')
     
     # record the prefix
     self.prefix = input[1:]
     
     # if you get here, connection is succesfully established with LBR
     
     # update status
     self._updateStatus(self.STATUS_CONNECTED)
     
     # no socket timeout from now on
     self.socket.settimeout(None)
     
     # start an LbrListener thread
     temp = LbrListener(self.socket,self._rxCb,self._disconnectedCb)
     temp.start()
예제 #12
0
 def _abortConnectionWithError(self,connectParams,reason):
     try:
         self._closeSocket()
     except (AttributeError,socket.error):
         pass
     raise ConnectionError(connectParams['username']+' '+reason)