Simple test for USSD message.
Dependencies: CellularModem USBHost
Fork of CellularUSBModem by
USBSerialStream.cpp
00001 /* USBSerialStream.cpp */ 00002 /* Copyright (C) 2012 mbed.org, MIT License 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00007 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all copies or 00011 * substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00014 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00015 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00016 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00018 */ 00019 00020 #define __DEBUG__ 0 00021 #ifndef __MODULE__ 00022 #define __MODULE__ "USBSerialStream.cpp" 00023 #endif 00024 00025 #include "core/fwk.h" 00026 00027 #include <cstring> 00028 00029 #include "USBSerialStream.h" 00030 00031 00032 USBSerialStream::USBSerialStream(IUSBHostSerial& serial) : m_serial(serial), m_serialTxFifoEmpty(true), 00033 m_availableSphre(1), m_spaceSphre(1), m_inBuf() 00034 { 00035 m_availableSphre.wait(); 00036 m_spaceSphre.wait(); 00037 //Attach interrupts 00038 m_serial.attach(this); 00039 } 00040 00041 /*virtual*/ USBSerialStream::~USBSerialStream() 00042 { 00043 m_serial.attach(NULL); 00044 } 00045 00046 //0 for non-blocking (returns immediately), -1 for infinite blocking 00047 /*virtual*/ int USBSerialStream::read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout/*=osWaitForever*/) 00048 { 00049 DBG("Trying to read at most %d chars", maxLength); 00050 int ret = waitAvailable(timeout); 00051 if(ret) 00052 { 00053 WARN("Error %d while waiting for incoming data", ret); 00054 return ret; 00055 } 00056 int a = available(); //Prevent macro issues 00057 int readLen = MIN( a, maxLength ); 00058 *pLength = readLen; 00059 00060 setupReadableISR(false); 00061 while(readLen--) 00062 { 00063 m_inBuf.dequeue(buf); 00064 buf++; 00065 } 00066 setupReadableISR(true); 00067 DBG("Read %d chars successfully", *pLength); 00068 return OK; 00069 } 00070 00071 /*virtual*/ size_t USBSerialStream::available() 00072 { 00073 setupReadableISR(false); //m_inBuf.available() is not reentrant 00074 size_t len = m_inBuf.available(); 00075 setupReadableISR(true); 00076 return len; 00077 } 00078 00079 /*virtual*/ int USBSerialStream::waitAvailable(uint32_t timeout/*=osWaitForever*/) //Wait for data to be available 00080 { 00081 int ret; 00082 if(available()) //Is data already available? 00083 { 00084 while( m_availableSphre.wait(0) > 0 ); //Clear the queue as data is available 00085 return OK; 00086 } 00087 00088 DBG("Waiting for data availability %d ms (-1 is infinite)", timeout); 00089 ret = m_availableSphre.wait(timeout); //Wait for data to arrive or for abort 00090 if(ret <= 0) 00091 { 00092 DBG("Timeout"); 00093 return NET_TIMEOUT; 00094 } 00095 if(!m_inBuf.available()) //Even if abort has been called, return that data is available 00096 { 00097 DBG("Aborted"); 00098 return NET_INTERRUPTED; 00099 } 00100 DBG("Finished waiting"); 00101 while( m_availableSphre.wait(0) > 0 ); //Clear the queue as data is available 00102 return OK; 00103 } 00104 00105 /*virtual*/ int USBSerialStream::abortRead() //Abort current reading (or waiting) operation 00106 { 00107 if( /*!available()*/true ) //If there is data pending, no need to abort 00108 { 00109 m_availableSphre.release(); //Force exiting the waiting state 00110 } 00111 else 00112 { 00113 DBG("Serial is readable"); ; 00114 } 00115 return OK; 00116 } 00117 00118 void USBSerialStream::setupReadableISR(bool en) 00119 { 00120 m_serial.setupIrq(en, IUSBHostSerial::RxIrq); 00121 } 00122 00123 void USBSerialStream::readable() //Callback from m_serial when new data is available 00124 { 00125 while(m_serial.readable()) 00126 { 00127 m_inBuf.queue(m_serial.getc()); 00128 } 00129 m_serial.readPacket(); //Start read of next packet 00130 m_availableSphre.release(); //Force exiting the waiting state 00131 } 00132 00133 //0 for non-blocking (returns immediately), -1 for infinite blocking 00134 /*virtual*/ int USBSerialStream::write(uint8_t* buf, size_t length, uint32_t timeout/*=-1*/) 00135 { 00136 DBG("Trying to write %d chars", length); 00137 do 00138 { 00139 int ret = waitSpace(timeout); 00140 if(ret) 00141 { 00142 WARN("Error %d while waiting for space", ret); 00143 return ret; 00144 } 00145 int s = space(); //Prevent macro issues 00146 int writeLen = MIN( s, length ); 00147 DBG("Writing %d chars", writeLen); 00148 setupWriteableISR(false); 00149 while(writeLen) 00150 { 00151 m_outBuf.queue(*buf); 00152 buf++; 00153 length--; 00154 writeLen--; 00155 } 00156 //If m_serial tx fifo is empty we need to start the packet write 00157 if( m_outBuf.available() && m_serialTxFifoEmpty ) 00158 { 00159 writeable(); 00160 } 00161 setupWriteableISR(true); 00162 } while(length); 00163 00164 DBG("Write successful"); 00165 return OK; 00166 } 00167 00168 /*virtual*/ size_t USBSerialStream::space() 00169 { 00170 setupWriteableISR(false); //m_outBuf.available() is not reentrant 00171 size_t len = CIRCBUF_SIZE - m_outBuf.available(); 00172 setupWriteableISR(true); 00173 return len; 00174 } 00175 00176 /*virtual*/ int USBSerialStream::waitSpace(uint32_t timeout/*=-1*/) //Wait for space to be available 00177 { 00178 int ret; 00179 if(space()) //Is still space already left? 00180 { 00181 while( m_spaceSphre.wait(0) > 0); //Clear the queue as space is available 00182 return OK; 00183 } 00184 00185 DBG("Waiting for data space %d ms (-1 is infinite)", timeout); 00186 ret = m_spaceSphre.wait(timeout); //Wait for space to be made or for abort 00187 if(ret <= 0) 00188 { 00189 DBG("Timeout"); 00190 return NET_TIMEOUT; 00191 } 00192 if(!space()) //Even if abort has been called, return that space is available 00193 { 00194 DBG("Aborted"); 00195 return NET_INTERRUPTED; 00196 } 00197 while( m_spaceSphre.wait(0) > 0); //Clear the queue as space is available 00198 return OK; 00199 } 00200 00201 /*virtual*/ int USBSerialStream::abortWrite() //Abort current writing (or waiting) operation 00202 { 00203 if( !space() ) //If there is space left, no need to abort 00204 { 00205 m_spaceSphre.release(); //Force exiting the waiting state 00206 } 00207 return OK; 00208 } 00209 00210 void USBSerialStream::setupWriteableISR(bool en) 00211 { 00212 m_serial.setupIrq(en, IUSBHostSerial::TxIrq); 00213 } 00214 00215 void USBSerialStream::writeable() //Callback from m_serial when new space is available 00216 { 00217 if(m_outBuf.isEmpty()) 00218 { 00219 m_serialTxFifoEmpty = true; 00220 } 00221 else 00222 { 00223 m_serialTxFifoEmpty = false; 00224 while(m_serial.writeable() && !m_outBuf.isEmpty()) 00225 { 00226 uint8_t c; 00227 m_outBuf.dequeue(&c); 00228 m_serial.putc((char)c); 00229 } 00230 m_serial.writePacket(); //Start packet write 00231 } 00232 if(!m_outBuf.isFull()) 00233 { 00234 m_spaceSphre.release(); //Force exiting the waiting state 00235 } 00236 }
Generated on Thu Jul 14 2022 01:13:56 by 1.7.2