mbed Phone Platform

Dependencies:   ulaw mbed ConfigFile

Committer:
okini3939
Date:
Fri Jan 07 18:20:41 2011 +0000
Revision:
4:41a3534d085f
Parent:
3:1d5dc4107558
Child:
5:30e2847d241b

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 2:e37117117e79 1 /** @file IpLine.cpp
okini3939 2:e37117117e79 2 * @brief IP Line Controller (mbed Phone Platform)
okini3939 2:e37117117e79 3 */
okini3939 2:e37117117e79 4
okini3939 2:e37117117e79 5 #include "IpLine.h"
okini3939 2:e37117117e79 6
okini3939 4:41a3534d085f 7 #define NET_RETRY (FREQ)
okini3939 4:41a3534d085f 8 #define NET_TIMEOUT (FREQ * 3)
okini3939 4:41a3534d085f 9 #define PACKET_IDENT 0x6465626d // "mbed"
okini3939 4:41a3534d085f 10
okini3939 3:1d5dc4107558 11 IpLine::IpLine (AnalogOut p_dac, AnalogIn p_adc) : dac(p_dac), adc(p_adc), dial(DIAL_SIZE), dabuf(DATA_SIZE * 4), adbuf(DATA_SIZE * 2)
okini3939 3:1d5dc4107558 12 , led1(LED1), led2(LED2), led3(LED3), led4(LED4) {
okini3939 2:e37117117e79 13 EthernetErr r;
okini3939 2:e37117117e79 14
okini3939 2:e37117117e79 15 mode = ModeOff;
okini3939 3:1d5dc4107558 16 status = StatusNone;
okini3939 2:e37117117e79 17 timeout = 0;
okini3939 3:1d5dc4107558 18 packet_num = 1;
okini3939 2:e37117117e79 19 dataskip = 0;
okini3939 2:e37117117e79 20
okini3939 2:e37117117e79 21 // dhcp
okini3939 2:e37117117e79 22 eth = new EthernetNetIf;
okini3939 2:e37117117e79 23 // eth = new EthernetNetIf(IpAddr(192,168,10,200), IpAddr(255,255,255,0), IpAddr(0,0,0,0), IpAddr(0,0,0,0));
okini3939 2:e37117117e79 24 r = eth->setup();
okini3939 2:e37117117e79 25 if (r) {
okini3939 2:e37117117e79 26 printf("Error %d in setup.\n", r);
okini3939 2:e37117117e79 27 return;
okini3939 2:e37117117e79 28 }
okini3939 2:e37117117e79 29
okini3939 2:e37117117e79 30 udpsock = new UDPSocket;
okini3939 2:e37117117e79 31 udpsock->setOnEvent(this, &IpLine::onLisnerEvent);
okini3939 2:e37117117e79 32 udpsock->bind(Host(eth->getIp(), UDPPORT));
okini3939 2:e37117117e79 33 }
okini3939 2:e37117117e79 34
okini3939 2:e37117117e79 35 /// 8KHz interrupt
okini3939 2:e37117117e79 36 void IpLine::intr () {
okini3939 2:e37117117e79 37 char c;
okini3939 2:e37117117e79 38
okini3939 2:e37117117e79 39 if (mode == ModeTalk && hook == HookOn) {
okini3939 2:e37117117e79 40 // dac
okini3939 2:e37117117e79 41 if (dabuf.available() < DATA_SIZE) {
okini3939 2:e37117117e79 42 // down sample
okini3939 2:e37117117e79 43 dabuf.get(c);
okini3939 2:e37117117e79 44 dabuf.get(c);
okini3939 2:e37117117e79 45 dac.write_u16(ulaw2pcm(c));
okini3939 3:1d5dc4107558 46 led1 = 0; led2 = 0; led3 = 1;
okini3939 2:e37117117e79 47 } else
okini3939 2:e37117117e79 48 if (dabuf.use() < DATA_SIZE) {
okini3939 2:e37117117e79 49 // over sample
okini3939 2:e37117117e79 50 if (dataskip) {
okini3939 2:e37117117e79 51 dataskip = 0;
okini3939 2:e37117117e79 52 } else {
okini3939 2:e37117117e79 53 if (! dabuf.get(c)) {
okini3939 2:e37117117e79 54 dac.write_u16(ulaw2pcm(c));
okini3939 2:e37117117e79 55 } else {
okini3939 4:41a3534d085f 56 dac.write_u16(gaussian());
okini3939 2:e37117117e79 57 }
okini3939 2:e37117117e79 58 dataskip = 1;
okini3939 2:e37117117e79 59 }
okini3939 4:41a3534d085f 60 led1 = 1; led2 = 0; led3 = 0;
okini3939 2:e37117117e79 61 } else {
okini3939 2:e37117117e79 62 // normal
okini3939 2:e37117117e79 63 dabuf.get(c);
okini3939 2:e37117117e79 64 dac.write_u16(ulaw2pcm(c));
okini3939 3:1d5dc4107558 65 led1 = 0; led2 = 1; led3 = 0;
okini3939 2:e37117117e79 66 }
okini3939 2:e37117117e79 67
okini3939 2:e37117117e79 68 // adc
okini3939 2:e37117117e79 69 // adbuf.put(pcm2ulaw(adc.read_u16()));
okini3939 2:e37117117e79 70 adbuf.put(adc.read_u16() >> 8);
okini3939 2:e37117117e79 71 }
okini3939 2:e37117117e79 72
okini3939 2:e37117117e79 73 if (timeout) {
okini3939 2:e37117117e79 74 timeout --;
okini3939 2:e37117117e79 75
okini3939 2:e37117117e79 76 if (timeout == 0) {
okini3939 2:e37117117e79 77 if (last.target) {
okini3939 2:e37117117e79 78 // re-try
okini3939 2:e37117117e79 79 send(&last);
okini3939 2:e37117117e79 80 timeout = NET_TIMEOUT;
okini3939 2:e37117117e79 81 last.target = PhoneNone;
okini3939 2:e37117117e79 82 } else {
okini3939 2:e37117117e79 83 // timeout
okini3939 2:e37117117e79 84 status = StatusNg;
okini3939 2:e37117117e79 85 }
okini3939 2:e37117117e79 86 }
okini3939 2:e37117117e79 87 }
okini3939 2:e37117117e79 88 }
okini3939 2:e37117117e79 89
okini3939 2:e37117117e79 90 /// network
okini3939 2:e37117117e79 91 void IpLine::poll () {
okini3939 2:e37117117e79 92
okini3939 2:e37117117e79 93 Net::poll();
okini3939 2:e37117117e79 94
okini3939 2:e37117117e79 95 if (mode == ModeTalk && adbuf.use() >= DATA_SIZE) {
okini3939 2:e37117117e79 96 // send
okini3939 2:e37117117e79 97 struct ipline_packet packet;
okini3939 2:e37117117e79 98
okini3939 2:e37117117e79 99 packet.len = adbuf.get(packet.data, DATA_SIZE);
okini3939 2:e37117117e79 100 if (packet.len > 0) {
okini3939 2:e37117117e79 101 packet.header.num = 0;
okini3939 2:e37117117e79 102 packet.header.target = remotetarget;
okini3939 2:e37117117e79 103 packet.header.mode = ModeData;
okini3939 2:e37117117e79 104 packet.header.status = StatusNone;
okini3939 2:e37117117e79 105 send(&packet);
okini3939 2:e37117117e79 106 }
okini3939 2:e37117117e79 107 }
okini3939 2:e37117117e79 108 }
okini3939 2:e37117117e79 109
okini3939 2:e37117117e79 110 /// recv packet
okini3939 2:e37117117e79 111 void IpLine::onLisnerEvent (UDPSocketEvent e) {
okini3939 2:e37117117e79 112 int len;
okini3939 2:e37117117e79 113 struct ipline_packet packet;
okini3939 2:e37117117e79 114 Host recv;
okini3939 2:e37117117e79 115
okini3939 2:e37117117e79 116 if (e != UDPSOCKET_READABLE) return;
okini3939 2:e37117117e79 117
okini3939 2:e37117117e79 118 // get data
okini3939 3:1d5dc4107558 119 len = udpsock->recvfrom((char *)&packet, sizeof(struct ipline_packet), &recv);
okini3939 2:e37117117e79 120
okini3939 4:41a3534d085f 121 if (packet.header.ident != PACKET_IDENT) return;
okini3939 3:1d5dc4107558 122
okini3939 3:1d5dc4107558 123 led4 = 1;
okini3939 2:e37117117e79 124 if (packet.header.status != StatusNone) {
okini3939 2:e37117117e79 125 // recv ack
okini3939 2:e37117117e79 126 if (packet.header.num == last.num) {
okini3939 2:e37117117e79 127 status = packet.header.status;
okini3939 2:e37117117e79 128 timeout = 0;
okini3939 2:e37117117e79 129 }
okini3939 2:e37117117e79 130
okini3939 2:e37117117e79 131 } else
okini3939 2:e37117117e79 132 if (packet.header.mode == ModeData && len > sizeof(struct ipline_header)) {
okini3939 2:e37117117e79 133 // data
okini3939 2:e37117117e79 134
okini3939 2:e37117117e79 135 dabuf.put(packet.data, packet.len);
okini3939 2:e37117117e79 136
okini3939 2:e37117117e79 137 } else
okini3939 2:e37117117e79 138 if (len == sizeof(struct ipline_header)) {
okini3939 2:e37117117e79 139 // enter
okini3939 2:e37117117e79 140 packet.header.status = StatusNg;
okini3939 2:e37117117e79 141
okini3939 2:e37117117e79 142 switch (packet.header.mode) {
okini3939 2:e37117117e79 143 case ModeRing:
okini3939 2:e37117117e79 144 // ring --> onhook, dial
okini3939 2:e37117117e79 145 if (mode == ModeReady) {
okini3939 2:e37117117e79 146 dial.put(1);
okini3939 2:e37117117e79 147 dial.put(10);
okini3939 2:e37117117e79 148 dial.put(packet.header.target);
okini3939 2:e37117117e79 149 dial.put(12);
okini3939 2:e37117117e79 150 hook = HookOn;
okini3939 2:e37117117e79 151 remote = recv;
okini3939 2:e37117117e79 152 packet.header.status = StatusOk;
okini3939 2:e37117117e79 153 }
okini3939 2:e37117117e79 154 break;
okini3939 2:e37117117e79 155
okini3939 2:e37117117e79 156 case ModeBT:
okini3939 2:e37117117e79 157 case ModeDisconnect:
okini3939 2:e37117117e79 158 if (recv.getIp() == remote.getIp()) {
okini3939 2:e37117117e79 159 hook = HookOff;
okini3939 2:e37117117e79 160 packet.header.status = StatusOk;
okini3939 2:e37117117e79 161 }
okini3939 2:e37117117e79 162 break;
okini3939 2:e37117117e79 163
okini3939 2:e37117117e79 164 case ModeTalk:
okini3939 2:e37117117e79 165 if (recv.getIp() == remote.getIp()) {
okini3939 3:1d5dc4107558 166 adbuf.clear();
okini3939 3:1d5dc4107558 167 dabuf.clear();
okini3939 2:e37117117e79 168 hook = HookOn;
okini3939 2:e37117117e79 169 packet.header.status = StatusOk;
okini3939 2:e37117117e79 170 }
okini3939 2:e37117117e79 171 break;
okini3939 2:e37117117e79 172 }
okini3939 2:e37117117e79 173
okini3939 2:e37117117e79 174 // send ack
okini3939 2:e37117117e79 175 send(&packet.header);
okini3939 2:e37117117e79 176 timeout = NET_RETRY;
okini3939 3:1d5dc4107558 177 /*
okini3939 2:e37117117e79 178 for (int i = 0; i < len; i ++) {
okini3939 2:e37117117e79 179 printf(" %02x", ((char *)&packet)[i]);
okini3939 2:e37117117e79 180 }
okini3939 3:1d5dc4107558 181 */
okini3939 2:e37117117e79 182 }
okini3939 3:1d5dc4107558 183 led4 = 0;
okini3939 2:e37117117e79 184 }
okini3939 2:e37117117e79 185
okini3939 2:e37117117e79 186
okini3939 2:e37117117e79 187 /// send packet (header only)
okini3939 2:e37117117e79 188 void IpLine::send (struct ipline_header *header) {
okini3939 2:e37117117e79 189
okini3939 4:41a3534d085f 190 header->ident = PACKET_IDENT;
okini3939 2:e37117117e79 191 if (! header->num) {
okini3939 2:e37117117e79 192 header->num = packet_num;
okini3939 2:e37117117e79 193 packet_num ++;
okini3939 2:e37117117e79 194 if (packet_num >= 65536) packet_num = 1;
okini3939 2:e37117117e79 195 }
okini3939 2:e37117117e79 196 udpsock->sendto((char *)header, sizeof(struct ipline_header), &remote);
okini3939 2:e37117117e79 197 memcpy(&last, header, sizeof(struct ipline_header));
okini3939 2:e37117117e79 198
okini3939 2:e37117117e79 199 for (int i = 0; i < sizeof(struct ipline_header); i ++) {
okini3939 2:e37117117e79 200 printf(" %02x", ((char *)header)[i]);
okini3939 2:e37117117e79 201 }
okini3939 2:e37117117e79 202 printf("(H)\r\n");
okini3939 2:e37117117e79 203 }
okini3939 2:e37117117e79 204
okini3939 2:e37117117e79 205 /// send packet
okini3939 2:e37117117e79 206 void IpLine::send (struct ipline_packet *packet) {
okini3939 2:e37117117e79 207
okini3939 4:41a3534d085f 208 packet->header.ident = PACKET_IDENT;
okini3939 2:e37117117e79 209 if (! packet->header.num) {
okini3939 2:e37117117e79 210 packet->header.num = packet_num;
okini3939 2:e37117117e79 211 packet_num ++;
okini3939 2:e37117117e79 212 if (packet_num >= 65536) packet_num = 1;
okini3939 2:e37117117e79 213 }
okini3939 2:e37117117e79 214 udpsock->sendto((char *)packet, sizeof(struct ipline_packet), &remote);
okini3939 2:e37117117e79 215 }
okini3939 2:e37117117e79 216
okini3939 2:e37117117e79 217 /// change mode
okini3939 2:e37117117e79 218 int IpLine::enter (enum Mode newmode) {
okini3939 2:e37117117e79 219 struct ipline_header header;
okini3939 2:e37117117e79 220
okini3939 2:e37117117e79 221 mode = newmode;
okini3939 2:e37117117e79 222 status = StatusOk;
okini3939 2:e37117117e79 223
okini3939 2:e37117117e79 224 switch (mode) {
okini3939 2:e37117117e79 225 case ModeReady:
okini3939 2:e37117117e79 226 hook = HookOff;
okini3939 2:e37117117e79 227 break;
okini3939 2:e37117117e79 228
okini3939 2:e37117117e79 229 case ModeBT:
okini3939 2:e37117117e79 230 case ModeDisconnect:
okini3939 2:e37117117e79 231 hook = HookOff;
okini3939 2:e37117117e79 232 case ModeRing:
okini3939 2:e37117117e79 233 case ModeTalk:
okini3939 3:1d5dc4107558 234 adbuf.clear();
okini3939 3:1d5dc4107558 235 dabuf.clear();
okini3939 2:e37117117e79 236 status = StatusNone;
okini3939 2:e37117117e79 237 header.num = 0;
okini3939 2:e37117117e79 238 header.target = remotetarget;
okini3939 2:e37117117e79 239 header.mode = mode;
okini3939 2:e37117117e79 240 header.status = status;
okini3939 2:e37117117e79 241 send(&header);
okini3939 2:e37117117e79 242 timeout = NET_RETRY;
okini3939 2:e37117117e79 243 break;
okini3939 2:e37117117e79 244 }
okini3939 2:e37117117e79 245
okini3939 2:e37117117e79 246 return 0;
okini3939 2:e37117117e79 247 }
okini3939 2:e37117117e79 248
okini3939 2:e37117117e79 249 /// return status
okini3939 2:e37117117e79 250 int IpLine::scan (enum Scan type) {
okini3939 2:e37117117e79 251
okini3939 2:e37117117e79 252 switch (type) {
okini3939 2:e37117117e79 253 case ScanMode:
okini3939 2:e37117117e79 254 return mode;
okini3939 2:e37117117e79 255
okini3939 2:e37117117e79 256 case ScanStatus:
okini3939 2:e37117117e79 257 return status;
okini3939 2:e37117117e79 258
okini3939 2:e37117117e79 259 case ScanHook:
okini3939 2:e37117117e79 260 return hook;
okini3939 2:e37117117e79 261
okini3939 2:e37117117e79 262 case ScanDial:
okini3939 2:e37117117e79 263 char c;
okini3939 2:e37117117e79 264 if (dial.get(c) == 0)
okini3939 2:e37117117e79 265 return c;
okini3939 2:e37117117e79 266 break;
okini3939 2:e37117117e79 267
okini3939 2:e37117117e79 268 }
okini3939 2:e37117117e79 269
okini3939 2:e37117117e79 270 return -1;
okini3939 2:e37117117e79 271 }
okini3939 2:e37117117e79 272
okini3939 2:e37117117e79 273 /// set target
okini3939 2:e37117117e79 274 void IpLine::settarget (enum PhoneType target, char *host) {
okini3939 2:e37117117e79 275 int ip0, ip1, ip2, ip3;
okini3939 2:e37117117e79 276
okini3939 2:e37117117e79 277 remotetarget = target;
okini3939 2:e37117117e79 278 if (host[0] >= '0' && host[0] <= '9') {
okini3939 2:e37117117e79 279 sscanf(host, "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
okini3939 2:e37117117e79 280 remote.setIp(IpAddr(ip0, ip1, ip2, ip3));
okini3939 2:e37117117e79 281 remote.setName(NULL);
okini3939 2:e37117117e79 282 } else {
okini3939 2:e37117117e79 283 remote.setIp(NULL);
okini3939 2:e37117117e79 284 remote.setName(host);
okini3939 2:e37117117e79 285 }
okini3939 2:e37117117e79 286 remote.setPort(UDPPORT);
okini3939 2:e37117117e79 287 }
okini3939 4:41a3534d085f 288
okini3939 4:41a3534d085f 289 unsigned long IpLine::xor128 () {
okini3939 4:41a3534d085f 290 static unsigned long x = 123456789;
okini3939 4:41a3534d085f 291 static unsigned long y = 362436069, z = 521288629, w = 88675123;
okini3939 4:41a3534d085f 292 unsigned long t;
okini3939 4:41a3534d085f 293 t = (x ^ (x << 11));
okini3939 4:41a3534d085f 294 x = y; y = z; z = w;
okini3939 4:41a3534d085f 295 return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)) );
okini3939 4:41a3534d085f 296 }
okini3939 4:41a3534d085f 297
okini3939 4:41a3534d085f 298 int IpLine::gaussian () {
okini3939 4:41a3534d085f 299 int i, j;
okini3939 4:41a3534d085f 300
okini3939 4:41a3534d085f 301 j = 0;
okini3939 4:41a3534d085f 302 for (i = 0; i < 12; i ++) {
okini3939 4:41a3534d085f 303 j = j + (xor128() >> 16);
okini3939 4:41a3534d085f 304 }
okini3939 4:41a3534d085f 305 j = (j - 0x60000) & 0xffff;
okini3939 4:41a3534d085f 306 return 0x3fff + (j >> 1);
okini3939 4:41a3534d085f 307 }