mbed Phone Platform
Dependencies: ulaw mbed ConfigFile
IpLine.cpp
- Committer:
- okini3939
- Date:
- 2010-12-26
- Revision:
- 1:0f82c574096f
- Child:
- 2:e37117117e79
File content as of revision 1:0f82c574096f:
#include "IpLine.h" 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) { EthernetErr r; mode = ModeOff; status = StatusOk; timeout = 0; packet_num = 0; dataskip = 0; // dhcp eth = new EthernetNetIf; r = eth->setup(); if (r) { printf("Error %d in setup.\n", r); return; } udpsock = new UDPSocket; udpsock->setOnEvent(this, &IpLine::onLisnerEvent); udpsock->bind(Host(eth->getIp(), UDPPORT)); } /// 8KHz interrupt void IpLine::poll () { char c; if (mode == ModeTalk && hook) { // dac if (dabuf.available() < DATA_SIZE) { // down sample dabuf.get(c); dabuf.get(c); dac.write_u16(ulaw2pcm(c)); } else if (dabuf.use() < DATA_SIZE) { // over sample if (dataskip) { dataskip = 0; } else { if (! dabuf.get(c)) { dac.write_u16(ulaw2pcm(c)); } else { // dac.write_u16(gaussian()); } dataskip = 1; } } else { // normal dabuf.get(c); dac.write_u16(ulaw2pcm(c)); } // adc adbuf.put(pcm2ulaw(adc.read_u16())); } if (timeout) { timeout --; if (timeout == 0) { if (last.target) { // re-try send(last); timeout = FREQ; last.target = PhoneNone; } else { // timeout status = StatusNg; } } } } /// network void IpLine::netpoll () { if (mode == ModeTalk && adbuf.use() >= DATA_SIZE) { // send struct ipline_packet packet; packet.len = adbuf.get(packet.data, sizeof(packet.data)); if (packet.len > 0) { packet.header.target = remotetarget; packet.header.mode = ModeData; packet.header.status = StatusNone; send(packet); } } Net::poll(); } /// recv packet void IpLine::onLisnerEvent (UDPSocketEvent e) { int len; struct ipline_packet packet; Host recv; if (e != UDPSOCKET_READABLE) return; // get data len = udpsock->recvfrom((char *)&packet, sizeof(packet), &recv); if (packet.header.status != StatusNone) { // recv ack if (packet.header.num == last.num) { status = packet.header.status; timeout = 0; } } else if (packet.header.mode == ModeData) { // data dabuf.put(packet.data, packet.len); } else if (mode == ModeTalk && len > sizeof(struct ipline_header)) { // enter packet.header.status = StatusNg; switch (packet.header.mode) { case ModeRing: // ring --> onhook, dial if (mode == ModeReady) { dial.put(11); dial.put(packet.header.target); dial.put(12); hook = HookOn; remote = recv; packet.header.status = StatusOk; } break; case ModeBT: case ModeDisconnect: if (recv.getIp() == remote.getIp()) { hook = HookOff; packet.header.status = StatusOk; } break; case ModeTalk: if (recv.getIp() == remote.getIp()) { hook = HookOn; packet.header.status = StatusOk; } break; } // send ack send(packet.header); timeout = FREQ; } } /// send packet (header only) void IpLine::send (struct ipline_header &header) { header.num = packet_num; udpsock->sendto((char *)&header, sizeof(header), &remote); memcpy(&last, &header, sizeof(last)); packet_num ++; if (packet_num >= 65536) packet_num = 1; } /// send packet void IpLine::send (struct ipline_packet &packet) { packet.header.num = packet_num; udpsock->sendto((char *)&packet, sizeof(packet), &remote); packet_num ++; if (packet_num >= 256) packet_num = 0; } /// change mode int IpLine::enter (enum Mode newmode) { struct ipline_header header; mode = newmode; status = StatusOk; switch (mode) { case ModeReady: hook = HookOff; break; case ModeRing: case ModeTalk: case ModeBT: case ModeDisconnect: status = StatusNone; header.target = remotetarget; header.mode = mode; header.status = status; send(header); timeout = FREQ; break; } return 0; } /// return status int IpLine::scan (enum Scan type) { switch (type) { case ScanMode: return mode; case ScanStatus: return status; case ScanHook: return hook; case ScanDial: char c; if (dial.get(c) == 0) return c; break; } return -1; } /// set target void IpLine::settarget (enum PhoneType target, char *host) { int ip0, ip1, ip2, ip3; remotetarget = target; if (host[0] >= '0' && host[0] <= '9') { sscanf(host, "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3); remote.setIp(IpAddr(ip0, ip1, ip2, ip3)); remote.setName(NULL); } else { remote.setIp(NULL); remote.setName(host); } remote.setPort(UDPPORT); }