#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h> 
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define IPCKEY 0x437800

int main(int argc, char *argv[])
{
    int addr;
    unsigned short *m_data;
    int id;
    int length = 0x1000*2;
    int shm_id, i;
    key_t key;
    char rw[10]="R";
    if (argc <= 2)
    {
        fprintf(stderr, "usage: %s slave_id addr [W]|[R]\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    id = atoi(argv[1]);
    addr = atoi(argv[2]);
    fprintf(stderr, "argc%d\n", argc);
    if (argc > 3 && strlen(argv[3]) > 0)
        strcpy(rw,argv[3]);  

    char pathname[30];
    strcpy(pathname, "/tmp");
    #ifdef IPCKEY
        key = 0x437800 | id;
    #else
        key = ftok(pathname, id);
    #endif

    

    if (key == -1)
    {
        perror("ftok error");
        return -1;
    }
    printf("key=%d\n", key);

    printf("[%s] [%s] %d %d\n",rw,"R",strlen(rw),(strncmp(rw,"R",1) == 0));
    if(strncmp(rw,"R",1) == 0)
    {
        shm_id = shmget(key, 0, 0);
        if (shm_id == -1)
        {
            perror("shmget error");
            return -1;
        }
        printf("shm_id=%d\n", shm_id);
        m_data = (unsigned short *)shmat(shm_id, NULL, 0);
        if(m_data == NULL) return 0;
        while (1)
        {
            int value = 0;
            char *p = (char *)&m_data[addr];
            value = (p[0]<<8) + p[1];
            fprintf(stderr, "%s  [%04x]=%d(%04x)\n", argv[1], addr, value, value);
            sleep(1);
        }
    }else if(strncmp(rw,"W",1) == 0)
    {
        uint16_t count = 0;
        shm_id=shmget(key,length,IPC_CREAT|IPC_EXCL|0600); 
        if(shm_id==-1 && errno == EEXIST) {
            shm_id=shmget(key,length,0); 
        }
        printf("shm_id=%d\n", shm_id);
        m_data = (unsigned short *)shmat(shm_id, NULL, 0);
        if(m_data == NULL) return 0;
        while (1)
        {
            count++;
            uint16_t value = (count>>8) + ((count&0xff)<<8);
            char *p = (char *)&m_data[addr];
            memcpy(p,&value,sizeof(value));
            sleep(1);
        }
    }else
    {
        return -1;
    }



    if (shmdt(m_data) == -1)
    {
        perror("detach error");
        return -1;
    }
    return 0;
}