Mifare read APDU command recived 63 00 - nfc

All!
I'm trying to read data from mifare card 1k.
to get ID
I send: 0xFF 0xCA 0x00 0x00 0x00
Recive: 0x00 0x00 0x00 0x00 0x00 0x00 - ??? it's normal?
to load auth key to reader
I send: 0xFF 0x82 0x00 0x00 0x06 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
Recive: 90 00 - it's ok
to authenticate in block 01
I send: 0xFF 0x86 0x00 0x00 0x05 0x01 0x00 0x01 0x60 0x00
Recive: 90 00 - it's ok
to read data from block 01
I send: 0xFF 0xB0 0x00 0x01 0x0F
Recive: 63 00 - how a understand it's authentication error
I can't understand - why?
My code:
#include "stdafx.h"
#include "Winscard.h"
LPTSTR pmszReaders = NULL;
LPTSTR pmszCards = NULL;
LPTSTR pReader;
LPTSTR pCard;
LONG lReturn, lReturn2;
DWORD cch = SCARD_AUTOALLOCATE;
SCARDCONTEXT hSC;
SCARD_READERSTATE readerState;
LPCTSTR readerName = L"ACS ACR1222 1S Dual Reader 0";
SCARDHANDLE hCardHandle;
DWORD dwAP;
BYTE pbRecv[50];
DWORD dwRecv;
BYTE cmdGetData[] = {0xFF, 0xCA, 0x00, 0x00, 0x00};
BYTE cmdLoadKey[] = {0xFF, 0x82, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
BYTE cmdAuthBlock01[] = {0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, 0x01, 0x60, 0x00};
BYTE cmdReadBlock01[] = {0xFF, 0xB0, 0x00, 0x01, 0x0F};
int _tmain(int argc, _TCHAR* argv[]) {
lReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hSC);
if ( SCARD_S_SUCCESS != lReturn )
printf("Failed SCardEstablishContext\n");
else {
lReturn = SCardListReaders(hSC, NULL, (LPTSTR)&pmszReaders, &cch );
if (lReturn != SCARD_S_SUCCESS) {
printf("Failed SCardListReaders\n");
} else {
pReader = pmszReaders;
while ( '\0' != *pReader ) {
printf("Reader: %S\n", pReader );
pReader = pReader + wcslen((wchar_t *)pReader) + 1;
}
}
memset(&readerState,0,sizeof(readerState));
readerState.szReader = pmszReaders;
lReturn = SCardConnect( hSC, pmszReaders, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCardHandle, &dwAP );
if ( SCARD_S_SUCCESS != lReturn ) {
printf("Failed SCardConnect\n");
system("pause");
exit(1);
} else {
printf("Success SCardConnect\n");
switch ( dwAP ) {
case SCARD_PROTOCOL_T0:
printf("Active protocol T0\n");
break;
case SCARD_PROTOCOL_T1:
printf("Active protocol T1\n");
break;
case SCARD_PROTOCOL_UNDEFINED:
default:
printf("Active protocol unnegotiated or unknown\n");
break;
}
}
lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdGetData, sizeof(cmdGetData), NULL, pbRecv, &dwRecv);
if ( SCARD_S_SUCCESS != lReturn ) {
printf("Failed SCardTransmit\n");
} else {
printf("Success SCardTransmit\n");
printf("Read %u bytes\n", dwRecv);
for(byte i=0;i<dwRecv;i++) {
printf("%x ", pbRecv[i]);
}
printf("\n");
}
lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdLoadKey, sizeof(cmdLoadKey), NULL, pbRecv, &dwRecv);
if ( SCARD_S_SUCCESS != lReturn ) {
printf("Failed SCardTransmit\n");
} else {
printf("Success SCardTransmit\n");
printf("Read %u bytes\n", dwRecv);
for(byte i=0;i<dwRecv;i++) {
printf("%x ", pbRecv[i]);
}
printf("\n");
}
lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdAuthBlock01, sizeof(cmdAuthBlock01), NULL, pbRecv, &dwRecv);
if ( SCARD_S_SUCCESS != lReturn ) {
printf("Failed SCardTransmit\n");
} else {
printf("Success SCardTransmit\n");
printf("Read %u bytes\n", dwRecv);
for(byte i=0;i<dwRecv;i++) {
printf("%x ", pbRecv[i]);
}
printf("\n");
}
lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdReadBlock01, sizeof(cmdReadBlock01), NULL, pbRecv, &dwRecv);
if ( SCARD_S_SUCCESS != lReturn ) {
printf("Failed SCardTransmit\n");
} else {
printf("Success SCardTransmit\n");
printf("Read %u bytes\n", dwRecv);
for(byte i=0;i<dwRecv;i++) {
printf("%x ", pbRecv[i]);
}
printf("\n");
}
}
lReturn = SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
if ( SCARD_S_SUCCESS != lReturn ) {
printf("Failed SCardDisconnect\n");
} else {
printf("Success SCardDisconnect\n");
}
system("pause");
return 0;
}
Can anyone explain why i got 63 00?
Thanks.

Afair your read command has to be: "0xFF, 0xB0, 0x00, BLOCK, 0x10". You send buffer length 0F - which is decimal 15 - but you have to read 16 Byte, which is 0x10.
Hope this helps

In Mifare Classic 1K tags There are 16 Sectors and each Sectors contains 4 Blocks and each block contains 16 bytes.
Sector 0 contains Block (0,1,2,3)
Sector 1 contains Block (4,5,6,7)
Sector 2 contains Block (8,9,10,11)
Sector 3 contains Block (12,13,14,15)....
Before Reading or writing from a block You must have to Authenticate its corresponding Sector using Key A or Key B of that sector. When Authentication is complete then you can read or write.
using this command you can authenticate sector 0 using KEY A(60)
byte[] authenticationByte = new byte[10];
authenticationByte = new byte[] { (byte) 0xFF, (byte) 0x86, (byte) 0x00,
(byte) 0x00, (byte) 0x05, (byte) 0x00,(byte) 0x00, (byte) 0x04,
(byte) 0x60,(byte) 0x00 };
When Authentication is succes then you will get 90 00. That is Success message. Else response is 63 00 , that means authentication failed. When Authentication complete then you can read block (0,1,2,3) cause sector 0 contains 4 block and those are block (0,1,2,3).
Here your problem is you are authenticating Sector 1 but trying to read data from Sector 0's blocks.
For more details you can read this Answer.
Sorry for bad English

Related

Only one IRQ comes in upon initializing IDT

I am trying to work on an x86 operating system and coding it in C. My OS uses GRUB-Multiboot and thus far I have been able to get a GDT working.
I am currently working on my IDT and have run into a problem. When my OS boots up, it receives one IRQ and no further ones. I do have the keyboard line enabled and I should be receiving IRQs from that whenever I click a key but this is not the case.
What comes up upon startup:
Here is the code for idt.c:
#include <stdint.h>
#include "idt.h"
#include "lib/stdio.h"
#include "include/io.h"
// Define the Interrupt Descriptor Table (IDT)
struct idt_entry_t idt[IDT_ENTRIES];
struct idt_entry_t idt_entries[IDT_ENTRIES];
// Load the IDT pointer
struct idt_ptr_t idt_ptr = {
.limit = sizeof(idt) - 1,
.base = (uint32_t)&idt
};
typedef struct registers {
uint32_t ds; // Data segment selector
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha
uint32_t int_no, err_code; // Interrupt number and error code (if applicable)
uint32_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically
} registers_t;
// Define an IRQ handler function
void irq_handler(registers_t *regs)
{
nanos_printf("Received an IRQ!\n");
// Send an EOI (end-of-interrupt) signal to the PICs
outb(0xA0, 0x20); // Send reset signal to slave
outb(0x20, 0x20); // Send reset signal to master
return;
}
void isr_handler()
{
nanos_printf("\n\nSTOP\n\nException occurred... halting...");
// Halt the CPU
for (;;);
}
void idt_load()
{
asm volatile("lidt %0" : : "m"(idt_ptr));
}
void idt_init(void)
{
// Disable interrupts
__asm__ __volatile__("cli");
// Setup the PIC(s)
outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, 0x20);
outb(0xA1, 0x28);
outb(0x21, 0x04);
outb(0x21, 0x01);
outb(0x21, 0xFB);
outb(0xA1, 0xFF);
// Print a message to indicate that IDT is being loaded
nanos_printf("Loading IDT\n");
// Initialize the IDT pointer
idt_ptr.limit = sizeof(idt) - 1;
idt_ptr.base = (uint32_t)&idt;
// Set each IDT entry to the default handler
for (int i = 0; i < IDT_ENTRIES; i++)
{
idt_set_gate(i, (uint32_t)isr_handler, 0x08, 0x8E);
}
// Set the IRQ entries in the IDT
idt_set_gate(32, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(33, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(34, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(35, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(36, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(37, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(38, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(39, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(40, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(41, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(42, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(43, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(44, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(45, (uint32_t)irq_handler, 0x08, 0x8E);
// Send initialization control word 1 and 2 to both PICs
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // Initialization Control Word 1
io_wait();
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
io_wait();
// Send initialization control word 3 to both PICs
outb(PIC1_DATA, 0x20); // Initialization Control Word 3: IRQ 0-7 map to IDT entries 0x20-0x27
io_wait();
outb(PIC2_DATA, 0x28); // Initialization Control Word 3: IRQ 8-15 map to IDT entries 0x28-0x2F
io_wait();
// Send initialization control word 4 to both PICs
outb(PIC1_DATA, ICW4_8086);
io_wait();
outb(PIC2_DATA, ICW4_8086);
io_wait();
// Unmask IRQs
outb(PIC1_DATA, 0x0);
outb(PIC2_DATA, 0x0);
// Load IDT
idt_load();
// Enable interrupts
__asm__ __volatile__("sti");
nanos_printf("IDT loaded\n");
}
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
{
// Set the base address
idt[num].base_lo = base & 0xFFFF;
idt[num].base_hi = (base >> 16) & 0xFFFF;
// Set the selector
idt[num].sel = sel;
// Set the always0 field
idt[num].always0 = 0;
// Set the flags
idt[num].flags = flags;
}
And here is idt.h:
#ifndef IDT_H
#define IDT_H
#include <stdint.h>
// Number of entries in the IDT
#define IDT_ENTRIES 256
// Struct for IDT entry
struct idt_entry_t {
uint16_t base_lo; // Lower 16 bits of handler function address
uint16_t sel; // Kernel segment selector
uint8_t always0; // Must always be zero
uint8_t flags; // Flags for entry (present, privilege level, type)
uint16_t base_hi; // Upper 16 bits of handler function address
} __attribute__((packed));
// Struct for IDT pointer
struct idt_ptr_t {
uint16_t limit; // Size of IDT
uint32_t base; // Base address of IDT
} __attribute__((packed));
// Define macros for setting flags in IDT entries
#define IDT_PRESENT_BIT 0x80
#define IDT_RING0 0x00
#define IDT_RING3 0x60
#define IDT_INT_GATE 0x0E
#define IDT_TRAP_GATE 0x0F
#define IDT_SIZE 0x08
// Define an IRQ handler function
void irq_handler();
// Define an ISR handler function
void isr_handler();
// Define a function to load the IDT
void idt_load();
// Define a function to initialize the IDT
void idt_init(void);
// Define a function to set a gate in the IDT
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags);
#endif // IDT_H
The issue seems to lie within the IRQ handler itself not returning. I do send reset signals to both the master and slave PIC inside of irq_handler() which is inside of idt.c.
And yes, I do have an infinite loop at the end of my kernel_main():
void kernel_main(void)
{
clear_screen();
nanos_printf("Hello NanOS!\n");
gdt_init();
nanos_printf("Initialized Global Descriptor Table.\n");
idt_init();
nanos_printf("Initialized Interrupt Descriptor Table.\n");
while (true) {}
}
Problem:
I tried to click keys on the keyboard to receive a keyboard IRQ but I only receive one IRQ at the start. I dabbled in OSDEV a few years back and from what I remember the PICs receive more than one IRQ upon startup anyways.

IsoDep Tag send always 0x0B as result for all APDUs

I've a problem with my MobiGo2F terminal.
The Android system version is 10. When I send APDUs to my smartcard,
I always receive 0B as result. Find below my code:
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Tag tagI = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
byte[] serial=intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
Log.v("SN : ", Utils.bytesToHex(serial));
assert tagI != null;
byte[] payload = detectTagData(tagI).getBytes();
IsoDep tag = IsoDep.get(tagI);
byte[] APDU = {
(byte) 0x00, // CLA Class
(byte) 0x84, // INS Instruction
(byte) 0x00, // P1 Parameter 1
(byte) 0x00, // P2 Parameter 2
(byte) 0x08 // LE maximal number of bytes expected in result
};
byte[] result = new byte[0];
try {
tag.connect();
tag.setTimeout(10000);
result = tag.transceive(APDU);
Log.v("result =", Utils.bytesToHex(result) + " & lenght = " + result.length);
} catch (Exception e) {
e.printStackTrace();
}
}
The result that I got is:
Result
I received 0B for any APDUs that I send. Normally, ISO7816 describe APDU response as 2 bytes, SW1 and SW2.
Need your support and enjoy Code!

Analog measurement incorrect on Teensy 2.0++

I have a Joystick wired up to my Teensy 2.0++ and I want to read the analog values from it.
I took this implementation from PJRC:
static uint8_t aref = (1<<REFS0); // default to AREF = Vcc, this is a 5V Vcc Teensy
void analogReference(uint8_t mode)
{
aref = mode & 0xC0;
}
// Mux input
int16_t adc_read(uint8_t mux)
{
#if defined(__AVR_AT90USB162__)
return 0;
#else
uint8_t low;
ADCSRA = (1<<ADEN) | ADC_PRESCALER; // enable ADC
ADCSRB = (1<<ADHSM) | (mux & 0x20); // high speed mode
ADMUX = aref | (mux & 0x1F); // configure mux input
ADCSRA = (1<<ADEN) | ADC_PRESCALER | (1<<ADSC); // start the conversion
while (ADCSRA & (1<<ADSC)) ; // wait for result
low = ADCL; // must read LSB first
return (ADCH << 8) | low; // must read MSB only once!
#endif
}
// Arduino compatible pin input
int16_t analogRead(uint8_t pin)
{
#if defined(__AVR_ATmega32U4__)
static const uint8_t PROGMEM pin_to_mux[] = {
0x00, 0x01, 0x04, 0x05, 0x06, 0x07,
0x25, 0x24, 0x23, 0x22, 0x21, 0x20};
if (pin >= 12) return 0;
return adc_read(pgm_read_byte(pin_to_mux + pin));
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
if (pin >= 8) return 0;
return adc_read(pin);
#else
return 0;
#endif
}
I have my X and Y pins wired up to F1 and F0, and I want to retrieve values with the following code:
long map(long x, long in_min, long in_max, long out_min, long out_max) // map method shamelessy ripped from Arduino
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
joy_ly = map(analogRead(0), 0, 65535, 0, 255);
joy_lx = map(analogRead(1), 0, 65535, 0, 255);
I measured my Joystick with a multimeter and it works perfectly (around 2.43V on center, 0V on min, and 5V on max), but the center value always ends up being very close to zero.
Is there anything I'm doing wrong?
NOTE: This is an at90usb1286 chip.
The ADC max value is 1024, not 65535.

crc16 implementation java

I am having problems with calculating CRC-16 implementation of a byte array in java. Basically I am trying to send bytes to a RFID that starts writing to a tag. I can see the checksum value of array by looking tcpdump command on mac. But my goal is to generate it by myself. Here is my byte array which should generate 0xbe,0xd9:
byte[] bytes = new byte[]{(byte) 0x55,(byte) 0x08,(byte) 0x68, (byte) 0x14,
(byte) 0x93, (byte) 0x01, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06,
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00,
(byte) 0x13, (byte) 0x50, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x22, (byte) 0x09, (byte) 0x11};
0x55 is the header. As the documentation says it will be excluded.
Whenever I try this array on java (with 0xbe,0xd9), RFID works. My problem is the generating of those checksum values. I searched almost entire web but no chance. I couldn't find any algorithm that produces 0xbe,0xd9.
Any idea is most welcome for me. Thanks in advance.
edit: here is the protocol that provided with rfid
I'm not really sure if this is the correct translation in Java of the C crc16 algorithm....
but it shows the correct result for your example!
Please compare other results with Mac's CRC16 and stress-test it before using it.
public class Crc16 {
public static void main(String... a) {
byte[] bytes = new byte[] { (byte) 0x08, (byte) 0x68, (byte) 0x14, (byte) 0x93, (byte) 0x01, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x01,
(byte) 0x00, (byte) 0x13, (byte) 0x50, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x22, (byte) 0x09,
(byte) 0x11 };
byte[] byteStr = new byte[4];
Integer crcRes = new Crc16().calculate_crc(bytes);
System.out.println(Integer.toHexString(crcRes));
byteStr[0] = (byte) ((crcRes & 0x000000ff));
byteStr[1] = (byte) ((crcRes & 0x0000ff00) >>> 8);
System.out.printf("%02X\n%02X", byteStr[0],byteStr[1]);
}
int calculate_crc(byte[] bytes) {
int i;
int crc_value = 0;
for (int len = 0; len < bytes.length; len++) {
for (i = 0x80; i != 0; i >>= 1) {
if ((crc_value & 0x8000) != 0) {
crc_value = (crc_value << 1) ^ 0x8005;
} else {
crc_value = crc_value << 1;
}
if ((bytes[len] & i) != 0) {
crc_value ^= 0x8005;
}
}
}
return crc_value;
}
}
There is a CRC16 implementation in the Java runtime (rt.jar) already.
Please see grepcode for the source.
You will probably be able to see it in your IDE if you search for CRC16:
Maybe are you looking for this?
Crc16 in java
I use the same array (variable "table") in this method:
public Integer computeCrc16(byte[] data) {
int crc = 0x0000;
for (byte b : data) {
crc = (crc >>> 8) ^ table[((crc ^ b) & 0xff)];
}
return (int) crc;
}
if you want ASCII character then change
byte[] bytes="02303131313233343031303345303903".getBytes();
Below is correct answer for HEX input ,
byte[] bytes = hexStringToByteArray("02303131313233343031303345303903");
public class CRC16 {
public static void main(String[] args) {
int[] table = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040,
};
byte[] bytes = hexStringToByteArray("02303131313233343031303345303903"); // for HEX
int crc16 = 0x0000;
for (byte b : bytes) {
crc16=table[(crc16 ^ b) & 0xff] ^ (crc16 >> 8);
}
crc16= crc16 & 0xFFFF;
System.out.println("CRC16 = " +Integer.toHexString(crc16));
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
}

Binding numeric keypad keys with Emacs 24 and OS/X

I'm currently trying out the Git HEAD version of Emacs 24 on OS/X as described in this article:
http://www.viget.com/extend/emacs-24-rails-development-environment-from-scratch-to-productive-in-5-minu/
I'd like to bind some of the Macintosh extended keyboard numeric keypad keys to Emacs functions, but it doesn't seem to be working. When I do a "c-h k" to check the key details the key presses are not recognized. Ditto if I refer to them in a (global-set-key (kbd "kp-minus") ...) setting.
Is this an issue with using the development version of Emacs 24 or is it something about the Macintosh keyboard hardware and how Emacs sees it? Can anyone advise on the best way to go about this?
Thanks in advance,
Stu
I had the same issue with the keypad keys building emacs 24. The problem is the same with emacs 23. I patched the emacs 24 code as follows to correct the problem. Not sure this is a good solution but it works well enough for me.
index 91f0cbb..d537ee3 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
## -87,6 +87,7 ## static unsigned convert_ns_to_X_keysym[] =
NSBeginFunctionKey, 0x58,
NSSelectFunctionKey, 0x60,
NSPrintFunctionKey, 0x61,
+ NSClearLineFunctionKey, 0x0B,
NSExecuteFunctionKey, 0x62,
NSInsertFunctionKey, 0x63,
NSUndoFunctionKey, 0x65,
## -134,6 +135,35 ## static unsigned convert_ns_to_X_keysym[] =
0x1B, 0x1B /* escape */
};
+static unsigned convert_nskeypad_to_X_keysym[] =
+{
+ /* Arrow keys are both function and keypad keys */
+ NSLeftArrowFunctionKey, 0x51,
+ NSUpArrowFunctionKey, 0x52,
+ NSRightArrowFunctionKey, 0x53,
+ NSDownArrowFunctionKey, 0x54,
+
+ 0x41, 0xAE, /* KP_Decimal */
+ 0x43, 0xAA, /* KP_Multiply */
+ 0x45, 0xAB, /* KP_Add */
+ 0x4B, 0xAF, /* KP_Divide */
+ 0x4E, 0xAD, /* KP_Subtract */
+ 0x51, 0xBD, /* KP_Equal */
+ 0x52, 0xB0, /* KP_0 */
+ 0x53, 0xB1, /* KP_1 */
+ 0x54, 0xB2, /* KP_2 */
+ 0x55, 0xB3, /* KP_3 */
+ 0x56, 0xB4, /* KP_4 */
+ 0x57, 0xB5, /* KP_5 */
+ 0x58, 0xB6, /* KP_6 */
+ 0x59, 0xB7, /* KP_7 */
+ 0x5B, 0xB8, /* KP_8 */
+ 0x5C, 0xB9, /* KP_9 */
+
+ // The enter key is on the keypad but modifier isnt set
+ NSEnterCharacter, 0x8D
+};
+
static Lisp_Object Qmodifier_value;
Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone;
## -1924,13 +1954,33 ## ns_convert_key (unsigned code)
unsigned keysym;
/* An array would be faster, but less easy to read. */
for (keysym = 0; keysym < last_keysym; keysym += 2)
- if (code == convert_ns_to_X_keysym[keysym])
- return 0xFF00 | convert_ns_to_X_keysym[keysym+1];
+
+ if (code == convert_ns_to_X_keysym[keysym]) {
+ return 0xFF00 | convert_ns_to_X_keysym[keysym+1];
+ }
return 0;
/* if decide to use keyCode and Carbon table, use this line:
return code > 0xff ? 0 : 0xFF00 | ns_keycode_to_xkeysym_table[code]; */
}
+static unsigned
+ns_convert_keypad (unsigned code)
+/* --------------------------------------------------------------------------
+ Internal call used by NSView-keyDown.
+ -------------------------------------------------------------------------- */
+{
+ const unsigned last_keysym = (sizeof (convert_nskeypad_to_X_keysym)
+ / sizeof (convert_nskeypad_to_X_keysym[0]));
+ unsigned keysym;
+ /* An array would be faster, but less easy to read. */
+ for (keysym = 0; keysym < last_keysym; keysym += 2) {
+ if (code == convert_nskeypad_to_X_keysym[keysym]) {
+ return 0xFF00 | convert_nskeypad_to_X_keysym[keysym+1];
+ }
+ }
+ return 0;
+}
+
char *
x_get_keysym_name (int keysym)
## -4503,10 +4553,10 ## ns_term_shutdown (int sig)
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe);
int code;
unsigned fnKeysym = 0;
- int flags;
static NSMutableArray *nsEvArray;
static BOOL firstTime = YES;
int left_is_none;
+ unsigned int flags = [theEvent modifierFlags];
NSTRACE (keyDown);
## -4550,9 +4600,13 ## ns_term_shutdown (int sig)
code = ([[theEvent charactersIgnoringModifiers] length] == 0) ?
0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];
/* (Carbon way: [theEvent keyCode]) */
+
/* is it a "function key"? */
- fnKeysym = ns_convert_key (code);
+ if (code < 0x00ff && (flags & NSNumericPadKeyMask) )
+ fnKeysym = ns_convert_keypad([theEvent keyCode]);
+ else
+ fnKeysym = ns_convert_key(code);
if (fnKeysym)
{
/* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace',
## -4565,7 +4619,6 ## ns_term_shutdown (int sig)
/* are there modifiers? */
emacs_event->modifiers = 0;
- flags = [theEvent modifierFlags];
if (flags & NSHelpKeyMask)
emacs_event->modifiers |= hyper_modifier;
I tried this with an older Emacs:
This is GNU Emacs 22.2.1 (powerpc-apple-darwin9.5.0, GTK+ Version 2.10.13)
Built from the ports collection with +gtk +x11 and used with the X11 server XQuartz 2.1.6 (xorg-server 1.4.2-apple33), when I look with C-h lI get
<kp-0> ... <kp-9>
for the numbers. and
<kp-enter> <kp-subtract> <kp-multiply> <kp-divide> <kp-equal>
For the other keys.
I'd suggest to build the latest Emacs from MacPorts with the options +gtk and +x11.
Then I'd get the latest XQuartz and run Emacs over X11 (I prefer this to the more native builds because then Emacs always behaves the same regardless if it runs remotely on another OS (usually via ssh -Y) or locally.
I'll upgrade my ports to the latest Emacs next week and add the result for these also.
The problem is exclusive to the Cocoa variant of emacs. The problem did not exist in the Carbon version, which is emacs22. I updated the patch I posted above, which now works better. It will likely work with the Emacs23 code base using XCode 3. If you are using XCode 4, like me you will need to use the Emacs24 code base which is currently only available in the GIT repository. Here is a very nice description on building Emacs24 via XCode 4
[http://mikbe.tk/2011/04/18/build-emacs-with-xcode-4/][1]
Here's an Emacs 23.3 translation of the Emacs 24 patch M. D. Marchionna's posted on this page.
--- nsterm-orig.m 2011-11-13 17:51:47.000000000 -0500
+++ nsterm.m 2011-11-13 17:39:56.000000000 -0500
## -87,6 +87,7 ##
NSBeginFunctionKey, 0x58,
NSSelectFunctionKey, 0x60,
NSPrintFunctionKey, 0x61,
+ NSClearLineFunctionKey, 0x0B,
NSExecuteFunctionKey, 0x62,
NSInsertFunctionKey, 0x63,
NSUndoFunctionKey, 0x65,
## -134,6 +135,33 ##
0x1B, 0x1B /* escape */
};
+static unsigned convert_nskeypad_to_X_keysym[] =
+{
+ /* Arrow keys are both function and keypad keys */
+ NSLeftArrowFunctionKey, 0x51,
+ NSUpArrowFunctionKey, 0x52,
+ NSRightArrowFunctionKey, 0x53,
+ NSDownArrowFunctionKey, 0x54,
+
+ 0x41, 0xAE, /* KP_Decimal */
+ 0x43, 0xAA, /* KP_Multiply */
+ 0x45, 0xAB, /* KP_Add */
+ 0x4B, 0xAF, /* KP_Divide */
+ 0x4E, 0xAD, /* KP_Subtract */
+ 0x51, 0xBD, /* KP_Equal */
+ 0x52, 0xB0, /* KP_0 */
+ 0x53, 0xB1, /* KP_1 */
+ 0x54, 0xB2, /* KP_2 */
+ 0x55, 0xB3, /* KP_3 */
+ 0x56, 0xB4, /* KP_4 */
+ 0x57, 0xB5, /* KP_5 */
+ 0x58, 0xB6, /* KP_6 */
+ 0x59, 0xB7, /* KP_7 */
+ 0x5B, 0xB8, /* KP_8 */
+ 0x5C, 0xB9, /* KP_9 */
+ // The enter key is on the keypad but modifier isnt set
+ NSEnterCharacter, 0x8D
+};
/* Lisp communications */
Lisp_Object ns_input_file, ns_input_font, ns_input_fontsize, ns_input_line;
## -1842,6 +1870,23 ##
return code > 0xff ? 0 : 0xFF00 | ns_keycode_to_xkeysym_table[code]; */
}
+static unsigned
+ns_convert_keypad (unsigned code)
+/* --------------------------------------------------------------------------
+ Internal call used by NSView-keyDown.
+ -------------------------------------------------------------------------- */
+{
+ const unsigned last_keysym = (sizeof (convert_nskeypad_to_X_keysym)
+ / sizeof (convert_nskeypad_to_X_keysym[0]));
+ unsigned keysym;
+ /* An array would be faster, but less easy to read. */
+ for (keysym = 0; keysym < last_keysym; keysym += 2) {
+ if (code == convert_nskeypad_to_X_keysym[keysym]) {
+ return 0xFF00 | convert_nskeypad_to_X_keysym[keysym+1];
+ }
+ }
+ return 0;
+}
char *
x_get_keysym_name (int keysym)
## -4349,7 +4394,7 ##
struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
int code;
unsigned fnKeysym = 0;
- int flags;
+ unsigned int flags = [theEvent modifierFlags];
static NSMutableArray *nsEvArray;
static BOOL firstTime = YES;
## -4397,6 +4442,9 ##
/* (Carbon way: [theEvent keyCode]) */
/* is it a "function key"? */
+ if (code < 0x00ff && (flags & NSNumericPadKeyMask) )
+ fnKeysym = ns_convert_keypad([theEvent keyCode]);
+ else
fnKeysym = ns_convert_key (code);
if (fnKeysym)
{
## -4410,8 +4458,6 ##
/* are there modifiers? */
emacs_event->modifiers = 0;
- flags = [theEvent modifierFlags];
-
if (flags & NSHelpKeyMask)
emacs_event->modifiers |= hyper_modifier;

Resources