/* This souce code written by Michael Rolig (email: michael_rolig@alumni.macalester.edu) * This can be considered to be in the public domain * * modified for hidapi, by nishio@hh.iij4u.or.jp. * This code is still considered to be in the public domain * * cc -g radioshark.c -lhidapi-libusb -std=c99 */ #define __RCSID(_s) __asm(".section rcsid\n\t.asciz \"" _s "\"\n\t.previous") __RCSID("$Id: radioshark.c,v 1.6 2017/09/21 15:57:58 nishio Exp $"); #define SHARK_VENDID 0x077d /* Griffin's Vendor ID */ #define SHARK_DEVID 0x627a /* The radioSHARK's Device ID */ #define SEND_PACKET_LENGTH 6 /* size of an instruction packet */ #define MAX_STR 255 #include #include #include #include #include int debug = 0; void usage(int argc, const char **argv) { printf("%s [opts] [freq]\n\tchange state of radioSHARK\n\n", argv[0]); printf("opts:\n" " -blue : turn on blue LED (0-127) '-blue 127'\n" " -blink : turn on blue LED pulsing (0-127) '-blink 64'\n" " -red <0/1> : turn on/off red LED '-red 1'\n" "freq:\n" " AM --- 522 - 1710\n" " FM --- 76.0 - 108.0(effective range is 85.0 - 108.0)\n" " ignore tailing garbage\n"); } int write_packet(hid_device *handle, unsigned char packet[], int size) { int ret; ret = hid_write(handle, packet, size); if (ret < 0 || debug) { fprintf(stderr, "%s:\t", ret < 0 ? "Cannot set" : "write"); for (int i = 0; i < size; i++) { fprintf(stderr, "%2.2x%c", packet[i], i == size - 1 ? '\n' : ' '); } } return ret; } struct node { unsigned char *p; struct node *next; }; struct node * new_node() { struct node *p = malloc(sizeof (struct node)); p->next = NULL; p->p = malloc(SEND_PACKET_LENGTH); if (p == NULL || p->p == NULL) { perror("Cannot allocate new node\n"); exit(1); } memset(p->p, 0, SEND_PACKET_LENGTH); return p; } int main(int argc, const char **argv) { struct node root = { NULL, NULL}; struct node *cur_node = &root; /* Declare variables used later */ int ret; hid_device *handle; for (const char **p = argv + 1; *p; p++) { char buf[BUFSIZ]; unsigned char *PACKET; if (strcmp(*p, "-d") == 0) { debug++; continue; } struct node *node = new_node(); unsigned char *packet = node->p; if (strcmp(*p, "-blue") == 0 || strcmp(*p, "-blink") == 0) { int val = -1; packet[0] = (*p)[3] == 'u' ? 0xa0 : 0xa1; p++; if (*p && isdigit(**p)) { val = atoi(*p); } sprintf(buf, "%d", val); if (val < 0 || 127 < val || strcmp(buf, *p) != 0) { fprintf(stderr, "%s: %s %s... 0-127\n", argv[0], *(p - 1), *p); exit(2); } packet[1] = val; } else if (strcmp(*p, "-red") == 0) { ++p; if (*p && strcmp(*p, "0") == 0) { packet[0] = 0xA8; } else if (*p && strcmp(*p, "1") == 0) { packet[0] = 0xA9; } else { fprintf(stderr, "%s %s %s ... 0 or 1\n", argv[0], *(p - 1), *p); exit(2); } } else if (strcmp(*p, "-h") == 0) { usage(argc, argv); exit(0); } else if (*p && isdigit(**p)) { char *hz = NULL; double freq = 0.0; unsigned short efreq = 0; freq = atof(*p); packet[0] = 0xC0; if (522.0 <= freq && freq <= 1710.0) { efreq = (unsigned short)freq + 450; packet[1] = 0x12; hz = "kHz"; } else if (76.0 <= freq && freq <= 108.0) { efreq = ((freq * 1000) + 10700) / 12.5; efreq += 3; packet[1] = 0x02; // 0? hz = "MHz"; } else { fprintf(stderr, "%s: %s is band.\n", argv[0], *p); exit(2); } packet[2] = (efreq >> 8) & 0xFF; packet[3] = efreq & 0xFF; if (debug) { fprintf(stderr, "freq:\t%5g %s\t0x%4.4x\n", freq, hz, efreq); } } else { fprintf(stderr, "%s: unknown param(%s)\n\n", argv[0], *p); exit(2); } cur_node->next = node; cur_node = cur_node->next; } if (ret = hid_init()) { fprintf(stderr, "Cannot init hid lib\n"); exit(1); } if ((handle = hid_open(SHARK_VENDID, SHARK_DEVID, NULL)) == NULL) { fprintf(stderr, "Cannot open: device %4.4x:%x\n", SHARK_VENDID, SHARK_DEVID); exit(1); } if (debug) { wchar_t wstr[MAX_STR]; ret = hid_get_manufacturer_string(handle, wstr, MAX_STR); wprintf(L"mfr:\t%ls\n", wstr); ret = hid_get_product_string(handle, wstr, MAX_STR); wprintf(L"prod:\t%ls\n", wstr); } for (struct node *cur = root.next; cur; cur = cur->next) { if (!*cur->p) continue; if (write_packet(handle, cur->p, SEND_PACKET_LENGTH) < 0) { exit(1); } } hid_close(handle); exit(hid_exit()); } /* Retrieved from "http://wiki.linuxquestions.org/wiki/RadioSHARKSource" */