summaryrefslogtreecommitdiff
path: root/r2d2.c
diff options
context:
space:
mode:
Diffstat (limited to 'r2d2.c')
-rw-r--r--r2d2.c264
1 files changed, 0 insertions, 264 deletions
diff --git a/r2d2.c b/r2d2.c
deleted file mode 100644
index 07fcf6e..0000000
--- a/r2d2.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- r2d2 - interact with Sphero R2-D2
- Copyright (C) 2020 Ian Cowburn
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <unistd.h>
-#include <sys/socket.h>
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-#include <bluetooth/l2cap.h>
-
-typedef struct
-{
- const char *name;
- int command[20];
-} Command;
-
-static Command plain_commands[] =
-{
- {"laugh", {0x0A,0x18,0x00,0x1F,0x00,0x32,0x00,0x00,0x00,0x00,0x00,-1}},
- {"yes", {0x0A,0x17,0x05,0x41,0x00,0x0F,-1}},
- {"no", {0x0A,0x17,0x05,0x3F,0x00,0x10,-1}},
- {"alarm", {0x0A,0x17,0x05,0x17,0x00,0x07,-1}},
- {"angry", {0x0A,0x17,0x05,0x18,0x00,0x08,-1}},
- {"annoyed", {0x0A,0x17,0x05,0x19,0x00,0x09,-1}},
- {"ionblast", {0x0A,0x17,0x05,0x1A,0x00,0x0E,-1}},
- {"sad", {0x0A,0x17,0x05,0x1C,0x00,0x11,-1}},
- {"scared", {0x0A,0x17,0x05,0x1D,0x00,0x13,-1}},
- {"chatty", {0x0A,0x17,0x05,0x17,0x00,0x0A,-1}},
- {"confident", {0x0A,0x17,0x05,0x18,0x00,0x12,-1}},
- {"excited", {0x0A,0x17,0x05,0x19,0x00,0x0C,-1}},
- {"happy", {0x0A,0x17,0x05,0x1A,0x00,0x0D,-1}},
- {"laugh", {0x0A,0x17,0x05,0x1B,0x00,0x0F,-1}},
- {"surprise", {0x0A,0x17,0x05,0x1C,0x00,0x18,-1}},
- {"tripod", {0x0A,0x17,0x0D,0x1D,0x01,-1}},
- {"bipod", {0x0A,0x17,0x0D,0x1C,0x02,-1}},
- {NULL, {0}}
-};
-
-static unsigned char force_command[] =
-{
- 0x75,0x73,0x65,0x74,0x68,0x65,0x66,0x6F,0x72,0x63,0x65,0x2E,
- 0x2E,0x2E,0x62,0x61,0x6E,0x64
-};
-
-static Command wake_command =
-{
- "wakeup",
- {
- 0x0A,0x13,0x0D,0x00,-1
- }
-};
-
-static void Fatal(const char *call)
-{
- perror(call);
- exit(EXIT_FAILURE);
-}
-
-static unsigned char Checksum(const char *p, int len)
-{
- unsigned char c;
- int f;
-
- c = 0;
-
- for(f = 0; f < len; f++)
- {
- c += p[f];
- }
-
- c = ~c;
-
- return c;
-}
-
-static int Write(int sock, unsigned char *buff, int len)
-{
- int wr = 0;
- int tot = 0;
-
- while(tot < len)
- {
- wr = write(sock, buff + tot, len - tot);
-
- if (wr < 1)
- {
- return -1;
- }
-
- tot += wr;
- }
-
- return len;
-}
-
-static void CharWriteHandle(int sock, int handle,
- const unsigned char *cmd, int len)
-{
- unsigned char buff[1024];
- unsigned short *us;
-
- memcpy(buff + 3, cmd, len);
- len += 3;
-
- buff[0] = 0x12;
-
- us = (unsigned short *)(buff + 1);
- *us = htobs(handle);
-
- if (Write(sock, buff, len) == -1)
- {
- Fatal("write");
- }
-}
-
-static void SendCommand(int sock, int handle, const Command *cmd)
-{
- unsigned char buff[1024];
- unsigned short *us;
- int len;
- int f;
-
- for(f = 0; cmd->command[f] != -1; f++)
- {
- buff[f] = (unsigned char)cmd->command[f];
- }
-
- len = f;
-
- buff[len] = Checksum(buff, len);
- len++;
-
- memmove(buff + 1, buff, len++);
- buff[0] = 0x8du;
- buff[++len] = 0xd8u;
-
- CharWriteHandle(sock, handle, buff, len);
-}
-
-int main(int argc, char *argv[])
-{
- char address[32] = {0};
- struct sockaddr_l2 src_addr = {0};
- struct sockaddr_l2 dest_addr = {0};
- int base;
- int f;
- int sock;
-
- /* Get address
- */
- if (getenv("R2D2"))
- {
- snprintf(address, sizeof address, "%s", getenv("R2D2"));
- }
-
- if (argc > 2 && strcmp(argv[1], "-a") == 0)
- {
- snprintf(address, sizeof address, "%s", argv[2]);
- base = 3;
- }
- else
- {
- base = 1;
- }
-
- /* Check address and arguments supplied
- */
- if (!address[0])
- {
- fprintf(stderr, "%s: pass address or set R2D2 variable\n", argv[0]);
- return EXIT_FAILURE;
- }
-
- if (argc <= base)
- {
- fprintf(stderr, "%s: usage %s [-a address] command [..command]\n",
- argv[0], argv[0]);
- return EXIT_FAILURE;
- }
-
- /* Open connection to R2
- */
- sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
-
- if (sock == -1)
- {
- Fatal("socket");
- }
-
- src_addr.l2_family = AF_BLUETOOTH;
- src_addr.l2_cid = htobs(4);
- bacpy(&src_addr.l2_bdaddr, BDADDR_ANY);
- src_addr.l2_bdaddr_type = BDADDR_LE_RANDOM;
-
- if (bind(sock, (void *)&src_addr, sizeof(src_addr)) == -1)
- {
- Fatal("bind");
- }
-
- dest_addr.l2_family = AF_BLUETOOTH;
- dest_addr.l2_cid = htobs(4);
- str2ba(address, &dest_addr.l2_bdaddr);
- dest_addr.l2_bdaddr_type = BDADDR_LE_RANDOM;
-
- if (connect(sock, (void *)&dest_addr, sizeof(dest_addr)) == -1)
- {
- Fatal("connect");
- }
-
- CharWriteHandle(sock, 0x15, force_command, sizeof force_command);
- SendCommand(sock, 0x1c, &wake_command);
-
- for(f = base; f < argc; f++)
- {
- int n;
-
- Command *cmd = NULL;
-
- for(n = 0; plain_commands[n].name && !cmd; n++)
- {
- if (strcmp(argv[f], plain_commands[n].name) == 0)
- {
- cmd = plain_commands + n;
- }
- }
-
- if (cmd == NULL)
- {
- fprintf(stderr, "%s: unknown command %s\n", argv[0], argv[f]);
- }
- else
- {
- SendCommand(sock, 0x1c, cmd);
- }
- }
-
- /* All done
- */
- if (close(sock) == -1)
- {
- Fatal("close");
- }
-
- return EXIT_SUCCESS;
-}