Unified · Split
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -1,23 +0,0 @@ | ||
| 1 | −#include "dat.h" | |
| 2 | −#include "fns.h" | |
| 3 | −#include "error.h" | |
| 4 | −#include "audio.h" | |
| 5 | −#include "audio-tbls.c" | |
| 6 | − | |
| 7 | −Audio_t* | |
| 8 | −getaudiodev(void) | |
| 9 | −{ | |
| 10 | − return &av; | |
| 11 | −} | |
| 12 | − | |
| 13 | −void | |
| 14 | −audio_file_init(void) | |
| 15 | −{ | |
| 16 | − audio_info_init(&av); | |
| 17 | −} | |
| 18 | − | |
| 19 | −void | |
| 20 | −audio_file_open(Chan *c, int omode) | |
| 21 | −{ | |
| 22 | − | |
| 23 | −} | |
| @@ -1,142 +0,0 @@ | ||
| 1 | −#include <stdlib.h> | |
| 2 | −#include <stdio.h> | |
| 3 | − | |
| 4 | −struct alloc_node { | |
| 5 | − void *block; | |
| 6 | − struct alloc_node *next; | |
| 7 | −}; | |
| 8 | − | |
| 9 | −struct alloc_node *alloc_head = NULL; | |
| 10 | − | |
| 11 | −void add_alloc_node(void *block) | |
| 12 | −{ | |
| 13 | − struct alloc_node *node = malloc(sizeof(struct alloc_node)); | |
| 14 | − struct alloc_node *cur; | |
| 15 | − | |
| 16 | − node->block = block; | |
| 17 | − node->next = NULL; | |
| 18 | − if(alloc_head == NULL) { | |
| 19 | − alloc_head = node; | |
| 20 | − } else { | |
| 21 | − for(cur = alloc_head; ; cur = cur->next) { | |
| 22 | − if(cur->next == NULL) { | |
| 23 | − cur->next = node; | |
| 24 | − break; | |
| 25 | − } | |
| 26 | − } | |
| 27 | − } | |
| 28 | −} | |
| 29 | − | |
| 30 | −void del_alloc_node(void *block) | |
| 31 | −{ | |
| 32 | − struct alloc_node *cur; | |
| 33 | − struct alloc_node *prev; | |
| 34 | − | |
| 35 | − for(cur = alloc_head; cur != NULL; cur = cur->next) { | |
| 36 | − if(cur->block == block) { | |
| 37 | − if(cur == alloc_head) { | |
| 38 | − alloc_head = cur->next; | |
| 39 | − } else { | |
| 40 | − prev->next = cur->next; | |
| 41 | − } | |
| 42 | − free(cur); | |
| 43 | − return; | |
| 44 | − } | |
| 45 | − prev = cur; | |
| 46 | − } | |
| 47 | − fprintf(stderr, "del_alloc_node: could not find block %p\n", block); | |
| 48 | −} | |
| 49 | − | |
| 50 | −void auditcheck(char *file, int line) | |
| 51 | −{ | |
| 52 | − struct alloc_node *cur; | |
| 53 | − for(cur = alloc_head; cur != NULL; cur = cur->next) { | |
| 54 | − void *p = cur->block; | |
| 55 | − long hdr, canary; | |
| 56 | − size_t orig; | |
| 57 | − | |
| 58 | − hdr = *((long *)p - 2); | |
| 59 | − if(hdr != 0xcafeface) { | |
| 60 | − fprintf(stderr, "auditcheck (from %s:%d): bad header at block %p, found %x\n", | |
| 61 | − file, line, p, canary); | |
| 62 | − } | |
| 63 | − orig = *((size_t *) p - 1); | |
| 64 | − canary = *((long *)(p + orig)); | |
| 65 | − if(canary != 0xaaaaaaaa) { | |
| 66 | − fprintf(stderr, "auditcheck (from %s:%d): bad canary at block %p, found %x\n", | |
| 67 | − file, line, p, canary); | |
| 68 | − } | |
| 69 | − } | |
| 70 | −} | |
| 71 | − | |
| 72 | −void *auditmalloc(size_t orig) | |
| 73 | −{ | |
| 74 | − size_t size = orig + sizeof(size_t) + 2*sizeof(long); | |
| 75 | − void *ret; | |
| 76 | − ret = malloc(size); | |
| 77 | − if(ret == NULL) return NULL; | |
| 78 | − *((long *) ret) = 0xcafeface; | |
| 79 | − *(((size_t *) ret) + 1) = orig; | |
| 80 | − *((long *) ((char *)ret + orig + sizeof(long) + sizeof(size_t))) = 0xaaaaaaaa; | |
| 81 | − ret += sizeof(long) + sizeof(size_t); | |
| 82 | − add_alloc_node(ret); | |
| 83 | − return ret; | |
| 84 | −} | |
| 85 | − | |
| 86 | −void auditfree(void *p) | |
| 87 | −{ | |
| 88 | − long hdr, canary; | |
| 89 | − size_t orig; | |
| 90 | − | |
| 91 | − if(p == NULL) return; | |
| 92 | − | |
| 93 | − hdr = *((long *)p - 2); | |
| 94 | − if(hdr != 0xcafeface) { | |
| 95 | − fprintf(stderr, "auditfree: bad header at block %p, found %x\n", | |
| 96 | − p, canary); | |
| 97 | − } | |
| 98 | − orig = *((size_t *) p - 1); | |
| 99 | − canary = *((long *)(p + orig)); | |
| 100 | − if(canary != 0xaaaaaaaa) { | |
| 101 | − fprintf(stderr, "auditfree: bad canary at block %p, found %x\n", | |
| 102 | − p, canary); | |
| 103 | − } | |
| 104 | − del_alloc_node(p); | |
| 105 | − p = p - sizeof(long) - sizeof(size_t); | |
| 106 | − memset(p, 0xbadbad, orig + 2 * sizeof(long) + sizeof(size_t)); | |
| 107 | − free(p); | |
| 108 | −} | |
| 109 | − | |
| 110 | −char *auditstrdup(char *str) | |
| 111 | −{ | |
| 112 | − char *ret; | |
| 113 | − ret = auditmalloc((strlen(str) + 1) * sizeof(char)); | |
| 114 | − strcpy(ret, str); | |
| 115 | − return ret; | |
| 116 | −} | |
| 117 | − | |
| 118 | −void *auditcalloc(size_t nmemb, size_t size) | |
| 119 | −{ | |
| 120 | − size_t total = nmemb * size; | |
| 121 | − void *ret; | |
| 122 | − ret = auditmalloc(total); | |
| 123 | − memset(ret, 0, total); | |
| 124 | − return ret; | |
| 125 | −} | |
| 126 | − | |
| 127 | − | |
| 128 | −void *auditrealloc(void *p, size_t size) | |
| 129 | −{ | |
| 130 | − void *ret; | |
| 131 | − size_t orig = size; | |
| 132 | − del_alloc_node(p); | |
| 133 | − p = p - sizeof(size_t) - sizeof(long); | |
| 134 | − size += 2 * sizeof(long) + sizeof(size_t); | |
| 135 | − ret = realloc(p, size); | |
| 136 | − *(((size_t *) ret) + 1) = orig; | |
| 137 | − | |
| 138 | − ret += sizeof(size_t) + sizeof(long); | |
| 139 | − *((long *)(ret + orig)) = 0xaaaaaaaa; | |
| 140 | − add_alloc_node(ret); | |
| 141 | − return ret; | |
| 142 | −} | |
| @@ -1,11 +0,0 @@ | ||
| 1 | −#ifndef __AUDIT_H | |
| 2 | −#define __AUDIT_H | |
| 3 | −#define AUDITCHECK auditcheck(__FILE__, __LINE__) | |
| 4 | − | |
| 5 | −void auditcheck(void); | |
| 6 | −void *auditmalloc(size_t orig); | |
| 7 | −void auditfree(void *p); | |
| 8 | −char *auditstrdup(char *str); | |
| 9 | −void *auditcalloc(size_t nmemb, size_t size); | |
| 10 | −void *auditrealloc(void *p, size_t size); | |
| 11 | −#endif | |
| @@ -1,1241 +0,0 @@ | ||
| 1 | −/* TODO/BUGS in no order: | |
| 2 | − SMSes will be acknowledged regardless of whether anyone happens to be reading /phone/sms to see them, potentially losing SMSes if no one reads them before shutdown | |
| 3 | − translation from UTF-8 to GSM for sending SMSes | |
| 4 | − decode_sms is sloppy--should convert septets into octets, then convert octets into UTF-8 instead of trying to do it all at once. split off into separate functions? | |
| 5 | − handle sending/receiving multiple text messages and checking length of messages sent to /phone/sms | |
| 6 | − consider notifying RIL of screen state using RIL_REQUEST_SCREEN_STATE to conserve power | |
| 7 | − figure out why default SMSC address for send_sms does not work | |
| 8 | − too many assumptions made in phonewrite() about what the user sends (needs a \n, etc) | |
| 9 | − too many assumptions made in loop_for_data() about read() giving exactly the right amount of data | |
| 10 | − some of the created files will not be consistent across multiple read()s, i.e. if you read a few bytes of data, wait, then read a few more, the result may not make sense if things change in between. E.g. you may get "onf" if you read from /phone/ctl during a on/off transition | |
| 11 | − parcel code will go crazy if ints overflow | |
| 12 | − no way to give an error if SMSes don't send | |
| 13 | −*/ | |
| 14 | − | |
| 15 | −#include "dat.h" | |
| 16 | −#include "fns.h" | |
| 17 | −#include "error.h" | |
| 18 | −#include "version.h" | |
| 19 | −#include "mp.h" | |
| 20 | −#include "libsec.h" | |
| 21 | −#include "keyboard.h" | |
| 22 | −#include <stdio.h> | |
| 23 | −#include <cutils/sockets.h> | |
| 24 | −#include <stdlib.h> | |
| 25 | −#include <telephony/ril.h> | |
| 26 | −#include <cutils/jstring.h> | |
| 27 | −#include <arpa/inet.h> | |
| 28 | −#include <libgen.h> | |
| 29 | −#include <sys/types.h> | |
| 30 | −#include <sys/stat.h> | |
| 31 | −#include <fcntl.h> | |
| 32 | −#include <semaphore.h> | |
| 33 | −#include <dlfcn.h> | |
| 34 | −#include "asound.h" | |
| 35 | −#include "alsa_audio.h" | |
| 36 | − | |
| 37 | −// audio stuff taken from android source | |
| 38 | −#define AUDIO_HW_OUT_PERIOD_MULT 8 // (8 * 128 = 1024 frames) | |
| 39 | −#define AUDIO_HW_OUT_PERIOD_SZ (PCM_PERIOD_SZ_MIN * AUDIO_HW_OUT_PERIOD_MULT) | |
| 40 | −#define AUDIO_HW_OUT_PERIOD_CNT 4 | |
| 41 | −// RIL-related definitions | |
| 42 | − | |
| 43 | −#define RESPONSE_SOLICITED 0 | |
| 44 | −#define RESPONSE_UNSOLICITED 1 | |
| 45 | −#define POWER_ON 2000 | |
| 46 | −#define POWER_OFF 2001 | |
| 47 | − | |
| 48 | −struct RilClient { | |
| 49 | − void *prv; | |
| 50 | −}; | |
| 51 | − | |
| 52 | −typedef struct RilClient * HRilClient; | |
| 53 | − | |
| 54 | −typedef enum _SoundType { | |
| 55 | − SOUND_TYPE_VOICE, | |
| 56 | − SOUND_TYPE_SPEAKER, | |
| 57 | − SOUND_TYPE_HEADSET, | |
| 58 | − SOUND_TYPE_BTVOICE | |
| 59 | −} SoundType; | |
| 60 | − | |
| 61 | −typedef enum _AudioPath { | |
| 62 | − SOUND_AUDIO_PATH_HANDSET, | |
| 63 | − SOUND_AUDIO_PATH_HEADSET, | |
| 64 | − SOUND_AUDIO_PATH_SPEAKER, | |
| 65 | − SOUND_AUDIO_PATH_BLUETOOTH, | |
| 66 | − SOUND_AUDIO_PATH_BLUETOOTH_NO_NR, | |
| 67 | − SOUND_AUDIO_PATH_HEADPHONE | |
| 68 | −} AudioPath; | |
| 69 | − | |
| 70 | −typedef enum _SoundClockCondition { | |
| 71 | − SOUND_CLOCK_STOP, | |
| 72 | − SOUND_CLOCK_START | |
| 73 | −} SoundClockCondition; | |
| 74 | − | |
| 75 | −// Inferno-related globals | |
| 76 | − | |
| 77 | −enum | |
| 78 | −{ | |
| 79 | − Qdir, | |
| 80 | − Qctl, | |
| 81 | − Qsms, | |
| 82 | − Qphone, | |
| 83 | − Qsignal, | |
| 84 | − Qstatus, | |
| 85 | − Qcalls | |
| 86 | −}; | |
| 87 | − | |
| 88 | −Dirtab phonetab[] = | |
| 89 | −{ | |
| 90 | − ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, | |
| 91 | − "ctl", {Qctl}, 0, 0666, | |
| 92 | − "sms", {Qsms}, 0, 0666, | |
| 93 | − "phone", {Qphone}, 0, 0666, | |
| 94 | − "signal", {Qsignal}, 0, 0666, | |
| 95 | − "status", {Qstatus}, 0, 0666, | |
| 96 | − "calls", {Qcalls}, 0, 0666, | |
| 97 | −}; | |
| 98 | − | |
| 99 | −Queue *phoneq; | |
| 100 | −Queue *smsq; | |
| 101 | − | |
| 102 | −static int signal_strength; | |
| 103 | −static int fd; | |
| 104 | −static int power_state = 0; | |
| 105 | −static struct { | |
| 106 | − sem_t sem; | |
| 107 | − char *msg; | |
| 108 | −} status_msg; | |
| 109 | − | |
| 110 | −static struct { | |
| 111 | − RWLock l; | |
| 112 | − RIL_Call *cs; | |
| 113 | − int num; | |
| 114 | −} calls; | |
| 115 | − | |
| 116 | −/* RIL client library globals */ | |
| 117 | −static void *ril_client_handle; | |
| 118 | −static HRilClient ril_client = NULL; | |
| 119 | −HRilClient (*openClientRILD)(void); | |
| 120 | −int (*disconnectRILD)(HRilClient); | |
| 121 | −int (*closeClientRILD)(HRilClient); | |
| 122 | −int (*isConnectedRILD)(HRilClient); | |
| 123 | −int (*connectRILD)(HRilClient); | |
| 124 | −int (*setCallVolume)(HRilClient, SoundType, int); | |
| 125 | −int (*setCallAudioPath)(HRilClient, AudioPath); | |
| 126 | −int (*setCallClockSync)(HRilClient, SoundClockCondition); | |
| 127 | − | |
| 128 | − | |
| 129 | −void loop_for_data(void *v); | |
| 130 | −void send_sms(char *smsc_pdu, char *pdu); | |
| 131 | −char *encode_sms(char *dest, char *msg); | |
| 132 | −void dial(char *number); | |
| 133 | −void activate_net(void); | |
| 134 | −void deactivate_net(void); | |
| 135 | −void radio_power(int power); | |
| 136 | − | |
| 137 | −void phoneinit(void) | |
| 138 | −{ | |
| 139 | − calls.cs = NULL; | |
| 140 | − calls.num = 0; | |
| 141 | − memset(&calls.l, 0, sizeof(RWLock)); | |
| 142 | − | |
| 143 | − phoneq = qopen(512, 0, nil, nil); | |
| 144 | − if(phoneq == 0) | |
| 145 | − panic("no memory"); | |
| 146 | − smsq = qopen(512, 0, nil, nil); | |
| 147 | − if(smsq == 0) | |
| 148 | − panic("no memory"); | |
| 149 | − | |
| 150 | − sem_init(&status_msg.sem, 0, 0); | |
| 151 | − | |
| 152 | − // set up proper permissions (need to be user radio, group radio to | |
| 153 | − // access socket) | |
| 154 | − if(setegid(1001) == -1) { | |
| 155 | − perror("setegid(1001) failed"); | |
| 156 | − } | |
| 157 | − if(seteuid(1001) == -1) { | |
| 158 | − perror("seteuid(1001) failed"); | |
| 159 | − } | |
| 160 | − fd = socket_local_client("rild", | |
| 161 | − ANDROID_SOCKET_NAMESPACE_RESERVED, | |
| 162 | − SOCK_STREAM); | |
| 163 | − if(fd == -1) { | |
| 164 | − perror("socket_local_client failed"); | |
| 165 | − } | |
| 166 | − // set privileges back to root/root | |
| 167 | − if(seteuid(0) == -1) { | |
| 168 | − perror("seteuid(0) failed"); | |
| 169 | − } | |
| 170 | − if(setegid(0) == -1) { | |
| 171 | − perror("setegid(0) failed"); | |
| 172 | − } | |
| 173 | − kproc("phone", loop_for_data, 0, 0); | |
| 174 | − // Load RIL client functions, used for setting call volume, etc | |
| 175 | − ril_client_handle = dlopen("libsecril-client.so", RTLD_NOW); | |
| 176 | − if(ril_client_handle == NULL) { | |
| 177 | − fprintf(stderr, "opening libsecril-client.so failed: %s\n", | |
| 178 | − dlerror()); | |
| 179 | − } | |
| 180 | − openClientRILD = dlsym(ril_client_handle, "OpenClient_RILD"); | |
| 181 | − disconnectRILD = dlsym(ril_client_handle, "Disconnect_RILD"); | |
| 182 | − closeClientRILD = dlsym(ril_client_handle, "CloseClient_RILD"); | |
| 183 | − isConnectedRILD = dlsym(ril_client_handle, "isConnected_RILD"); | |
| 184 | − connectRILD = dlsym(ril_client_handle, "Connect_RILD"); | |
| 185 | − setCallVolume = dlsym(ril_client_handle, "SetCallVolume"); | |
| 186 | − setCallAudioPath = dlsym(ril_client_handle, "SetCallAudioPath"); | |
| 187 | − setCallClockSync = dlsym(ril_client_handle, "SetCallClockSync"); | |
| 188 | − | |
| 189 | − ril_client = openClientRILD(); | |
| 190 | − if(ril_client == NULL) { | |
| 191 | − fprintf(stderr, "error in openClientRILD()\n"); | |
| 192 | − } | |
| 193 | − if(connectRILD(ril_client) != 0) { | |
| 194 | − fprintf(stderr, "error while attempting to connectRILD()\n"); | |
| 195 | − } | |
| 196 | −} | |
| 197 | − | |
| 198 | −static Chan *phoneattach(char *spec) | |
| 199 | −{ | |
| 200 | − // setup kprocs if necessary | |
| 201 | − return devattach('f', spec); | |
| 202 | −} | |
| 203 | − | |
| 204 | −static Walkqid *phonewalk(Chan *c, Chan *nc, char **name, int nname) | |
| 205 | −{ | |
| 206 | − return devwalk(c, nc, name, nname, phonetab, nelem(phonetab), devgen); | |
| 207 | −} | |
| 208 | − | |
| 209 | −static int phonestat(Chan *c, uchar *db, int n) | |
| 210 | −{ | |
| 211 | − return devstat(c, db, n, phonetab, nelem(phonetab), devgen); | |
| 212 | −} | |
| 213 | − | |
| 214 | −static Chan *phoneopen(Chan *c, int omode) | |
| 215 | −{ | |
| 216 | − c = devopen(c, omode, phonetab, nelem(phonetab), devgen); | |
| 217 | − | |
| 218 | − switch((ulong) c->qid.path) { | |
| 219 | − case Qstatus: | |
| 220 | − get_reg_state(); | |
| 221 | − break; | |
| 222 | − case Qcalls: | |
| 223 | − get_current_calls(); | |
| 224 | − break; | |
| 225 | − } | |
| 226 | − | |
| 227 | − return c; | |
| 228 | −} | |
| 229 | − | |
| 230 | −static void phoneclose(Chan *c) | |
| 231 | −{ | |
| 232 | − if((c->flag & COPEN) == 0) | |
| 233 | − return; | |
| 234 | −} | |
| 235 | − | |
| 236 | −static long phoneread(Chan *c, void *va, long n, vlong offset) | |
| 237 | −{ | |
| 238 | − char buf[255]; | |
| 239 | − if(c->qid.type & QTDIR) { | |
| 240 | − return devdirread(c, va, n, phonetab, nelem(phonetab), devgen); | |
| 241 | − } | |
| 242 | − | |
| 243 | − switch((ulong) c->qid.path) { | |
| 244 | − case Qctl: | |
| 245 | − return readstr(offset, va, n, power_state ? "on\n" : "off\n"); | |
| 246 | − case Qphone: | |
| 247 | − return qread(phoneq, va, n); | |
| 248 | − case Qsms: | |
| 249 | − // FIXME only acknowledge when an SMS is being read | |
| 250 | − acknowledge_sms(); | |
| 251 | − return qread(smsq, va, n); | |
| 252 | − case Qsignal: | |
| 253 | − snprintf(buf, sizeof(buf), "%d\n", signal_strength); | |
| 254 | − return readstr(offset, va, n, buf); | |
| 255 | − case Qstatus: | |
| 256 | − sem_wait(&status_msg.sem); | |
| 257 | − // terrible | |
| 258 | − if(offset < strlen(status_msg.msg)) { | |
| 259 | − sem_post(&status_msg.sem); | |
| 260 | − } | |
| 261 | − // FIXME lock | |
| 262 | − return readstr(offset, va, n, status_msg.msg); | |
| 263 | − case Qcalls: | |
| 264 | − return readstr(offset, va, n, "fixme\n"); | |
| 265 | − } | |
| 266 | − return 0; | |
| 267 | −} | |
| 268 | − | |
| 269 | −static long phonewrite(Chan *c, void *va, long n, vlong offset) | |
| 270 | −{ | |
| 271 | − char *pdu; | |
| 272 | − char *split; | |
| 273 | −// char *args[5]; | |
| 274 | − char *str; | |
| 275 | −// int nargs = 0, i; | |
| 276 | − | |
| 277 | − if(c->qid.type & QTDIR) | |
| 278 | − error(Eperm); | |
| 279 | − switch((ulong) c->qid.path) { | |
| 280 | − case Qctl: | |
| 281 | − str = malloc((n + 1) * sizeof(char)); | |
| 282 | − strncpy(str, va, n); | |
| 283 | − ((char *)str)[n] = '\0'; | |
| 284 | − printf("Qctl: va = %s\n", str); | |
| 285 | − ((char *) str)[strlen(str) - 1] = '\0'; // get rid of newline | |
| 286 | − if(strcmp(str, "on") == 0) { | |
| 287 | − radio_power(1); | |
| 288 | − } else if(strcmp(str, "off") == 0) { | |
| 289 | − radio_power(0); | |
| 290 | − } else if(strcmp(str, "net on") == 0) { | |
| 291 | − activate_net(); | |
| 292 | − } else if(strcmp(str, "net off") == 0) { | |
| 293 | − deactivate_net(); | |
| 294 | − } | |
| 295 | − free(str); | |
| 296 | − break; | |
| 297 | − case Qsms: | |
| 298 | − printf("Qsms: got %d bytes\n", n); | |
| 299 | − ((char *)va)[n] = '\0'; | |
| 300 | − printf("Qsms: va = %s\n", va); | |
| 301 | − ((char *) va)[strlen(va) - 1] = '\0'; // get rid of newline | |
| 302 | − split = strstr(va, ":"); | |
| 303 | − if(split == NULL) break; | |
| 304 | − *split = '\0'; | |
| 305 | − split++; | |
| 306 | − | |
| 307 | − printf("dest = %s msg = %s\n", va, split); | |
| 308 | − pdu = encode_sms(va, split); | |
| 309 | − printf("pdu = %s\n", pdu); | |
| 310 | − send_sms("07912180958729f4", pdu); | |
| 311 | − free(pdu); | |
| 312 | − break; | |
| 313 | − case Qphone: | |
| 314 | − str = malloc((n + 1) * sizeof(char)); | |
| 315 | − strncpy(str, va, n); | |
| 316 | − str[n] = '\0'; | |
| 317 | − printf("Qphone: va = %s\n", str); | |
| 318 | − /*nargs = gettokens(va, args, 5, " \n"); | |
| 319 | − if(strcmp(args[0]*/ | |
| 320 | − ((char *) str)[strlen(str) - 1] = '\0'; // get rid of newline | |
| 321 | − if(strncmp(str, "answer", 6) == 0) { | |
| 322 | − answer(); | |
| 323 | − return n; | |
| 324 | − } else if(strncmp(str, "dial", 4) == 0) { | |
| 325 | − split = strstr(str, " "); | |
| 326 | − if(split == NULL) break; | |
| 327 | − *split = '\0'; | |
| 328 | − split++; | |
| 329 | − | |
| 330 | − dial(split); | |
| 331 | − } | |
| 332 | − free(str); | |
| 333 | − break; | |
| 334 | − } | |
| 335 | − return n; | |
| 336 | −} | |
| 337 | − | |
| 338 | −Dev phonedevtab = { | |
| 339 | − 'f', | |
| 340 | − "phone", | |
| 341 | − | |
| 342 | − phoneinit, | |
| 343 | − phoneattach, | |
| 344 | − phonewalk, | |
| 345 | − phonestat, | |
| 346 | − phoneopen, | |
| 347 | − devcreate, | |
| 348 | − phoneclose, | |
| 349 | − phoneread, | |
| 350 | − devbread, | |
| 351 | − phonewrite, | |
| 352 | − devbwrite, | |
| 353 | − devremove, | |
| 354 | − devwstat | |
| 355 | −}; | |
| 356 | − | |
| 357 | −/* Parcel-handling code */ | |
| 358 | −#define PAD_SIZE(s) (((s)+3)&~3) | |
| 359 | − | |
| 360 | −struct parcel { | |
| 361 | − char *data; | |
| 362 | − size_t offset; | |
| 363 | − size_t capacity; | |
| 364 | − size_t size; | |
| 365 | −}; | |
| 366 | − | |
| 367 | −int parcel_init(struct parcel *p) | |
| 368 | −{ | |
| 369 | − p->data = malloc(sizeof(int32_t)); // arbitrary size to start with | |
| 370 | − if(p->data == NULL) return -1; | |
| 371 | − p->size = 0; | |
| 372 | − p->capacity = sizeof(int32_t); | |
| 373 | − p->offset = 0; | |
| 374 | − return 0; | |
| 375 | −} | |
| 376 | − | |
| 377 | −int parcel_grow(struct parcel *p, size_t size) | |
| 378 | −{ | |
| 379 | − char *new = realloc(p->data, p->capacity + size); | |
| 380 | − | |
| 381 | − if(new == NULL) { | |
| 382 | − return -1; | |
| 383 | − } | |
| 384 | − p->data = new; | |
| 385 | − p->capacity += size; | |
| 386 | − return 0; | |
| 387 | −} | |
| 388 | − | |
| 389 | −void parcel_free(struct parcel *p) | |
| 390 | −{ | |
| 391 | − free(p->data); | |
| 392 | − p->size = 0; | |
| 393 | − p->capacity = 0; | |
| 394 | − p->offset = 0; | |
| 395 | −} | |
| 396 | − | |
| 397 | −int32_t parcel_r_int32(struct parcel *p) | |
| 398 | −{ | |
| 399 | − int32_t ret; | |
| 400 | − ret = *((int32_t *) (p->data + p->offset)); | |
| 401 | − p->offset += sizeof(int32_t); | |
| 402 | − return ret; | |
| 403 | −} | |
| 404 | − | |
| 405 | −int parcel_w_int32(struct parcel *p, int32_t val) | |
| 406 | −{ | |
| 407 | − for(;;) { | |
| 408 | − printf("parcel_w_int32(%d): offset = %d, cap = %d, size = %d\n", | |
| 409 | − val, p->offset, p->capacity, p->size); | |
| 410 | − if(p->offset + sizeof(int32_t) < p->capacity) { | |
| 411 | − // There's enough space | |
| 412 | − *((int32_t *) (p->data + p->offset)) = val; | |
| 413 | − p->offset += sizeof(int32_t); | |
| 414 | − p->size += sizeof(int32_t); | |
| 415 | − break; | |
| 416 | − } else { | |
| 417 | − // Grow data and retry | |
| 418 | − if(parcel_grow(p, sizeof(int32_t)) == -1) { | |
| 419 | − return -1; | |
| 420 | − } | |
| 421 | − } | |
| 422 | − } | |
| 423 | − return 0; | |
| 424 | −} | |
| 425 | − | |
| 426 | −int parcel_w_string(struct parcel *p, char *str) | |
| 427 | −{ | |
| 428 | − char16_t *s16; | |
| 429 | − size_t s16_len; | |
| 430 | − size_t len; | |
| 431 | − | |
| 432 | − printf("parcel_w_string\n"); | |
| 433 | − if(str == NULL) { | |
| 434 | − parcel_w_int32(p, -1); | |
| 435 | − return 0; | |
| 436 | − } | |
| 437 | − // we have to avoid strdup8to16 here because inferno doesn't like us | |
| 438 | − // free()ing the memory that strdup8to16 creates. | |
| 439 | − s16_len = strlen8to16(str); | |
| 440 | − s16 = malloc(sizeof(char16_t) * s16_len); | |
| 441 | − strcpy8to16(s16, str, &s16_len); | |
| 442 | − if(parcel_w_int32(p, s16_len) == -1) { | |
| 443 | − return -1; | |
| 444 | − } | |
| 445 | − len = (s16_len + 1) * sizeof(char16_t); | |
| 446 | − for(;;) { | |
| 447 | − size_t padded = PAD_SIZE(len); | |
| 448 | − /*printf("parcel_w_string(\"%s\"): offset %d, cap %d, size %d\n", | |
| 449 | − str, p->offset, p->capacity, p->size);*/ | |
| 450 | − if(p->offset + len < p->capacity) { | |
| 451 | − // There's enough space | |
| 452 | − memcpy(p->data + p->offset, s16, s16_len * sizeof(char16_t)); | |
| 453 | − *((char16_t *) (p->data + p->offset + len)) = 0; | |
| 454 | − p->offset += padded; | |
| 455 | − p->size += padded; | |
| 456 | − if (padded != len) { | |
| 457 | − //printf("Writing %ld bytes, padded to %ld\n", len, padded); | |
| 458 | −#if BYTE_ORDER == BIG_ENDIAN | |
| 459 | − static const uint32_t mask[4] = { | |
| 460 | − 0x00000000, 0xffffff00, 0xffff0000, 0xff000000 | |
| 461 | − }; | |
| 462 | −#endif | |
| 463 | −#if BYTE_ORDER == LITTLE_ENDIAN | |
| 464 | − static const uint32_t mask[4] = { | |
| 465 | − 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff | |
| 466 | − }; | |
| 467 | −#endif | |
| 468 | − //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len], | |
| 469 | − // *reinterpret_cast<void**>(data+padded-4)); | |
| 470 | − *((uint32_t*)(p->data+p->offset+padded-4)) &= mask[padded-len]; | |
| 471 | − } | |
| 472 | − break; | |
| 473 | − } else { | |
| 474 | − // Grow data and retry | |
| 475 | − if(parcel_grow(p, padded) == -1) { | |
| 476 | − free(s16); | |
| 477 | − return -1; | |
| 478 | − } | |
| 479 | − } | |
| 480 | − } | |
| 481 | − free(s16); | |
| 482 | − return 0; | |
| 483 | −} | |
| 484 | − | |
| 485 | −char *parcel_r_string(struct parcel *p) | |
| 486 | −{ | |
| 487 | − char *ret; | |
| 488 | − int len = parcel_r_int32(p); | |
| 489 | − printf("parcel_r_string: len = %d\n", len); | |
| 490 | − if(len < 0) return NULL; // this is how a null string is sent | |
| 491 | − ret = strndup16to8((char16_t *) (p->data + p->offset), len); | |
| 492 | − p->offset += PAD_SIZE((len + 1) * sizeof(char16_t)); | |
| 493 | − return ret; | |
| 494 | −} | |
| 495 | − | |
| 496 | −size_t parcel_data_avail(struct parcel *p) | |
| 497 | −{ | |
| 498 | − return (p->size - p->offset); | |
| 499 | −} | |
| 500 | − | |
| 501 | −/* Received SMS - we get a hex string representation of the data. | |
| 502 | − Roughly, the layout of the data is: | |
| 503 | − 1 byte - length of SMS center information | |
| 504 | − 1 byte - the format of the number (91 is the standard) | |
| 505 | − (length above - 1) bytes - the number, nibble-swapped and padded with an | |
| 506 | − f if needed | |
| 507 | − 1 byte - properties of the message, generally we can ignore this | |
| 508 | − 1 byte - length of sender number (in digits, not bytes) | |
| 509 | − variable bytes - sender number, nibble-swapped and padded if needed | |
| 510 | − 1 byte - protocol identifier - can ignore this probably | |
| 511 | − 1 byte - data coding scheme - again can hopefully be ignored | |
| 512 | − 7 bytes - timestamp, again nibble-swapped: y, m, d, h, m, s, timezone | |
| 513 | − * timezone is in units of +15 min vs. GMT. If most sig. bit is | |
| 514 | − 1, value is in units of -15 min vs. GMT. | |
| 515 | − 1 byte - length of message in characters (NOT in bytes) | |
| 516 | − rest of bytes - message. if ASCII 7-bit, compacted to save space through | |
| 517 | − an encoding mechanism. | |
| 518 | − For more information see http://www.dreamfabric.com/sms/ or GSM 03.38 | |
| 519 | −*/ | |
| 520 | − | |
| 521 | −struct recvd_sms { | |
| 522 | − char *src_num; | |
| 523 | − char *service_center; | |
| 524 | − char *msg; | |
| 525 | − char *timestamp; | |
| 526 | −}; | |
| 527 | − | |
| 528 | −char gsm_to_ascii(char gsm); | |
| 529 | −int decode_sms(char *hexstr, struct recvd_sms *sms); | |
| 530 | −void acknowledge_sms(void); | |
| 531 | − | |
| 532 | −void usage(char *name); | |
| 533 | − | |
| 534 | − | |
| 535 | −/* SMS-related functions */ | |
| 536 | − | |
| 537 | −// writes UTF-8 translation to out and returns number of bytes written | |
| 538 | −int gsm_to_utf8(char gsm, char *out) | |
| 539 | −{ | |
| 540 | − switch(gsm) { | |
| 541 | − case '\0': *out = '@'; return 1; | |
| 542 | − case 1: out[0] = 0xC2; out[1] = 0xA3; return 2; // £ | |
| 543 | − case 2: *out = '$'; return 1; | |
| 544 | − case 3: out[0] = 0xC2; out[1] = 0xA5; return 2; // ¥ | |
| 545 | − case 4: out[0] = 0xC3; out[1] = 0xA8; return 2; // è | |
| 546 | − case 5: out[0] = 0xC3; out[1] = 0xA9; return 2; // é | |
| 547 | − case 6: out[0] = 0xC3; out[1] = 0xB9; return 2; // ù | |
| 548 | − case 7: out[0] = 0xC3; out[1] = 0xAC; return 2; // ì | |
| 549 | − case 8: out[0] = 0xC3; out[1] = 0xB2; return 2; // ò | |
| 550 | − case 9: out[0] = 0xC3; out[1] = 0x87; return 2; // Ç | |
| 551 | − case 11: out[0] = 0xC3; out[1] = 0x98; return 2; // Ø | |
| 552 | − case 12: out[0] = 0xC3; out[1] = 0xB8; return 2; // ø | |
| 553 | − case 14: out[0] = 0xC3; out[1] = 0x85; return 2; // Å | |
| 554 | − case 15: out[0] = 0xC3; out[1] = 0xA5; return 2; // å | |
| 555 | − case 16: out[0] = 0xCE; out[1] = 0x94; return 2; // Δ | |
| 556 | − case 17: *out = '_'; return 1; | |
| 557 | − case 18: out[0] = 0xCE; out[1] = 0xA6; return 2; // Φ | |
| 558 | − case 19: out[0] = 0xCE; out[1] = 0x93; return 2; // Γ | |
| 559 | − case 20: out[0] = 0xCE; out[1] = 0x9B; return 2; // Λ | |
| 560 | − case 21: out[0] = 0xCE; out[1] = 0xA9; return 2; // Ω | |
| 561 | − case 22: out[0] = 0xCE; out[1] = 0xA0; return 2; // Π | |
| 562 | − case 23: out[0] = 0xCE; out[1] = 0xA8; return 2; // Ψ | |
| 563 | − case 24: out[0] = 0xCE; out[1] = 0xA3; return 2; // Σ | |
| 564 | − case 25: out[0] = 0xCE; out[1] = 0x98; return 2; // Θ | |
| 565 | − case 26: out[0] = 0xCE; out[1] = 0x9E; return 2; // Ξ | |
| 566 | − case 27: // extension character | |
| 567 | − *out = '?'; return 1; | |
| 568 | − case 28: out[0] = 0xC3; out[1] = 0x86; return 2; // Æ | |
| 569 | − case 29: out[0] = 0xC3; out[1] = 0xA6; return 2; // æ | |
| 570 | − case 30: out[0] = 0xC3; out[1] = 0x9F; return 2; // ß | |
| 571 | − case 31: out[0] = 0xC3; out[1] = 0x89; return 2; // É | |
| 572 | − case 36: out[0] = 0xC2; out[1] = 0xA4; return 2; // ¤ | |
| 573 | − case 64: out[0] = 0xC2; out[1] = 0xA1; return 2; // ¡ | |
| 574 | − case 91: out[0] = 0xC3; out[1] = 0x84; return 2; // Ä | |
| 575 | − case 92: out[0] = 0xC3; out[1] = 0x96; return 2; // Ö | |
| 576 | − case 93: out[0] = 0xC3; out[1] = 0x91; return 2; // Ñ | |
| 577 | − case 94: out[0] = 0xC3; out[1] = 0x9C; return 2; // Ü | |
| 578 | − case 95: out[0] = 0xC2; out[1] = 0xA7; return 2; // § | |
| 579 | − case 96: out[0] = 0xC2; out[1] = 0xBF; return 2; // ¿ | |
| 580 | − case 123: out[0] = 0xC3; out[1] = 0xA4; return 2; // ä | |
| 581 | − case 124: out[0] = 0xC3; out[1] = 0xB6; return 2; // ö | |
| 582 | − case 125: out[0] = 0xC3; out[1] = 0xB1; return 2; // ñ | |
| 583 | − case 126: out[0] = 0xC3; out[1] = 0xBC; return 2; // ü | |
| 584 | − case 127: out[0] = 0xC3; out[1] = 0xA0; return 2; // à | |
| 585 | − default: *out = gsm; return 1; | |
| 586 | − } | |
| 587 | − *out = 'a'; printf("out = %02x\n", *out); return 1; | |
| 588 | −} | |
| 589 | − | |
| 590 | −char *hexify(char *bytes, size_t len) | |
| 591 | −{ | |
| 592 | − char *hexarray[256]; | |
| 593 | − int i, j; | |
| 594 | − char *ret; | |
| 595 | − for(i = 0; i < 256; i++) { | |
| 596 | − hexarray[i] = (char *) malloc(3 * sizeof(char)); | |
| 597 | − snprintf(hexarray[i], 3, "%02x", i); | |
| 598 | − } | |
| 599 | − ret = (char *) malloc((len * 2 + 1) * sizeof(char)); | |
| 600 | − for(i = 0, j = 0; i < len; i++, j += 2) { | |
| 601 | − ret[j] = hexarray[(unsigned char) bytes[i]][0]; | |
| 602 | − ret[j + 1] = hexarray[(unsigned char) bytes[i]][1]; | |
| 603 | − } | |
| 604 | − ret[j] = '\0'; | |
| 605 | − for(i = 0; i < 256; i++) { | |
| 606 | − free(hexarray[i]); | |
| 607 | − } | |
| 608 | − return ret; | |
| 609 | −} | |
| 610 | − | |
| 611 | −int decode_sms(char *hexstr, struct recvd_sms *sms) | |
| 612 | −{ | |
| 613 | − int smsc_len, src_len, curpos, msg_len; | |
| 614 | − char *endptr; | |
| 615 | − char **bytes; | |
| 616 | − char *service_center, *src_num, *timestamp, *msg; | |
| 617 | − int len, i, j, oldbits, numoldbits, utf8msglen = 0; | |
| 618 | − char msgbytes[160]; | |
| 619 | − | |
| 620 | − /* first, split the string up into hex representations of the bytes-- | |
| 621 | − this makes things much easier overall */ | |
| 622 | − len = strlen(hexstr); | |
| 623 | − if(len % 2 != 0) { | |
| 624 | − fprintf(stderr, "malformed hex string passed to decode_sms\n"); | |
| 625 | − return -1; | |
| 626 | − } | |
| 627 | − bytes = (char **) malloc((len / 2) * sizeof(char *)); | |
| 628 | − for(i = 0; i < len / 2; i++) { | |
| 629 | − bytes[i] = (char *) malloc(3 * sizeof(char)); | |
| 630 | − bytes[i][0] = hexstr[i * 2]; | |
| 631 | − bytes[i][1] = hexstr[i * 2 + 1]; | |
| 632 | − bytes[i][2] = '\0'; | |
| 633 | − } | |
| 634 | − | |
| 635 | − // decode the service center number | |
| 636 | − smsc_len = strtol(bytes[0], &endptr, 16); | |
| 637 | − if(strcmp(bytes[1], "91")) { | |
| 638 | − fprintf(stderr, "unsupported number format for sender: %s", | |
| 639 | − bytes[1]); | |
| 640 | − } | |
| 641 | − service_center = (char *) malloc((smsc_len + 2) * sizeof(char)); | |
| 642 | − service_center[0] = '\0'; | |
| 643 | − for(i = 2, j = 0; i < smsc_len + 1; i++, j += 2) { | |
| 644 | − // number is nibble-swapped | |
| 645 | − service_center[j] = bytes[i][1]; | |
| 646 | − if(bytes[i][0] == 'f') { // num may be padded with 'f' at end | |
| 647 | − service_center[j + 1] = '\0'; | |
| 648 | − } else { | |
| 649 | − service_center[j + 1] = bytes[i][0]; | |
| 650 | − } | |
| 651 | − } | |
| 652 | − service_center[j] = '\0'; | |
| 653 | − curpos = i; | |
| 654 | − sms->service_center = service_center; | |
| 655 | − | |
| 656 | − // next, decode the sender's number | |
| 657 | − src_len = strtol(bytes[curpos + 1], NULL, 16); | |
| 658 | − src_num = (char *) malloc((src_len + 2) * sizeof(char)); | |
| 659 | − // convert src_len from # of digits to # of bytes | |
| 660 | − src_len = (src_len % 2 == 0) ? src_len : src_len + 1; | |
| 661 | − src_len = src_len / 2; | |
| 662 | − if(strcmp(bytes[curpos + 2], "91")) { | |
| 663 | − fprintf(stderr, "unsupported number format for sender: %s", | |
| 664 | − bytes[curpos + 2]); | |
| 665 | − } | |
| 666 | − for(i = curpos + 3, j = 0; i < curpos + 3 + src_len; i++, j += 2) { | |
| 667 | − // number is nibble-swapped | |
| 668 | − src_num[j] = bytes[i][1]; | |
| 669 | − if(bytes[i][0] == 'f') { // num may be padded with 'f' at end | |
| 670 | − src_num[j + 1] = '\0'; | |
| 671 | − } else { | |
| 672 | − src_num[j + 1] = bytes[i][0]; | |
| 673 | − } | |
| 674 | − } | |
| 675 | − src_num[j] = '\0'; | |
| 676 | − sms->src_num = src_num; | |
| 677 | − curpos = i; | |
| 678 | − | |
| 679 | − // Timestamp | |
| 680 | − // TODO: may want to convert this to a time_t value as well | |
| 681 | − | |
| 682 | − timestamp = (char *) malloc(15 * sizeof(char)); | |
| 683 | − for(i = curpos + 2, j = 0; i < curpos + 9; i++, j += 2) { | |
| 684 | − // number is nibble-swapped | |
| 685 | − timestamp[j] = bytes[i][1]; | |
| 686 | − timestamp[j + 1] = bytes[i][0]; | |
| 687 | − } | |
| 688 | − curpos = i; | |
| 689 | − timestamp[j] = '\0'; | |
| 690 | − sms->timestamp = timestamp; | |
| 691 | − | |
| 692 | − // Message | |
| 693 | − | |
| 694 | − msg_len = (len / 2) - (curpos + 1); | |
| 695 | − for(i = curpos + 1, j = 0; i < len / 2, j < msg_len; i++, j++) { | |
| 696 | − msgbytes[j] = strtol(bytes[i], NULL, 16); | |
| 697 | − } | |
| 698 | − // Calculate the # of UTF-8 bytes the message will take up by | |
| 699 | − // doing a first pass with gsm_to_ascii - this is terrible and could | |
| 700 | − // probably be done in a better way. FIXME | |
| 701 | −/* oldbits = 0; | |
| 702 | − numoldbits = 0; | |
| 703 | − for(i = 0, j = 0; i < msg_len; i++) { | |
| 704 | − int numbits = (i % 7) + 1; | |
| 705 | − int newbits; | |
| 706 | − char garbage[4]; | |
| 707 | − newbits = msgbytes[i] >> (8 - numbits); | |
| 708 | − newbits &= (1 << numbits) - 1; | |
| 709 | − msgbytes[i] = msgbytes[i] & ((1 << (8 - numbits)) - 1); | |
| 710 | − msgbytes[i] = msgbytes[i] << numoldbits; | |
| 711 | − // repurpose gsm_to_utf8 to just give us the length. bad | |
| 712 | − utf8msglen += gsm_to_utf8(((msgbytes[i] & ((1 << (8 - numbits)) - 1)) << numoldbits) | oldbits, garbage); | |
| 713 | − if(numbits == 7) { | |
| 714 | − utf8msglen += gsm_to_utf8(newbits, garbage); | |
| 715 | − newbits = 0; | |
| 716 | − numbits = 0; | |
| 717 | − } | |
| 718 | − oldbits = newbits; | |
| 719 | − numoldbits = numbits; | |
| 720 | − } | |
| 721 | − printf("calculated utf8msglen = %d\n", utf8msglen); | |
| 722 | −*/ | |
| 723 | − // FIXME | |
| 724 | − utf8msglen = 400; | |
| 725 | − msg = (char *) malloc((utf8msglen + 1) * sizeof(char)); | |
| 726 | − | |
| 727 | − // convert message to UTF-8 | |
| 728 | − oldbits = 0; | |
| 729 | − numoldbits = 0; | |
| 730 | − for(i = 0, j = 0; i < msg_len; i++) { | |
| 731 | − int numbits = (i % 7) + 1; | |
| 732 | − int newbits; | |
| 733 | − newbits = msgbytes[i] >> (8 - numbits); | |
| 734 | − newbits &= (1 << numbits) - 1; | |
| 735 | − msgbytes[i] = msgbytes[i] & ((1 << (8 - numbits)) - 1); | |
| 736 | − msgbytes[i] = msgbytes[i] << numoldbits; | |
| 737 | − // GSM alphabet is different than UTF-8 alphabet | |
| 738 | − j += gsm_to_utf8(msgbytes[i] | oldbits, msg + j); | |
| 739 | − if(numbits == 7) { | |
| 740 | − msg[j] = newbits; | |
| 741 | − j++; | |
| 742 | − newbits = 0; | |
| 743 | − numbits = 0; | |
| 744 | − } | |
| 745 | − oldbits = newbits; | |
| 746 | − numoldbits = numbits; | |
| 747 | − } | |
| 748 | − msg[j] = '\0'; | |
| 749 | − sms->msg = msg; | |
| 750 | − // cleanup | |
| 751 | − for(i = 0; i < len / 2; i++) { | |
| 752 | − free(bytes[i]); | |
| 753 | − } | |
| 754 | − free(bytes); | |
| 755 | − return 0; | |
| 756 | −} | |
| 757 | − | |
| 758 | −char *encode_sms(char *destnum, char *msg) | |
| 759 | −{ | |
| 760 | − int i, j, actual_dest_len, enc_msg_len, ret_len; | |
| 761 | − char dest_len[3]; | |
| 762 | − char *dest; | |
| 763 | − char *enc_msg, *final_msg, *ret; | |
| 764 | − // dest_len is the hex representation of the length of the phone # | |
| 765 | − snprintf(dest_len, 3, "%02x", strlen(destnum)); | |
| 766 | − actual_dest_len = (strlen(destnum) % 2 == 0) ? strlen(destnum) : strlen(destnum) + 1; | |
| 767 | − dest = (char *) malloc((actual_dest_len + 1) * sizeof(char)); | |
| 768 | − for(i = 0; i < actual_dest_len; i += 2) { | |
| 769 | − if(destnum[i + 1] != '\0') { | |
| 770 | − dest[i] = destnum[i + 1]; | |
| 771 | − } else { | |
| 772 | − dest[i] = 'f'; | |
| 773 | − } | |
| 774 | − dest[i + 1] = destnum[i]; | |
| 775 | − } | |
| 776 | − dest[i] = '\0'; | |
| 777 | −// printf("dest = %s\n", dest); | |
| 778 | − enc_msg_len = strlen(msg) - (strlen(msg) / 8); | |
| 779 | − enc_msg = (char *) malloc((enc_msg_len + 1) * sizeof(char)); | |
| 780 | − for(i = 0, j = 0; i < strlen(msg); i++, j++) { | |
| 781 | − int numbits = (i + 1) % 8; | |
| 782 | − char bits; | |
| 783 | − if(numbits == 0) { | |
| 784 | − j--; | |
| 785 | − continue; | |
| 786 | − } | |
| 787 | − bits = msg[i + 1] & ((1 << numbits) - 1); | |
| 788 | − enc_msg[j] = msg[i] >> numbits - 1; | |
| 789 | −// printf("once shifted by %d: %hhx\n", numbits, enc_msg[j]); | |
| 790 | − enc_msg[j] = enc_msg[j] | (bits << (8 - numbits)); | |
| 791 | −// printf("bits << (8 - numbits) %hhx\n", bits << (8 - numbits)); | |
| 792 | −// printf("%hhx\n", enc_msg[j]); | |
| 793 | − fflush(stdout); | |
| 794 | − } | |
| 795 | − final_msg = hexify(enc_msg, enc_msg_len); | |
| 796 | − ret_len = 14 + strlen(dest) + strlen(final_msg); | |
| 797 | − ret = (char *) malloc((ret_len + 1) * sizeof(char)); | |
| 798 | − // FIXME: too much of the sent msg is hardcoded | |
| 799 | − snprintf(ret, ret_len + 1, "0120%s91%s0000%02x%s", dest_len, dest, strlen(msg), final_msg); | |
| 800 | −// printf("%s\n", ret); | |
| 801 | − free(enc_msg); | |
| 802 | − free(final_msg); | |
| 803 | − free(dest); | |
| 804 | − return ret; | |
| 805 | −} | |
| 806 | − | |
| 807 | −/* functions that actually belong here */ | |
| 808 | − | |
| 809 | −void handle_error(int seq, int error) | |
| 810 | −{ | |
| 811 | − // RIL error messages | |
| 812 | − char *errmsgs[] = { "no error", "radio not available", "generic failure", "password incorrect", "need SIM PIN2", "need SIM PUK2", "request not supported", "cancelled", "cannot access network during voice calls", "cannot access network before registering to network", "retry sending sms", "no SIM", "no subscription", "mode not supported", "FDN list check failed", "illegal SIM or ME" }; | |
| 813 | − char *errmsg = errmsgs[error]; | |
| 814 | − switch(seq) { | |
| 815 | − case RIL_REQUEST_SEND_SMS: | |
| 816 | − qproduce(smsq, errmsg, strlen(errmsg)); | |
| 817 | − break; | |
| 818 | − } | |
| 819 | −} | |
| 820 | − | |
| 821 | −void interpret_sol_response(struct parcel *p) | |
| 822 | −{ | |
| 823 | − int seq, error, i, num, offset = 0; | |
| 824 | − char buf[200]; | |
| 825 | − seq = parcel_r_int32(p); | |
| 826 | − error = parcel_r_int32(p); | |
| 827 | − printf("received sol response: seq: %d err: %d\n", seq, error); | |
| 828 | − if(error != 0) { | |
| 829 | − handle_error(seq, error); | |
| 830 | − return; | |
| 831 | − } | |
| 832 | − switch(seq) { | |
| 833 | − case RIL_REQUEST_SETUP_DATA_CALL: | |
| 834 | − if(!parcel_data_avail(p)) return; | |
| 835 | − num = parcel_r_int32(p); | |
| 836 | − printf("num = %d\n", num); | |
| 837 | − for(i = 0; i < num; i++) { | |
| 838 | − printf("%s\n", parcel_r_string(p)); | |
| 839 | − } | |
| 840 | − break; | |
| 841 | − case POWER_ON: | |
| 842 | − power_state = 1; | |
| 843 | − break; | |
| 844 | − case POWER_OFF: | |
| 845 | − power_state = 0; | |
| 846 | − break; | |
| 847 | − case RIL_REQUEST_REGISTRATION_STATE: | |
| 848 | − if(!parcel_data_avail(p)) return; | |
| 849 | − num = parcel_r_int32(p); | |
| 850 | − offset = 0; | |
| 851 | − for(i = 0; i < num; i++) { | |
| 852 | − offset += snprintf(buf + offset, sizeof(buf) - offset, "%s\n", parcel_r_string(p)); | |
| 853 | − } | |
| 854 | − // FIXME lock | |
| 855 | − free(status_msg.msg); | |
| 856 | − status_msg.msg = strdup(buf); | |
| 857 | − sem_post(&status_msg.sem); | |
| 858 | − break; | |
| 859 | − case RIL_REQUEST_DIAL: | |
| 860 | −// setCallClockSync(ril_client, SOUND_CLOCK_START); | |
| 861 | − printf("setcallvolume returned %d\n", | |
| 862 | − setCallVolume(ril_client, SOUND_TYPE_VOICE, 4)); | |
| 863 | − printf("setcallaudiopath returned %d\n", setCallAudioPath(ril_client, SOUND_AUDIO_PATH_HANDSET)); | |
| 864 | − printf("setcallvolume returned %d\n", | |
| 865 | − setCallVolume(ril_client, SOUND_TYPE_VOICE, 4)); | |
| 866 | − printf("got RIL_REQUEST_DIAL success\n"); | |
| 867 | − set_mute(0); | |
| 868 | −// setCallClockSync(ril_client, SOUND_CLOCK_START); | |
| 869 | − break; | |
| 870 | − case RIL_REQUEST_GET_CURRENT_CALLS: | |
| 871 | − // DEBUG | |
| 872 | − printf("current pos: %d\n", p->offset); | |
| 873 | − for(i = 0; i < p->size; i++) { | |
| 874 | − printf("%02x ", p->data[i]); | |
| 875 | − } | |
| 876 | − printf("\n"); | |
| 877 | − | |
| 878 | − if(!parcel_data_avail(p)) { | |
| 879 | − break; | |
| 880 | − } | |
| 881 | − | |
| 882 | − wlock(&calls.l); | |
| 883 | − free(calls.cs); | |
| 884 | − num = parcel_r_int32(p); | |
| 885 | − calls.num = num; | |
| 886 | − calls.cs = malloc(num * sizeof(RIL_Call)); | |
| 887 | − if(calls.cs == NULL) { | |
| 888 | − wunlock(&calls.l); | |
| 889 | − fprintf(stderr, "malloc failed while making %d RIL_Calls\n", num); | |
| 890 | − break; | |
| 891 | − } | |
| 892 | − | |
| 893 | − for(i = 0; i < num; i++) { | |
| 894 | − printf("processing call %d\n", i); | |
| 895 | − calls.cs[i].state = parcel_r_int32(p); | |
| 896 | − printf("state %d\n", calls.cs[i].state); | |
| 897 | − calls.cs[i].index = parcel_r_int32(p); | |
| 898 | − calls.cs[i].toa = parcel_r_int32(p); | |
| 899 | − calls.cs[i].isMpty = parcel_r_int32(p); | |
| 900 | − calls.cs[i].isMT = parcel_r_int32(p); | |
| 901 | − calls.cs[i].als = parcel_r_int32(p); | |
| 902 | − calls.cs[i].isVoice = parcel_r_int32(p); | |
| 903 | − printf("isVoice\n"); | |
| 904 | − fflush(stdout); | |
| 905 | − calls.cs[i].isVoicePrivacy = parcel_r_int32(p); | |
| 906 | − printf("isVoicePrivacy\n"); | |
| 907 | − fflush(stdout); | |
| 908 | − calls.cs[i].number = parcel_r_string(p); | |
| 909 | − printf("number %s\n", calls.cs[i].number); | |
| 910 | − fflush(stdout); | |
| 911 | − calls.cs[i].numberPresentation = parcel_r_int32(p); | |
| 912 | − calls.cs[i].name = parcel_r_string(p); | |
| 913 | − calls.cs[i].namePresentation = parcel_r_int32(p); | |
| 914 | − calls.cs[i].uusInfo = parcel_r_int32(p) ? | |
| 915 | − malloc(sizeof(RIL_UUS_Info)) : | |
| 916 | − NULL; | |
| 917 | − if(calls.cs[i].uusInfo != NULL) { | |
| 918 | − // FIXME not implemented yet | |
| 919 | − printf("debug: got uusInfo\n"); | |
| 920 | − } | |
| 921 | − } | |
| 922 | − printf("about to wunlock\n"); | |
| 923 | − wunlock(&calls.l); | |
| 924 | − for(i = 0; i < calls.num; i++) { | |
| 925 | − RIL_Call c = calls.cs[i]; | |
| 926 | − printf("call %d:\n state %d\n index %d\n toa %d\n" | |
| 927 | − "isMpty %d\n isMT %d\n als %d\n isVoice %d\n" | |
| 928 | − "isVoicePrivacy %d\n number %s\n" | |
| 929 | − "numberPresentation %d\n name %s\n" | |
| 930 | − "namePresentation %d\n", | |
| 931 | − i, c.state, c.index, c.toa, c.isMpty, c.isMT, | |
| 932 | − c.als, c.isVoice, c.isVoicePrivacy, c.number, | |
| 933 | − c.numberPresentation, c.name, | |
| 934 | − c.namePresentation); | |
| 935 | − } | |
| 936 | − break; | |
| 937 | − } | |
| 938 | −} | |
| 939 | − | |
| 940 | −void interpret_unsol_response(struct parcel *p) | |
| 941 | −{ | |
| 942 | − int resp_type; | |
| 943 | − char buf[300]; | |
| 944 | − int l; | |
| 945 | − struct recvd_sms sms; | |
| 946 | − resp_type = parcel_r_int32(p); | |
| 947 | −// printf("unsolicited: type = %d, data left = %d\n", resp_type, | |
| 948 | −// parcel_data_avail(p)); | |
| 949 | − switch(resp_type) { | |
| 950 | − case RIL_UNSOL_RESPONSE_NEW_SMS: | |
| 951 | − decode_sms(parcel_r_string(p), &sms); | |
| 952 | − l = snprintf(buf, sizeof(buf), "%s (%s): %s\n", sms.src_num, | |
| 953 | − sms.timestamp, sms.msg); | |
| 954 | − buf[l] = '\0'; | |
| 955 | − qproduce(smsq, buf, strlen(buf)); | |
| 956 | − | |
| 957 | − free(sms.msg); | |
| 958 | − free(sms.service_center); | |
| 959 | − free(sms.src_num); | |
| 960 | − free(sms.timestamp); | |
| 961 | − break; | |
| 962 | − case RIL_UNSOL_CALL_RING: | |
| 963 | − printf("incoming call\n"); | |
| 964 | − qproduce(phoneq, "ring\n", 5); | |
| 965 | − break; | |
| 966 | − case RIL_UNSOL_SIGNAL_STRENGTH: | |
| 967 | − signal_strength = parcel_r_int32(p) / 6; // signal strength from cell tower | |
| 968 | − // TODO: use bit error rate instead of cell tower reception | |
| 969 | − // when available (during a call) | |
| 970 | − break; | |
| 971 | − } | |
| 972 | −} | |
| 973 | − | |
| 974 | −// FIXME: read() needs to be handled better in this function, allow it to | |
| 975 | −// underrun and just loop again to get the rest of the data | |
| 976 | −void loop_for_data(void *v) | |
| 977 | −{ | |
| 978 | − seteuid(1001); | |
| 979 | − for(;;) { | |
| 980 | − int msglen, readlen, type, i, ret; | |
| 981 | − char *buf; | |
| 982 | − struct parcel p; | |
| 983 | − | |
| 984 | − parcel_init(&p); | |
| 985 | − if((ret = read(fd, &msglen, sizeof(msglen))) != sizeof(msglen)) { | |
| 986 | − perror("loop_for_data"); | |
| 987 | − fprintf(stderr, "EOF while reading parcel length\n"); | |
| 988 | − fprintf(stderr, "read returned %d\n", ret); | |
| 989 | − return; | |
| 990 | − } | |
| 991 | − msglen = ntohl(msglen); | |
| 992 | − buf = (char *) malloc(msglen * sizeof(char)); | |
| 993 | − if(buf == NULL) { | |
| 994 | − fprintf(stderr, "devphone:loop_for_data: malloc failed when attempting to allocate %d bytes\n", msglen); | |
| 995 | − return; | |
| 996 | − } | |
| 997 | − readlen = read(fd, buf, msglen); | |
| 998 | − if(readlen != msglen) { | |
| 999 | − fprintf(stderr, "msglen = %d readlen = %d\n", msglen, | |
| 1000 | − readlen); | |
| 1001 | − fprintf(stderr, | |
| 1002 | − "got too much or not enough data, aborting\n"); | |
| 1003 | − free(buf); | |
| 1004 | − return; | |
| 1005 | − } | |
| 1006 | − /* for(i = 0; i < readlen; i++) { | |
| 1007 | − printf("%02x", buf[i]); | |
| 1008 | − } | |
| 1009 | − printf("\n");*/ | |
| 1010 | − parcel_grow(&p, msglen); | |
| 1011 | − memcpy(p.data, buf, msglen); | |
| 1012 | − p.size = msglen; | |
| 1013 | − // printf("Received %d bytes of data from rild.\n", msglen); | |
| 1014 | − type = parcel_r_int32(&p); | |
| 1015 | − if(type == RESPONSE_SOLICITED) { | |
| 1016 | − interpret_sol_response(&p); | |
| 1017 | − } else { | |
| 1018 | − interpret_unsol_response(&p); | |
| 1019 | − } | |
| 1020 | − parcel_free(&p); | |
| 1021 | − free(buf); | |
| 1022 | − sleep(2); // FIXME may not be necessary | |
| 1023 | − } | |
| 1024 | −} | |
| 1025 | − | |
| 1026 | −void send_ril_parcel(struct parcel *p) | |
| 1027 | −{ | |
| 1028 | − int pktlen, ret; | |
| 1029 | − pktlen = htonl(p->size); | |
| 1030 | − ret = write(fd, (void *)&pktlen, sizeof(pktlen)); | |
| 1031 | − if(ret < 0) perror("write to ril failed"); | |
| 1032 | − ret = write(fd, p->data, p->size); | |
| 1033 | − if(ret < 0) perror("write to ril failed"); | |
| 1034 | −} | |
| 1035 | − | |
| 1036 | −void answer(void) | |
| 1037 | −{ | |
| 1038 | − struct parcel p; | |
| 1039 | − | |
| 1040 | − parcel_init(&p); | |
| 1041 | − parcel_w_int32(&p, RIL_REQUEST_ANSWER); | |
| 1042 | − parcel_w_int32(&p, RIL_REQUEST_ANSWER); | |
| 1043 | − | |
| 1044 | − send_ril_parcel(&p); | |
| 1045 | − parcel_free(&p); | |
| 1046 | −} | |
| 1047 | − | |
| 1048 | −// power is 1 for on and 0 for off | |
| 1049 | −void radio_power(int power) | |
| 1050 | −{ | |
| 1051 | − struct parcel p; | |
| 1052 | − | |
| 1053 | − parcel_init(&p); | |
| 1054 | − printf("setting radio power to %d\n", power); | |
| 1055 | − parcel_w_int32(&p, RIL_REQUEST_RADIO_POWER); | |
| 1056 | − parcel_w_int32(&p, power ? POWER_ON : POWER_OFF); | |
| 1057 | − parcel_w_int32(&p, 1); | |
| 1058 | − parcel_w_int32(&p, power); | |
| 1059 | − | |
| 1060 | − send_ril_parcel(&p); | |
| 1061 | − parcel_free(&p); | |
| 1062 | −} | |
| 1063 | − | |
| 1064 | −void dial(char *number) | |
| 1065 | −{ | |
| 1066 | − struct parcel p; | |
| 1067 | − struct mixer *mixer; | |
| 1068 | − struct pcm *pcm; | |
| 1069 | − unsigned flags = PCM_OUT; | |
| 1070 | − struct mixer_ctl *ctl; | |
| 1071 | − | |
| 1072 | −// flags |= (AUDIO_HW_OUT_PERIOD_MULT - 1) << PCM_PERIOD_SZ_SHIFT; | |
| 1073 | − // flags |= (AUDIO_HW_OUT_PERIOD_CNT - PCM_PERIOD_CNT_MIN) << PCM_PERIOD_CNT_SHIFT; | |
| 1074 | − | |
| 1075 | − setCallClockSync(ril_client, SOUND_CLOCK_START); | |
| 1076 | − | |
| 1077 | − set_mute(0); | |
| 1078 | − | |
| 1079 | − printf("isConnectedRILD = %d\n", isConnectedRILD(ril_client)); | |
| 1080 | − | |
| 1081 | −// pcm = pcm_open(flags); | |
| 1082 | − | |
| 1083 | − mixer = mixer_open(); | |
| 1084 | − if(mixer == NULL) { | |
| 1085 | − fprintf(stderr, "failed to open mixer\n"); | |
| 1086 | − } | |
| 1087 | − | |
| 1088 | − ctl = mixer_get_control(mixer, "Input Source", 0); | |
| 1089 | − mixer_ctl_select(ctl, "Default"); | |
| 1090 | − | |
| 1091 | − ctl = mixer_get_control(mixer, "Voice Call Path", 0); | |
| 1092 | − mixer_ctl_select(ctl, "RCV"); | |
| 1093 | − | |
| 1094 | − printf("setcallvolume returned %d\n", | |
| 1095 | − setCallVolume(ril_client, SOUND_TYPE_SPEAKER, 4)); | |
| 1096 | − printf("setcallaudiopath returned %d\n", setCallAudioPath(ril_client, SOUND_AUDIO_PATH_HANDSET)); | |
| 1097 | − printf("setcallvolume returned %d\n", | |
| 1098 | − setCallVolume(ril_client, SOUND_TYPE_VOICE, 4)); | |
| 1099 | − | |
| 1100 | − | |
| 1101 | − printf("before mixer_close\n"); | |
| 1102 | − fflush(stdout); | |
| 1103 | −// mixer_close(mixer); | |
| 1104 | − printf("after mixer_close"); | |
| 1105 | − fflush(stdout); | |
| 1106 | − set_mute(0); | |
| 1107 | − | |
| 1108 | − printf("before parcel_init\n"); | |
| 1109 | − fflush(stdout); | |
| 1110 | − | |
| 1111 | − parcel_init(&p); | |
| 1112 | − printf("after parcel_init\n"); | |
| 1113 | − fflush(stdout); | |
| 1114 | − parcel_w_int32(&p, RIL_REQUEST_DIAL); | |
| 1115 | − parcel_w_int32(&p, RIL_REQUEST_DIAL); | |
| 1116 | − printf("before parcel_w_string\n"); | |
| 1117 | − fflush(stdout); | |
| 1118 | − parcel_w_string(&p, number); | |
| 1119 | − printf("after parcel_w_string\n"); | |
| 1120 | − fflush(stdout); | |
| 1121 | − parcel_w_int32(&p, 0); | |
| 1122 | − parcel_w_int32(&p, 0); | |
| 1123 | − parcel_w_int32(&p, 0); | |
| 1124 | − | |
| 1125 | − send_ril_parcel(&p); | |
| 1126 | − parcel_free(&p); | |
| 1127 | −} | |
| 1128 | − | |
| 1129 | −void activate_net(void) | |
| 1130 | −{ | |
| 1131 | − struct parcel p; | |
| 1132 | − | |
| 1133 | − parcel_init(&p); | |
| 1134 | − parcel_w_int32(&p, RIL_REQUEST_SETUP_DATA_CALL); // request ID | |
| 1135 | − parcel_w_int32(&p, RIL_REQUEST_SETUP_DATA_CALL); // seq number (?) | |
| 1136 | − parcel_w_int32(&p, 7); // undocumented magic. | |
| 1137 | − parcel_w_string(&p, "1"); // CDMA or GSM. 1 = GSM | |
| 1138 | − parcel_w_string(&p, "0"); // data profile. 0 = default | |
| 1139 | − parcel_w_string(&p, "wap.cingular"); // APN name | |
| 1140 | − parcel_w_string(&p, "WAP@CINGULARGPRS.COM"); // APN user | |
| 1141 | − parcel_w_string(&p, "cingular1"); // APN passwd | |
| 1142 | − parcel_w_string(&p, "0"); // auth type. 0 usually | |
| 1143 | − | |
| 1144 | − send_ril_parcel(&p); | |
| 1145 | − parcel_free(&p); | |
| 1146 | −} | |
| 1147 | − | |
| 1148 | −void deactivate_net(void) | |
| 1149 | −{ | |
| 1150 | − struct parcel p; | |
| 1151 | − | |
| 1152 | − parcel_init(&p); | |
| 1153 | − parcel_w_int32(&p, RIL_REQUEST_DEACTIVATE_DATA_CALL); | |
| 1154 | − parcel_w_int32(&p, RIL_REQUEST_DEACTIVATE_DATA_CALL); | |
| 1155 | − parcel_w_string(&p, "1"); // FIXME: this should be the CID returned by | |
| 1156 | − // RIL_REQUEST_SETUP_DATA_CALL response | |
| 1157 | − send_ril_parcel(&p); | |
| 1158 | − parcel_free(&p); | |
| 1159 | −} | |
| 1160 | − | |
| 1161 | −void send_sms(char *smsc_pdu, char *pdu) | |
| 1162 | −{ | |
| 1163 | − struct parcel p; | |
| 1164 | − | |
| 1165 | − parcel_init(&p); | |
| 1166 | − parcel_w_int32(&p, RIL_REQUEST_SEND_SMS); | |
| 1167 | − parcel_w_int32(&p, RIL_REQUEST_SEND_SMS); | |
| 1168 | − parcel_w_int32(&p, 2); | |
| 1169 | − parcel_w_string(&p, smsc_pdu); | |
| 1170 | − parcel_w_string(&p, pdu); | |
| 1171 | − | |
| 1172 | − send_ril_parcel(&p); | |
| 1173 | − parcel_free(&p); | |
| 1174 | −} | |
| 1175 | − | |
| 1176 | −void acknowledge_sms(void) | |
| 1177 | −{ | |
| 1178 | − struct parcel p; | |
| 1179 | − | |
| 1180 | − parcel_init(&p); | |
| 1181 | − parcel_w_int32(&p, RIL_REQUEST_SMS_ACKNOWLEDGE); | |
| 1182 | − parcel_w_int32(&p, RIL_REQUEST_SMS_ACKNOWLEDGE); | |
| 1183 | − parcel_w_int32(&p, 2); | |
| 1184 | − parcel_w_int32(&p, 1); // success | |
| 1185 | − parcel_w_int32(&p, 0); // failure cause if necessary | |
| 1186 | − | |
| 1187 | − send_ril_parcel(&p); | |
| 1188 | − parcel_free(&p); | |
| 1189 | −} | |
| 1190 | − | |
| 1191 | −void get_reg_state(void) | |
| 1192 | −{ | |
| 1193 | − struct parcel p; | |
| 1194 | − | |
| 1195 | − parcel_init(&p); | |
| 1196 | − parcel_w_int32(&p, RIL_REQUEST_REGISTRATION_STATE); | |
| 1197 | − parcel_w_int32(&p, RIL_REQUEST_REGISTRATION_STATE); | |
| 1198 | − | |
| 1199 | − send_ril_parcel(&p); | |
| 1200 | − parcel_free(&p); | |
| 1201 | −} | |
| 1202 | − | |
| 1203 | −void set_mute(int muted) | |
| 1204 | −{ | |
| 1205 | − struct parcel p; | |
| 1206 | − | |
| 1207 | − parcel_init(&p); | |
| 1208 | − parcel_w_int32(&p, RIL_REQUEST_SET_MUTE); | |
| 1209 | − parcel_w_int32(&p, RIL_REQUEST_SET_MUTE); | |
| 1210 | − parcel_w_int32(&p, 1); | |
| 1211 | − parcel_w_int32(&p, muted); | |
| 1212 | − | |
| 1213 | − send_ril_parcel(&p); | |
| 1214 | − parcel_free(&p); | |
| 1215 | −} | |
| 1216 | − | |
| 1217 | −void get_current_calls(void) | |
| 1218 | −{ | |
| 1219 | − struct parcel p; | |
| 1220 | − | |
| 1221 | − parcel_init(&p); | |
| 1222 | − parcel_w_int32(&p, RIL_REQUEST_GET_CURRENT_CALLS); | |
| 1223 | − parcel_w_int32(&p, RIL_REQUEST_GET_CURRENT_CALLS); | |
| 1224 | − | |
| 1225 | − send_ril_parcel(&p); | |
| 1226 | − parcel_free(&p); | |
| 1227 | −} | |
| 1228 | − | |
| 1229 | −void hangup(int index) | |
| 1230 | −{ | |
| 1231 | − struct parcel p; | |
| 1232 | − | |
| 1233 | − parcel_init(&p); | |
| 1234 | − parcel_w_int32(&p, RIL_REQUEST_HANGUP); | |
| 1235 | − parcel_w_int32(&p, RIL_REQUEST_HANGUP); | |
| 1236 | − parcel_w_int32(&p, 1); | |
| 1237 | − parcel_w_int32(&p, index); | |
| 1238 | − | |
| 1239 | − send_ril_parcel(&p); | |
| 1240 | − parcel_free(&p); | |
| 1241 | −} | |
| @@ -88,4 +88,5 @@ void modinit(void){ · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | int dontcompile = 1; |
| 90 | 90 | char* conffile = "emu-g"; |
| 91 | +#define KERNDATE 0 | |
| 91 | 92 | ulong kerndate = KERNDATE; |
Binary file not shown.