diff options
Diffstat (limited to 'r2d2.c')
-rw-r--r-- | r2d2.c | 264 |
1 files changed, 0 insertions, 264 deletions
@@ -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; -} |