2013-03-21 2 views
0

저는 블루투스 프로토콜을 파싱하기 위해 파이썬 구성 라이브러리를 사용하고 있습니다. 라이브러리의 링크는 here파이썬 구성 라이브러리 (바이너리 데이터를 구문 분석하기위한)에서 나머지 데이터를 하나의 필드로 그룹화하는 방법은 무엇입니까?

입니다. 프로토콜이 실제로 복잡해지기 때문에 저는 하나의 giganic 구조를 만드는 대신 여러 단계로 파싱을 세분했습니다. 지금은 이미이 구조에 큰 원시 데이터를 분석 : 당신이 페이로드의 길이가 34 인 PDU_length로 표시됩니다 볼 수 있듯이

Container({'CRC': 'd\xcbT', 
'CRC_OK': 1, 
'Channel': 38, 
'RSSI': 43, 
'access_addr': 2391391958L, 
'header': Container({'TxAdd': False, 'PDU_length': 34, 'PDU_Type': 'ADV_IND', 'RxAdd': False}), 
'payload': '2\x15\x00a\x02\x00\x02\x01\x06\x07\x03\x03\x18\x02\x18\x04\x18\x03\x19\x00\x02\x02\n\xfe\t\tAS-D1532'}) 

페이로드의 구조는 다음과 같습니다 첫째

을 [ 6 옥텟 : AdvertAddress] [0-31 옥텟의 나머지 데이터 : AdvertData]

그러나 페이로드를 독립형 구조로 파싱하기 시작했을 때 나는 구조체의 컨텍스트에서 34 길이를 잃어 버렸습니다. 유효 탑재량. 처음 6 옥텟을 AdvertAddress로 구문 분석하고 나머지 데이터를 AdvertData로 그룹화하는 방법은 무엇입니까?

내 현재 솔루션은 다음과 같습니다

length = len(payload) #I didn't use PDU_length but len(payload) gives me back 34 also. 
ADVERT_PAYLOAD = Struct("ADVERT_PAYLOAD", 
    Field("AdvertAddress",6), 
    Field("AdvertData",length-6), 
) 
print ADVERT_PAYLOAD.parse(payload) 

이 올바른 출력을 제공합니다. 하지만 분명히 모든 페이로드의 크기가 34가 아닙니다.이 메서드는 나를 구성해야합니다. ADVERT_PAYLOAD eveytime 새 페이로드를 구문 분석해야합니다.

문서를 여러 번 읽었지만 관련 항목을 찾을 수 없습니다. 페이로드의 길이에 대한 지식을 ADVERT_PAYLOAD의 컨텍스트에 전달하는 방법이나 parse 메서드에 전달 된 인수의 길이를 얻을 수있는 방법이 없습니다.

아마도이 문제에 대한 해결책이 없습니다. 그런데 대부분의 사람들은 어떻게 그런 프로토콜 데이터를 분석합니까? 페이로드로 나아감에 따라 더 많은 유형으로 세분화되며 더 작은 유형의 구문을 파싱해야합니다. 상위 구조를 구축하고, 더 작은 구조를 포함하는 작은 구조를 내장해야합니까? 나는 그런 큰 물건을 만드는 것에 대해 어떻게 가야하는지 상상할 수 없다. 사전에

감사합니다.

답변

1

GreedyRange는 문자의 목록을 얻을 것이다, 그리고 JoinAdapter 함께 모든 문자에 참여합니다 :

class JoinAdapter(Adapter): 
    def _decode(self, obj, context): 
     return "".join(obj) 

ADVERT_PAYLOAD = Struct("ADVERT_PAYLOAD", 
    Field("AdvertAddress",6), 
    JoinAdapter(GreedyRange(Field("AdvertData", 1))) 
) 

payload = '2\x15\x00a\x02\x00\x02\x01\x06\x07\x03\x03\x18\x02\x18\x04\x18\x03\x19\x00\x02\x02\n\xfe\t\tAS-D1532' 
print ADVERT_PAYLOAD.parse(payload) 

출력 : 나는 범위 나 greedyrange 사용에 대한 생각하지만 난 것을보고 포기

Container: 
    AdvertAddress = '2\x15\x00a\x02\x00' 
    AdvertData = '\x02\x01\x06\x07\x03\x03\x18\x02\x18\x04\x18\x03\x19\x00\x02\x02\n\xfe\t\tAS-D1532' 
+0

둘 다리스트를 생성합니다. 아마 다른 방법이 없을 것 같습니다. 나는 대답으로 이것을 받아 들인다. 그런데 심도있는 구조화 된 프로토콜의 경우 큰 중첩 구문을 구성합니까? 아니면 단계별로 구문 분석합니까? 구문 분석해야하는 AdvertData에는 구조가 더 있습니다. – foresightyj

+1

단계별로 구현하기가 쉽습니다. 단계별로 먼저 수행 한 다음 중첩 된 큰 구조로 변환하려고합니다. – HYRY