Why is the MTU different for With Response vs Without Response? - ios

On iOS when I request the MTU I get different values for .withoutResponse vs .withResponse. I realize it could be different since the function takes that parameter, but why is it different?
Here's on device (BLE 4.2):
(lldb) po peripheral.maximumWriteValueLength(for: .withoutResponse)
182
(lldb) po peripheral.maximumWriteValueLength(for: .withResponse)
512
On another device (BLE 5) I get:
(lldb) po peripheral.maximumWriteValueLength(for: .withoutResponse)
509
(lldb) po peripheral.maximumWriteValueLength(for: .withResponse)
512

Write Without Response is directly related to the MTU. (MTU - 3).
When you use writeWithResponse, iOS can either perform a Write With Response (max value length is MTU - 3), or a "Write Long Characteristic Values", which uses several ATT transactions to write the value. In the latter case the only restricting factor is the maximum length of a characteristic value, which is set to 512 bytes by the standard.

Related

Write BLE gatt characteristic on Android — error status 255

Experimenting with sample kotlin program, trying to read/write BLE device with channels from 0-7
When reading it gives me value like this: (0x06)
onCharacteristicRead(), status=0, value=[uuid='ba7e7814-5b67-43d3-bd80-e72cc83ae801', hexValue=[06]]
but when trying to write same output it gives me, it gives me error GATT 255, out of range:
CharacteristicWriteOperation{MAC='00:A0:50:E8:78:86', characteristic=[uuid='ba7e7814-5b67-43d3-bd80-e72cc83ae801', hexValue=[30, 36]]}
onCharacteristicWrite(), status=255, value=[uuid='ba7e7814-5b67-43d3-bd80-e72cc83ae801']
What you read: [0x06]
onCharacteristicRead(), status=0, value=[uuid='ba7e7814-5b67-43d3-bd80-e72cc83ae801', hexValue=[06]]
What you wrote: [0x30, 0x36] (which may correspond to String "06" as ASCII hex value for '0' is 0x30 and for '6' is 0x36)
CharacteristicWriteOperation{MAC='00:A0:50:E8:78:86', characteristic=[uuid='ba7e7814-5b67-43d3-bd80-e72cc83ae801', hexValue=[30, 36]]}
You probably want to write back hexadecimal value 0x06, not the string "06"
Status 255 is GATT_OUT_OF_RANGE which means that the written value is outside of range accepted by your peripheral.

How to read a byte of the Serial Presence Detect (SPD) data from the DIMM after 255(FF) bytes?

I have got SMBus Base Address Register,
and program the SMBus Transmit Slave Address Register with the DIMM SMBus address, SMBBASE 04h.
Then program the SMBus Host Command Register with the DIMM’s SPD data offset to be read, SMBBASE 03h.
But the Host Command Register (HCMD)—Offset 3h is Size: 8 bits(255/FF),
So How can I read the after 255 bytes?
For example:
DDR4 Serial Presence Detect (SPD) Table:
Byte 320 : Module Manufacturer ID Code
I need to read Byte 320.
My code like this
unsigned ReadByte(unsigned SMBase_addr,unsigned i)
{
unsigned val;
outportb(SMBase_addr,0x1e);
outportb(SMBase_addr 0x04,0xa7);
outportb(SMBase_addr 0x03,i);
outportb(SMBase_addr 0x02,0x48);
while((inportb(SMBase_addr))&0x01){
delay(10);
}
val=inportb(SMBase_addr 0x05);
return val;
}
for(i=0;i<383;i )
{
data=ReadByte(SMBase_addr,i);
printf("%4x",data);
}
and I change
outportb(SMBase_addr 0x03,i);
to
outportw(SMBase_addr 0x03,i);
Host Status Register return 0x44, Device Error (DERR).
At least in Linux PC,
You need to write SMBus address 0x37 first to reach page 1. (Let write 0 to SMbus addr 32)
Than ALL of your DDR4 RAM SPD switches to Page 1.
Just use regular functions for writing & reading required addresses.
Than switch to page 0 by writing SMBus address 0x36 after.
Trying to read DDR4 SPD?
They have 2 pages of 256 bytes each, and you need a dummy write to a special predefined address 0x6E to switch all SPD chips to page 1 (where your byte 320 is located), and than write to 0x6C switch them back to page 0 (to prevent an SPD read failure during next boot).
Read this datasheet on page 12 for more info.

SP605 Spartan 6 DDR3 addressing

the following post is quite long, but since I have had trouble making the SP605 board properly interact with the DDR3 for over a month now, hopefully this will be useful to others in the same situation as I find myself in. I am pretty certain it's a simple configuration or conceptual error, but I would be more than happy to have this resolved soon.
=== SCENARIO ===
I have created a USB-UART interface to communicate with the FPGA and control the DDR3. Using the IP generator in ISE, I generated a MIG wrapper and then I designed the memory interface controller. However, I have referenced manuals ug388 and ug416, but I have not been able to have the DDR3 behave as expected.
=== PROBLEM STATEMENT ===
Playing around with the burst lengths for write and read commands, I am able to get data back from the DDR3, yet the addressing scheme does not seem to be correct as data is duplicated in addresses 0 and 1, 2 and 3, 4 and 5, and so forth. Also, whenever I write into address 0, for example, nothing changes. Then, when I write into address 1, both addresses 0 and 1 are updated with the data value I just sent. It seems I am "losing" half of the memory space due to this coupled effect.
=== DDR3 IP CONFIGURATION ===
The setup for the DDR3 using the IP generator – considering the SP605 board scenario – is listed below. In sum, I activated the DDR3 Bank 3 and configured Port0 to be 32-bit bidirectional.
Memory selection:
Enable AXI interface: unchecked
Use extended MCB performance range: unchecked
Memory type for bank 3: DDR3 SDRAM
Memory type for bank 1: none
Options for C3 – DDR3 SDRAM
Frequency: 400 MHz
Memory part: MTJ41J64M16XX-187E
Memory options for C3 – DDR3 SDRAM
Output driver impedance control: RZQ/6
RTT (nominal) – ODT: RZQ/4
Auto self refresh: enabled
Port configuration for C3 – DDR3 SDRAM
Two 32-bit bi-directional and four 32-bit unidirectional ports
Port0: checked
Port1: unchecked
Port2: unchecked
Port3: unchecked
Port4: unchecked
Port5: unchecked
Memory address mapping selection: row-bank-column
FPGA options for C3 – DDR3 SDRAM
Memory interface pin termination: Calibrated input termination
Select RZQ pin location: R7
Select ZIO pin location: W4
Debug signals for memory controller: disable
System clock: differential
=== DATA STRUCTURE ===
From Matlab, I send in a 64-bit command which should write or read the DDR3 based on the address and data provided in this command.
wire [00:00] cmd_instruction = usb_data[63:63]; // ‘0’ = write; ‘1’ = read
wire [27:00] cmd_address = usb_data[62:37]; // 26-bit address
wire [31:00] cmd_data = usb_data[31:00]; // 32-bit data
In ug388, the following can be extracted:
Page 20: The address is 26 bits wide.
C_MEM_ADDR_WIDTH = 13
C_MEM_BANKADDR_WIDTH = 3
C_MEM_NUM_COL_BITS = 10
C_P0_DATA_PORT_SIZE = 32 // 32-bit data ports
C_P0_MASK_SIZE = 4 // 4 bytes = 32 bits (1 mask bit = 1 entire data byte)
Pages 26-27: Command data structure.
pX_cmd_addr[29:0]: 30-bit address, however the last two bits should = “00” since every word (32 bits) is formed by 4 bytes.
pX_cmd_bl[5:0]: Burst length of 1 is obtained by setting this signal to 0.
pX_cmd_instr[2:0]: The only command instructions used are write=”000” and read=”001”.
Page 28: Write data structure.
pX_wr_mask[PX_MASKSIZE-1:0]: 4-bit mask is set to “0000” so that all 4 bytes are always written into the memory.
=== SIGNAL ASSIGNMENTS ===
Using all this information, I assigned my signals in the following manner:
assign p0_mcb_cmd_instr = {2'b00, cmd_instruction};
assign p0_mcb_cmd_addr = {2’d0, cmd_address, 2'd0};
assign p0_mcb_cmd_bl = 6'd0;
assign p0_mcb_wr_data = cmd_data;
assign p0_mcb_wr_mask = 4'd0;
localparam C3_MEM_BURST_LEN = 8;
=== CONCLUSIONS ===
Based on the configuration, does anyone know what the expected behavior of my controller should be?
If any additional information is necessary for clarification, please let me know.
Thanks a lot,
Bruno.

CoreBluetooth: number of bytes sent != number of bytes received

I have an app that is acting as a peripheral and another app that is acting as a central.
The central app is reading a characteristic on the peripheral:
[self.service.peripheral readValueForCharacteristic:self.packetCharacteristic]
The peripheral handles the request as such:
- (void)peripheralManager:(CBPeripheralManager *)manager didReceiveWriteRequests:(NSArray *)requests
{
for (CBATTRequest *request in requests)
{
if ([request.characteristic.UUID isEqual:self.service.packetCharacteristic.UUID])
{
NSData *value = self.packets[0]; // This value's length logs at 512 bytes, tested 500 bytes too
request.value = value;
[self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
}
}
}
The size of NSData *value is equal to 512 bytes. Note that I have also tested this with 500 bytes.
The central then receives the the delegate call as such:
- (void)didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (characteristic == self.packetCharacteristic)
{
NSLog(#"PACKET RECEIVED: %lu bytes", (unsigned long)characteristic.value.length);
}
}
The NSLog statement states that the value received is 536 bytes regardless of if I send 500 or 512 bytes. The bytes sent and the bytes received are identical until about a quarter of the way through (by looking at the HEX value provided by Xcode), the rest of the bytes are completely different.
The questions are as follows:
1. Why am I receiving more bytes than I have sent?
2. What are these bytes? What do they represent?
3. Where can I find documentation on this? I have reviewed the CoreBluetooth docs/guides over and over and can't find anything indicating that this could happen.
4. Could this be related to endianness?
EDIT #1
Ok, so I have done a little bit more testing and found out the following...
The MTU seems to be 134 bytes (from iOS to iOS). As soon as the data being sent is equal or bigger than 134 bytes, CoreBluetooth is calling peripheralManager:didReceiveReadRequest: 4 times.
My assumption is that because the data being sent is at least equal to the MTU, CoreBluetooth doesn't know whether or not it is done sending all the data. Therefore it calls peripheralManager:didReceiveReadRequest: N number of times until N x MTU covers the maximum possible size of a characteristic's value (512 bytes). In my particular case, 4 x 134 bytes equals the magical 536 bytes.
Note that the request's offset is being updated every time, in my particular case, 0, 134, 268, 402.
Edit #2
Ok, figured it out.
I was semi-right in my assumption. CoreBluetooth calls peripheralManager:didReceiveReadRequest: N time until the data being sent is smaller than the MTU. If the data being sent is equal or larger than the MTU, CoreBluetooth will keep calling peripheralManager:didReceiveReadRequest: until it N x MTU covers the max size (512 bytes). If the data % MTU == 0 then peripheralManager:didReceiveReadRequest: will be called one last time where you have to return 0 bytes.
Answering my own question.
Look at edit #2.

Scapy - retrieving RSSI from WiFi packets

I'm trying to get RSSI or signal strength from WiFi packets.
I want also RSSI from 'WiFi probe requests' (when somebody is searching for a WiFi hotspots).
I managed to see it from kismet logs but that was only to make sure it is possible - I don't want to use kismet all the time.
For 'full time scanning' I'm using scapy. Does anybody know where can I find the RSSI or signal strength (in dBm) from the packets sniffed with scapy? I don't know how is the whole packet built - and there are a lot of 'hex' values which I don't know how to parse/interpret.
I'm sniffing on both interfaces - wlan0 (detecting when somebody connects to my hotspot), and mon.wlan0 (detecting when somebody is searching for hotspots).
Hardware (WiFi card) I use is based on Prism chipset (ISL3886). However test with Kismet was ran on Atheros (AR2413) and Intel iwl4965.
Edit1:
Looks like I need to access somehow information stored in PrismHeader:
http://trac.secdev.org/scapy/browser/scapy/layers/dot11.py
line 92 ?
Anybody knows how to enter this information?
packet.show() and packet.show2() don't show anything from this Class/Layer
Edit2:
After more digging it appears that the interface just isn't set correctly and that's why it doesn't collect all necessary headers.
If I run kismet and then sniff packets from that interface with scapy there is more info in the packet:
###[ RadioTap dummy ]###
version= 0
pad= 0
len= 26
present= TSFT+Flags+Rate+Channel+dBm_AntSignal+Antenna+b14
notdecoded= '8`/\x08\x00\x00\x00\x00\x10\x02\x94\t\xa0\x00\xdb\x01\x00\x00'
...
Now I only need to set the interface correctly without using kismet.
Here is a valuable scapy extension that improves scapy.layers.dot11.Packet's parsing of present not decoded fields.
https://github.com/ivanlei/airodump-iv/blob/master/airoiv/scapy_ex.py
Just use:
import scapy_ex
And:
packet.show()
It'll look like this:
###[ 802.11 RadioTap ]###
version = 0
pad = 0
RadioTap_len= 18
present = Flags+Rate+Channel+dBm_AntSignal+Antenna+b14
Flags = 0
Rate = 2
Channel = 1
Channel_flags= 160
dBm_AntSignal= -87
Antenna = 1
RX_Flags = 0
To summarize:
signal strength was not visible because something was wrong in the way that 'monitor mode' was set (not all headers were passed/parsed by sniffers). This monitor interface was created by hostapd.
now I'm setting monitor mode on interface with airmon-ng - tcpdump, scapy show theese extra headers.
Edited: use scapy 2.4.1+ (or github dev version). Most recent versions now correctly decode the « notdecoded » part
For some reason the packet structure has changed. Now dBm_AntSignal is the first element in notdecoded.
I am not 100% sure of this solution but I used sig_str = -(256 - ord(packet.notdecoded[-2:-1])) to reach first element and I get values that seems to be dBm_AntSignal.
I am using OpenWRT in a TP-Link MR3020 with extroot and Edward Keeble Passive Wifi Monitoring project with some modifications.
I use scapy_ex.py and I had this information:
802.11 RadioTap
version = 0
pad = 0
RadioTap_len= 36
present = dBm_AntSignal+Lock_Quality+b22+b24+b25+b26+b27+b29
dBm_AntSignal= 32
Lock_Quality= 8
If someone still has the same issue, I think I have found the solution:
I believe this is the right cut for the RSSI value:
sig_str = -(256-ord(packet.notdecoded[-3:-2]))
and this one is for the noise level:
noise_str = -(256-ord(packet.notdecoded[-2:-1]))
The fact that it says "RadioTap" suggests that the device may supply Radiotap headers, not Prism headers, even though it has a Prism chipset. The p54 driver appears to be a "SoftMAC driver", in which case it'll probably supply Radiotap headers; are you using the p54 driver or the older prism54 driver?
I have similar problem, I set up the monitor mode with airmon-ng and I can see the dBm level in tcpdump but whenever I try the sig_str = -(256-ord(packet.notdecoded[-4:-3])) I get -256 because the returned value from notdecoded in 0. Packet structure looks like this.
version = 0
pad = 0
len = 36
present = TSFT+Flags+Rate+Channel+dBm_AntSignal+b14+b29+Ext
notdecoded= ' \x08\x00\x00\x00\x00\x00\x00\x1f\x02\xed\x07\x05
.......

Resources