mbed Phone Platform

Dependencies:   ulaw mbed ConfigFile

Committer:
okini3939
Date:
Fri Jan 21 16:06:15 2011 +0000
Revision:
6:bd62b12de751
Parent:
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 6:bd62b12de751 11 IpLine::IpLine (EthernetNetIf *p_eth, AnalogOut p_dac, AnalogIn p_adc) : dac(p_dac), adc(p_adc), dial(DIAL_SIZE), dabuf(DATA_SIZE * 4), adbuf(DATA_SIZE * 2)
okini3939 5:30e2847d241b 12 , led_y(p25), led_g(p26), eth_link(P1_25), eth_speed(P1_26) {
okini3939 2:e37117117e79 13
okini3939 2:e37117117e79 14 mode = ModeOff;
okini3939 3:1d5dc4107558 15 status = StatusNone;
okini3939 2:e37117117e79 16 timeout = 0;
okini3939 3:1d5dc4107558 17 packet_num = 1;
okini3939 2:e37117117e79 18 dataskip = 0;
okini3939 6:bd62b12de751 19 timerled = 0;
okini3939 2:e37117117e79 20
okini3939 6:bd62b12de751 21 eth = p_eth;
okini3939 5:30e2847d241b 22 led_g = eth_link ? 0 : 1;
okini3939 2:e37117117e79 23
okini3939 2:e37117117e79 24 udpsock = new UDPSocket;
okini3939 2:e37117117e79 25 udpsock->setOnEvent(this, &IpLine::onLisnerEvent);
okini3939 2:e37117117e79 26 udpsock->bind(Host(eth->getIp(), UDPPORT));
okini3939 2:e37117117e79 27 }
okini3939 2:e37117117e79 28
okini3939 2:e37117117e79 29 /// 8KHz interrupt
okini3939 2:e37117117e79 30 void IpLine::intr () {
okini3939 2:e37117117e79 31 char c;
okini3939 2:e37117117e79 32
okini3939 2:e37117117e79 33 if (mode == ModeTalk && hook == HookOn) {
okini3939 2:e37117117e79 34 // dac
okini3939 5:30e2847d241b 35
okini3939 2:e37117117e79 36 if (dabuf.available() < DATA_SIZE) {
okini3939 2:e37117117e79 37 // down sample
okini3939 2:e37117117e79 38 dabuf.get(c);
okini3939 5:30e2847d241b 39 dac.write_u16(ulaw2pcm(c));
okini3939 2:e37117117e79 40 dabuf.get(c);
okini3939 2:e37117117e79 41 } else
okini3939 2:e37117117e79 42 if (dabuf.use() < DATA_SIZE) {
okini3939 2:e37117117e79 43 // over sample
okini3939 2:e37117117e79 44 if (dataskip) {
okini3939 2:e37117117e79 45 dataskip = 0;
okini3939 2:e37117117e79 46 } else {
okini3939 2:e37117117e79 47 if (! dabuf.get(c)) {
okini3939 2:e37117117e79 48 dac.write_u16(ulaw2pcm(c));
okini3939 2:e37117117e79 49 } else {
okini3939 6:bd62b12de751 50 //dac.write_u16(gaussian());
okini3939 2:e37117117e79 51 }
okini3939 2:e37117117e79 52 dataskip = 1;
okini3939 2:e37117117e79 53 }
okini3939 2:e37117117e79 54 } else {
okini3939 2:e37117117e79 55 // normal
okini3939 2:e37117117e79 56 dabuf.get(c);
okini3939 2:e37117117e79 57 dac.write_u16(ulaw2pcm(c));
okini3939 2:e37117117e79 58 }
okini3939 2:e37117117e79 59
okini3939 2:e37117117e79 60 // adc
okini3939 6:bd62b12de751 61 if (wait) {
okini3939 6:bd62b12de751 62 wait --;
okini3939 6:bd62b12de751 63 } else {
okini3939 6:bd62b12de751 64 adbuf.put(pcm2ulaw(adc.read_u16()));
okini3939 6:bd62b12de751 65 // adbuf.put(adc.read_u16() >> 8);
okini3939 6:bd62b12de751 66 }
okini3939 2:e37117117e79 67 }
okini3939 2:e37117117e79 68
okini3939 5:30e2847d241b 69 if (timeout > 1) timeout --;
okini3939 6:bd62b12de751 70 if (timerled > 0) timerled --;
okini3939 2:e37117117e79 71 }
okini3939 2:e37117117e79 72
okini3939 2:e37117117e79 73 /// network
okini3939 2:e37117117e79 74 void IpLine::poll () {
okini3939 2:e37117117e79 75
okini3939 2:e37117117e79 76 Net::poll();
okini3939 2:e37117117e79 77
okini3939 5:30e2847d241b 78 led_g = eth_link ? 0 : 1;
okini3939 6:bd62b12de751 79 if (! timerled) led_y = 0;
okini3939 5:30e2847d241b 80
okini3939 2:e37117117e79 81 if (mode == ModeTalk && adbuf.use() >= DATA_SIZE) {
okini3939 2:e37117117e79 82 // send
okini3939 2:e37117117e79 83 struct ipline_packet packet;
okini3939 2:e37117117e79 84
okini3939 2:e37117117e79 85 packet.len = adbuf.get(packet.data, DATA_SIZE);
okini3939 2:e37117117e79 86 if (packet.len > 0) {
okini3939 2:e37117117e79 87 packet.header.num = 0;
okini3939 2:e37117117e79 88 packet.header.target = remotetarget;
okini3939 2:e37117117e79 89 packet.header.mode = ModeData;
okini3939 2:e37117117e79 90 packet.header.status = StatusNone;
okini3939 2:e37117117e79 91 send(&packet);
okini3939 2:e37117117e79 92 }
okini3939 2:e37117117e79 93 }
okini3939 5:30e2847d241b 94
okini3939 5:30e2847d241b 95 if (timeout == 1) {
okini3939 5:30e2847d241b 96 if (last.target != PhoneNone) {
okini3939 5:30e2847d241b 97 // re-try
okini3939 5:30e2847d241b 98 send(&last);
okini3939 5:30e2847d241b 99 timeout = NET_TIMEOUT;
okini3939 5:30e2847d241b 100 last.target = PhoneNone;
okini3939 5:30e2847d241b 101 } else {
okini3939 5:30e2847d241b 102 // timeout
okini3939 5:30e2847d241b 103 status = StatusNg;
okini3939 5:30e2847d241b 104 }
okini3939 5:30e2847d241b 105 timeout = 0;
okini3939 5:30e2847d241b 106 }
okini3939 2:e37117117e79 107 }
okini3939 2:e37117117e79 108
okini3939 2:e37117117e79 109 /// recv packet
okini3939 2:e37117117e79 110 void IpLine::onLisnerEvent (UDPSocketEvent e) {
okini3939 2:e37117117e79 111 int len;
okini3939 2:e37117117e79 112 struct ipline_packet packet;
okini3939 2:e37117117e79 113 Host recv;
okini3939 2:e37117117e79 114
okini3939 2:e37117117e79 115 if (e != UDPSOCKET_READABLE) return;
okini3939 2:e37117117e79 116
okini3939 2:e37117117e79 117 // get data
okini3939 3:1d5dc4107558 118 len = udpsock->recvfrom((char *)&packet, sizeof(struct ipline_packet), &recv);
okini3939 6:bd62b12de751 119 led_y = 1;
okini3939 6:bd62b12de751 120 timerled = FREQ / 10;
okini3939 2:e37117117e79 121
okini3939 4:41a3534d085f 122 if (packet.header.ident != PACKET_IDENT) return;
okini3939 3:1d5dc4107558 123
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 5:30e2847d241b 135 if (packet.len <= len - sizeof(struct ipline_header) - 2) {
okini3939 5:30e2847d241b 136 dabuf.put(packet.data, packet.len);
okini3939 5:30e2847d241b 137 }
okini3939 2:e37117117e79 138
okini3939 2:e37117117e79 139 } else
okini3939 2:e37117117e79 140 if (len == sizeof(struct ipline_header)) {
okini3939 2:e37117117e79 141 // enter
okini3939 2:e37117117e79 142 packet.header.status = StatusNg;
okini3939 2:e37117117e79 143
okini3939 2:e37117117e79 144 switch (packet.header.mode) {
okini3939 2:e37117117e79 145 case ModeRing:
okini3939 2:e37117117e79 146 // ring --> onhook, dial
okini3939 2:e37117117e79 147 if (mode == ModeReady) {
okini3939 6:bd62b12de751 148 dial.put(11);
okini3939 2:e37117117e79 149 dial.put(packet.header.target);
okini3939 2:e37117117e79 150 dial.put(12);
okini3939 2:e37117117e79 151 hook = HookOn;
okini3939 2:e37117117e79 152 remote = recv;
okini3939 2:e37117117e79 153 packet.header.status = StatusOk;
okini3939 2:e37117117e79 154 }
okini3939 2:e37117117e79 155 break;
okini3939 2:e37117117e79 156
okini3939 2:e37117117e79 157 case ModeBT:
okini3939 2:e37117117e79 158 case ModeDisconnect:
okini3939 2:e37117117e79 159 if (recv.getIp() == remote.getIp()) {
okini3939 2:e37117117e79 160 hook = HookOff;
okini3939 2:e37117117e79 161 packet.header.status = StatusOk;
okini3939 2:e37117117e79 162 }
okini3939 2:e37117117e79 163 break;
okini3939 2:e37117117e79 164
okini3939 2:e37117117e79 165 case ModeTalk:
okini3939 2:e37117117e79 166 if (recv.getIp() == remote.getIp()) {
okini3939 2:e37117117e79 167 hook = HookOn;
okini3939 2:e37117117e79 168 packet.header.status = StatusOk;
okini3939 2:e37117117e79 169 }
okini3939 2:e37117117e79 170 break;
okini3939 2:e37117117e79 171 }
okini3939 2:e37117117e79 172
okini3939 2:e37117117e79 173 // send ack
okini3939 2:e37117117e79 174 send(&packet.header);
okini3939 6:bd62b12de751 175
okini3939 2:e37117117e79 176 for (int i = 0; i < len; i ++) {
okini3939 2:e37117117e79 177 printf(" %02x", ((char *)&packet)[i]);
okini3939 2:e37117117e79 178 }
okini3939 6:bd62b12de751 179 printf("\r\n");
okini3939 6:bd62b12de751 180
okini3939 2:e37117117e79 181 }
okini3939 2:e37117117e79 182 }
okini3939 2:e37117117e79 183
okini3939 2:e37117117e79 184
okini3939 2:e37117117e79 185 /// send packet (header only)
okini3939 2:e37117117e79 186 void IpLine::send (struct ipline_header *header) {
okini3939 2:e37117117e79 187
okini3939 5:30e2847d241b 188 led_y = 1;
okini3939 6:bd62b12de751 189 timerled = FREQ / 10;
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
okini3939 2:e37117117e79 200 /// send packet
okini3939 2:e37117117e79 201 void IpLine::send (struct ipline_packet *packet) {
okini3939 2:e37117117e79 202
okini3939 5:30e2847d241b 203 led_y = 1;
okini3939 6:bd62b12de751 204 timerled = FREQ / 10;
okini3939 4:41a3534d085f 205 packet->header.ident = PACKET_IDENT;
okini3939 2:e37117117e79 206 if (! packet->header.num) {
okini3939 2:e37117117e79 207 packet->header.num = packet_num;
okini3939 2:e37117117e79 208 packet_num ++;
okini3939 2:e37117117e79 209 if (packet_num >= 65536) packet_num = 1;
okini3939 2:e37117117e79 210 }
okini3939 2:e37117117e79 211 udpsock->sendto((char *)packet, sizeof(struct ipline_packet), &remote);
okini3939 2:e37117117e79 212 }
okini3939 2:e37117117e79 213
okini3939 2:e37117117e79 214 /// change mode
okini3939 2:e37117117e79 215 int IpLine::enter (enum Mode newmode) {
okini3939 2:e37117117e79 216 struct ipline_header header;
okini3939 2:e37117117e79 217
okini3939 6:bd62b12de751 218 if (eth_link) return -1; // link down
okini3939 6:bd62b12de751 219
okini3939 2:e37117117e79 220 mode = newmode;
okini3939 2:e37117117e79 221 status = StatusOk;
okini3939 2:e37117117e79 222
okini3939 2:e37117117e79 223 switch (mode) {
okini3939 2:e37117117e79 224 case ModeReady:
okini3939 2:e37117117e79 225 hook = HookOff;
okini3939 5:30e2847d241b 226 adbuf.clear();
okini3939 5:30e2847d241b 227 dabuf.clear();
okini3939 6:bd62b12de751 228 wait = FREQ / 2;
okini3939 2:e37117117e79 229 break;
okini3939 2:e37117117e79 230
okini3939 2:e37117117e79 231 case ModeBT:
okini3939 2:e37117117e79 232 case ModeDisconnect:
okini3939 2:e37117117e79 233 hook = HookOff;
okini3939 2:e37117117e79 234 case ModeRing:
okini3939 2:e37117117e79 235 case ModeTalk:
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 5:30e2847d241b 306 return 0x3fff + (j >> 2);
okini3939 4:41a3534d085f 307 }