sdp_client.c (7907f06931c075b55e3402fa469abbe35eebee25) sdp_client.c (f8fbdce0c5067e7e7edd3a29934b1f9b79c8ff2d)
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 133 unchanged lines hidden (view full) ---

142 log_error("l2cap_send() -> err %d", err);
143 break;
144 }
145}
146
147
148static void parse_service_search_attribute_response(uint8_t* packet){
149 uint16_t offset = 3;
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 133 unchanged lines hidden (view full) ---

142 log_error("l2cap_send() -> err %d", err);
143 break;
144 }
145}
146
147
148static void parse_service_search_attribute_response(uint8_t* packet){
149 uint16_t offset = 3;
150 uint16_t parameterLength = READ_NET_16(packet,offset);
150 uint16_t parameterLength = big_endian_read_16(packet,offset);
151 offset+=2;
152 // AttributeListByteCount <= mtu
151 offset+=2;
152 // AttributeListByteCount <= mtu
153 uint16_t attributeListByteCount = READ_NET_16(packet,offset);
153 uint16_t attributeListByteCount = big_endian_read_16(packet,offset);
154 offset+=2;
155
156 if (attributeListByteCount > mtu){
157 log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in found attribute list is larger then the MaximumAttributeByteCount.");
158 return;
159 }
160
161 // AttributeLists

--- 13 unchanged lines hidden (view full) ---

175 if (parameterLength != offset - 5){
176 log_error("Error parsing ServiceSearchAttributeResponse: wrong size of parameters, number of expected bytes%u, actual number %u.", parameterLength, offset);
177 }
178}
179
180void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
181 // uint16_t handle;
182 if (packet_type == L2CAP_DATA_PACKET){
154 offset+=2;
155
156 if (attributeListByteCount > mtu){
157 log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in found attribute list is larger then the MaximumAttributeByteCount.");
158 return;
159 }
160
161 // AttributeLists

--- 13 unchanged lines hidden (view full) ---

175 if (parameterLength != offset - 5){
176 log_error("Error parsing ServiceSearchAttributeResponse: wrong size of parameters, number of expected bytes%u, actual number %u.", parameterLength, offset);
177 }
178}
179
180void sdp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
181 // uint16_t handle;
182 if (packet_type == L2CAP_DATA_PACKET){
183 uint16_t responseTransactionID = READ_NET_16(packet,1);
183 uint16_t responseTransactionID = big_endian_read_16(packet,1);
184 if ( responseTransactionID != transactionID){
185 log_error("Missmatching transaction ID, expected %u, found %u.", transactionID, responseTransactionID);
186 return;
187 }
188
189 if (packet[0] != SDP_ServiceSearchAttributeResponse
190 && packet[0] != SDP_ServiceSearchResponse
191 && packet[0] != SDP_ServiceAttributeResponse){

--- 45 unchanged lines hidden (view full) ---

237 if (sdp_client_state != W4_CONNECT) break;
238 // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16), local_mtu(16), remote_mtu(16)
239 if (packet[2]) {
240 log_error("SDP Client Connection failed.");
241 sdp_parser_handle_done(packet[2]);
242 break;
243 }
244 sdp_cid = channel;
184 if ( responseTransactionID != transactionID){
185 log_error("Missmatching transaction ID, expected %u, found %u.", transactionID, responseTransactionID);
186 return;
187 }
188
189 if (packet[0] != SDP_ServiceSearchAttributeResponse
190 && packet[0] != SDP_ServiceSearchResponse
191 && packet[0] != SDP_ServiceAttributeResponse){

--- 45 unchanged lines hidden (view full) ---

237 if (sdp_client_state != W4_CONNECT) break;
238 // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16), local_mtu(16), remote_mtu(16)
239 if (packet[2]) {
240 log_error("SDP Client Connection failed.");
241 sdp_parser_handle_done(packet[2]);
242 break;
243 }
244 sdp_cid = channel;
245 mtu = READ_BT_16(packet, 17);
246 // handle = READ_BT_16(packet, 9);
245 mtu = little_endian_read_16(packet, 17);
246 // handle = little_endian_read_16(packet, 9);
247 log_info("SDP Client Connected, cid %x, mtu %u.", sdp_cid, mtu);
248
249 sdp_client_state = W2_SEND;
250 if (can_send_now(sdp_cid)) send_request(sdp_cid);
251
252 break;
253 case L2CAP_EVENT_CREDITS:
254 case DAEMON_EVENT_HCI_PACKET_SENT:
255 if (can_send_now(sdp_cid)) send_request(sdp_cid);
256 break;
257 case L2CAP_EVENT_CHANNEL_CLOSED: {
247 log_info("SDP Client Connected, cid %x, mtu %u.", sdp_cid, mtu);
248
249 sdp_client_state = W2_SEND;
250 if (can_send_now(sdp_cid)) send_request(sdp_cid);
251
252 break;
253 case L2CAP_EVENT_CREDITS:
254 case DAEMON_EVENT_HCI_PACKET_SENT:
255 if (can_send_now(sdp_cid)) send_request(sdp_cid);
256 break;
257 case L2CAP_EVENT_CHANNEL_CLOSED: {
258 if (sdp_cid != READ_BT_16(packet, 2)) {
259 // log_info("Received L2CAP_EVENT_CHANNEL_CLOSED for cid %x, current cid %x\n", READ_BT_16(packet, 2),sdp_cid);
258 if (sdp_cid != little_endian_read_16(packet, 2)) {
259 // log_info("Received L2CAP_EVENT_CHANNEL_CLOSED for cid %x, current cid %x\n", little_endian_read_16(packet, 2),sdp_cid);
260 break;
261 }
262 log_info("SDP Client disconnected.");
263 uint8_t status = sdp_client_state == QUERY_COMPLETE ? 0 : SDP_QUERY_INCOMPLETE;
264 sdp_client_state = INIT;
265 sdp_parser_handle_done(status);
266 break;
267 }

--- 5 unchanged lines hidden (view full) ---

273
274static uint16_t setup_service_search_attribute_request(uint8_t * data){
275
276 uint16_t offset = 0;
277 transactionID++;
278 // uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
279 data[offset++] = SDP_ServiceSearchAttributeRequest;
280 // uint16_t transactionID
260 break;
261 }
262 log_info("SDP Client disconnected.");
263 uint8_t status = sdp_client_state == QUERY_COMPLETE ? 0 : SDP_QUERY_INCOMPLETE;
264 sdp_client_state = INIT;
265 sdp_parser_handle_done(status);
266 break;
267 }

--- 5 unchanged lines hidden (view full) ---

273
274static uint16_t setup_service_search_attribute_request(uint8_t * data){
275
276 uint16_t offset = 0;
277 transactionID++;
278 // uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
279 data[offset++] = SDP_ServiceSearchAttributeRequest;
280 // uint16_t transactionID
281 net_store_16(data, offset, transactionID);
281 big_endian_store_16(data, offset, transactionID);
282 offset += 2;
283
284 // param legnth
285 offset += 2;
286
287 // parameters:
288 // ServiceSearchPattern - DES (min 1 UUID, max 12)
289 uint16_t serviceSearchPatternLen = de_get_len(serviceSearchPattern);
290 memcpy(data + offset, serviceSearchPattern, serviceSearchPatternLen);
291 offset += serviceSearchPatternLen;
292
293 // MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu
282 offset += 2;
283
284 // param legnth
285 offset += 2;
286
287 // parameters:
288 // ServiceSearchPattern - DES (min 1 UUID, max 12)
289 uint16_t serviceSearchPatternLen = de_get_len(serviceSearchPattern);
290 memcpy(data + offset, serviceSearchPattern, serviceSearchPatternLen);
291 offset += serviceSearchPatternLen;
292
293 // MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu
294 net_store_16(data, offset, mtu);
294 big_endian_store_16(data, offset, mtu);
295 offset += 2;
296
297 // AttibuteIDList
298 uint16_t attributeIDListLen = de_get_len(attributeIDList);
299 memcpy(data + offset, attributeIDList, attributeIDListLen);
300 offset += attributeIDListLen;
301
302 // ContinuationState - uint8_t number of cont. bytes N<=16
303 data[offset++] = continuationStateLen;
304 // - N-bytes previous response from server
305 memcpy(data + offset, continuationState, continuationStateLen);
306 offset += continuationStateLen;
307
308 // uint16_t paramLength
295 offset += 2;
296
297 // AttibuteIDList
298 uint16_t attributeIDListLen = de_get_len(attributeIDList);
299 memcpy(data + offset, attributeIDList, attributeIDListLen);
300 offset += attributeIDListLen;
301
302 // ContinuationState - uint8_t number of cont. bytes N<=16
303 data[offset++] = continuationStateLen;
304 // - N-bytes previous response from server
305 memcpy(data + offset, continuationState, continuationStateLen);
306 offset += continuationStateLen;
307
308 // uint16_t paramLength
309 net_store_16(data, 3, offset - 5);
309 big_endian_store_16(data, 3, offset - 5);
310
311 return offset;
312}
313
314#ifdef ENABLE_SDP_EXTRA_QUERIES
315void parse_service_record_handle_list(uint8_t* packet, uint16_t total_count, uint16_t current_count){
316 sdp_parser_handle_service_search(packet, total_count, current_count);
317}
318
319static uint16_t setup_service_search_request(uint8_t * data){
320 uint16_t offset = 0;
321 transactionID++;
322 // uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
323 data[offset++] = SDP_ServiceSearchRequest;
324 // uint16_t transactionID
310
311 return offset;
312}
313
314#ifdef ENABLE_SDP_EXTRA_QUERIES
315void parse_service_record_handle_list(uint8_t* packet, uint16_t total_count, uint16_t current_count){
316 sdp_parser_handle_service_search(packet, total_count, current_count);
317}
318
319static uint16_t setup_service_search_request(uint8_t * data){
320 uint16_t offset = 0;
321 transactionID++;
322 // uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
323 data[offset++] = SDP_ServiceSearchRequest;
324 // uint16_t transactionID
325 net_store_16(data, offset, transactionID);
325 big_endian_store_16(data, offset, transactionID);
326 offset += 2;
327
328 // param legnth
329 offset += 2;
330
331 // parameters:
332 // ServiceSearchPattern - DES (min 1 UUID, max 12)
333 uint16_t serviceSearchPatternLen = de_get_len(serviceSearchPattern);
334 memcpy(data + offset, serviceSearchPattern, serviceSearchPatternLen);
335 offset += serviceSearchPatternLen;
336
337 // MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu
326 offset += 2;
327
328 // param legnth
329 offset += 2;
330
331 // parameters:
332 // ServiceSearchPattern - DES (min 1 UUID, max 12)
333 uint16_t serviceSearchPatternLen = de_get_len(serviceSearchPattern);
334 memcpy(data + offset, serviceSearchPattern, serviceSearchPatternLen);
335 offset += serviceSearchPatternLen;
336
337 // MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu
338 net_store_16(data, offset, mtu);
338 big_endian_store_16(data, offset, mtu);
339 offset += 2;
340
341 // ContinuationState - uint8_t number of cont. bytes N<=16
342 data[offset++] = continuationStateLen;
343 // - N-bytes previous response from server
344 memcpy(data + offset, continuationState, continuationStateLen);
345 offset += continuationStateLen;
346
347 // uint16_t paramLength
339 offset += 2;
340
341 // ContinuationState - uint8_t number of cont. bytes N<=16
342 data[offset++] = continuationStateLen;
343 // - N-bytes previous response from server
344 memcpy(data + offset, continuationState, continuationStateLen);
345 offset += continuationStateLen;
346
347 // uint16_t paramLength
348 net_store_16(data, 3, offset - 5);
348 big_endian_store_16(data, 3, offset - 5);
349
350 return offset;
351}
352
353
354static uint16_t setup_service_attribute_request(uint8_t * data){
355
356 uint16_t offset = 0;
357 transactionID++;
358 // uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
359 data[offset++] = SDP_ServiceAttributeRequest;
360 // uint16_t transactionID
349
350 return offset;
351}
352
353
354static uint16_t setup_service_attribute_request(uint8_t * data){
355
356 uint16_t offset = 0;
357 transactionID++;
358 // uint8_t SDP_PDU_ID_t.SDP_ServiceSearchRequest;
359 data[offset++] = SDP_ServiceAttributeRequest;
360 // uint16_t transactionID
361 net_store_16(data, offset, transactionID);
361 big_endian_store_16(data, offset, transactionID);
362 offset += 2;
363
364 // param legnth
365 offset += 2;
366
367 // parameters:
368 // ServiceRecordHandle
362 offset += 2;
363
364 // param legnth
365 offset += 2;
366
367 // parameters:
368 // ServiceRecordHandle
369 net_store_32(data, offset, serviceRecordHandle);
369 big_endian_store_32(data, offset, serviceRecordHandle);
370 offset += 4;
371
372 // MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu
370 offset += 4;
371
372 // MaximumAttributeByteCount - uint16_t 0x0007 - 0xffff -> mtu
373 net_store_16(data, offset, mtu);
373 big_endian_store_16(data, offset, mtu);
374 offset += 2;
375
376 // AttibuteIDList
377 uint16_t attributeIDListLen = de_get_len(attributeIDList);
378 memcpy(data + offset, attributeIDList, attributeIDListLen);
379 offset += attributeIDListLen;
380
381 // ContinuationState - uint8_t number of cont. bytes N<=16
382 data[offset++] = continuationStateLen;
383 // - N-bytes previous response from server
384 memcpy(data + offset, continuationState, continuationStateLen);
385 offset += continuationStateLen;
386
387 // uint16_t paramLength
374 offset += 2;
375
376 // AttibuteIDList
377 uint16_t attributeIDListLen = de_get_len(attributeIDList);
378 memcpy(data + offset, attributeIDList, attributeIDListLen);
379 offset += attributeIDListLen;
380
381 // ContinuationState - uint8_t number of cont. bytes N<=16
382 data[offset++] = continuationStateLen;
383 // - N-bytes previous response from server
384 memcpy(data + offset, continuationState, continuationStateLen);
385 offset += continuationStateLen;
386
387 // uint16_t paramLength
388 net_store_16(data, 3, offset - 5);
388 big_endian_store_16(data, 3, offset - 5);
389
390 return offset;
391}
392
393static void parse_service_search_response(uint8_t* packet){
394 uint16_t offset = 3;
389
390 return offset;
391}
392
393static void parse_service_search_response(uint8_t* packet){
394 uint16_t offset = 3;
395 uint16_t parameterLength = READ_NET_16(packet,offset);
395 uint16_t parameterLength = big_endian_read_16(packet,offset);
396 offset+=2;
397
396 offset+=2;
397
398 uint16_t totalServiceRecordCount = READ_NET_16(packet,offset);
398 uint16_t totalServiceRecordCount = big_endian_read_16(packet,offset);
399 offset+=2;
400
399 offset+=2;
400
401 uint16_t currentServiceRecordCount = READ_NET_16(packet,offset);
401 uint16_t currentServiceRecordCount = big_endian_read_16(packet,offset);
402 offset+=2;
403 if (currentServiceRecordCount > totalServiceRecordCount){
404 log_error("CurrentServiceRecordCount is larger then TotalServiceRecordCount.");
405 return;
406 }
407
408 parse_service_record_handle_list(packet+offset, totalServiceRecordCount, currentServiceRecordCount);
409 offset+=(currentServiceRecordCount * 4);

--- 9 unchanged lines hidden (view full) ---

419
420 if (parameterLength != offset - 5){
421 log_error("Error parsing ServiceSearchResponse: wrong size of parameters, number of expected bytes%u, actual number %u.", parameterLength, offset);
422 }
423}
424
425static void parse_service_attribute_response(uint8_t* packet){
426 uint16_t offset = 3;
402 offset+=2;
403 if (currentServiceRecordCount > totalServiceRecordCount){
404 log_error("CurrentServiceRecordCount is larger then TotalServiceRecordCount.");
405 return;
406 }
407
408 parse_service_record_handle_list(packet+offset, totalServiceRecordCount, currentServiceRecordCount);
409 offset+=(currentServiceRecordCount * 4);

--- 9 unchanged lines hidden (view full) ---

419
420 if (parameterLength != offset - 5){
421 log_error("Error parsing ServiceSearchResponse: wrong size of parameters, number of expected bytes%u, actual number %u.", parameterLength, offset);
422 }
423}
424
425static void parse_service_attribute_response(uint8_t* packet){
426 uint16_t offset = 3;
427 uint16_t parameterLength = READ_NET_16(packet,offset);
427 uint16_t parameterLength = big_endian_read_16(packet,offset);
428 offset+=2;
429
430 // AttributeListByteCount <= mtu
428 offset+=2;
429
430 // AttributeListByteCount <= mtu
431 uint16_t attributeListByteCount = READ_NET_16(packet,offset);
431 uint16_t attributeListByteCount = big_endian_read_16(packet,offset);
432 offset+=2;
433
434 if (attributeListByteCount > mtu){
435 log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in found attribute list is larger then the MaximumAttributeByteCount.");
436 return;
437 }
438
439 // AttributeLists

--- 38 unchanged lines hidden ---
432 offset+=2;
433
434 if (attributeListByteCount > mtu){
435 log_error("Error parsing ServiceSearchAttributeResponse: Number of bytes in found attribute list is larger then the MaximumAttributeByteCount.");
436 return;
437 }
438
439 // AttributeLists

--- 38 unchanged lines hidden ---