diff --git a/boards.txt b/boards.txt new file mode 100644 index 0000000..336c291 --- /dev/null +++ b/boards.txt @@ -0,0 +1,32 @@ +# WizIO 2018 Georgi Angelov +# https://github.com/Wiz-IO/Arduino-Quectel-M66 +# the.wizarda@gmail.com +# +# Arduino Core and platform. +# For more info: +# https:\\github.com\arduino\Arduino\wiki\Arduino-IDE-1.5---3rd-party-Hardware-specification + +menu.firmware=Firmware + +M66.build.core=opencpu +M66.build.variant=m66 +M66.name=Quectel M66 Module +M66.build.board=Quectel M66 +M66.build.compiler_path={runtime.tools.bc66_gcc.path}\bin\ +M66.build.mcu=-march=armv5te -mfloat-abi=soft -mfpu=vfp -mthumb-interwork +M66.build.extra_flags= +M66.build.f_cpu=260000000L + +M66.menu.firmware.V1=M66FAR01A12BT +M66.menu.firmware.V1.build.firmware=M66FAR01A12BT + +M66.upload.maximum_size=368640 +M66.upload.maximum_data_size=102400 +M66.upload.tool=m66 +M66.upload.protocol=quectel +M66.upload.use_1200bps_touch=false +M66.upload.wait_for_upload_port=false +M66.upload.native_usb=false +M66.upload.via_ssh=false + + diff --git a/cores/opencpu/Arduino.h b/cores/opencpu/Arduino.h new file mode 100644 index 0000000..3e01be1 --- /dev/null +++ b/cores/opencpu/Arduino.h @@ -0,0 +1,79 @@ +/* + Arduino.h - Main include file for the Arduino SDK + Copyright (c) 2005-2013 Arduino Team. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 28 September 2018 by Georgi Angelov +*/ + +#ifndef Arduino_h +#define Arduino_h + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "pgmspace.h" +#include "binary.h" +#include "constants.h" + + unsigned int seconds(void); + unsigned int millis(void); + unsigned int micros(void); + void delay(unsigned int); + void delayMicroseconds(unsigned int us); + + void pinMode(uint8_t, uint8_t); + void digitalWrite(uint8_t, uint8_t); + int digitalRead(uint8_t); + + void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); + uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); + + unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) __attribute__((weak)); + unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout) __attribute__((weak)); + + void yield(void) __attribute__((weak)); + void interrupts(void) __attribute__((weak)); + void noInterrupts(void) __attribute__((weak)); + void attachInterrupt(uint8_t, void (*)(void), int mode) __attribute__((weak)); + void detachInterrupt(uint8_t) __attribute__((weak)); + +#ifdef __cplusplus +} // extern "C" + +//////////////////////////////////////////////////////////////////////////////////////////////// + +#include "WCharacter.h" +#include "WString.h" + +long random(long); +long random(long howsmall, long howbig); +void randomSeed(unsigned long seed); +long map(long x, long in_min, long in_max, long out_min, long out_max); +unsigned int makeWord(unsigned int w); +unsigned int makeWord(unsigned char h, unsigned char l); + +void noTone(uint8_t _pin) __attribute__((weak)); +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) __attribute__((weak)); + +#endif //__cplusplus + +#endif //Arduino_h diff --git a/cores/opencpu/Client.h b/cores/opencpu/Client.h new file mode 100644 index 0000000..b8e5d93 --- /dev/null +++ b/cores/opencpu/Client.h @@ -0,0 +1,45 @@ +/* + Client.h - Base class that provides Client + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef client_h +#define client_h +#include "Print.h" +#include "Stream.h" +#include "IPAddress.h" + +class Client : public Stream { + +public: + virtual int connect(IPAddress ip, uint16_t port) =0; + virtual int connect(const char *host, uint16_t port) =0; + virtual size_t write(uint8_t) =0; + virtual size_t write(const uint8_t *buf, size_t size) =0; + virtual int available() = 0; + virtual int read() = 0; + virtual int read(uint8_t *buf, size_t size) = 0; + virtual int peek() = 0; + virtual void flush() = 0; + virtual void stop() = 0; + virtual uint8_t connected() = 0; + virtual operator bool() = 0; +protected: + uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; +}; + +#endif diff --git a/cores/opencpu/DEV.cpp b/cores/opencpu/DEV.cpp new file mode 100644 index 0000000..2a3301c --- /dev/null +++ b/cores/opencpu/DEV.cpp @@ -0,0 +1,97 @@ +#include "DEV.h" + +void DeviceClass::getImsi(char *buffer, uint32_t size) +{ + if (buffer && size > 15) + { + memset(buffer, 0, size); + api_getIMSI(buffer); + } +} + +void DeviceClass::getImsi(String &s) +{ + char buffer[16]; + memset(buffer, 0, 16); + api_getIMSI(buffer); + s = buffer; +} + +void DeviceClass::getImei(char *buffer, uint32_t size) +{ + if (buffer && size > 15) + { + memset(buffer, 0, size); + api_getIMEI(buffer); + } +} + +void DeviceClass::getImei(String &s) +{ + char buffer[16]; + memset(buffer, 0, 16); + api_getIMEI(buffer); + s = buffer; +} + +int DeviceClass::getSimStatus() +{ + return api_getSimStatus(); // 0 = READY, +} + +void DeviceClass::enterPin(const char *pin) +{ + int res; + if (pin) + { + Dev.ril.sendf("AP+CPIN =\"%s\"", pin); + if (ril.waitForResponse() == 1) + return; + } + TRACE("[PIN] ERROR\n"); + while (true) + Ql_Sleep(1000); +} + +void DeviceClass::waitSimReady(const char *pin) +{ + int status; + do + { + delayEx(100); + status = api_getSimStatus(); + if (status == -666) // TODO status enum + enterPin(pin); + } while (0 != status); +} + +void DeviceClass::waitCreg() +{ + while (1) + { + int res = getCreg(); + if (res == 5 || res == 1) + break; + delayEx(100); + } +} + +void DeviceClass::waitCgreg() +{ + while (1) + { + int res = getCgreg(); + if (res == 5 || res == 1) + break; + delayEx(100); + } +} + +void DeviceClass::waitCereg(){ + waitCreg(); + delay(200); + waitCgreg(); + delay(200); +} + +DeviceClass Dev; \ No newline at end of file diff --git a/cores/opencpu/DEV.h b/cores/opencpu/DEV.h new file mode 100644 index 0000000..bd04b73 --- /dev/null +++ b/cores/opencpu/DEV.h @@ -0,0 +1,99 @@ +#ifndef __DEV_H__ +#define __DEV_H__ + +#include +#include "RilClass.h" +extern HardwareSerial Virtual; + +typedef void (*vCallback)(void); +typedef void (*uCallback)(u32, u32); +typedef void (*mCallback)(ST_MSG *msg); + +class DeviceClass +{ + public: + DeviceClass() + { + onMessage = NULL; + onUrc = NULL; + wtdID = -1; + } + + RilClass ril = RilClass(Virtual); + RilClass &operator=(RilClass &ril); + void begin() + { + ril.begin(); + } + + mCallback onMessage; + void m_Message(ST_MSG *m) + { + if (onMessage) + onMessage(m); + } + + uCallback onUrc; + void m_Urc(u32 urc, u32 data) + { + if (onUrc) + onUrc(urc, data); + } + + const char *getVersion() { return api_getVersion(); } + void getImsi(char *imsi, uint32_t size = 16); + void getImsi(String &s); + + void getImei(char *imei, uint32_t size = 16); + void getImei(String &s); + + int getSimStatus(); + void waitSimReady(const char *pin = NULL); + void enterPin(const char *pin); + + int getCreg() { return api_getNetworkState(1); } + void waitCreg(); + + int getCgreg() { return api_getNetworkState(2); } + void waitCgreg(); + void waitCereg(); + + void reset() { Ql_Reset(0); } + void powerOff() { Ql_PowerDown(1); } + int powerReason() { return Ql_GetPowerOnReason(); } + void Sleep() { Ql_SleepEnable(); } + void noSleep() { Ql_SleepDisable(); } + + ///for pin pulse + int watchdog(uint8_t pin, unsigned int interval = 1000) + { + if (interval < 200) + interval == 200; + //A2Q(pin); + return Ql_WTD_Init(0, (Enum_PinName)pin, interval); + } + ///internal watchdog + void beginWatchdog(unsigned int interval = 1000) + { + if (interval < 400) + interval = 400; + wtdID = Ql_WTD_Start(interval); + } + void endWatchdog() + { + if (wtdID > 0) + Ql_WTD_Stop(wtdID); + } + void kickWatchdog() + { + if (wtdID > 0) + Ql_WTD_Feed(wtdID); + } + + private: + int wtdID; +}; + +extern DeviceClass Dev; + +#endif //__DEV_H__ \ No newline at end of file diff --git a/cores/opencpu/GPRS.cpp b/cores/opencpu/GPRS.cpp new file mode 100644 index 0000000..66ccd83 --- /dev/null +++ b/cores/opencpu/GPRS.cpp @@ -0,0 +1,72 @@ +#include + +void GPRS::onActive(u8 id, s32 ret, void *gprs) +{ + DEBUG_GPRS("onActive( %d %d )", id, ret); + if (gprs) + { + GPRS *p = (GPRS *)gprs; + p->result = (ret == GPRS_PDP_ALREADY || ret == GPRS_PDP_SUCCESS); + Ql_OS_SetEvent(p->event, 1); + } +} + +void GPRS::onDeactive(u8 id, s32 ret, void *user) +{ + DEBUG_GPRS("onDeactivedGPRS( %d %d )", id, ret); +} + +bool GPRS::act(bool blocked) +{ + int r = Ql_GPRS_ActivateEx(id, blocked); // 150 sec + if (GPRS_PDP_SUCCESS == r || GPRS_PDP_SUCCESS == r) + return true; + DEBUG_GPRS("Ql_GPRS_ActivateEx( %d ) = %d", id, r); + //todo non-blocked + Ql_OS_WaitEvent(event, 1); + return result; +} + +bool GPRS::deact(void) +{ + int r = Ql_GPRS_Deactivate(id); + if (GPRS_PDP_SUCCESS == r || GPRS_PDP_SUCCESS == r) + return true; + DEBUG_GPRS("Ql_GPRS_Deactivate( %d ) = %d", id, r); // 2 = GPRS_PDP_WOULDBLOCK + //todo non-blocked + Ql_OS_WaitEvent(event, 1); + return result; +} + +bool GPRS::begin(const char *name, const char *user, const char *pass) +{ + if (name) + Ql_snprintf((char *)st_apn.apnName, sizeof(st_apn.apnName), name); + else + Ql_snprintf((char *)st_apn.apnName, sizeof(st_apn.apnName), "name"); + + if (user) + Ql_snprintf((char *)st_apn.apnUserId, sizeof(st_apn.apnUserId), user); + else + Ql_snprintf((char *)st_apn.apnUserId, sizeof(st_apn.apnUserId), "user"); + + if (pass) + Ql_snprintf((char *)st_apn.apnUserId, sizeof(st_apn.apnUserId), pass); + else + Ql_snprintf((char *)st_apn.apnUserId, sizeof(st_apn.apnUserId), "pass"); + if (0 == event) + event = Ql_OS_CreateEvent((char *)"GPRS_EVENT"); + int res = Ql_GPRS_Config(id, &st_apn); + return (res == GPRS_PDP_ALREADY || res == GPRS_PDP_SUCCESS); +} +bool GPRS::begin() +{ + return begin(NULL, NULL, NULL); +} + +bool GPRS::begin(const char *name) +{ + return begin(name, NULL, NULL); +} + +GPRS gprs(0); \ No newline at end of file diff --git a/cores/opencpu/GPRS.h b/cores/opencpu/GPRS.h new file mode 100644 index 0000000..8ce7d94 --- /dev/null +++ b/cores/opencpu/GPRS.h @@ -0,0 +1,38 @@ +#include + +#define DEBUG_GPRS(F, ...) DBG("[GPRS] " F "\n", ##__VA_ARGS__) + +class GPRS +{ +protected: + u8 id; + ST_PDPContxt_Callback st_callbacks; + ST_GprsConfig st_apn; + static void onDeactive(u8 id, s32 ret, void *gprs); + static void onActive(u8 id, s32 ret, void *gprs); + bool result; + u32 event; + +public: + GPRS(u8 context) + { + id = context; + result = -1; + st_callbacks.Callback_GPRS_Actived = onActive; + st_callbacks.CallBack_GPRS_Deactived = onDeactive; + Ql_snprintf((char *)st_apn.apnName, sizeof(st_apn.apnName), "name"); + Ql_snprintf((char *)st_apn.apnUserId, sizeof(st_apn.apnUserId), "user"); + Ql_snprintf((char *)st_apn.apnUserId, sizeof(st_apn.apnUserId), "pass"); + event = Ql_OS_CreateEvent((char *)"GPRS_EVENT"); + Ql_GPRS_Config(id, &st_apn); + Ql_GPRS_Register(context, &st_callbacks, this); + }; + bool begin(); + bool begin(const char *apn); + bool begin(const char *apn, const char *name, const char *pass); + bool act(bool blocked = true); // blocking mode + bool deact(void); + bool acted; +}; + +extern GPRS gprs; diff --git a/cores/opencpu/HardwareSerial.cpp b/cores/opencpu/HardwareSerial.cpp new file mode 100644 index 0000000..23a526a --- /dev/null +++ b/cores/opencpu/HardwareSerial.cpp @@ -0,0 +1,142 @@ +/* + * Created on: 01.01.2019 + * Author: Georgi Angelov + */ + +#include +#include +#include "Arduino.h" +#include + +#define DEBUG_UART TRACE + +extern "C" void debug_enable(unsigned long port); +extern "C" void debug_disable(void); + +void HardwareSerial::debug(void) +{ + debug_enable(port); +} + +void HardwareSerial::nodebug(void) +{ + debug_disable(); +} + +/*static*/ void HardwareSerial::callback(Enum_SerialPort port, Enum_UARTEventType event, bool pinLevel, void *serial) +{ + //DBG("[UART] callback port=%d, event=%d\n", port, event); + if (NULL == serial) + return; + if (event == EVENT_UART_READY_TO_READ) + { + uint8_t c; + HardwareSerial *p = (HardwareSerial *)serial; + while (Ql_UART_Read((Enum_SerialPort)port, &c, 1) > 0) + { + //DEBUG_UART("%c", c); + if (p->save(c)) + return; + } + } +} + +HardwareSerial::HardwareSerial(uint32_t id) +{ + port = (Enum_SerialPort)id; + _rx_buffer_head = _rx_buffer_tail = 0; +} + +void HardwareSerial::begin(unsigned long baud, void *config) // TODO +{ + _rx_buffer_head = _rx_buffer_tail = 0; + Ql_memset(_rx_buffer, 0, SERIAL_RX_BUFFER_SIZE); + int res = Ql_UART_Register(port, (CallBack_UART_Notify)this->callback, this); + DEBUG_UART("Ql_UART_Register( %d ) = %d\n", port, res); + if (config) + res = Ql_UART_OpenEx(port, (ST_UARTDCB *)config); + else + res = Ql_UART_Open(port, baud, FC_NONE); + DEBUG_UART("Ql_UART_Open( %d ) = %d\n", port, res); +} + +void HardwareSerial::begin(unsigned long baud) +{ + begin(baud, NULL); +} + +void HardwareSerial::end() +{ + Ql_UART_Close(port); + DEBUG_UART("Ql_UART_Close( %d )\n", port); + _rx_buffer_head = _rx_buffer_tail; +} + +size_t HardwareSerial::write(uint8_t c) +{ + //DEBUG_UART("> %c\n", c); + return Ql_UART_Write(port, &c, 1); +} + +size_t HardwareSerial::write(const uint8_t *buf, size_t size) +{ + if (buf && size) + { + //DEBUG_UART("> %s\n", buf); + return Ql_UART_Write(port, (uint8_t *)buf, size); + } + return 0; +} + +int HardwareSerial::available(void) +{ + return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE; +} + +int HardwareSerial::peek(void) +{ + if (_rx_buffer_head == _rx_buffer_tail) + return -1; + else + return _rx_buffer[_rx_buffer_tail]; +} + +int HardwareSerial::read(void) +{ + if (_rx_buffer_head == _rx_buffer_tail) + { + return -1; + } + else + { + unsigned char c = _rx_buffer[_rx_buffer_tail]; + _rx_buffer_tail = (buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE; + return c; + } +} + +void HardwareSerial::clear(int who) +{ + if (who & 0x10) + { + Ql_UART_ClrTxBuffer(port); + } + if (who & 0x01) + { + Ql_UART_ClrRxBuffer(port); + _rx_buffer_head = _rx_buffer_tail = 0; + Ql_memset(_rx_buffer, 0, SERIAL_RX_BUFFER_SIZE); + } +} + +int HardwareSerial::save(uint8_t c) +{ + uint32_t i = (uint32_t)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE; + if (i != _rx_buffer_tail) + { + _rx_buffer[_rx_buffer_head] = c; + _rx_buffer_head = i; + return 0; // saved + } + return 1; // full +} \ No newline at end of file diff --git a/cores/opencpu/HardwareSerial.h b/cores/opencpu/HardwareSerial.h new file mode 100644 index 0000000..fdf6a30 --- /dev/null +++ b/cores/opencpu/HardwareSerial.h @@ -0,0 +1,50 @@ +/* + * Created on: 01.01.2019 + * Author: Georgi Angelov + */ + +#ifndef HardwareSerial_h +#define HardwareSerial_h + +#include +#include + +#define SERIAL_RX_BUFFER_SIZE 256 +typedef uint8_t buffer_index_t; + +class HardwareSerial : public Stream +{ +protected: + static void callback(Enum_SerialPort port, Enum_UARTEventType event, bool pinLevel, void *serial); + Enum_SerialPort port; + + volatile buffer_index_t _rx_buffer_head; + volatile buffer_index_t _rx_buffer_tail; + unsigned _rx_buffer[SERIAL_RX_BUFFER_SIZE]; + +public: + int save(uint8_t c); + HardwareSerial(uint32_t id); + void debug(void); + void nodebug(void); + void begin(unsigned long baud, void *user); + void begin(unsigned long baud); + void end(); + size_t setRxBufferSize(size_t new_size); + void clear(int who = -1); //ALL, x01=rx, x10=tx + virtual int available(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void){}; + virtual size_t write(uint8_t); + inline size_t write(unsigned long n) { return write((uint8_t)n); } + inline size_t write(long n) { return write((uint8_t)n); } + inline size_t write(unsigned int n) { return write((uint8_t)n); } + inline size_t write(int n) { return write((uint8_t)n); } + size_t write(const char *buf); + size_t write(const uint8_t *buf, size_t size); + using Print::write; + operator bool() { return true; } +}; + +#endif diff --git a/cores/opencpu/IPAddress.cpp b/cores/opencpu/IPAddress.cpp new file mode 100644 index 0000000..2e42a94 --- /dev/null +++ b/cores/opencpu/IPAddress.cpp @@ -0,0 +1,123 @@ +/* + IPAddress.cpp - Base class that provides IPAddress + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include + +IPAddress::IPAddress() +{ + _address.dword = 0; +} + +IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) +{ + _address.bytes[0] = first_octet; + _address.bytes[1] = second_octet; + _address.bytes[2] = third_octet; + _address.bytes[3] = fourth_octet; +} + +IPAddress::IPAddress(uint32_t address) +{ + _address.dword = address; +} + +IPAddress::IPAddress(const uint8_t *address) +{ + memcpy(_address.bytes, address, sizeof(_address.bytes)); +} + +bool IPAddress::fromString(const char *address) +{ + uint16_t acc = 0; // Accumulator + uint8_t dots = 0; + + while (*address) + { + char c = *address++; + if (c >= '0' && c <= '9') + { + acc = acc * 10 + (c - '0'); + if (acc > 255) + { + // Value out of [0..255] range + return false; + } + } + else if (c == '.') + { + if (dots == 3) + { + // Too much dots (there must be 3 dots) + return false; + } + _address.bytes[dots++] = acc; + acc = 0; + } + else + { + // Invalid char + return false; + } + } + + if (dots != 3) + { + // Too few dots (there must be 3 dots) + return false; + } + _address.bytes[3] = acc; + return true; +} + +IPAddress &IPAddress::operator=(const uint8_t *address) +{ + memcpy(_address.bytes, address, sizeof(_address.bytes)); + return *this; +} + +IPAddress &IPAddress::operator=(uint32_t address) +{ + _address.dword = address; + return *this; +} + +bool IPAddress::operator==(const uint8_t *addr) const +{ + return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0; +} + +size_t IPAddress::printTo(Print &p) const +{ + size_t n = 0; + for (int i = 0; i < 3; i++) + { + n += p.print(_address.bytes[i], DEC); + n += p.print('.'); + } + n += p.print(_address.bytes[3], DEC); + return n; +} + +String IPAddress::toString() const +{ + char szRet[16]; + sprintf(szRet,"%u.%u.%u.%u", _address.bytes[0], _address.bytes[1], _address.bytes[2], _address.bytes[3]); + return String(szRet); +} \ No newline at end of file diff --git a/cores/opencpu/IPAddress.h b/cores/opencpu/IPAddress.h new file mode 100644 index 0000000..f08f013 --- /dev/null +++ b/cores/opencpu/IPAddress.h @@ -0,0 +1,79 @@ +/* + IPAddress.h - Base class that provides IPAddress + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPAddress_h +#define IPAddress_h + +#include +#include "Printable.h" +#include "WString.h" + +// A class to make it easier to handle and pass around IP addresses + +class IPAddress : public Printable { +private: + union { + uint8_t bytes[4]; // IPv4 address + uint32_t dword; + } _address; + + // Access the raw byte array containing the address. Because this returns a pointer + // to the internal structure rather than a copy of the address this function should only + // be used when you know that the usage of the returned uint8_t* will be transient and not + // stored. + uint8_t* raw_address() { return _address.bytes; }; + +public: + // Constructors + IPAddress(); + IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + IPAddress(uint32_t address); + IPAddress(const uint8_t *address); + + bool fromString(const char *address); + bool fromString(const String &address) { return fromString(address.c_str()); } + + // Overloaded cast operator to allow IPAddress objects to be used where a pointer + // to a four-byte uint8_t array is expected + operator uint32_t() const { return _address.dword; }; + bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; }; + bool operator==(const uint8_t* addr) const; + + // Overloaded index operator to allow getting and setting individual octets of the address + uint8_t operator[](int index) const { return _address.bytes[index]; }; + uint8_t& operator[](int index) { return _address.bytes[index]; }; + + // Overloaded copy operators to allow initialisation of IPAddress objects from other types + IPAddress& operator=(const uint8_t *address); + IPAddress& operator=(uint32_t address); + + virtual size_t printTo(Print& p) const; + String toString() const; + + friend class EthernetClass; + friend class UDP; + friend class Client; + friend class Server; + friend class DhcpClass; + friend class DNSClient; +}; + +//const IPAddress INADDR_NONE(0,0,0,0); + +#endif diff --git a/cores/opencpu/Print.cpp b/cores/opencpu/Print.cpp new file mode 100644 index 0000000..9655d5a --- /dev/null +++ b/cores/opencpu/Print.cpp @@ -0,0 +1,315 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 03 August 2015 by Chuck Todd + */ + +#include +#include +#include +#include +#include "Arduino.h" + +#include "Print.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) + { + if (write(*buffer++)) + n++; + else + break; + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + PGM_P p = reinterpret_cast(ifsh); + size_t n = 0; + while (1) + { + unsigned char c = pgm_read_byte(p++); + if (c == 0) + break; + if (write(c)) + n++; + else + break; + } + return n; +} + +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long)b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long)n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long)n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) + { + return write(n); + } + else if (base == 10) + { + if (n < 0) + { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } + else + { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) + return write(n); + else + return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable &x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + return write("\r\n"); +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable &x) +{ + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) +{ + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) + base = 10; + + do + { + char c = n % base; + n /= base; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while (n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + if (isnan(number)) + return print("nan"); + if (isinf(number)) + return print("inf"); + if (number > 4294967040.0) + return print("ovf"); // constant determined empirically + if (number < -4294967040.0) + return print("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i = 0; i < digits; ++i) + rounding /= 10.0; + + number += rounding; + + // Extract the integer part of the number and print it + unsigned long int_part = (unsigned long)number; + double remainder = number - (double)int_part; + n += print(int_part); + + // Print the decimal point, but only if there are digits beyond + if (digits > 0) + { + n += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + int toPrint = int(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} + +size_t Print::printf(const char *format, ...) +{ + va_list arg; + va_start(arg, format); + char temp[64]; + char *buffer = temp; + size_t len = vsnprintf(temp, sizeof(temp), format, arg); + va_end(arg); + if (len > sizeof(temp) - 1) + { + buffer = new char[len + 1]; + if (!buffer) + { + return 0; + } + va_start(arg, format); + vsnprintf(buffer, len + 1, format, arg); + va_end(arg); + } + len = write((const uint8_t *)buffer, len); + if (buffer != temp) + { + delete[] buffer; + } + return len; +} \ No newline at end of file diff --git a/cores/opencpu/Print.h b/cores/opencpu/Print.h new file mode 100644 index 0000000..7f7a918 --- /dev/null +++ b/cores/opencpu/Print.h @@ -0,0 +1,95 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Print_h +#define Print_h + +#include +#include // for size_t + +#include "WString.h" +#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar +#undef BIN +#endif +#define BIN 2 + +class Print +{ + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } + public: + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *)buffer, size); + } + + // default to zero, meaning "a single write may block" + // should be overriden by subclasses with buffering + virtual int availableForWrite() { return 0; } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); + + size_t printf(const char *format, ...); + + virtual void flush() { /* Empty implementation for backward compatibility */ } +}; + +#endif diff --git a/cores/opencpu/Printable.h b/cores/opencpu/Printable.h new file mode 100644 index 0000000..2a1b2e9 --- /dev/null +++ b/cores/opencpu/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/cores/opencpu/RilCLass.cpp b/cores/opencpu/RilCLass.cpp new file mode 100644 index 0000000..65da622 --- /dev/null +++ b/cores/opencpu/RilCLass.cpp @@ -0,0 +1,164 @@ + +#include "RilClass.h" + +#define RIL_MIN_RESPONSE_OR_URC_WAIT_TIME_MS 20 + +RilClass::RilClass(HardwareSerial &uart) : _uart(&uart), + _atCommandState(AT_COMMAND_IDLE), + _ready(1), + _responseDataStorage(NULL) +{ + _buffer.reserve(256); +} + +int RilClass::noop() +{ + send("AT"); + return (waitForResponse() == 1); +} + +int RilClass::single(const char *command) +{ + send(command); + return (waitForResponse() == 1); +} + +size_t RilClass::write(uint8_t c) +{ + return _uart->write(c); +} + +size_t RilClass::write(const uint8_t *buf, size_t size) +{ + return _uart->write(buf, size); +} + +void RilClass::send(const char *command) +{ + TRACE("[RIL] Send: %s\n", command); + _uart->clear(); + _uart->println(command); + _atCommandState = AT_COMMAND_IDLE; + _ready = 0; +} + +void RilClass::sendf(const char *fmt, ...) +{ + char buf[BUFSIZ]; + va_list ap; + va_start((ap), (fmt)); + vsnprintf(buf, sizeof(buf) - 1, fmt, ap); + va_end(ap); + send(buf); +} + +int RilClass::waitForResponse(unsigned long timeout, String *responseDataStorage) +{ + _responseDataStorage = responseDataStorage; + for (unsigned long start = millis(); (millis() - start) < timeout;) + { + int r = ready(); + if (r != 0) + { + _responseDataStorage = NULL; + return r; + } + } + _responseDataStorage = NULL; + _buffer = ""; + return -1; +} + +int RilClass::waitForPrompt(unsigned long timeout) +{ + for (unsigned long start = millis(); (millis() - start) < timeout;) + { + ready(); + if (_buffer.endsWith(">")) + return 1; + } + return -1; +} + +int RilClass::ready() +{ + poll(); + return _ready; +} + +void RilClass::poll() +{ + arduinoProcessMessages(50); + while (_uart->available()) + { + char c = _uart->read(); + _buffer += c; + TRACE("%c", c); + switch (_atCommandState) + { + case AT_COMMAND_IDLE: + default: + { + if (_buffer.startsWith("AT") && _buffer.endsWith("\r\n")) + { + _atCommandState = AT_RECEIVING_RESPONSE; + _buffer = ""; + } + else if (_buffer.endsWith("\r\n")) + { + _buffer = ""; + } + break; + } + + case AT_RECEIVING_RESPONSE: + { + if (c == '\n') + { + int responseResultIndex = _buffer.lastIndexOf("OK\r\n"); + if (responseResultIndex != -1) + { + _ready = 1; + } + else + { + responseResultIndex = _buffer.lastIndexOf("ERROR\r\n"); + if (responseResultIndex != -1) + { + _ready = 2; + } + else + { + responseResultIndex = _buffer.lastIndexOf("NO CARRIER\r\n"); + if (responseResultIndex != -1) + { + _ready = 3; + } + } + } + if (_ready != 0) + { + if (_responseDataStorage != NULL) + { + _buffer.remove(responseResultIndex); + _buffer.trim(); + *_responseDataStorage = _buffer; + _responseDataStorage = NULL; + } + _atCommandState = AT_COMMAND_IDLE; + _buffer = ""; + return; + } + } + break; + } + } //switch + } //while +} + +void RilClass::setResponseDataStorage(String *responseDataStorage) +{ + _responseDataStorage = responseDataStorage; +} + +RilClass Ril(Virtual1); \ No newline at end of file diff --git a/cores/opencpu/RilClass.h b/cores/opencpu/RilClass.h new file mode 100644 index 0000000..a2fbf40 --- /dev/null +++ b/cores/opencpu/RilClass.h @@ -0,0 +1,55 @@ +#ifndef _RILCLASS_H +#define _RILCLASS_H + +#include +#include +extern HardwareSerial Virtual1; + +class RilClass +{ +public: + RilClass(HardwareSerial &uart); + + void begin() + { + _uart->end(); + _uart->begin(0); + } + void end() { _uart->end(); } + + int noop(); + int single(const char *command); + + size_t write(uint8_t c); + size_t write(const uint8_t *, size_t); + + void send(const char *command); + void send(const String &command) { send(command.c_str()); } + void sendf(const char *fmt, ...); + + int waitForResponse(unsigned long timeout = 500, String *responseDataStorage = NULL); + int waitForPrompt(unsigned long timeout = 500); + int ready(); + void poll(); + void setResponseDataStorage(String *responseDataStorage); + + int SMS_formatText(bool f); + int SMS_characterSet(const char *cs); + int SMS_begin(const char *to); + int SMS_end(); + +private: + HardwareSerial *_uart; + enum + { + AT_COMMAND_IDLE, + AT_RECEIVING_RESPONSE + } _atCommandState; + int _ready; + String _buffer; + String *_responseDataStorage; +}; + +extern RilClass Ril; + +#endif //_RIL_CLASS_H \ No newline at end of file diff --git a/cores/opencpu/RingBuffer.h b/cores/opencpu/RingBuffer.h new file mode 100644 index 0000000..9508688 --- /dev/null +++ b/cores/opencpu/RingBuffer.h @@ -0,0 +1,143 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef __cplusplus + +#ifndef _RING_BUFFER_ +#define _RING_BUFFER_ + +#include + +// Define constants and variables for buffering incoming serial data. We're +// using a ring buffer (I think), in which head is the index of the location +// to which to write the next incoming character and tail is the index of the +// location from which to read. +// defined in interface.h +#ifndef SERIAL_BUFFER_SIZE +#define SERIAL_BUFFER_SIZE 256 +#endif + +template +class RingBufferN +{ +public: + uint8_t _aucBuffer[N]; + volatile int _iHead; + volatile int _iTail; + +public: + RingBufferN(void); + void store_char(uint8_t c); + void clear(); + int read_char(); + int available(); + int availableForStore(); + int peek(); + bool isFull(); + +private: + int nextIndex(int index); +}; + +typedef RingBufferN RingBuffer; + +template RingBufferN::RingBufferN(void) +{ + memset(_aucBuffer, 0, N); + clear(); +} + +template +void RingBufferN::store_char(uint8_t c) +{ + int i = nextIndex(_iHead); + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + if (i != _iTail) + { + _aucBuffer[_iHead] = c; + _iHead = i; + } +} + +template +void RingBufferN::clear() +{ + _iHead = 0; + _iTail = 0; +} + +template +int RingBufferN::read_char() +{ + if (_iTail == _iHead) + return -1; + + uint8_t value = _aucBuffer[_iTail]; + _iTail = nextIndex(_iTail); + + return value; +} + +template +int RingBufferN::available() +{ + int delta = _iHead - _iTail; + + if (delta < 0) + return N + delta; + else + return delta; +} + +template +int RingBufferN::availableForStore() +{ + if (_iHead >= _iTail) + return N - 1 - _iHead + _iTail; + else + return _iTail - _iHead - 1; +} + +template +int RingBufferN::peek() +{ + if (_iTail == _iHead) + return -1; + + return _aucBuffer[_iTail]; +} + +template +int RingBufferN::nextIndex(int index) +{ + return (uint32_t)(index + 1) % N; +} + +template +bool RingBufferN::isFull() +{ + return (nextIndex(_iHead) == _iTail); +} + +#endif /* _RING_BUFFER_ */ + +#endif /* __cplusplus */ diff --git a/cores/opencpu/Server.h b/cores/opencpu/Server.h new file mode 100644 index 0000000..69e3e39 --- /dev/null +++ b/cores/opencpu/Server.h @@ -0,0 +1,30 @@ +/* + Server.h - Base class that provides Server + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef server_h +#define server_h + +#include "Print.h" + +class Server : public Print { +public: + virtual void begin() =0; +}; + +#endif diff --git a/cores/opencpu/Stream.cpp b/cores/opencpu/Stream.cpp new file mode 100644 index 0000000..d284631 --- /dev/null +++ b/cores/opencpu/Stream.cpp @@ -0,0 +1,319 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + + findMulti/findUntil routines written by Jim Leonard/Xuth + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait + +// protected method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// protected method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) +{ + int c; + while (1) { + c = timedPeek(); + + if( c < 0 || + c == '-' || + (c >= '0' && c <= '9') || + (detectDecimal && c == '.')) return c; + + switch( lookahead ){ + case SKIP_NONE: return -1; // Fail code. + case SKIP_WHITESPACE: + switch( c ){ + case ' ': + case '\t': + case '\r': + case '\n': break; + default: return -1; // Fail code. + } + case SKIP_ALL: + break; + } + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, strlen(target), NULL, 0); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + if (terminator == NULL) { + MultiTarget t[1] = {{target, targetLen, 0}}; + return findMulti(t, 1) == 0 ? true : false; + } else { + MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; + return findMulti(t, 2) == 0 ? true : false; + } +} + +// returns the first valid (long) integer value from the current position. +// lookahead determines how parseInt looks ahead in the stream. +// See LookaheadMode enumeration at the top of the file. +// Lookahead is terminated by the first character that is not a valid part of an integer. +// Once parsing commences, 'ignore' will be skipped in the stream. +long Stream::parseInt(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(lookahead, false); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == ignore) + ; // ignore this character + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == ignore ); + + if(isNegative) + value = -value; + return value; +} + +// as parseInt but returns a floating point value +float Stream::parseFloat(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + bool isFraction = false; + long value = 0; + int c; + float fraction = 1.0; + + c = peekNextDigit(lookahead, true); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == ignore) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + if (length < 1) return 0; + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + if (t->len <= 0) + return t - targets; + } + + while (1) { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + // the simple case is if we match, deal with that first. + if (c == t->str[t->index]) { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do { + --t->index; + // first check if current char works against the new current index + if (c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) { + t->index++; + break; + } + + // otherwise we just try the next index + } while (t->index); + } + } + // unreachable + return -1; +} diff --git a/cores/opencpu/Stream.h b/cores/opencpu/Stream.h new file mode 100644 index 0000000..8e950c7 --- /dev/null +++ b/cores/opencpu/Stream.h @@ -0,0 +1,129 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include +#include "Print.h" + +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(ignore) parseInt(ignore) +#define getFloat() parseFloat() +#define getFloat(ignore) parseFloat(ignore) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +// This enumeration provides the lookahead options for parseInt(), parseFloat() +// The rules set out here are used until either the first valid character is found +// or a time out occurs due to lack of input. +enum LookaheadMode{ + SKIP_ALL, // All invalid characters are ignored. + SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. + SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. +}; + +#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field + +class Stream : public Print +{ + protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // read stream with timeout + int timedPeek(); // peek stream with timeout + int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout + + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + + Stream() {_timeout=1000;} + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + unsigned long getTimeout(void) { return _timeout; } + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) { return find ((char *)target); } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } + // returns true if target string is found, false if timed out + + bool find(char target) { return find (&target, 1); } + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } + + long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // returns the first valid (long) integer value from the current position. + // lookahead determines how parseInt looks ahead in the stream. + // See LookaheadMode enumeration at the top of the file. + // Lookahead is terminated by the first character that is not a valid part of an integer. + // Once parsing commences, 'ignore' will be skipped in the stream. + + float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } + float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } + // These overload exists for compatibility with any class that has derived + // Stream and used parseFloat/Int with a custom ignore character. To keep + // the public API simple, these overload remains protected. + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + +#undef NO_IGNORE_CHAR +#endif diff --git a/cores/opencpu/Tone.h b/cores/opencpu/Tone.h new file mode 100644 index 0000000..125ba6d --- /dev/null +++ b/cores/opencpu/Tone.h @@ -0,0 +1,17 @@ +#ifndef __TONE_H__ +#define __TONE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef __cplusplus +} +#endif + +extern void tone(uint8_t pin, unsigned int frequency, unsigned long duration = 0); +extern void noTone(uint8_t pin); + +#endif //Tone.h \ No newline at end of file diff --git a/cores/opencpu/Udp.h b/cores/opencpu/Udp.h new file mode 100644 index 0000000..0acdb43 --- /dev/null +++ b/cores/opencpu/Udp.h @@ -0,0 +1,93 @@ +/* + * Udp.cpp: Library to send/receive UDP packets. + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#ifndef udp_h +#define udp_h + +#include +#include +#include +#include + +class UDP : public Stream +{ + +public: + virtual uint8_t begin(uint16_t) = 0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t beginMulticast(IPAddress, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure + virtual void stop() = 0; // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port) = 0; + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port) = 0; + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket() = 0; + // Write a single byte into the packet + virtual size_t write(uint8_t) = 0; + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size) = 0; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket() = 0; + // Number of bytes remaining in the current packet + virtual int available() = 0; + // Read a single byte from the current packet + virtual int read() = 0; + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char *buffer, size_t len) = 0; + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char *buffer, size_t len) = 0; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek() = 0; + virtual void flush() = 0; // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP() = 0; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() = 0; + +protected: + uint8_t *rawIPAddress(IPAddress &addr) { return addr.raw_address(); }; +}; + +#endif diff --git a/cores/opencpu/WCharacter.h b/cores/opencpu/WCharacter.h new file mode 100644 index 0000000..c58d262 --- /dev/null +++ b/cores/opencpu/WCharacter.h @@ -0,0 +1,169 @@ +/* + WCharacter.h - Character utility functions for Wiring & Arduino + Copyright (c) 2010 Hernando Barragan. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Character_h +#define Character_h + +#include +#include "interface.h" + +// WCharacter.h prototypes +inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); +inline boolean isAlpha(int c) __attribute__((always_inline)); +inline boolean isAscii(int c) __attribute__((always_inline)); +inline boolean isWhitespace(int c) __attribute__((always_inline)); +inline boolean isControl(int c) __attribute__((always_inline)); +inline boolean isDigit(int c) __attribute__((always_inline)); +inline boolean isGraph(int c) __attribute__((always_inline)); +inline boolean isLowerCase(int c) __attribute__((always_inline)); +inline boolean isPrintable(int c) __attribute__((always_inline)); +inline boolean isPunct(int c) __attribute__((always_inline)); +inline boolean isSpace(int c) __attribute__((always_inline)); +inline boolean isUpperCase(int c) __attribute__((always_inline)); +inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); +inline int toAscii(int c) __attribute__((always_inline)); +inline int toLowerCase(int c) __attribute__((always_inline)); +inline int toUpperCase(int c)__attribute__((always_inline)); + + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline boolean isAlphaNumeric(int c) +{ + return ( isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline boolean isAlpha(int c) +{ + return ( isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline boolean isAscii(int c) +{ + return ( isascii (c) == 0 ? false : true); +} + + +// Checks for a blank character, that is, a space or a tab. +inline boolean isWhitespace(int c) +{ + return ( isblank (c) == 0 ? false : true); +} + + +// Checks for a control character. +inline boolean isControl(int c) +{ + return ( iscntrl (c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline boolean isDigit(int c) +{ + return ( isdigit (c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline boolean isGraph(int c) +{ + return ( isgraph (c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline boolean isLowerCase(int c) +{ + return (islower (c) == 0 ? false : true); +} + + +// Checks for any printable character including space. +inline boolean isPrintable(int c) +{ + return ( isprint (c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline boolean isPunct(int c) +{ + return ( ispunct (c) == 0 ? false : true); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline boolean isSpace(int c) +{ + return ( isspace (c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline boolean isUpperCase(int c) +{ + return ( isupper (c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline boolean isHexadecimalDigit(int c) +{ + return ( isxdigit (c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) +{ + return toascii (c); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) +{ + return tolower (c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) +{ + return toupper (c); +} + +#endif \ No newline at end of file diff --git a/cores/opencpu/WMath.cpp b/cores/opencpu/WMath.cpp new file mode 100644 index 0000000..69ce3ae --- /dev/null +++ b/cores/opencpu/WMath.cpp @@ -0,0 +1,43 @@ +#include + +void randomSeed(unsigned long seed) +{ + if (seed != 0) + { + srand(seed); + } +} + +long random(long howbig) +{ + if (howbig == 0) + { + return 0; + } + return rand() % howbig; +} + +long random(long howsmall, long howbig) +{ + if (howsmall >= howbig) + { + return howsmall; + } + long diff = howbig - howsmall; + return random(diff) + howsmall; +} + +long map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +unsigned int makeWord(unsigned int w) +{ + return w; +} + +unsigned int makeWord(unsigned char h, unsigned char l) +{ + return (h << 8) | l; +} diff --git a/cores/opencpu/WProgram.h b/cores/opencpu/WProgram.h new file mode 100644 index 0000000..7cb21a4 --- /dev/null +++ b/cores/opencpu/WProgram.h @@ -0,0 +1 @@ +#include "Arduino.h" \ No newline at end of file diff --git a/cores/opencpu/WString.cpp b/cores/opencpu/WString.cpp new file mode 100644 index 0000000..31e7122 --- /dev/null +++ b/cores/opencpu/WString.cpp @@ -0,0 +1,752 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WString.h" +#include "interface.h" +#include "dtostrf.h" + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::String(double value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::~String() +{ + free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +void String::move(String &rhs) +{ + if (buffer) { + if (rhs && capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(float num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(double num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(const __FlashStringHelper * str) +{ + if (!str) return 0; + int length = strlen_P((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } else if (diff < 0) { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::remove(unsigned int index){ + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove(index, (unsigned int)-1); +} + +void String::remove(unsigned int index, unsigned int count){ + if (index >= len) { return; } + if (count <= 0) { return; } + if (count > len - index) { count = len - index; } + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count,len - index); + buffer[len] = 0; +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + return float(toDouble()); +} + +double String::toDouble(void) const +{ + if (buffer) return atof(buffer); + return 0; +} diff --git a/cores/opencpu/WString.h b/cores/opencpu/WString.h new file mode 100644 index 0000000..7159971 --- /dev/null +++ b/cores/opencpu/WString.h @@ -0,0 +1,229 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c); + explicit String(unsigned char, unsigned char base=10); + explicit String(int, unsigned char base=10); + explicit String(unsigned int, unsigned char base=10); + explicit String(long, unsigned char base=10); + explicit String(unsigned long, unsigned char base=10); + explicit String(float, unsigned char decimalPlaces=2); + explicit String(double, unsigned char decimalPlaces=2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const {return len;} + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr); return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + { getBytes((unsigned char *)buf, bufsize, index); } + const char* c_str() const { return buffer; } + char* begin() { return buffer; } + char* end() { return buffer + length(); } + const char* begin() const { return c_str(); } + const char* end() const { return c_str() + length(); } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + double toDouble(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + void move(String &rhs); + #endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/cores/opencpu/api/AT_TOK.c b/cores/opencpu/api/AT_TOK.c new file mode 100644 index 0000000..6127b18 --- /dev/null +++ b/cores/opencpu/api/AT_TOK.c @@ -0,0 +1,129 @@ +#include "AT_TOK.h" + +char * strpbrk(const char *s1, const char *s2) +{ + register const char * scanp; + register int c, sc; + while ((c = *s1++) != 0) + { + for (scanp = s2; (sc = *scanp++) != 0;) + if (sc == c) + return ((char *)(s1 - 1)); + } + return (NULL); +} + +char * strsep(char **stringp, const char *delim) +{ + if (*stringp == NULL) { return NULL; } + char *token_start = *stringp; + *stringp = strpbrk(token_start, delim); + if (*stringp) + { + **stringp = '\0'; + (*stringp)++; + } + return token_start; +} + +int at_tok_start(char **p_cur) +{ + if (*p_cur == NULL) return -1; + *p_cur = Ql_strchr(*p_cur, ':'); + if (*p_cur == NULL) return -1; + (*p_cur)++; + return 0; +} + +void skipWhiteSpace(char **p_cur) +{ + if (*p_cur == NULL) return; + while (**p_cur != '\0' && isspace(**p_cur)) (*p_cur)++; +} + +static void skipNextComma(char **p_cur) +{ + if (*p_cur == NULL) return; + while (**p_cur != '\0' && **p_cur != ',') (*p_cur)++; + if (**p_cur == ',') (*p_cur)++; +} + +char * nextTok(char **p_cur) +{ + char *ret = NULL; + skipWhiteSpace(p_cur); + if (*p_cur == NULL) + { + ret = NULL; + } else if (**p_cur == CHR_QUOTES) + { + (*p_cur)++; + ret = strsep(p_cur, STR_QUOTES); + skipNextComma(p_cur); + } else { + ret = strsep(p_cur, ","); + } + return ret; +} + +static int at_tok_nextint_base(char **p_cur, int *p_out, int base, int uns) +{ + char *ret; + if (*p_cur == NULL) { + return -1; + } + ret = nextTok(p_cur); + if (ret == NULL) { + return -1; + } else { + long l; + char *end; + if (uns) + l = strtoul(ret, &end, base); + else + l = strtol(ret, &end, base); + *p_out = (int)l; + if (end == ret) { + return -1; + } + } + return 0; +} + +int at_tok_nextint(char **p_cur, int *p_out) +{ + return at_tok_nextint_base(p_cur, p_out, 10, 0); +} + +int at_tok_nexthexint(char **p_cur, int *p_out) +{ + return at_tok_nextint_base(p_cur, p_out, 16, 1); +} + +int at_tok_nextbool(char **p_cur, char *p_out) +{ + int ret; + int result; + ret = at_tok_nextint(p_cur, &result); + if (ret < 0) + return -1; + if (!(result == 0 || result == 1)) + return -1; + if (p_out != NULL) + *p_out = (char)result; + return ret; +} + +int at_tok_nextstr(char **p_cur, char **p_out) +{ + if (*p_cur == NULL) + return -1; + *p_out = nextTok(p_cur); + return 0; +} + +/** returns 1 on "has more tokens" and 0 if no */ +int at_tok_hasmore(char **p_cur) +{ + return ! (*p_cur == NULL || **p_cur == '\0'); +} diff --git a/cores/opencpu/api/AT_TOK.h b/cores/opencpu/api/AT_TOK.h new file mode 100644 index 0000000..adbc15b --- /dev/null +++ b/cores/opencpu/api/AT_TOK.h @@ -0,0 +1,36 @@ +#ifndef _AT_TOK_H_ +#define _AT_TOK_H_ + +#define __OCPU_AT_TOK_SUPPORT__ + +/* + * android_hardware_ril /reference-ril/at_tok.c + * https://searchcode.com/codesearch/view/40550194/ + */ + +#include "ql_type.h" +#include "ql_stdlib.h" +#include "ql_system.h" +#include +#include +#include +#include + +#define CHR_DELIM ':' +#define CHR_QUOTES '"' +#define STR_QUOTES "\"" + +int isspace(int c); +char * strpbrk(const char *s1, const char *s2); +char * strsep(char **stringp, const char *delim); +void skipWhiteSpace(char **p_cur); +char * nextTok(char **p_cur); + +int at_tok_start(char **p_cur); +int at_tok_nextint(char **p_cur, int *p_out); +int at_tok_nexthexint(char **p_cur, int *p_out); +int at_tok_nextbool(char **p_cur, char *p_out); +int at_tok_nextstr(char **p_cur, char **out); +int at_tok_hasmore(char **p_cur); + +#endif /* _AT_TOK_H_ */ diff --git a/cores/opencpu/api/api.h b/cores/opencpu/api/api.h new file mode 100644 index 0000000..ce7c89b --- /dev/null +++ b/cores/opencpu/api/api.h @@ -0,0 +1,129 @@ +/* + * api.h M66 + * + * Created on: 02.03.2019 + * Author: Georgi Angelov + */ + +#ifndef API_H_ +#define API_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include +#include +#include +#include + + /* portable character for multichar character set */ + typedef char kal_char; + /* portable wide character for unicode character set */ + typedef unsigned short kal_wchar; + /* portable 8-bit unsigned integer */ + typedef unsigned char kal_uint8; + /* portable 8-bit signed integer */ + typedef signed char kal_int8; + /* portable 16-bit unsigned integer */ + typedef unsigned short int kal_uint16; + /* portable 16-bit signed integer */ + typedef signed short int kal_int16; + /* portable 32-bit unsigned integer */ + typedef unsigned int kal_uint32; + /* portable 32-bit signed integer */ + typedef signed int kal_int32; + /* portable 64-bit unsigned integer */ + typedef unsigned long long kal_uint64; + /* portable 64-bit signed integer */ + typedef signed long long kal_int64; + /* boolean representation */ + typedef enum + { + KAL_FALSE, /* FALSE value */ + KAL_TRUE /* TRUE value */ + } kal_bool; + typedef unsigned short WCHAR; + +#ifndef NULL +#define NULL 0 +#endif + + int api_strcmp(const char *s1, const char *s2); + int api_check_api(void); + const char *api_getVersion(void); + int api_messages_available(void); + + int wiz__vsnprintf(char *s, unsigned int n, const char *f, va_list a); + int api_vsnprintf(char *s, unsigned int n, const char *f, va_list a); + long api_strtol(const char *nptr, char **endptr, int base); + unsigned long int api_strtoul(const char *str, char **endptr, int base); // todo + + int api_atoi(const char *str); + long int api_atol(const char *str); + + unsigned int api_getRandomSeed(void); + unsigned int api_rand(); + unsigned int api_srand(unsigned int r); + + unsigned int waitMs(unsigned int ms); + unsigned int api_getMicro(void); + void api_delayMicro(unsigned int us); + + int api_getIMEI(char *imei); + int api_getIMSI(char *imsi); + int api_getSimStatus(void); + int api_getNetworkState(unsigned char type) /* 1 or 2 */; + int api_getSignalLevel(void); + int api_isCFUN(unsigned char cfun_state); + + typedef enum + { + SOC_OOBINLINE = 0x01 << 0, /* not support yet */ + SOC_LINGER = 0x01 << 1, /* linger on close */ + SOC_NBIO = 0x01 << 2, /* Nonblocking */ + SOC_ASYNC = 0x01 << 3, /* Asynchronous notification */ + SOC_NODELAY = 0x01 << 4, /* disable Nagle algorithm or not */ + SOC_KEEPALIVE = 0x01 << 5, /* enable/disable the keepalive */ + SOC_RCVBUF = 0x01 << 6, /* set the socket receive buffer size */ + SOC_SENDBUF = 0x01 << 7, /* set the socket send buffer size */ + SOC_NREAD = 0x01 << 8, /* no. of bytes for read, only for soc_getsockopt */ + SOC_PKT_SIZE = 0x01 << 9, /* datagram max packet size */ + SOC_SILENT_LISTEN = 0x01 << 10, /* SOC_SOCK_SMS property */ + SOC_QOS = 0x01 << 11, /* set the socket qos */ + SOC_TCP_MAXSEG = 0x01 << 12, /* set the max segmemnt size */ + SOC_IP_TTL = 0x01 << 13, /* set the IP TTL value */ + SOC_LISTEN_BEARER = 0x01 << 14, /* enable listen bearer */ + SOC_UDP_ANY_FPORT = 0x01 << 15, /* enable UDP any foreign port */ + SOC_WIFI_NOWAKEUP = 0x01 << 16, /* send packet in power saving mode */ + SOC_UDP_NEED_ICMP = 0x01 << 17, /* deliver NOTIFY(close) for ICMP error */ + SOC_IP_HDRINCL = 0x01 << 18, /* IP header included for raw sockets */ + SOC_IPSEC_POLICY = 0x01 << 19, /* ip security policy */ + SOC_TCP_ACKED_DATA = 0x01 << 20, /* TCPIP acked data */ + SOC_TCP_DELAYED_ACK = 0x01 << 21, /* TCP delayed ack */ + SOC_TCP_SACK = 0x01 << 22, /* TCP selective ack */ + SOC_TCP_TIME_STAMP = 0x01 << 23, /* TCP time stamp */ + SOC_TCP_ACK_MSEG = 0x01 << 24 /* TCP ACK multiple segment */ + } soc_option_enum; + + int api_soc_getsockopt(unsigned char s, unsigned int option, void *val, unsigned char size); + int api_soc_setsockopt(unsigned char s, unsigned int option, void *val, unsigned char size); + unsigned int api_soc_htonl(unsigned int a); + unsigned short api_soc_htons(unsigned short a); + + int api_base64Decode(const char *src, int srcl, char *dst, int dstl); + int api_base64Encode(const char *src, int srcl, char *dst, int dstl, bool auto_line_wrap); + + // TODO + int api_SaveAndSetIRQMask(void) __attribute__((weak)); + void api_RestoreIRQMask(int) __attribute__((weak)); + +#ifdef __cplusplus +} +#endif + +#endif /* API_H_ */ \ No newline at end of file diff --git a/cores/opencpu/arduino_main.cpp b/cores/opencpu/arduino_main.cpp new file mode 100644 index 0000000..f993434 --- /dev/null +++ b/cores/opencpu/arduino_main.cpp @@ -0,0 +1,127 @@ +/* M66 + * Created on: 01.01.2019 + * Author: Georgi Angelov + */ + +#include +#include +extern DeviceClass Dev; + +extern void initVariant() __attribute__((weak)); +extern void setup(); +extern void loop(); + +static struct +{ + uint32_t wait; + uint32_t event; + ST_MSG msg; +} arduino = {10 /* default task wait */, 0, {0, 0, 0, 0}}; + +void arduinoSetWait(u32 wait) +{ + arduino.wait = wait == 0 ? 1 : wait; +} + +static inline bool arduinoInit(void) +{ + if (0 == arduino.event) + arduino.event = Ql_OS_CreateEvent((char *)"AEVENT"); // once + return arduino.event == 0; +} + +static inline void arduinoDispatchMessages(void) +{ + switch (arduino.msg.message) + { + case MSG_ID_URC_INDICATION: + Dev.m_Urc(arduino.msg.param1, arduino.msg.param2); + break; + default: + Dev.m_Message(&arduino.msg); + break; + } +} + +void arduinoProcessMessages(unsigned int wait) +{ + u32 id = Ql_OS_GetActiveTaskId(); + if (ARDUINO_TASK_ID == id) + { + Ql_OS_GetMessage(&arduino.msg); // there is always more than zero + Ql_OS_SendMessage(id, MSG_PROCESS_MESSAGES, 0, 0); // send one message + arduinoDispatchMessages(); + } + Ql_Sleep(wait); +} + +void delayEx(unsigned int ms) +{ +#define BLOCK_TIME 100 + unsigned int count = ms / BLOCK_TIME; + while (count--) + arduinoProcessMessages(BLOCK_TIME); // step + arduinoProcessMessages(ms % BLOCK_TIME); // remain +} + +/// Arduino Task +extern "C" void proc_arduino(int id) +{ + TRACE("[A] proc_arduino\n"); + while (arduino.event == 0) + Ql_Sleep(10); + Ql_OS_WaitEvent(arduino.event, EVENT_FLAG0); // wait ril ready + initVariant(); + Ql_OS_SendMessage(id, MSG_PROCESS_MESSAGES, 0, 0); // dont touch + TRACE("[A] BEGIN\n"); + arduinoProcessMessages(arduino.wait); + setup(); + while (true) + { + arduinoProcessMessages(arduino.wait); + loop(); + } +} + +/// Main Task +extern "C" void proc_main_task(int taskId) +{ + TRACE("[M] proc_main_task\n"); + if (api_check_api()) + { + TRACE("[M] ERROR Firmware not support\n"); + abort(); + } + TRACE("[M] proc_main_task\n"); + if (arduinoInit()) + { + TRACE("[M] ERROR arduinoInit()\n"); + abort(); + } + __libc_init_array(); + entry_main(taskId); // if exist - OpenCPU style + ST_MSG m; + while (true) + { + Ql_OS_GetMessage(&m); + switch (m.message) + { + case MSG_ID_RIL_READY: + Ql_RIL_Initialize(); + Ql_OS_SetEvent(arduino.event, EVENT_FLAG0); // start arduino + TRACE("[M] RIL READY\n"); + break; + case MSG_ID_URC_INDICATION: + if (m.message > URC_GPRS_NW_STATE_IND) // ignore first urc-s + Ql_OS_SendMessage(ARDUINO_TASK_ID, m.message, m.param1, m.param2); // resend to arduino task + break; + default: + Ql_OS_SendMessage(ARDUINO_TASK_ID, m.message, m.param1, m.param2); // resend to arduino task + break; + } // SWITCH + } // WHILE +} + +extern "C" void proc_reserved1(int); +extern "C" void proc_reserved2(int); +/////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/cores/opencpu/binary.h b/cores/opencpu/binary.h new file mode 100644 index 0000000..aec4c73 --- /dev/null +++ b/cores/opencpu/binary.h @@ -0,0 +1,534 @@ +/* + binary.h - Definitions for binary constants + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Binary_h +#define Binary_h + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif diff --git a/cores/opencpu/cbuf.cpp b/cores/opencpu/cbuf.cpp new file mode 100644 index 0000000..47839af --- /dev/null +++ b/cores/opencpu/cbuf.cpp @@ -0,0 +1,208 @@ +/* + cbuf.cpp - Circular buffer implementation + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "cbuf.h" + +cbuf::cbuf(size_t size) : next(NULL), _size(size + 1), _buf(new char[size + 1]), _bufend(_buf + size + 1), _begin(_buf), _end(_begin) +{ +} + +cbuf::~cbuf() +{ + delete[] _buf; +} + +size_t cbuf::resizeAdd(size_t addSize) +{ + return resize(_size + addSize); +} + +size_t cbuf::resize(size_t newSize) +{ + + size_t bytes_available = available(); + newSize += 1; + // not lose any data + // if data can be lost use remove or flush before resize + if ((newSize < bytes_available) || (newSize == _size)) + { + return _size; + } + + char *newbuf = new char[newSize]; + char *oldbuf = _buf; + + if (!newbuf) + { + return _size; + } + + if (_buf) + { + read(newbuf, bytes_available); + memset((newbuf + bytes_available), 0x00, (newSize - bytes_available)); + } + + _begin = newbuf; + _end = newbuf + bytes_available; + _bufend = newbuf + newSize; + _size = newSize; + + _buf = newbuf; + delete[] oldbuf; + + return _size; +} + +size_t cbuf::available() const +{ + if (_end >= _begin) + { + return _end - _begin; + } + return _size - (_begin - _end); +} + +size_t cbuf::size() +{ + return _size; +} + +size_t cbuf::room() const +{ + if (_end >= _begin) + { + return _size - (_end - _begin) - 1; + } + return _begin - _end - 1; +} + +int cbuf::peek() +{ + if (empty()) + { + return -1; + } + + return static_cast(*_begin); +} + +size_t cbuf::peek(char *dst, size_t size) +{ + size_t bytes_available = available(); + size_t size_to_read = (size < bytes_available) ? size : bytes_available; + size_t size_read = size_to_read; + char *begin = _begin; + if (_end < _begin && size_to_read > (size_t)(_bufend - _begin)) + { + size_t top_size = _bufend - _begin; + memcpy(dst, _begin, top_size); + begin = _buf; + size_to_read -= top_size; + dst += top_size; + } + memcpy(dst, begin, size_to_read); + return size_read; +} + +int cbuf::read() +{ + if (empty()) + { + return -1; + } + + char result = *_begin; + _begin = wrap_if_bufend(_begin + 1); + return static_cast(result); +} + +size_t cbuf::read(char *dst, size_t size) +{ + size_t bytes_available = available(); + size_t size_to_read = (size < bytes_available) ? size : bytes_available; + size_t size_read = size_to_read; + if (_end < _begin && size_to_read > (size_t)(_bufend - _begin)) + { + size_t top_size = _bufend - _begin; + memcpy(dst, _begin, top_size); + _begin = _buf; + size_to_read -= top_size; + dst += top_size; + } + memcpy(dst, _begin, size_to_read); + _begin = wrap_if_bufend(_begin + size_to_read); + return size_read; +} + +size_t cbuf::write(char c) +{ + if (full()) + { + return 0; + } + + *_end = c; + _end = wrap_if_bufend(_end + 1); + return 1; +} + +size_t cbuf::write(const char *src, size_t size) +{ + size_t bytes_available = room(); + size_t size_to_write = (size < bytes_available) ? size : bytes_available; + size_t size_written = size_to_write; + if (_end >= _begin && size_to_write > (size_t)(_bufend - _end)) + { + size_t top_size = _bufend - _end; + memcpy(_end, src, top_size); + _end = _buf; + size_to_write -= top_size; + src += top_size; + } + memcpy(_end, src, size_to_write); + _end = wrap_if_bufend(_end + size_to_write); + return size_written; +} + +void cbuf::flush() +{ + _begin = _buf; + _end = _buf; +} + +size_t cbuf::remove(size_t size) +{ + size_t bytes_available = available(); + if (size >= bytes_available) + { + flush(); + return 0; + } + size_t size_to_remove = (size < bytes_available) ? size : bytes_available; + if (_end < _begin && size_to_remove > (size_t)(_bufend - _begin)) + { + size_t top_size = _bufend - _begin; + _begin = _buf; + size_to_remove -= top_size; + } + _begin = wrap_if_bufend(_begin + size_to_remove); + return available(); +} \ No newline at end of file diff --git a/cores/opencpu/cbuf.h b/cores/opencpu/cbuf.h new file mode 100644 index 0000000..ba94cff --- /dev/null +++ b/cores/opencpu/cbuf.h @@ -0,0 +1,79 @@ +/* + cbuf.h - Circular buffer implementation + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __cbuf_h +#define __cbuf_h + +#include +#include +#include + +class cbuf +{ +public: + cbuf(size_t size); + ~cbuf(); + + size_t resizeAdd(size_t addSize); + size_t resize(size_t newSize); + size_t available() const; + size_t size(); + + size_t room() const; + + inline bool empty() const + { + return _begin == _end; + } + + inline bool full() const + { + return wrap_if_bufend(_end + 1) == _begin; + } + + int peek(); + size_t peek(char *dst, size_t size); + + int read(); + size_t read(char* dst, size_t size); + + size_t write(char c); + size_t write(const char* src, size_t size); + + void flush(); + size_t remove(size_t size); + + cbuf *next; + +private: + inline char* wrap_if_bufend(char* ptr) const + { + return (ptr == _bufend) ? _buf : ptr; + } + + size_t _size; + char* _buf; + const char* _bufend; + char* _begin; + char* _end; + +}; + +#endif//__cbuf_h \ No newline at end of file diff --git a/cores/opencpu/constants.h b/cores/opencpu/constants.h new file mode 100644 index 0000000..abbe36e --- /dev/null +++ b/cores/opencpu/constants.h @@ -0,0 +1,97 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_CONSTANTS_ +#define _WIRING_CONSTANTS_ + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#include + +#define LOW (0x0) +#define HIGH (0x1) + +#define CLOSE (0xFF) +#define INPUT (0) +#define INPUT_PULLUP (1<<1) +#define INPUT_PULLDOWN (1<<2) +#define OUTPUT (1<<3) +#define OUTPUT_LO (1<<4) +#define OUTPUT_HI (1<<5) + +#define CHANGE (0x2) +#define FALLING (0x3) +#define RISING (0x4) + +#define DEFAULT (0x1) +#define EXTERNAL (0x0) + +enum BitOrder { + LSBFIRST = 0, + MSBFIRST = 1 +}; + +typedef bool boolean; +typedef uint8_t byte; +typedef uint16_t word; + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define EULER 2.718281828459045235360287471352 + + +#ifdef abs +#undef abs +#endif +#define abs(x) ((x)>0?(x):-(x)) + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) + +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) + +//#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bit(b) (1UL << (b)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + +#ifndef _NOP +#define _NOP() do { __asm__ volatile ("nop"); } while (0) +#endif + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif /* _WIRING_CONSTANTS_ */ \ No newline at end of file diff --git a/cores/opencpu/cpp_m66.ld b/cores/opencpu/cpp_m66.ld new file mode 100644 index 0000000..40f928c --- /dev/null +++ b/cores/opencpu/cpp_m66.ld @@ -0,0 +1,68 @@ +MEMORY +{ + ROM (rx) : ORIGIN = 0x102C7040, LENGTH = 0x0005A000 + RAM (rwx) : ORIGIN = 0xf03D2000, LENGTH = 0x00019000 +} + +SECTIONS +{ + . = 0x102C7040; + .initdata : ALIGN(4) + { + KEEP(*(.initdata)); + } AT > ROM + + text : ALIGN(4) + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP( *(SORT(.preinit_array.*)) ) + KEEP( *(.preinit_init_array*) ) + PROVIDE_HIDDEN (__preinit_array_end = .); + + PROVIDE_HIDDEN (__init_array_start = .); + KEEP( *(SORT(.init_array.*)) ) + KEEP( *(.init_array*) ) + PROVIDE_HIDDEN (__init_array_end = .); + + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP( *(SORT(.fini_array.*)) ) + KEEP( *(.fini_array*) ) + PROVIDE_HIDDEN (__fini_array_end = .); + + *( .text .text.* i.* ) + *( .glue_7t ) + *( .glue_7 ) + *( .ctors ) + *( .dtors ) + *( .gnu.linkonce.t.* ) + *( .gnu.linkonce.r.* ) + *( .gcc_except_table ) + *( .rodata .rodata* .constdata* .conststring* ) + } AT > ROM + + .ARM.exidx : ALIGN(8) + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } AT > ROM + + .data : ALIGN(8) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data) + *(.data.*) + . = ALIGN (8); + _edata = .; + } > RAM AT > ROM + + .bss : ALIGN(8) + { + __bss_start__ = .; + *(.bss) + *(.bss.*) + . = ALIGN (8); + __bss_end__ = .; + } > RAM +} \ No newline at end of file diff --git a/cores/opencpu/custom_config.c b/cores/opencpu/custom_config.c new file mode 100644 index 0000000..d230704 --- /dev/null +++ b/cores/opencpu/custom_config.c @@ -0,0 +1,93 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * sys_config.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file is for some common system definition. Developer don't have to + * care. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ql_type.h" +#include "ril.h" +#include "ql_system.h" +#include "custom_heap_cfg.h" + +#define DEFAULT_VALUE1 (200) +#define DEFAULT_VALUE2 (30) + + +//const u32 HeapMemSize = HEAP_MEMSIZE; +//u8 OpenCPUHeapSpace[HEAP_MEMSIZE]; + + +/* +*-------------------------- +* Task Configuration +*-------------------------- +* TaskStackSize: +* The stack size of task. Range from 1K to 10K. +* If there are any file operations to do in task, +* the stack size of this task must be set to at least 4K. +*****************************************************************/ + +#ifdef TASK_ID_DEF +#undef TASK_ID_DEF +#endif +#ifdef TASK_DEFINITION +#undef TASK_DEFINITION +#endif +#define TASK_FUNC_DECLARATION +#include "ql_common.h" +TASK_DEFINITION_BEGIN +#include "custom_task_cfg.h" +TASK_DEFINITION_END +#undef TASK_FUNC_DECLARATION + + + +#ifdef TASK_FUNC_DECLARATION +#undef TASK_FUNC_DECLARATION +#endif +#ifdef TASK_ID_DEF +#undef TASK_ID_DEF +#endif +#define TASK_DEFINITION +#include "ql_common.h" +TASK_DEFINITION_BEGIN +#include "custom_task_cfg.h" +TASK_DEFINITION_END +#undef TASK_DEFINITION + + + +#define GPIO_DEFINITION +#include "ql_common.h" +GPIO_DEFINITION_BEGIN +#include "custom_gpio_cfg.h" +GPIO_DEFINITION_END +#undef GPIO_DEFINITION diff --git a/cores/opencpu/custom_feature_def.h b/cores/opencpu/custom_feature_def.h new file mode 100644 index 0000000..b12893f --- /dev/null +++ b/cores/opencpu/custom_feature_def.h @@ -0,0 +1,25 @@ +#ifndef __CUSTOM_FEATURE_DEF_H__ +#define __CUSTOM_FEATURE_DEF_H__ + +/************************************************************************ + * RIL Function on/off + ************************************************************************/ +#define __OCPU_RIL_SUPPORT__ +#define __OCPU_RIL_SMS_SUPPORT__ +#define __OCPU_RIL_CALL_SUPPORT__ +#define __OCPU_RIL_BT_SUPPORT__ + + + +/************************************************************************ + * FOTA Feature Definition + ************************************************************************/ +//#define __OCPU_FOTA_APP__ +//#define __OCPU_FOTA_BY_FTP__ +//#define __OCPU_FOTA_BY_HTTP__ + +/************************************************************************ + * Smart Cloud Support + ************************************************************************/ + #define __OCPU_SMART_CLOUD_SUPPORT__ +#endif //__CUSTOM_FEATURE_DEF_H__ diff --git a/cores/opencpu/custom_gpio_cfg.h b/cores/opencpu/custom_gpio_cfg.h new file mode 100644 index 0000000..91e8041 --- /dev/null +++ b/cores/opencpu/custom_gpio_cfg.h @@ -0,0 +1,71 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * custom_gpio_cfg.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file intends for GPIO initialization definition. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __CUSTOM_GPIO_CFG_H__ +#define __CUSTOM_GPIO_CFG_H__ + +/*======================================================================== +| +| GPIO initialization configurations. +|------------------------------------ +| IMPORTANT NOTES: +|------------------ +| +| This is the initialization list for GPIOs at the early of module booting. +| Developer can do configuring here if some GPIOs need to be initialized at +| the early booting. For example, some GPIO is used to control the power +| supply of peripheral. +| +| Besides this config list, developer may call Ql_GPIO_Init() to initialize +| the parameters of I/O interfaces dynamically. But it's later than the +| previous method on time sequence. +\=========================================================================*/ +/*---------------------------------------------------------------------------------------------- +{ Pin Name | Direction | Level | Pull Selection } + *---------------------------------------------------------------------------------------------*/ + +#if 0 // If needed, config GPIOs here +GPIO_ITEM(PINNAME_NETLIGHT, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_DTR, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_RI, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_DCD, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_CTS, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_RTS, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_RXD_AUX, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_TXD_AUX, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_PCM_CLK, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_PCM_SYNC, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_PCM_IN, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +GPIO_ITEM(PINNAME_PCM_OUT, PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP) +#endif + +#endif //__CUSTOM_GPIO_CFG_H__ diff --git a/cores/opencpu/custom_heap_cfg.h b/cores/opencpu/custom_heap_cfg.h new file mode 100644 index 0000000..75159c6 --- /dev/null +++ b/cores/opencpu/custom_heap_cfg.h @@ -0,0 +1,57 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * custom_heap_cfg.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file intends for heap space definition of OpenCPU application. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __CUSTOM_HEAP_CFG_H__ +#define __CUSTOM_HEAP_CFG_H__ + +/*======================================================================== +| +| Heap Configuration. +|------------------ +| Predefine a block of memory, and the o.s will allocate the memory from +| the predefined memory when calling Ql_MEM_Alloc(). +| Min value is 1, and max value depends one the max memory available. +| Unit in byte. +\=========================================================================*/ +/*======================================================================== +| +| Note. +|------------------ +| This method is no longer used On the new platform,the o.s will allocate +| the memory from the "RAM FILE" memory when calling Ql_MEM_Alloc(). +| The size of the "RAM FILE" about 500KB. +| Unit in byte. +\=========================================================================*/ + +//#define HEAP_MEMSIZE (30 * 1024) + +#endif //__CUSTOM_HEAP_CFG_H__ diff --git a/cores/opencpu/custom_sys_cfg.c b/cores/opencpu/custom_sys_cfg.c new file mode 100644 index 0000000..f90e465 --- /dev/null +++ b/cores/opencpu/custom_sys_cfg.c @@ -0,0 +1,108 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * custom_sys_cfg.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file intends for the system definitions of application. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "ril.h" +#include "ql_common.h" + +/*======================================================================== +| +| Customized configurations. +|------------------ +| Define the working modes of power key pin and emerg_off pin, and +| specify the GPIO for watchdog. +\=========================================================================*/ + +/************************************************************************/ +/* Configure the enable of application. */ +/* The possible values are 'APP_DISABLE' and 'APP_ENABLE', and the */ +/* default value is 'APP_ENABLE'. */ +/* APP_ENABLE: the application will work after downloading into module*/ +/* APP_DISABLE:the application will not work after downloading.In this*/ +/* case, the module still work as a STANDARD module. */ +/************************************************************************/ +static const ST_AppEnable appEnableCfg = { + APP_ENABLE +}; + +static const ST_PowerKeyCfg pwrkeyCfg = { + TRUE, // working mode for power-on on PWRKEY pin + /* + Module automatically powers on when feeding a low level to POWER_KEY pin. + + When set to FALSE, the callback that Ql_PwrKey_Register registers will be triggered. Application must + call Ql_LockPower () to lock power supply, or module will lose power when the level of PWRKEY pin goes high. + */ + + TRUE, // working mode for power-off on PWRKEY pin + /* + Module automatically powers off when feeding a low level to POWER_KEY pin. + + When set to FALSE, the callback that Ql_PwrKey_Register registers will be triggered. + Application may do post processing before switches off the module. + */ +}; + +/************************************************************************/ +/* Define the GPIO pin for external watchdog. */ +/* NOTES: */ +/* Customer may specify two GPIOs if needed. */ +/************************************************************************/ +static const ST_ExtWatchdogCfg wtdCfg = { + PINNAME_PCM_OUT, // Specify a pin which connects to the external watchdog + PINNAME_END // Specify another pin for watchdog if needed +}; +ST_ExtWatchdogCfg* Ql_WTD_GetWDIPinCfg(void) +{ + return (ST_ExtWatchdogCfg*)(&wtdCfg); +} + +/************************************************************************/ +/* Define the working mode of serial debug port (UART2). */ +/* */ +/* The serial debug port (UART2) may work as a common serial port, as */ +/* well as work as a special debug port that can debug some issues */ +/* underlay application. */ +/* Under the special debug mode, please refer to the document */ +/* "Catcher_Operation_UGD" for the usage of debug port */ +/************************************************************************/ +static const ST_DebugPortCfg debugPortCfg = { + BASIC_MODE // Set the serial debug port (UART2) to a common serial port + //ADVANCE_MODE // Set the serial debug port (UART2) to a special debug port +}; + +const ST_SystemConfig SystemCfg[] = { + {SYS_CONFIG_APP_ENABLE_ID, SYS_CONFIG_APPENABLE_DATA_SIZE,(void*)&appEnableCfg}, + {SYS_CONFIG_PWRKEY_DATA_ID, SYS_CONFIG_PWRKEY_DATA_SIZE, (void*)&pwrkeyCfg }, + {SYS_CONFIG_WATCHDOG_DATA_ID, SYS_CONFIG_WATCHDOG_DATA_SIZE, (void*)&wtdCfg }, + {SYS_CONFIG_DEBUG_MODE_ID, SYS_CONFIG_DEBUGMODE_DATA_SIZE,(void*)&debugPortCfg}, + {SYS_CONFIG_END, 0, NULL } +}; diff --git a/cores/opencpu/custom_task_cfg.h b/cores/opencpu/custom_task_cfg.h new file mode 100644 index 0000000..755ab79 --- /dev/null +++ b/cores/opencpu/custom_task_cfg.h @@ -0,0 +1,10 @@ + +TASK_ITEM(proc_main_task, main_task_id, 10*1024, DEFAULT_VALUE1, DEFAULT_VALUE2) +TASK_ITEM(proc_reserved1, reserved1_id, 10*1024, DEFAULT_VALUE1, DEFAULT_VALUE2) +TASK_ITEM(proc_reserved2, reserved2_id, 10*1024, DEFAULT_VALUE1, DEFAULT_VALUE2) +TASK_ITEM(proc_arduino, arduino3_id, 10*1024, DEFAULT_VALUE1, DEFAULT_VALUE2) + + + + + diff --git a/cores/opencpu/dbg.c b/cores/opencpu/dbg.c new file mode 100644 index 0000000..6c2cb40 --- /dev/null +++ b/cores/opencpu/dbg.c @@ -0,0 +1,87 @@ +/* + * debug.c + * + * Created on: 26.02.2019 + * Author: georgi.angelov + */ + +#include "ql_stdlib.h" +#include "ql_uart.h" +#include "dbg.h" +#include "api.h" + +static Enum_SerialPort debugPort = UART_PORT_END; +static u32 debugMutex = 0; + +void debug_enable(unsigned long port) +{ + if (0 == debugMutex) + debugMutex = Ql_OS_CreateMutex("DEBUG_MUTEX"); + debugPort = (Enum_SerialPort)port; +} + +void debug_disable(void) +{ + debugPort = (Enum_SerialPort)UART_PORT_END; +} + +#ifdef ENABLE_DEBUG + +static char bufferDebug[1024]; + +int log_printf(const char *frm, ...) +{ + if (0 == debugMutex) + return 0; + va_list arg; + va_start(arg, frm); + if (debugPort < UART_PORT1 || debugPort > UART_PORT3) + return 0; + if (debugMutex) + Ql_OS_TakeMutex(debugMutex); + int n = wiz__vsnprintf(bufferDebug, sizeof(bufferDebug), frm, arg); + va_end(arg); + if (n > 0) + n = Ql_UART_Write(debugPort, (u8 *)bufferDebug, n); + if (debugMutex) + Ql_OS_GiveMutex(debugMutex); + return n; +} + +void log_buf(const char *text, const unsigned char *buf, unsigned int len) +{ + char txt[17]; + char bufferDump[512]; + unsigned int i, idx = 0; + Ql_snprintf(bufferDump + idx, sizeof(bufferDump) - idx, "[DMP] '%s' (%u bytes)\n", text, (unsigned int)len); + log_printf(bufferDump); + idx = 0; + Ql_memset(txt, 0, sizeof(txt)); + for (i = 0; i < len; i++) + { + if (i >= 4096) + break; + if (i % 16 == 0) + { + if (i > 0) + { + Ql_snprintf(bufferDump + idx, sizeof(bufferDump) - idx, " %s\n", txt); + log_printf(bufferDump); + idx = 0; + Ql_memset(txt, 0, sizeof(txt)); + } + idx += Ql_snprintf(bufferDump + idx, sizeof(bufferDump) - idx, "%04X: ", (unsigned int)i); + } + idx += Ql_snprintf(bufferDump + idx, sizeof(bufferDump) - idx, " %02X", (unsigned int)buf[i]); + txt[i % 16] = (buf[i] > 31 && buf[i] < 127) ? buf[i] : '.'; + } + if (len > 0) + { + for (/* i = i */; i % 16 != 0; i++) + idx += Ql_snprintf(bufferDump + idx, sizeof(bufferDump) - idx, " "); + Ql_snprintf(bufferDump + idx, sizeof(bufferDump) - idx, " %s\n", txt); + log_printf(bufferDump); + } +} + +#endif \ No newline at end of file diff --git a/cores/opencpu/dbg.h b/cores/opencpu/dbg.h new file mode 100644 index 0000000..a483c14 --- /dev/null +++ b/cores/opencpu/dbg.h @@ -0,0 +1,35 @@ +/* + * debug.h + * + * Created on: 26.02.2019 + * Author: georgi.angelov + */ + +#ifndef DBG_H_ +#define DBG_H_ + +#define ENABLE_DEBUG +#define ENABLE_TRACE + +void debug_enable(unsigned long port); + +int log_printf(const char *frm, ...) __attribute__((weak)); +void log_buf(const char *text, const unsigned char *buf, unsigned int len) __attribute__((weak)); + +#ifdef ENABLE_DEBUG +# include "ql_trace.h" +# define DBG(FORMAT, ...) log_printf(FORMAT, ##__VA_ARGS__) +# define DMP(TEXT, BUFFER, LEN) log_buf(TEXT, (unsigned char *)BUFFER, LEN) +#else +# define DBG(FORMAT, ...) +# define DMP(TEXT, BUFFER, LEN) +#endif + + +#ifdef ENABLE_TRACE +# define TRACE Ql_Debug_Trace +#else +# define TRACE +#endif + +#endif /* DBG_H_ */ diff --git a/cores/opencpu/dtostrf.c b/cores/opencpu/dtostrf.c new file mode 100644 index 0000000..0d51ef2 --- /dev/null +++ b/cores/opencpu/dtostrf.c @@ -0,0 +1,28 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2013 Arduino. All rights reserved. + Written by Cristian Maglie + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +char *dtostrf (double val, signed char width, unsigned char prec, char *sout) { + char fmt[20]; + sprintf(fmt, "%%%d.%df", width, prec); + sprintf(sout, fmt, val); + return sout; +} diff --git a/cores/opencpu/dtostrf.h b/cores/opencpu/dtostrf.h new file mode 100644 index 0000000..748a642 --- /dev/null +++ b/cores/opencpu/dtostrf.h @@ -0,0 +1,34 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2013 Arduino. All rights reserved. + Written by Cristian Maglie + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __DTOSTRF__ +#define __DTOSTRF__ + +#ifdef __cplusplus +extern "C" { +#endif + +char *dtostrf (double val, signed char width, unsigned char prec, char *sout); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cores/opencpu/fota/inc/fota_ftp.h b/cores/opencpu/fota/inc/fota_ftp.h new file mode 100644 index 0000000..f12aada --- /dev/null +++ b/cores/opencpu/fota/inc/fota_ftp.h @@ -0,0 +1,40 @@ +#ifndef __FOTA_FTP_H__ +#define __FOTA_FTP_H__ + +#include "ql_type.h" +#include "ql_stdlib.h" + +typedef enum tagATCmdType { + FTP_ATQIFGCNT, + FTP_ATQICSGP, + FTP_ATQFTPOPEN, + FTP_ATQFTPCFG, + FTP_ATQFTPPATH, + FTP_ATQFTPGET, + FTP_ATQFTPCLOSE, + FTP_FOTAUPGRADE, +}AT_FTPCmdType; + +typedef struct { + s32 id; + u32 interval; + bool autoRepeat; + bool runState; +}ST_FTPTimer; + +#define UP_DATA_BUFFER_LEN 512 +#define FTP_SERVERADD_LEN 40 +#define FTP_FILEPATH_LEN 60 +#define FTP_USERNAME_LEN 20 +#define FTP_PASSWORD_LEN 20 +#define FTP_BINFILENAME_LEN 25 +#define FTP_SERVICE_PORT 21 + +#define APP_BINFILE_PATH "RAM" + +bool FTP_IsFtpServer(u8* URL); +s32 FTP_FotaMain(u8 contextId, u8* URL); + + +#endif + diff --git a/cores/opencpu/fota/inc/fota_http.h b/cores/opencpu/fota/inc/fota_http.h new file mode 100644 index 0000000..c4365ef --- /dev/null +++ b/cores/opencpu/fota/inc/fota_http.h @@ -0,0 +1,115 @@ +#ifndef __FOTA_HTTP_H__ +#define __FOTA_HTTP_H__ + +#include "ql_type.h" +#include "ql_stdlib.h" +#include "fota_http_code.h" + +/****************************************************************************** +* Macros +******************************************************************************/ +#define QUECTEL_HTTP_URL_LENGTH 200 +#define QUECTEL_HTTP_DOMAINNAME_LENGTH 150 +#define QUECTEL_HTTP_DATABUFFER_SIZE 512 +#define HTTP_SERVICE_PORT 80 +#define HTTP_GETREADTIMEROUT 120000 // 2 mins for read socket timerout +#define HTTP_GETREADTIMERID 0x2F + + +typedef enum HttpResultTag +{ + HTTP_RESULT_ERROR_WOULDBLOCK=-2, + + HTTP_RESULT_OK=0, + HTTP_RESULT_ERROR_SOC_CLOSE, + HTTP_RESULT_ERROR_HTTP_RELOCATION, + HTTP_RESULT_ERROR_HTTP_RESPONSE_FAILED, + HTTP_RESULT_ERROR_DECODEERROR, + END_OF_HTTP_RESULT +}HttpResult_e; + + +typedef struct HttpMainContextTag +{ + u8 contextId; /*relation for tcpip*/ + u8 sourceid; /*relation for tcpip*/ + u8 socketid;/*relation for tcpip*/ + + bool bpeersocketclose; + + u32 httpGettimeout; + u32 httpGetHeadTimer; + bool httpGettimerstate; + + u32 downloadsize; + u32 downloadtimeout; + u32 httpDownloadTimer; + + u8 Address[QUECTEL_HTTP_URL_LENGTH+1]; + u32 AddressValidLegth; + + u32 ContentLength; + + bool getbody; + u32 receivedbodydata; + + u8 hostip[30]; + u16 hostport; + u8 hostname[QUECTEL_HTTP_DOMAINNAME_LENGTH+1]; + u8 hostipAddres[5]; + + u8 *http_socketdata_p; // porint to the http socket received buffer + u8 *genhttp_dstconstptr; + u16 genhttp_dstconstsize; + u16 genhttp_dstpos; + s32 genhttp_dstvaliddatalen; + + HttpHeader_t httpheader; + + u8 httpversion; +}HttpMainContext_t; + + + +extern HttpMainContext_t httpMainContext; + +void http_TimerCallback(u32 timerId, void* param); +void Callback_GetIpByHostName(u8 contexId, u8 requestId, s32 errCode, u32 ipAddrCnt, u32* ipAddr); + + +/***************************************************************** +* GPRS and Socket callback function +******************************************************************/ +void HttpCallback_GPRS_Actived(u8 contexId, s32 errCode, void* customParam); +void HttpCallBack_GPRS_Deactived(u8 contextId, s32 errCode, void* customParam ); + +/***************************************************************** +*socket callback function +******************************************************************/ +void Httpcallback_socket_connect(s32 socketId, s32 errCode, void* customParam); +void Httpcallback_socket_close(s32 socketId, s32 errCode, void* customParam); +void Httpcallback_socket_accept(s32 listenSocketId, s32 errCode, void* customParam); +void Httpcallback_socket_read(s32 socketId, s32 errCode, void* customParam); +void Httpcallback_socket_write(s32 socketId, s32 errCode, void* customParam); + +bool HTTP_IsHttpServer(u8* URL); + +s32 HTTP_FotaMain(u8 contextId, u8* URL); + +void http_initialize(void); + +void http_ConnectToServer(void); + +s32 http_SendHttpGetHead( s32 socketId); + +s8 http_RecvHttpHead(s32 socketid, bool bContinue); + +s8 http_RecvHttpBody(s32 socketid, bool bContinue); + +s8 http_RecvHttpChunkedBody(s32 socketid, bool bContinue); + +bool http_DecodeURL(u8 *Address, u32 *AddressValidLegth, u8 *hostip, u16 hostiplength, + u8 *hostname, u16 hostnamelength, u16 *hostport); + + +#endif diff --git a/cores/opencpu/fota/inc/fota_http_code.h b/cores/opencpu/fota/inc/fota_http_code.h new file mode 100644 index 0000000..e1877d3 --- /dev/null +++ b/cores/opencpu/fota/inc/fota_http_code.h @@ -0,0 +1,84 @@ +#ifndef __FOTA_HTTP_CODE_H__ +#define __FOTA_HTTP_CODE_H__ + +#include "ql_type.h" +#include "ql_stdlib.h" + + +#define HTTP_VALUE_LENGTH 50 + +#define CHAR_IS_LOWER( alpha_char ) \ + ( ( (alpha_char >= 'a') && (alpha_char <= 'z') ) ? 1 : 0 ) + +#define CHAR_IS_UPPER( alpha_char ) \ + ( ( (alpha_char >= 'A') && (alpha_char <= 'Z') ) ? 1 : 0 ) + + typedef enum HttpHeaderFieldTag +{ + HTTP_HEADERFIELD_END=0, + HTTP_HEADERFIELD_RESPONSEHEAD,/*http responsehead ·*/ + HTTP_HEADERFIELD_GETMOTHED, + HTTP_HEADERFIELD_POSTMOTHED, + HTTP_HEADERFIELD_URL, + HTTP_HEADERFIELD_PROTOL, + HTTP_HEADERFIELD_HOST, + HTTP_HEADERFIELD_ACCEPT, + HTTP_HEADERFIELD_ACCEPT_CHARSET, + HTTP_HEADERFIELD_CACHE_CONTROL, + HTTP_HEADERFIELD_PRAGMA, + HTTP_HEADERFIELD_CONNECTION, + HTTP_HEADERFIELD_USERAGENT, + HTTP_HEADERFIELD_ACCEPT_LANGUAGE, + HTTP_HEADERFIELD_X_WAP_PROFILE, + HTTP_HEADERFIELD_LINESYMBOL, + HTTP_HEADERFIELD_CONTENT_TYPE, + HTTP_HEADERFIELD_CONTENT_LENGTH, + HTTP_HEADERFIELD_TRANSFER_ENCODING_CHUNKED, + HTTP_HEADERFIELD_DATE, + END_OF_HTTP_HEADERFIELD +} HttpHeaderField_e; +typedef struct HttpLineValueTag +{ + HttpHeaderField_e filedtype; + u8 valuetype; + u32 valuelength; + u8 value[HTTP_VALUE_LENGTH]; +}HttpLineValue_t; + +typedef enum HttpCodeResultTag +{ + HTTP_CODERESULT_OK =0, + HTTP_CODERESULT_END =1, /*end*/ + HTTP_CODERESULT_BUFFERFULL = 2, /*buffer full*/ + HTTP_CODERESULT_DATAABSENT = 3, /*data */ + HTTP_CODERESULT_ERROR = -1 +} HttpCodeResult_e; + +typedef struct HttpHeaderTag +{ + s32 httpresponse;/*HTTP response*/ + u8 *urladdress;/*print to the url address, */ + u16 urladdress_length;/*not include the \0 */ + u8 hostnameorip[50]; + u8 *Accept; + u8 *Content_Type; + u16 hostport; + u32 ContentLength; /*Content length*/ + + bool ContentLength_Exist_InHttpResponse; + bool Transfer_Encoding_Is_chunked; + + u8 *Connection; // Keep-Alive + u8 *User_Agent; // QUECTEL_MODULE + u8 *Accept_Charset;//"utf-8, us-ascii" + u8 *Cache_Control;//"no-cache" + u8 *x_wap_profile; + u8 *Pragma;//"no-cache" + u8 *Accept_Language; //"en" +}HttpHeader_t; + + +s32 http_DecodeHeader(HttpHeader_t *httpheader, u8 *decode_buffer, s32 decode_buffer_length, s32 *decode_length); + +#endif + diff --git a/cores/opencpu/fota/inc/fota_main.h b/cores/opencpu/fota/inc/fota_main.h new file mode 100644 index 0000000..24fc9df --- /dev/null +++ b/cores/opencpu/fota/inc/fota_main.h @@ -0,0 +1,134 @@ + +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * fota_main.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * This file is for upgrading application processing by FOTA. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __FOTA_MAIN_H__ +#define __FOTA_MAIN_H__ +#include "ql_type.h" +#include "ql_uart.h" +#include "ql_gpio.h" + +/****************************************************************************** +* Macros +******************************************************************************/ +#define UPGRADE_APP_DEBUG_ENABLE 0 +#if UPGRADE_APP_DEBUG_ENABLE > 0 +#define UPGRADE_APP_DEBUG_PORT UART_PORT1 +#define DBG_BUF_LEN 512 +#define UPGRADE_APP_DEBUG(BUF,...) QL_TRACE_LOG(UPGRADE_APP_DEBUG_PORT,BUF,DBG_BUF_LEN,__VA_ARGS__) +#else +#define UPGRADE_APP_DEBUG(BUF,...) +#endif + +#define FOTA_DBG_SMPL_PRINT_EN 1 +#if FOTA_DBG_SMPL_PRINT_EN > 0 +#define FOTA_DBG_PRINT_PORT UART_PORT1 +#define FOTA_DBG_PRINT(STR) Ql_UART_Write(FOTA_DBG_PRINT_PORT, (u8*)(STR), Ql_strlen((const char *)(STR))) +#else +#define FOTA_DBG_PRINT(STR) +#endif + +#define MSG_ID_RESET_MODULE_REQ (MSG_ID_URC_INDICATION + 3) +#define MSG_ID_FTP_RESULT_IND (MSG_ID_URC_INDICATION + 4) + +#define FTP_RESULT_SUCCEED 0 +#define FTP_RESULT_FAILED -1 + +typedef enum{ + UP_FOTAINITFAIL, // Fota init failed. + UP_START,//Fota upgrade start£¬ + UP_URLDECODEFAIL, + UP_CONNECTING,// connect to the server + UP_CONNECTED,// connect ok + UP_GETTING_FILE,// download the bin file + UP_GET_FILE_OK,// the bin file get ok, + UP_SYSTEM_REBOOT,//before system reboot£¬reporting this state. + UP_UPGRADFAILED, + FOTA_STATE_END +}Upgrade_State; + +typedef bool (* Callback_Upgrade_State)(Upgrade_State state, s32 fileDLPercent); +extern Upgrade_State g_FOTA_State; +extern Callback_Upgrade_State Fota_UpgardeState; +#define FOTA_UPGRADE_IND(x,y,z) if(NULL != Fota_UpgardeState) {z=Fota_UpgardeState(x,y);} + +/***************************************************************** +* Function: Ql_FOTA_StartUpgrade +* +* Description: +* This function launches the upgrading application processing by FOTA. +* User may use FTP or HTTP as the GPRS data transmission channel. +* +* Parameters: +* url: +* the URL address of the destination bin file. +* +* The URL format for http is: http://hostname/filePath/fileName:port +* NOTE: if ":port" is be ignored, it means the port is the default port of http (80 port) +* +* The URL format for ftp is: ftp://hostname/filePath/fileName:port@username:password +* NOTE:1. If ":port" is be ignored, it means the port is the default port of ftp (21 port) +* If no username and password, "@username:password" can be ignored. +* 2. you must make sure there is no '@' char before the "@username:password" string. +* +* eg1: ftp://www.jjj.com/filePath/xxx.bin:8021@username:password +* eg2: ftp://www.jjj.com/filePath/xxx.bin@username:password +* eg3: ftp://192.168.10.10/filePath/APP.bin +* eg4: http://23.11.67.89/filePath/xxx.bin +* eg5: http://www.quectel.com:8080/filePath/xxx.bin +* +* apnCfg: +* the APN related parameters. +* +* callbcak_UpgradeState_Ind: +* callback function that reports the upgrading state. +* If it's NULL, a default callback function "Fota_Upgrade_States" will be adopted. +* Return: +* 0 indicates this function successes. +* -1 indicates this function failure. +*****************************************************************/ +s32 Ql_FOTA_StartUpgrade(u8* url, ST_GprsConfig* apnCfg, Callback_Upgrade_State callbcak_UpgradeState_Ind); + +/***************************************************************** +* Function: Ql_FOTA_StopUpgrade +* +* Description: +* This function stop upgrading application processing by FOTA. +* +* Parameters: +* None. +* Return: +* +*****************************************************************/ +s32 Ql_FOTA_StopUpgrade(void); + +#endif //__FOTA_MAIN_H__ diff --git a/cores/opencpu/fota/src/fota_ftp.c b/cores/opencpu/fota/src/fota_ftp.c new file mode 100644 index 0000000..d7e3a7a --- /dev/null +++ b/cores/opencpu/fota/src/fota_ftp.c @@ -0,0 +1,553 @@ +#include "custom_feature_def.h" +#include "ql_common.h" +#include "ql_system.h" +#include "ql_type.h" +#include "ql_gprs.h" +#include "ql_timer.h" +#include "ql_fota.h" +#include "ql_fs.h" +#include "ql_error.h" +#include "ril.h" +#include "ril_util.h" +#include "ril_ftp.h" +#include "ril_network.h" +#include "fota_ftp.h" +#include "fota_main.h" + +#ifdef __OCPU_FOTA_BY_FTP__ +#define FTP_CONNECT_ATTEMPTS (5) // max 5 times for attempt to connect, or restart module +static u8 Contextid; +static s32 SerPort; +static u8 ServerAdder[FTP_SERVERADD_LEN] = {0x0}; // ip string or domain name +static u8 FilePath[FTP_FILEPATH_LEN] = {0x0}; // file in the server path +static u8 Ftp_userName[FTP_USERNAME_LEN] = {0x0}; +static u8 Ftp_Possword[FTP_PASSWORD_LEN] = {0x0}; +static u8 appBin_fName[FTP_BINFILENAME_LEN] = {0x0}; + +extern ST_FotaConfig FotaConfig; +extern u8 Fota_apn[MAX_GPRS_APN_LEN]; +extern u8 Fota_userid[MAX_GPRS_USER_NAME_LEN]; +extern u8 Fota_passwd[MAX_GPRS_PASSWORD_LEN]; +extern CallBack_Ftp_Download FtpGet_IND_CB; + +#if UPGRADE_APP_DEBUG_ENABLE > 0 +extern char FOTA_DBGBuffer[DBG_BUF_LEN]; +#endif + +static void FTP_Program(void); + +static void DoUpgrade(void); +static bool FTP_DecodeURL(u8 *URL, s32 URLlength, u8 *serverAdd, u8* filePath, u8* binFile, u8* ftpUserName, u8 *ftpUserPassword, s32* serverPort); + +s32 FTP_FotaMain(u8 contextId, u8* URL) +{ + s32 retValue; + bool ftpDecodeURL; + + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Fota ftp Main entry !-->\r\n"); + FOTA_DBG_PRINT("Enter into FTP_FotaMain()"); + + ftpDecodeURL = FTP_DecodeURL(URL, Ql_strlen((char*)URL), ServerAdder, FilePath, appBin_fName, Ftp_userName, Ftp_Possword, &SerPort); + if(!ftpDecodeURL) + { + FOTA_UPGRADE_IND(UP_URLDECODEFAIL,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--ftp DECODE URL FAILED !!!-->\r\n"); + FOTA_DBG_PRINT("Fail to decode FTP URL\r\n"); + return -1; + } + Contextid = contextId; + + FTP_Program(); + + return 0; +} + +bool FTP_IsFtpServer(u8* URL) +{ + char buffer[5]; + Ql_memcpy(buffer, URL, sizeof(buffer)); + Ql_StrToUpper(buffer); + if(NULL == Ql_strstr(buffer, "FTP")) + { + return FALSE; + } + else + { + return TRUE; + } +} + +void FTP_Callback_OnDownload(s32 result,s32 size) +{ + s32 ret; + bool retValue; + if (result) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<---image bin file size =%d--->\r\n",size); + FOTA_DBG_PRINT("Succeed in downloading image bin via FTP\r\n"); + FOTA_UPGRADE_IND(UP_GET_FILE_OK,100,retValue); + }else{ + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- FTP fails to get file, cause=%d -->\r\n", size); + FOTA_DBG_PRINT("Fail to download image bin via FTP\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + } + ret = RIL_FTP_QFTPCLOSE(); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- FTP close connection, ret=%d -->\r\n", ret); + FOTA_DBG_PRINT("<-- Close ftp connection -->\r\n"); + + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Deactivating PDP context -->\r\n"); + FOTA_DBG_PRINT("<-- Deactivating PDP context -->\r\n"); + ret = RIL_FTP_QIDEACT(); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Released PDP context, ret=%d -->\r\n", ret); + FOTA_DBG_PRINT("<-- Released PDP context -->\r\n"); + + // Start to do upgrading by FOTA + if (result) + { + #if 1 + DoUpgrade(); + #else + // Don't do FOTA, just do FTP repeatedly (for test) + Ql_OS_SendMessage(main_task_id, MSG_ID_FTP_RESULT_IND, FTP_RESULT_SUCCEED, 0); + #endif + } + else + { + Ql_OS_SendMessage(main_task_id, MSG_ID_FTP_RESULT_IND, FTP_RESULT_FAILED, 0); + } +} + +static void FTP_Program(void) +{ + s32 ret; + u8 attempts = 0; + bool retValue; + u32 fileSize = 0; + + ret = RIL_NW_SetGPRSContext(Contextid); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Set GPRS PDP context, ret=%d -->\r\n", ret); + FOTA_DBG_PRINT("<-- Set GPRS PDP context -->\r\n"); + + ret = RIL_NW_SetAPN(1,(char*)Fota_apn,(char*)Fota_userid,(char*)Fota_passwd); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Set GPRS APN, ret=%d -->\r\n", ret); + FOTA_DBG_PRINT("<-- Set GPRS APN -->\r\n"); + + FOTA_UPGRADE_IND(UP_CONNECTING,0,retValue); + do + { + ret = RIL_FTP_QFTPOPEN(ServerAdder, SerPort, Ftp_userName, Ftp_Possword, 1); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- FTP open connection, ret=%d -->\r\n", ret); + if (RIL_AT_SUCCESS == ret) + { + attempts = 0; + FOTA_UPGRADE_IND(UP_CONNECTED,0,retValue); + FOTA_DBG_PRINT("<-- Open ftp connection -->\r\n"); + break; + } + attempts++; + FOTA_DBG_PRINT("<-- Retry to open FTP 2s later -->\r\n"); + Ql_Sleep(2000); + } while (attempts < FTP_CONNECT_ATTEMPTS); + if (FTP_CONNECT_ATTEMPTS == attempts) + { + FOTA_DBG_PRINT("<-- Fail to open ftp connection for 5 times -->\r\n"); + + // Infor the caller to reset the module + Ql_OS_SendMessage(main_task_id, MSG_ID_RESET_MODULE_REQ, attempts, ret); + return; + } + + ret = RIL_FTP_QFTPCFG(4, (u8*)APP_BINFILE_PATH); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Set local storage, ret=%d -->\r\n", ret); + FOTA_DBG_PRINT("<-- Set local storage -->\r\n"); + + ret = RIL_FTP_QFTPPATH(FilePath); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Set remote path, ret=%d -->\r\n", ret); + FOTA_DBG_PRINT("<-- Set remote path -->\r\n"); + + ret = RIL_FTP_QFTPSIZE(appBin_fName,&fileSize); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Get file Size, ret=%d,fileSize=%d -->\r\n", ret,fileSize); + FOTA_DBG_PRINT("<-- Get file Size -->\r\n"); + + FOTA_UPGRADE_IND(UP_GETTING_FILE,0,retValue); + // By default, 3min time out in RIL + ret = RIL_FTP_QFTPGET(appBin_fName, fileSize, FTP_Callback_OnDownload); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Downloading FTP file, ret=%d -->\r\n", ret); + if (ret < 0) + { + ret = RIL_FTP_QFTPCLOSE(); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- FTP close connection, ret=%d -->\r\n", ret); + FOTA_DBG_PRINT("<-- Close ftp connection -->\r\n"); + + ret = RIL_FTP_QIDEACT(); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Release PDP context, ret=%d -->\r\n", ret); + FOTA_DBG_PRINT("<-- Released PDP context -->\r\n"); + + // Inform the caller of FTP downloading failed + Ql_OS_SendMessage(main_task_id, MSG_ID_FTP_RESULT_IND, FTP_RESULT_FAILED, ret); + } + FOTA_DBG_PRINT("<-- Downloading FTP file -->\r\n"); +} + +void DoUpgrade(void) +{ + u32 filesize,fd_file; + u8 *file_buffer=NULL; + s32 ret2,ret3; + u32 realLen,lenToRead; + bool retValue; + u8 binfilePath[FTP_BINFILENAME_LEN+4]; + + // Prepare update data + if (!Ql_strncmp(APP_BINFILE_PATH,"UFS", 3))//UFS + { + Ql_sprintf((char*)binfilePath,"%s",(char*)appBin_fName); + } + else + { + Ql_sprintf((char*)binfilePath,"%s:%s",APP_BINFILE_PATH,(char*)appBin_fName); + } + + ret2 = Ql_FS_Check((char*)binfilePath); + if (QL_RET_OK == ret2) + { + filesize = Ql_FS_GetSize((char*)binfilePath); + if(filesize < 0) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"\r\n<-- Fail to get size (App) Failed ret =%d-->\r\n",filesize); + FOTA_DBG_PRINT("<-- Fail to get file size -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + return; + } + + if (Ql_strncmp((char*)binfilePath,"RAM:", 4)) + { + fd_file = Ql_FS_Open((char*)binfilePath, QL_FS_READ_ONLY); + } + else + { + fd_file = Ql_FS_OpenRAMFile((char*)binfilePath, QL_FS_READ_ONLY, filesize); + } + + if(fd_file < 0) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"\r\n<-- Fail to open (App) !!-->\n"); + FOTA_DBG_PRINT("<-- Fail to open file -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + return ; + } + file_buffer = Ql_MEM_Alloc(UP_DATA_BUFFER_LEN); + if(NULL ==file_buffer) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"\r\n<-- fota ftp memory allocation failed !!-->\r\n"); + FOTA_DBG_PRINT("<-- Fail allocate memory -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + return ; + } + /*Write App bin to flash*/ + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Processing data before update -->\r\n"); + FOTA_DBG_PRINT("<-- Processing data before update -->\r\n"); + while(filesize>0) + { + if (filesize <= UP_DATA_BUFFER_LEN) + { + lenToRead = filesize; + } else { + lenToRead = UP_DATA_BUFFER_LEN; + } + ret3 = Ql_FS_Read(fd_file, file_buffer, lenToRead, &realLen); + if(ret3 != 0) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--Ql_FS_Read failed(ret =%d)-->\r\n",ret3); + FOTA_DBG_PRINT("<-- Fail to read file -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + return ; + } + // UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- lenToRead %d ret=%d-->\r\n", lenToRead,ret3); + ret3 = Ql_FOTA_WriteData(realLen,(s8*)file_buffer); + if(ret3 != 0) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--Ql_FOTA_WriteData failed(ret =%d)-->\r\n",ret3); + FOTA_DBG_PRINT("<-- Ql_FOTA_WriteData() failed -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + return ; + } + filesize -= realLen; + // UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- lenToRead %d Fota write, len=%d, ret=%d, filesize=%d -->\r\n", lenToRead,realLen, ret3, filesize); + //Ql_Sleep(10); + } + if(NULL != file_buffer) + { + Ql_MEM_Free(file_buffer); + file_buffer = NULL; + } + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- Finish processing data -->\r\n"); + FOTA_DBG_PRINT("<-- Finish processing data -->\r\n"); + Ql_FS_Close(fd_file); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- Close file -->\r\n"); + FOTA_DBG_PRINT("<-- Close file -->\r\n"); + } + else //if (QL_RET_ERR_FILENOTFOUND == ret2) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"\r\n<-- App Bin(%s) does not exsit ret=%d-->\r\n", (char*)binfilePath,ret2); + FOTA_DBG_PRINT("<-- App Bin file does not exsit -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + return; + } + Ql_Sleep(300); + ret3 = Ql_FOTA_Finish(); //Finish the upgrade operation ending with calling this API + if(ret3 != 0) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"\r\n<-- Fota App Finish Fail!(ret =%d) -->\r\n",ret3); + FOTA_DBG_PRINT("<-- Ql_FOTA_Finish() failed -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + return; + } + + FOTA_DBG_PRINT("<-- Delete file -->\r\n"); + Ql_FS_Delete((char*)binfilePath); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- Delete file -->\r\n"); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- Start to Update! If you return TRUE in the fota upgrade callback in the UP_SYSTEM_REBOOT case, the module will automatically restart.-->\r\n"); + FOTA_DBG_PRINT("<-- Start to Update! If you return TRUE in the fota upgrade callback in the UP_SYSTEM_REBOOT case, the module will automatically restart.-->\r\n"); + + // Start to upgrade + FOTA_UPGRADE_IND(UP_SYSTEM_REBOOT,100,retValue); + if(NULL == Fota_UpgardeState || (retValue))// if fota upgrade callback function return TRUE in the UP_SYSTEM_REBOOT case ,the system upgrade app at once. + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Fota upgrade callback return TRUE!!, system reboot for upgrade now-->\r\n"); + FOTA_DBG_PRINT("<--Fota upgrade callback return TRUE!!, system reboot for upgrade now-->\r\n"); + Ql_Sleep(300); + ret3=Ql_FOTA_Update(); + if(0 != ret3) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"\r\n<-- Ql_Fota_Update FAILED!ret3=%d -->\r\n",ret3); + FOTA_DBG_PRINT("<-- Ql_FOTA_Update() failed -->\r\n"); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"\r\n<-- Reboot 1 second later ... -->\r\n"); + FOTA_DBG_PRINT("<-- Reboot 1 second later ... -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + Ql_Sleep(1000); + //Ql_Reset(0); + } + else + { + //If update OK, module will reboot automatically + } + } + else + { + // if upgrade state callback function return false, you must call Ql_FOTA_Update function before you reboot the system + } +} + +bool FTP_DecodeURL(u8 *URL, s32 URLlength, u8 *serverAdd, u8* filePath, u8* binFile, u8* ftpUserName, u8 *ftpUserPassword, s32* serverPort) +{ + u8 hstr[7]; + u32 j,i; + u8 *phostnamehead; + u8 *phostnameTail; + char portStr[8]; + bool ret = FALSE; + u8 *puri=URL; + u32 datalen = URLlength; + u32 filePathLen,binfilenameLen; + *serverPort = FTP_SERVICE_PORT; + + do + { + /* Resolve ftp:// */ + Ql_memset(hstr,0,7); + + if((datalen) < 7) + break; + Ql_memcpy(hstr,URL,7); + for(i=0;i<6;i++) + { + if( (hstr[i]>= 'A') && (hstr[i] <= 'Z')) + hstr[i] = Ql_tolower(hstr[i]); + } + if(NULL != Ql_strstr((char *)hstr,"ftp://")) + { + puri = URL + 6; + datalen -= 6; + } + else + { + break; + } + i=0; + /* retrieve host name */ + phostnamehead = puri; + phostnameTail = puri; + while(i FTP_SERVERADD_LEN) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--server Addess is too long!!! (the buffer limit size is %d)->\r\n",FTP_SERVERADD_LEN); + FOTA_DBG_PRINT("<--server Addess is too long!!! (the buffer limit size is 40)->\r\n"); + break; + } + Ql_memcpy((char*)serverAdd,(char*)phostnamehead, i); // here is server ip or domain name. + // UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--!!serverAdd=%s-->\r\n",serverAdd); + + if(datalen >= i) + datalen -= i; + else + break; + + + /* retrieve file path , image file name and ,port eg /filepath/file/xxx.bin:8021@user...... or /filepath/file/xxx.bin@user...... */ + puri+=i; + i = 0; + phostnamehead = puri; + phostnameTail = puri; + while(puri[i] !=':' && puri[i] !='@' && i= i) + { + datalen -= i; + } + else // no @username:password eg : ftp://192.168.10.10/file/test.bin + { + j = i; + while(puri[j] !='/' && j>0) // the last '/' char + { + j--; + } + binfilenameLen = (i-j-1); + filePathLen = i-(i-j); + if((binfilenameLen > FTP_BINFILENAME_LEN) ||(filePathLen > FTP_FILEPATH_LEN)) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--!! bin file name len(%d) or filePath(lne %d) is to loog ! limit len(binfilename=%d, filePath=%d)->\r\n",binfilenameLen,filePathLen,FTP_BINFILENAME_LEN,FTP_FILEPATH_LEN); + FOTA_DBG_PRINT("<--!! bin file name len or filePath is to loog ! limit len(binfilename=25, filePath=60)->\r\n"); + break; + } + Ql_memcpy((char *)binFile, (char *)(puri+j+1),binfilenameLen); + Ql_memcpy((char *)filePath, (char *)phostnamehead, filePathLen); + break; + } + + /* retrieve file path , image file name /filepath/file/xxx.bin@user...... */ + if(puri[i] =='@' ) // no port number , it means port number is 21 + { + j = i; + while(puri[j] !='/' && j>0) // the last '/' char + { + j--; + } + binfilenameLen = (i-j-1); + filePathLen = i-(i-j); + if((binfilenameLen > FTP_BINFILENAME_LEN) ||(filePathLen > FTP_FILEPATH_LEN)) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--@@ bin file name len(%d) or filePath(lne %d) is to loog ! limit len(binfilename=%d, filePath=%d)->\r\n",binfilenameLen,filePathLen,FTP_BINFILENAME_LEN,FTP_FILEPATH_LEN); + FOTA_DBG_PRINT("<--@@ bin file name len(%d) or filePath(lne %d) is to loog ! limit len(binfilename=25, filePath=60)->\r\n"); + break; + } + Ql_memcpy((char *)binFile, (char *)(puri+j+1),binfilenameLen); + Ql_memcpy((char *)filePath, (char *)phostnamehead, filePathLen); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--@@binFile=%s filePath=%s datalen=%d-->\r\n",binFile,filePath,datalen); + } + /* retrieve file path , image file name and port /filepath/file/xxx.bin:8021@user...... */ + else// else if (puri[i] ==':') ftp port number. + { + j = i; + while(puri[j] !='/' && j>0) // the last '/' char + { + j--; + } + binfilenameLen = (i-j-1); + filePathLen = i-(i-j); + if((binfilenameLen > FTP_BINFILENAME_LEN) ||(filePathLen > FTP_FILEPATH_LEN)) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--## bin file name len(%d) or filePath(lne %d) is to loog ! limt len(binfilename=%d, filePath=%d)->\r\n",binfilenameLen,filePathLen,FTP_BINFILENAME_LEN,FTP_FILEPATH_LEN); + FOTA_DBG_PRINT("<--## bin file name len or filePath is to loog ! limit len(binfilename=25, filePath=60)->\r\n"); + break; + } + Ql_memcpy((char *)binFile, (char *)(puri+j+1),binfilenameLen); + Ql_memcpy((char *)filePath, (char *)phostnamehead, filePathLen); + + puri+=i; // puri = :port@username.... + i = 0; + phostnamehead = puri; + phostnameTail = puri; + while(i= i) + datalen -= i; + else + break; + Ql_memset(portStr, 0x00,sizeof(portStr)); + Ql_memcpy(portStr, phostnamehead+1, i-1); + *serverPort = Ql_atoi(portStr); + // UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--&&portStr=%s server port=%d-->\r\n",portStr,*serverPort); + } + + /* retrieve the ftp username and password eg @username:password */ + puri+=i; + i = 0; + phostnamehead = puri; + phostnameTail = puri; + while(puri[i] !=':' && i= i) + datalen -= i; + else + break; + if(0 == datalen)// no user password + { + if(i > FTP_USERNAME_LEN) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--@@ ftp user name(len %d) is to loog ! limit len(%d)->\r\n",i,FTP_USERNAME_LEN); + FOTA_DBG_PRINT("<--@@ ftp user name is to loog ! limit len(20)->\r\n"); + break; + } + Ql_memcpy(ftpUserName,phostnamehead+1,i); // ftp user name + } + else + { + if((i-1 > FTP_USERNAME_LEN) || (datalen > FTP_PASSWORD_LEN)) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--@@ ftp user name(len %d) or password(len=%d)is to loog ! limit len(username=%d, pwd =%d)->\r\n",i-1,datalen,FTP_USERNAME_LEN,FTP_PASSWORD_LEN); + FOTA_DBG_PRINT("<--@@ ftp user name or passwordis to loog ! limit len(username=20, pwd =20)->\r\n"); + break; + } + Ql_memcpy(ftpUserName,phostnamehead+1,i-1); // ftp user name + Ql_memcpy(ftpUserPassword,phostnamehead+i+1,datalen); //user password + } + + ret =TRUE; + }while(FALSE); + + if(*(filePath+Ql_strlen((const char*)filePath)-1) != '/'){ + Ql_memcpy((void*)(filePath+Ql_strlen((const char*)filePath)), (const void*)"/", 1); // file path end with '/' + } + //Ql_memcpy((void*)(filePath+Ql_strlen((const char*)filePath)), (const void*)"/", 1); // file path end with '/' + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--serverAdd=%s, file path=%s, image filename=%s-->\r\n",ServerAdder,FilePath,appBin_fName); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--ftp user name=%s, user password =%s serverPort=%d-->\r\n",Ftp_userName, Ftp_Possword,*serverPort); + FOTA_DBG_PRINT("<--serverAdd="); + FOTA_DBG_PRINT(ServerAdder); + FOTA_DBG_PRINT(" file path="); + FOTA_DBG_PRINT(FilePath); + FOTA_DBG_PRINT("image filename="); + FOTA_DBG_PRINT(appBin_fName); + FOTA_DBG_PRINT("\r\n"); + FOTA_DBG_PRINT("<--ftp user name="); + FOTA_DBG_PRINT(Ftp_userName); + FOTA_DBG_PRINT(" user password ="); + FOTA_DBG_PRINT(Ftp_Possword); + FOTA_DBG_PRINT(" serverPort=xxx-->\r\n"); + return ret; +} + +#endif //__OCPU_FOTA_BY_FTP__ diff --git a/cores/opencpu/fota/src/fota_http.c b/cores/opencpu/fota/src/fota_http.c new file mode 100644 index 0000000..32b9e20 --- /dev/null +++ b/cores/opencpu/fota/src/fota_http.c @@ -0,0 +1,766 @@ +#include "custom_feature_def.h" +#include "ql_stdlib.h" +#include "ql_common.h" +#include "ql_type.h" +#include "ql_socket.h" +#include "ql_timer.h" +#include "ql_fota.h" +#include "ql_gprs.h" +#include "fota_http.h" +#include "fota_http_code.h" +#include "fota_main.h" + +#ifdef __OCPU_FOTA_BY_HTTP__ + +extern ST_GprsConfig Fota_gprsCfg; +extern u8 Fota_apn[10]; +extern u8 Fota_userid[10]; +extern u8 Fota_passwd[10]; + +#if UPGRADE_APP_DEBUG_ENABLE > 0 +extern char FOTA_DBGBuffer[DBG_BUF_LEN]; +#endif + +extern Callback_Upgrade_State Fota_UpgardeState; + +/***************************************************************** +* Global Variables +******************************************************************/ +ST_PDPContxt_Callback Httpcallback_gprs_func = +{ + //HttpCallback_GPRS_Actived, + NULL, + HttpCallBack_GPRS_Deactived +}; + +ST_SOC_Callback Httpcallback_SOC_func= +{ + Httpcallback_socket_connect, + Httpcallback_socket_close, + Httpcallback_socket_accept, + Httpcallback_socket_read, + Httpcallback_socket_write +}; + +HttpMainContext_t httpMainContext; +void http_GetImagefilefromServer(); + +char* HttpGetHead[] = +{ + "GET %s HTTP/1.1\r\n", // "%s" URL address; + "Host: %s:%d\r\n", // "%s" host name or ip %s port; port is not need + "Accept: */*\r\n", + "User-Agent: QUECTEL_MODULE\r\n", + "Connection: Keep-Alive\r\n", + "\r\n", +}; + + +bool HTTP_IsHttpServer(u8* URL) +{ + char buffer[5]; + Ql_memcpy(buffer, URL, sizeof(buffer)); + Ql_StrToUpper(buffer); + if(NULL == Ql_strstr(buffer, "HTTP")) + { + return FALSE; + } + else + { + return TRUE; + } +} + +s32 HTTP_FotaMain(u8 contextId, u8* URL) +{ + s32 ret; + bool retValue; + bool httpDecodeURL; + u8* pUserName = NULL; + HttpMainContext_t *httpContext_p =&httpMainContext; + + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Fota http Main entry !-->\r\n"); + FOTA_DBG_PRINT("Enter into HTTP_FotaMain\r\n"); + + /***************************************************************** + Register the GPRS callback function first. + ******************************************************************/ + ret = Ql_GPRS_Register(contextId, &Httpcallback_gprs_func, NULL); + + /***************************************************************** + config the GPRS , set the APN. + ******************************************************************/ + Ql_memset(&Fota_gprsCfg,0x00, sizeof(Fota_gprsCfg)); + Ql_strcpy(Fota_gprsCfg.apnName, Fota_apn); + Ql_strcpy(Fota_gprsCfg.apnUserId, Fota_userid); + Ql_strcpy(Fota_gprsCfg.apnPasswd, Fota_passwd); + Fota_gprsCfg.authtype = 0; + ret = Ql_GPRS_Config(contextId, &Fota_gprsCfg); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Ql_GPRS_Config (RET =%d) -->\r\n", ret); + FOTA_DBG_PRINT("<-- Config GPRS -->\r\n"); + ret = Ql_GPRS_ActivateEx(contextId, TRUE); + if(GPRS_PDP_SUCCESS != ret && GPRS_PDP_ALREADY != ret) + { + + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--GPRS ACTIVATE FAILD return(err =%d)-->\r\n", ret); + FOTA_DBG_PRINT("<-- Fail to activate GPRS -->\r\n"); + return -1; + } + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--GPRS ACTIVATE successfully(%d) -->\r\n", ret); + FOTA_DBG_PRINT("<-- Successfully activate GPRS -->\r\n"); + + http_initialize(); + httpContext_p->socketid = Ql_SOC_CreateEx(contextId,SOC_TYPE_TCP, Ql_OS_GetActiveTaskId(), Httpcallback_SOC_func); + if(httpContext_p->socketid <0) + { + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Create socket FAILD return(err =%d) -->\r\n", httpContext_p->socketid); + FOTA_DBG_PRINT("<-- Fail to create socket -->\r\n"); + return -1; + } + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Create socket successfully(%d) -->\r\n", ret); + + pUserName = Ql_strstr(URL, "@"); + if(NULL == pUserName)// http URL : http://23.11.67.89/file/xxx.bin@userName:passowrd + { + // no userName and password + httpContext_p->AddressValidLegth = Ql_strlen(URL); + Ql_memcpy(httpContext_p->Address, URL,httpContext_p->AddressValidLegth); + } + else + { + httpContext_p->AddressValidLegth = pUserName - URL; + Ql_memcpy(httpContext_p->Address, URL,httpContext_p->AddressValidLegth); + } + + httpDecodeURL = http_DecodeURL(httpContext_p->Address,&httpContext_p->AddressValidLegth, httpContext_p->hostip, sizeof(httpContext_p->hostip), + httpContext_p->hostname, sizeof(httpContext_p->hostname), &httpContext_p->hostport); + if(!httpDecodeURL) + { + FOTA_UPGRADE_IND(UP_URLDECODEFAIL,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--HTTP DECODE URL FAILED !!!-->\r\n"); + FOTA_DBG_PRINT("<-- HTTP DECODE URL FAILED !!! -->\r\n"); + } + + if(httpContext_p->hostip[0] != 0) // host name is ip string + { + u32 hostipAddr = 0; + ret = Ql_IpHelper_ConvertIpAddr(httpContext_p->hostip,&hostipAddr); + if(SOC_SUCCESS == ret) + { + Ql_memcpy(httpContext_p->hostipAddres, &hostipAddr, sizeof(hostipAddr)); + FOTA_UPGRADE_IND(UP_CONNECTING,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Convert Ip Address successfully,m_ipaddress=%d,%d,%d,%d-->\r\n",httpContext_p->hostipAddres[0],httpContext_p->hostipAddres[1],httpContext_p->hostipAddres[2],httpContext_p->hostipAddres[3]); + FOTA_DBG_PRINT("<--Convert Ip Address successfully,m_ipaddress="); + FOTA_DBG_PRINT(httpContext_p->hostipAddres); + FOTA_DBG_PRINT(" -->\r\n"); + http_GetImagefilefromServer(); + } + else + { + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Ql_IpHelper_ConvertIpAddr FAILD(err =%d)--> \r\n", ret); + FOTA_DBG_PRINT("<--Ql_IpHelper_ConvertIpAddr FAILD --> \r\n"); + return -1; + } + } + else // host name is domain name + { + ret = Ql_IpHelper_GetIPByHostName(contextId, 0,httpContext_p->hostname,Callback_GetIpByHostName); + if(SOC_WOULDBLOCK != ret && SOC_SUCCESS != ret) + { + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Ql_IpHelper_GetIPByHostName failed (err =%d)--> \r\n", ret); + } + + //to do http_GetImagefilefromServer function in the Callback_GetIpByHostName callback function + } + + return 0; +} + +void http_initialize(void) +{ + HttpMainContext_t *httpContext_p = &httpMainContext; + + httpContext_p->downloadtimeout = 0; + httpContext_p->httpDownloadTimer = 0; + + Ql_memset(httpContext_p->hostip,0,sizeof(httpContext_p->hostip)); + Ql_memset(httpContext_p->hostname,0,sizeof(httpContext_p->hostname)); + Ql_memset(httpContext_p->Address,0,sizeof(httpContext_p->Address)); + Ql_memset(httpContext_p->hostipAddres,0,sizeof(httpContext_p->hostipAddres)); + httpContext_p->AddressValidLegth = 0; + httpContext_p->hostport = HTTP_SERVICE_PORT; + httpContext_p->contextId = -1; + httpContext_p->socketid = -1; + + httpContext_p->httpGettimeout = HTTP_GETREADTIMEROUT; + httpContext_p->httpGetHeadTimer = HTTP_GETREADTIMERID; + httpContext_p->httpGettimerstate = FALSE; + + httpContext_p->http_socketdata_p = NULL; + httpContext_p->genhttp_dstconstsize = QUECTEL_HTTP_DATABUFFER_SIZE; + httpContext_p->genhttp_dstpos = 0; + httpContext_p->genhttp_dstvaliddatalen = 0; + + httpContext_p->ContentLength = 0; + httpContext_p->getbody = FALSE; + httpContext_p->receivedbodydata = 0; + + httpContext_p->httpversion = 1; + +} + +void http_GetImagefilefromServer() +{ + s32 ret; + bool retValue; + HttpMainContext_t *httpContext_p = &httpMainContext; + + ret = Ql_SOC_ConnectEx(httpContext_p->socketid, (u32)(httpContext_p->hostipAddres), httpContext_p->hostport, TRUE); + if(SOC_SUCCESS != ret) + { + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Ql_SOC_ConnectEx failed (err =%d)-->\r\n", ret); + FOTA_DBG_PRINT("<--Ql_SOC_ConnectEx failed -->\r\n"); + return; + } + + FOTA_UPGRADE_IND(UP_CONNECTED,0,retValue); + httpContext_p->bpeersocketclose = FALSE; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--the module connect to the server successfully !-->\r\n"); + FOTA_DBG_PRINT("<--the module connect to the server successfully !-->\r\n"); + + ret = http_SendHttpGetHead( httpContext_p->socketid); + if(TRUE != ret) // send http head failed ,close the socket and stop upgrade. + { + Ql_SOC_Close(httpContext_p->socketid); + httpContext_p->socketid = -1; + httpContext_p->bpeersocketclose = TRUE; + if(NULL != httpContext_p->http_socketdata_p) + { + Ql_MEM_Free((void *)(httpContext_p->http_socketdata_p)); + httpContext_p->http_socketdata_p = NULL; + } + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--http_SendHttpGetHead failed (err =%d)-->\r\n", ret); + FOTA_DBG_PRINT("<--http_SendHttpGetHead failed -->\r\n"); + return; + } + + FOTA_UPGRADE_IND(UP_GETTING_FILE,0,retValue); + Ql_Timer_Register(httpContext_p->httpGetHeadTimer, http_TimerCallback, NULL); + Ql_Timer_Start(httpContext_p->httpGetHeadTimer, httpContext_p->httpGettimeout, FALSE); + httpContext_p->httpGettimerstate = TRUE; + + return; + +} + + +s32 http_SendHttpGetHead( s32 socketId) +{ + s32 ret; + s32 retValue; + char sendBuffer[200]; + char Address[200]; + HttpMainContext_t *httpContext_p = &httpMainContext; + + // http head: (GET........ ) + Ql_memset(sendBuffer, 0x00, sizeof(sendBuffer)); + Ql_memset(Address, 0x00, sizeof(Address)); + Ql_strncpy(Address, httpContext_p->Address, httpContext_p->AddressValidLegth); + Ql_sprintf(sendBuffer,HttpGetHead[0],Address); + ret = Ql_SOC_Send(socketId, sendBuffer, Ql_strlen(sendBuffer)); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--send GET:<%s> \r\n",sendBuffer); + FOTA_DBG_PRINT("<--send GET: \r\n"); + FOTA_DBG_PRINT(sendBuffer); + if(ret != Ql_strlen(sendBuffer)) + {return -1;} + + // http head: (Host: ........ ) + Ql_memset(sendBuffer, 0x00, sizeof(sendBuffer)); + if(httpContext_p->hostip[0] != 0) + { + Ql_sprintf(sendBuffer,HttpGetHead[1],httpContext_p->hostip, httpContext_p->hostport); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--httpContext_p->hostip<%s> -->\r\n",httpContext_p->hostip); + FOTA_DBG_PRINT("<--httpContext_p->hostip: "); + FOTA_DBG_PRINT(httpContext_p->hostip); + } + else + { + Ql_sprintf(sendBuffer,HttpGetHead[1],httpContext_p->hostname,httpContext_p->hostport); + } + ret = Ql_SOC_Send(socketId, sendBuffer, Ql_strlen(sendBuffer)); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--send Host:<%s> \r\n",sendBuffer); + FOTA_DBG_PRINT("<--send Host: "); + FOTA_DBG_PRINT(sendBuffer); + if(ret != Ql_strlen(sendBuffer)) + {return -1;} + + // http head: (Accept: ........ ) + Ql_memset(sendBuffer, 0x00, sizeof(sendBuffer)); + Ql_memcpy(sendBuffer, HttpGetHead[2], Ql_strlen(HttpGetHead[2])); + ret = Ql_SOC_Send(socketId, sendBuffer, Ql_strlen(sendBuffer)); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--send Accept:<%s> \r\n",sendBuffer); + FOTA_DBG_PRINT("<--send Accept: "); + FOTA_DBG_PRINT(sendBuffer); + if(ret != Ql_strlen(sendBuffer)) + {return -1;} + + // http head: (User-Agent: ........ ) + Ql_memset(sendBuffer, 0x00, sizeof(sendBuffer)); + Ql_memcpy(sendBuffer, HttpGetHead[3], Ql_strlen(HttpGetHead[3])); + ret = Ql_SOC_Send(socketId, sendBuffer, Ql_strlen(sendBuffer)); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--send User-Agent:<%s> \r\n",sendBuffer); + FOTA_DBG_PRINT("<--send User-Agent: "); + FOTA_DBG_PRINT(sendBuffer); + if(ret != Ql_strlen(sendBuffer)) + {return -1;} + + // http head: (Connection: ........ ) + Ql_memset(sendBuffer, 0x00, sizeof(sendBuffer)); + Ql_memcpy(sendBuffer, HttpGetHead[4], Ql_strlen(HttpGetHead[4])); + ret = Ql_SOC_Send(socketId, sendBuffer, Ql_strlen(sendBuffer)); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--send Connection:<%s> \r\n",sendBuffer); + FOTA_DBG_PRINT("<--send Connection: "); + FOTA_DBG_PRINT(sendBuffer); + if(ret != Ql_strlen(sendBuffer)) + {return -1;} + + // http head: ( \r\n ) + Ql_memset(sendBuffer, 0x00, sizeof(sendBuffer)); + Ql_memcpy(sendBuffer, HttpGetHead[5], Ql_strlen(HttpGetHead[5])); + ret = Ql_SOC_Send(socketId, sendBuffer, Ql_strlen(sendBuffer)); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--send end:<%s> \r\n",sendBuffer); + FOTA_DBG_PRINT("<--send end: "); + FOTA_DBG_PRINT(sendBuffer); + if(ret != Ql_strlen(sendBuffer)) + {return -1;} + + // send http head successfully , malloc a buffer for http data form the socket now!! + httpContext_p->http_socketdata_p = (u8 *)Ql_MEM_Alloc(QUECTEL_HTTP_DATABUFFER_SIZE); + if(NULL == httpContext_p->http_socketdata_p) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--Malloc memory buffer for http socket buffer failed !--> \r\n"); + FOTA_DBG_PRINT("<--Malloc memory buffer for http socket buffer failed !--> \r\n"); + return -1; + } + httpContext_p->genhttp_dstconstptr = httpContext_p->http_socketdata_p; + + return TRUE; +} + +s8 http_RecvHttpHead(s32 socketid, bool bContinue) +{ + HttpMainContext_t *httpContext_p = &httpMainContext; + bool entryfunctionexe = TRUE; + s32 iret; + HttpHeader_t *httpheader = &httpContext_p->httpheader; + + u8 *recvbuffer; + s32 recvlength; + s32 willrecvlength; + s32 decode_length; + + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, " <--http_RecvHttpHead entry !-->\r\n"); + FOTA_DBG_PRINT(" <--http_RecvHttpHead entry !-->\r\n"); + if(!bContinue) + { + httpheader->ContentLength_Exist_InHttpResponse = FALSE; + httpheader->Transfer_Encoding_Is_chunked = FALSE; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<-- httpRecvHttpHead bContinue= FALSE-->"); + FOTA_DBG_PRINT("<-- httpRecvHttpHead bContinue= FALSE-->"); + } + +cuntinuerecvdata: + + if(httpContext_p->genhttp_dstpos) + { + Ql_memcpy(httpContext_p->genhttp_dstconstptr, httpContext_p->genhttp_dstconstptr + httpContext_p->genhttp_dstpos , httpContext_p->genhttp_dstvaliddatalen); + httpContext_p->genhttp_dstpos = 0; + } + + recvbuffer = httpContext_p->genhttp_dstconstptr+httpContext_p->genhttp_dstvaliddatalen; + willrecvlength = httpContext_p->genhttp_dstconstsize - httpContext_p->genhttp_dstvaliddatalen; + + recvlength = 0; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--want read socket datalength=%d-->\r\n", willrecvlength); + FOTA_DBG_PRINT("<--want read socket datalength=%d-->\r\n"); + /*receive buffer is full*/ + if(willrecvlength && (!httpContext_p->bpeersocketclose)) + { + recvlength = Ql_SOC_Recv(httpContext_p->socketid, recvbuffer, willrecvlength); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--socket read received length = %d -->\r\n", recvlength); + //UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--http head:%s -->\r\n", recvbuffer);//if receive http head fail, you can debug via this message log. + if(recvlength == SOC_WOULDBLOCK) + { + if(FALSE == httpContext_p->httpGettimerstate) + { + Ql_Timer_Start(httpContext_p->httpGetHeadTimer,httpContext_p->httpGettimeout,FALSE); + httpContext_p->httpGettimerstate = FALSE; + } + return HTTP_RESULT_ERROR_WOULDBLOCK; + } + else if(recvlength <= 0) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--http soc_recv == 0-->"); + FOTA_DBG_PRINT("<--http soc_recv == 0-->"); + httpContext_p->bpeersocketclose = TRUE; + return HTTP_RESULT_ERROR_SOC_CLOSE; + } + //else if(recvlength > 0) + else + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--http head recv dataLen = %d-->\r\n",recvlength); + } + } + else/*receive buffer is full, and not receive http head !!*/ + { + recvlength = 0; + return HTTP_RESULT_ERROR_DECODEERROR; + } + //if(recvlength > 0) + { + httpContext_p->genhttp_dstvaliddatalen += recvlength; + do + { + iret = http_DecodeHeader(httpheader, httpContext_p->genhttp_dstconstptr + httpContext_p->genhttp_dstpos, httpContext_p->genhttp_dstvaliddatalen, &decode_length); + if((iret == HTTP_CODERESULT_OK) || (iret == HTTP_CODERESULT_END)) + { + httpContext_p->genhttp_dstpos += decode_length; + httpContext_p->genhttp_dstvaliddatalen -= decode_length; + } + } while(iret == HTTP_CODERESULT_OK); + + if(iret == HTTP_CODERESULT_END) + { + if ((httpheader->httpresponse/100) == 3) /* Will.Shao, for http download, 2012.05.22 */ + return HTTP_RESULT_ERROR_HTTP_RELOCATION; + else if((httpheader->httpresponse/100) != 2) + return HTTP_RESULT_ERROR_HTTP_RESPONSE_FAILED; + + /*there is no ContentLength ,*/ + if(!httpheader->ContentLength_Exist_InHttpResponse) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--httpRecvHttpHead not exist ContentLength !-->\r\n"); + FOTA_DBG_PRINT("<--httpRecvHttpHead not exist ContentLength !-->\r\n"); + httpheader->ContentLength = 0xFFFFFFFF; + } + else + { + + } + /*http head receive end, start to receive the body data now! */ + httpContext_p->ContentLength = httpheader->ContentLength; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--httpRecvHttpHead() Get ContentLength= %d-->\r\n",httpContext_p->ContentLength); + httpContext_p->getbody = TRUE; + if(0xFFFFFFFF ==httpContext_p->ContentLength) + { + iret = http_RecvHttpChunkedBody(httpContext_p->socketid, FALSE); + return iret; + } + else + { + iret = http_RecvHttpBody(httpContext_p->socketid, FALSE); + return iret; + } + + } + else if(iret == HTTP_CODERESULT_DATAABSENT) + { + if(httpContext_p->bpeersocketclose) + { + if ((httpheader->httpresponse/100) == 3) + return HTTP_RESULT_ERROR_HTTP_RELOCATION; + else if((httpheader->httpresponse/100) != 2) + return HTTP_RESULT_ERROR_HTTP_RESPONSE_FAILED; + + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--httpRecvHttpHead() bpeersocketclose-->\r\n"); + FOTA_DBG_PRINT("<--httpRecvHttpHead() bpeersocketclose-->\r\n"); + return HTTP_RESULT_OK; + } + + /* data is not enough*/ + goto cuntinuerecvdata; + } + else //if(iret < 0) + { + return HTTP_RESULT_ERROR_DECODEERROR; + } + } + + return HTTP_RESULT_OK; +} + +s8 http_RecvHttpChunkedBody(s32 socketid, bool bContinue) +{ + bool retValue; + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue) ; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Don't support http chuned encode !!-->\r\n"); + FOTA_DBG_PRINT("<--Don't support http chuned encode !!-->\r\n"); + return -1; +} +s8 http_RecvHttpBody(s32 socketid, bool bContinue) +{ + HttpMainContext_t *httpContext_p = &httpMainContext; + s32 ret; + bool retValue; + s32 fileDLpresent; + s32 fileDLpresentReport; + u8 *recvbuffer; + s32 recvlength; + s32 willrecvlength; + +cuntinuerecvbodydata: + + if(httpContext_p->genhttp_dstpos) + { + Ql_memcpy(httpContext_p->genhttp_dstconstptr, httpContext_p->genhttp_dstconstptr + httpContext_p->genhttp_dstpos , httpContext_p->genhttp_dstvaliddatalen); + httpContext_p->genhttp_dstpos = 0; + } + + recvbuffer = httpContext_p->genhttp_dstconstptr+httpContext_p->genhttp_dstvaliddatalen; + willrecvlength = httpContext_p->genhttp_dstconstsize - httpContext_p->genhttp_dstvaliddatalen; + + recvlength = 0; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--socket read body willrecvlength=%d-->\r\n", willrecvlength); + + if(willrecvlength && (!httpContext_p->bpeersocketclose)) + { + recvlength = Ql_SOC_Recv(httpContext_p->socketid, recvbuffer, willrecvlength); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--socket read body recvlength = %d -->\r\n", recvlength); + if(recvlength == SOC_WOULDBLOCK) + { + if(FALSE == httpContext_p->httpGettimerstate) + { + Ql_Timer_Start(httpContext_p->httpGetHeadTimer,httpContext_p->httpGettimeout,FALSE); + httpContext_p->httpGettimerstate = FALSE; + } + return HTTP_RESULT_ERROR_WOULDBLOCK; + } + else if(recvlength <= 0) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--body http soc_recv == 0-->"); + FOTA_DBG_PRINT("<--body http soc_recv == 0-->\r\n"); + httpContext_p->bpeersocketclose = TRUE; + + return HTTP_RESULT_ERROR_SOC_CLOSE; + } + + httpContext_p->genhttp_dstvaliddatalen += recvlength; + //Ql_UART_Write(UART_PORT2, httpContext_p->genhttp_dstconstptr+httpContext_p->genhttp_dstpos,httpContext_p->genhttp_dstvaliddatalen ); + /************ write the data to fota temp region*********************/ + if(httpContext_p->receivedbodydata <= httpContext_p->ContentLength) + { + ret = Ql_FOTA_WriteData(httpContext_p->genhttp_dstvaliddatalen,(s8*)(httpContext_p->genhttp_dstconstptr+httpContext_p->genhttp_dstpos)); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- Fota write, len=%d, ret=%d, totlesize=%d -->\r\n", httpContext_p->receivedbodydata +httpContext_p->genhttp_dstvaliddatalen, ret, httpContext_p->ContentLength); + if(ret != 0) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--Ql_FOTA_WriteData failed(ret =%d)-->\r\n",ret); + FOTA_DBG_PRINT("<-- Ql_FOTA_WriteData failed -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + return -1; + } + //Ql_Sleep(100); + } + /*************************************************************/ + httpContext_p->receivedbodydata += httpContext_p->genhttp_dstvaliddatalen; + httpContext_p->genhttp_dstvaliddatalen = 0; + httpContext_p->genhttp_dstpos = 0; + } + + fileDLpresent = (100*(httpContext_p->receivedbodydata))/httpContext_p->ContentLength; + if((0 == fileDLpresent%5) && (fileDLpresent != fileDLpresentReport)) + { + fileDLpresentReport = fileDLpresent; + FOTA_UPGRADE_IND(UP_GETTING_FILE,fileDLpresentReport,retValue); + } + if(httpContext_p->receivedbodydata >= httpContext_p->ContentLength) + { + //Ql_SOC_Close(httpContext_p->socketid); + FOTA_DBG_PRINT("<-- Close socket -->\r\n"); + httpContext_p->socketid = -1; + httpContext_p->bpeersocketclose = TRUE; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--bodydata received End (%d)-->\r\n",httpContext_p->receivedbodydata); + FOTA_DBG_PRINT("<-- bodydata received End -->\r\n"); + //FOTA_UPGRADE_IND(UP_GET_FILE_OK,100,retValue); + FOTA_DBG_PRINT("<-- Downloading finished -->\r\n"); + if(NULL != httpContext_p->http_socketdata_p) + { + Ql_MEM_Free((void *)(httpContext_p->http_socketdata_p) ); + httpContext_p->http_socketdata_p = NULL; + } + Ql_Sleep(300); + ret = Ql_FOTA_Finish(); //Finish the upgrade operation ending with calling this API + if(ret !=0) + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--Ql_FOTA_Finish failed(ret =%d)-->\r\n",ret); + FOTA_DBG_PRINT("<-- Ql_FOTA_Finish failed -->\r\n"); + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + return -1; + } + + FOTA_UPGRADE_IND(UP_SYSTEM_REBOOT,100,retValue); + if((NULL == Fota_UpgardeState) ||retValue) // if fota upgrade callback function return TRUE in the UP_SYSTEM_REBOOT case ,the system upgrade app at once. + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Fota upgrade callback return TRUE!!, system reboot for upgrade now-->\r\n"); + FOTA_DBG_PRINT("<--Fota upgrade callback return TRUE!!, system reboot for upgrade now-->\r\n"); + Ql_Sleep(300); + ret = Ql_FOTA_Update(); // set a flag then reboot the system , then the will auto upgrade app.bin. + if(ret != 0) + { + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--Ql_FOTA_Update(ret =%d)-->\r\n",ret); + FOTA_DBG_PRINT("<-- Ql_FOTA_Finish failed -->\r\n"); + return -1; +// fota update failed + } + else + { + ////If update OK, module will reboot automaticly + } + } + else + { + // if upgrade state callback function return false, you must call Ql_FOTA_Update function before you reboot the system + return HTTP_RESULT_OK; + } + } + goto cuntinuerecvbodydata; +} + +void Httpcallback_socket_read(s32 socketId, s32 errCode, void* customParam ) +{ + HttpMainContext_t *httpContext_p = &httpMainContext; + bool retValue; + s8 ret = HTTP_RESULT_OK; + + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--callback socket read (socketId=%d, errCode=%d)--> \r\n",socketId, errCode); + if(SOC_SUCCESS != errCode) + { + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + Ql_MEM_Free(httpContext_p->http_socketdata_p); // read socket data error ,end the foat upgrade. + httpContext_p->http_socketdata_p = NULL; + return; + } + if(NULL == httpContext_p->http_socketdata_p) + { + // even if http head send success, and receive data form the http socket. but memory allocation failed ,return fota upgrade too . + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, " <--Because Malloc failed , so exit the socket read !--> \r\n"); + return; + } + if(TRUE == httpContext_p->httpGettimerstate) + { + Ql_Timer_Stop(httpContext_p->httpGetHeadTimer); + httpContext_p->httpGettimerstate = FALSE; + } + + if(0 == httpContext_p->ContentLength) // head received END + { + ret = http_RecvHttpHead(httpContext_p->socketid, TRUE); + } + else if(0xFFFFFFFF == httpContext_p->ContentLength)// chunked + { + ret = http_RecvHttpChunkedBody(httpContext_p->socketid, TRUE); + } + else + { + ret = http_RecvHttpBody(httpContext_p->socketid, TRUE); + } + + // Read http head (or http Body )failed . exit the upgrade. + if(HTTP_RESULT_OK !=ret && HTTP_RESULT_ERROR_WOULDBLOCK != ret) //receive failed + { + if(NULL != httpContext_p->http_socketdata_p) + { + Ql_MEM_Free((void *)(httpContext_p->http_socketdata_p)); + httpContext_p->http_socketdata_p = NULL; + } + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + } + + return; +} + +void HttpCallback_GPRS_Actived(u8 contexId, s32 errCode, void* customParam) +{ + // we used Ql_GPRS_ActivateEx function to activate the PDP,so this callback will not be invoked + return; +} +void HttpCallBack_GPRS_Deactived(u8 contextId, s32 errCode, void* customParam ) +{ + return; +} + +void Httpcallback_socket_connect(s32 socketId, s32 errCode, void* customParam ) +{ + // + return; +} + +void Httpcallback_socket_close(s32 socketId, s32 errCode, void* customParam ) +{ + + return; +} +void Httpcallback_socket_accept(s32 listenSocketId, s32 errCode, void* customParam ) +{ + + return; +} +void Httpcallback_socket_write(s32 socketId, s32 errCode, void* customParam ) +{ + return; +// http_callback_socket_notify(SOC_WRITE, socketId); +} + + +void Callback_GetIpByHostName(u8 contexId, u8 requestId, s32 errCode, u32 ipAddrCnt, u32* ipAddr) +{ + u8 i=0; + bool retValue; + HttpMainContext_t *httpContext_p = &httpMainContext; + u8* pu8IpAddr = (u8*)ipAddr; + if (errCode == SOC_SUCCESS) + { + for(i=0;i\r\n",i,pu8IpAddr[0],pu8IpAddr[1],pu8IpAddr[2],pu8IpAddr[3]); + } + Ql_memcpy(httpContext_p->hostipAddres,ipAddr, 4); + http_GetImagefilefromServer(); + } + else + { + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Callback_GetIpByHostName FAILD (err =%d)-->\r\n", errCode); + } +} + +void http_TimerCallback(u32 timerId, void* param) +{ + bool retValue; + HttpMainContext_t *httpContext_p = &httpMainContext; + if(HTTP_GETREADTIMERID == timerId)// http send get head ,but server no response. or read data form http server no response + { + FOTA_UPGRADE_IND(UP_UPGRADFAILED,0,retValue); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Http server no response !!-->\r\n"); + FOTA_DBG_PRINT("<--Http server no response !!-->\r\n"); + Ql_Sleep(100); + httpContext_p->httpGettimerstate = FALSE; + if(NULL != httpContext_p->http_socketdata_p) + { + Ql_MEM_Free((void *)(httpContext_p->http_socketdata_p)); + httpContext_p->http_socketdata_p = NULL; + } + } +} + + + +#endif //__OCPU_FOTA_BY_HTTP__ + diff --git a/cores/opencpu/fota/src/fota_http_code.c b/cores/opencpu/fota/src/fota_http_code.c new file mode 100644 index 0000000..f447c3c --- /dev/null +++ b/cores/opencpu/fota/src/fota_http_code.c @@ -0,0 +1,416 @@ +#include "ql_stdlib.h" +#include "ql_common.h" +#include "ql_type.h" +#include "ql_error.h" +#include "ql_uart.h" +#include "ql_socket.h" +#include "ql_timer.h" +#include "ql_fota.h" +#include "ql_gprs.h" +#include "ril_network.h" +#include "fota_http.h" +#include "fota_main.h" + +#ifdef __OCPU_FOTA_BY_HTTP__ + +#if UPGRADE_APP_DEBUG_ENABLE > 0 +extern char FOTA_DBGBuffer[DBG_BUF_LEN]; +#endif + +s32 quectel_stricmp_bylength(char *firststr, char *secondstr, int length) +{ + char firstchar; + char secondchar; + while (length) + { + firstchar = *firststr; + secondchar = *secondstr; + if (CHAR_IS_LOWER(firstchar)) + { + firstchar += 'A'-'a'; + } + if (CHAR_IS_LOWER(secondchar)) + { + secondchar += 'A'-'a'; + } + if(firstchar > secondchar) + return 1; + else if(firstchar < secondchar) + return -1; + firststr++; + secondstr++; + + length--; + } + + return 0; + +} +bool http_ip_check(char *phostName, s8 len) +{ + s16 i; + for(i=0;i '9') && (phostName[i] != '.')) + { + return FALSE; + } + } + return TRUE; + +} + +/*HTTP/1.1 200 OK*/ +static s32 DecodeHttpResult(u8 *startpos, s32 linelength) +{ + s32 code; + for(;linelength>0;linelength--) + { + if(*startpos == 0x20) + { + startpos++; + code =Ql_atoi(startpos); + return code; + } + startpos++; + } + return -1; +} + +/****************************************************************************** +* Function: +* +* Author: +* +* Parameters: +* +* Return: +* +* Description: +******************************************************************************/ +bool http_DecodeURL(u8 *Address, u32 *AddressValidLegth, u8 *hostip, u16 hostiplength, + u8 *hostname, u16 hostnamelength, u16 *hostport) +{ + u8 hstr[8]; + u32 i; + u8 *phostnamehead; + u8 *phostnameTail; + u8 ipadd[4]; + bool ret = FALSE; + bool ip_validity = FALSE; + u8 *puri=Address; + u32 datalen = *AddressValidLegth; + + *hostport = HTTP_SERVICE_PORT; + Ql_memset(hostip,0,hostiplength); + Ql_memset(hostname,0,hostnamelength); + + do + { + /*Decode http://*/ + Ql_memset(hstr,0,8); + + if((*AddressValidLegth) < 7) + break; + Ql_memcpy(hstr,Address,7); + for(i=0;i<7;i++) + { + if( (hstr[i]>= 'A') && (hstr[i] <= 'Z')) + hstr[i] = Ql_tolower(hstr[i]); + } + if(Ql_strcmp((char *)hstr,"http://") == 0) + { + puri = Address + 7; + datalen -= 7; + } + else + { + break; + } + i=0; + + /*host name*/ + phostnamehead = puri; + phostnameTail = puri; + + while(i=hostiplength) + break; + Ql_strcpy((char*)hostip, (char*)phostnamehead); + } + else + { + if(Ql_strlen((char*)phostnamehead)>=hostnamelength) + break; + Ql_strcpy((char*)hostname,(char*)phostnamehead); + } + *phostnameTail = hstr[0]; + + /*case http://78.129.161.20*/ + if(datalen >= i) + datalen -= i; + else + datalen = 0; + if(datalen == 0) + { + Address[0] = '/'; + *AddressValidLegth = 1; + ret = TRUE; + break; + } + + /* port */ + puri+=i; + i = 0; + if(*puri==':') + { + datalen -= 1; + puri++; + phostnamehead = puri; + phostnameTail = puri; + + while(*puri !='/' && i= i) + datalen -= i; + else + datalen = 0; + if(datalen == 0) + { + Address[0] = '/'; + *AddressValidLegth = 1; + ret = TRUE; + break; + } + /*get the path*/ + if(*puri=='/') + { + i=0; + while(i\r\n",hostname,hostip,*hostport); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--AddressValidLegth=%d, Address=%s-->\r\n",*AddressValidLegth, Address); + FOTA_DBG_PRINT("<--hostname="); + FOTA_DBG_PRINT(hostname); + FOTA_DBG_PRINT(" hostip="); + FOTA_DBG_PRINT(hostip); + FOTA_DBG_PRINT(" hostport=xx -->\r\n"); + FOTA_DBG_PRINT("<--AddressValidLegth=xx, Address="); + FOTA_DBG_PRINT(Address); + FOTA_DBG_PRINT("-->\r\n"); + Address[*AddressValidLegth] = hstr[0]; + + return ret; +} + +#if 1 +/********************************************* +*return NULL, means can't found "\r\n" string +*return NO NULL, return value print to the next line, +*linelength£¬the line length£» +***********************************************/ +u8* find_linesymbol(u8 *startpos, s32 length, s32 *linelength) +{ + static u8 linesymbol[2] = {0x0d,0x0a}; + u8 *talipos = startpos + length - 1; + + *linelength = 0; + if(length <= 1) + return NULL; + + do + { + if(Ql_memcmp(startpos, linesymbol, 2) == 0) + { + (*linelength) += 2; + return startpos+2; + } + + startpos++; + (*linelength)++; + }while(startpos\r\n"); + return NULL; +} + +static bool DecodeHttpLine(u8 *startpos, s32 linelength, HttpLineValue_t *lineValue) +{ + s32 i; + + //find the HTTP head + if((quectel_stricmp_bylength((char*)startpos, (char*)"HTTP",4) == 0) && (linelength > 4)) + { + i = DecodeHttpResult(startpos, linelength); + if((i==-1) || (i != 200))/*error response*/ + { + + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--http decode not 200 OK-->\r\n"); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--http response:%s-->\r\n",startpos); + FOTA_DBG_PRINT("<--http decode not 200 OK-->\r\n"); + FOTA_DBG_PRINT("<--http response:"); + FOTA_DBG_PRINT(startpos); + } + + lineValue->filedtype = HTTP_HEADERFIELD_RESPONSEHEAD; + lineValue->valuetype = 0; + lineValue->valuelength = 4; + *(s32*)lineValue->value = i; + return TRUE; + } + + /*Content-Length: 77*/ + if((linelength > 15) && (quectel_stricmp_bylength((char*)startpos, "CONTENT-LENGTH:", 15) == 0)) + { + lineValue->filedtype = HTTP_HEADERFIELD_CONTENT_LENGTH; + lineValue->valuetype = 0; + lineValue->valuelength = 4; + *(s32*)lineValue->value = Ql_atoi(startpos+15); + return TRUE; + } + + /*Transfer-Encoding: chunked*/ + if((linelength > 26) && (quectel_stricmp_bylength((char*)startpos, "TRANSFER-ENCODING: CHUNKED", 26)== 0)) + { + lineValue->filedtype = HTTP_HEADERFIELD_TRANSFER_ENCODING_CHUNKED; + lineValue->valuetype = 0; + lineValue->valuelength = 4; + return TRUE; + } + + /*Date: */ + if((linelength > 26) && (quectel_stricmp_bylength((char*)startpos, "DATE:", 5)== 0)) + { + lineValue->filedtype = HTTP_HEADERFIELD_DATE; + lineValue->valuetype = 0; + lineValue->valuelength = linelength-5; + Ql_strncpy((char*)(lineValue->value), (char*)(startpos+5), HTTP_VALUE_LENGTH); + lineValue->value[HTTP_VALUE_LENGTH-1] = 0; + if(lineValue->valuelength < HTTP_VALUE_LENGTH) + { + lineValue->value[lineValue->valuelength] = 0; + } + return TRUE; + } + + return FALSE; +} + +/****************************************************************************** +* Function: +* +* Author: +* +* Parameters: +* +* Return: + HTTP_CODERESULT_OK + HTTP_CODERESULT_END + HTTP_CODERESULT_DATAABSENT + HTTP_CODERESULT_ERROR +* Description: +******************************************************************************/ + +s32 dbg_httpresponse = 0; +u32 dbg_ContentLength = 0; +s32 http_DecodeHeader(HttpHeader_t *httpheader, u8 *decode_buffer, s32 decode_buffer_length, s32 *decode_length) +{ + u8 *tailpos; + s32 linelength; + u8 *startpos; + bool bret; + HttpLineValue_t lineValue; + HttpMainContext_t *httpContext_p = &httpMainContext; + + if(decode_length) + *decode_length = 0; + + tailpos = find_linesymbol(decode_buffer, decode_buffer_length, &linelength); + if(tailpos == NULL) + return HTTP_CODERESULT_DATAABSENT; + + *decode_length = linelength; + + bret = DecodeHttpLine(decode_buffer, linelength, &lineValue); + if(bret && lineValue.filedtype == HTTP_HEADERFIELD_RESPONSEHEAD) + { + httpheader->httpresponse = *((s32*)(lineValue.value)); + dbg_httpresponse = httpheader->httpresponse; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--http decode http response=%d-->\r\n",httpheader->httpresponse); + } + else if(bret && lineValue.filedtype == HTTP_HEADERFIELD_CONTENT_LENGTH) + { + httpheader->ContentLength = *((u32*)(lineValue.value)); + dbg_ContentLength = httpheader->ContentLength; + httpheader->ContentLength_Exist_InHttpResponse = TRUE; + httpheader->Transfer_Encoding_Is_chunked = FALSE; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer, "<--http decode ContentLength=%d-->\r\n",httpheader->ContentLength); + } + else if(bret && lineValue.filedtype == HTTP_HEADERFIELD_TRANSFER_ENCODING_CHUNKED) + { + httpheader->ContentLength = 0xFFFFFFFF; + dbg_ContentLength = httpheader->ContentLength; + httpheader->ContentLength_Exist_InHttpResponse = FALSE; + httpheader->Transfer_Encoding_Is_chunked = TRUE; + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--http decode TRANSFER_ENCODING_CHUNKED-->\r\n"); + FOTA_DBG_PRINT("<--http decode TRANSFER_ENCODING_CHUNKED-->\r\n"); + } + else if(bret && lineValue.filedtype == HTTP_HEADERFIELD_DATE) + { + // not need. + } + + { + if((linelength == 2) &&((httpheader->httpresponse/100) != 1))//lii modify for http 100 continue + { + return HTTP_CODERESULT_END; + } + } + + return HTTP_CODERESULT_OK; +} + +#endif + + + +#endif //__OCPU_FOTA_BY_HTTP__ + diff --git a/cores/opencpu/fota/src/fota_main.c b/cores/opencpu/fota/src/fota_main.c new file mode 100644 index 0000000..5d852ff --- /dev/null +++ b/cores/opencpu/fota/src/fota_main.c @@ -0,0 +1,176 @@ +#include "custom_feature_def.h" +#include "ql_common.h" +#include "ql_error.h" +#include "ql_type.h" +#include "ql_stdlib.h" +#include "ql_gprs.h" +#include "ql_fota.h" +#include "fota_ftp.h" +#include "fota_http.h" +#include "fota_main.h" + +#ifdef __OCPU_FOTA_APP__ +Upgrade_State g_FOTA_State = FOTA_STATE_END; +Callback_Upgrade_State Fota_UpgardeState = NULL ; +ST_FotaConfig FotaConfig; +ST_GprsConfig Fota_gprsCfg; +u8 Fota_apn[MAX_GPRS_APN_LEN] = "CMNET\0"; +u8 Fota_userid[MAX_GPRS_USER_NAME_LEN] = ""; +u8 Fota_passwd[MAX_GPRS_PASSWORD_LEN] = ""; + +#if UPGRADE_APP_DEBUG_ENABLE > 0 +char FOTA_DBGBuffer[DBG_BUF_LEN]; +#endif + +static bool Fota_Upgrade_States(Upgrade_State state, s32 fileDLPercent); + +extern ST_ExtWatchdogCfg* Ql_WTD_GetWDIPinCfg(void); +extern s32 Ql_GPRS_GetPDPCntxtState(u8 contextId); + +s32 Ql_FOTA_StartUpgrade(u8* url, ST_GprsConfig* apnCfg, Callback_Upgrade_State callbcak_UpgradeState_Ind) +{ + s32 ret = 0; + bool retValue; + u8 contextId; + + ret = Ql_GPRS_GetPDPContextId(); + if (GPRS_PDP_ERROR == ret) + { + FOTA_DBG_PRINT("Fail to get pdp context\r\n"); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- Fail to get pdp context\r\n -->\r\n"); + return -1; + } + contextId = (u8)ret; + + /*---------------------------------------------------*/ + Ql_memset((void *)(&FotaConfig), 0, sizeof(ST_FotaConfig)); + FotaConfig.Q_gpio_pin1 = Ql_WTD_GetWDIPinCfg()->pinWtd1; + FotaConfig.Q_feed_interval1 = 100; + FotaConfig.Q_gpio_pin2 = Ql_WTD_GetWDIPinCfg()->pinWtd2; + FotaConfig.Q_feed_interval2 = 100; + ret=Ql_FOTA_Init(&FotaConfig); + if(ret !=0) + { + FOTA_DBG_PRINT("Fail to Init FOTA\r\n"); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- Fota Init Failed (ret= %d FotaConfig.Q_gpio_pin1 =%d) -->\r\n",ret,FotaConfig.Q_gpio_pin1); + FOTA_UPGRADE_IND(UP_FOTAINITFAIL, 0,retValue); + return -1; + } + /*---------------------------------------------------*/ + + if(NULL != callbcak_UpgradeState_Ind) + { + Fota_UpgardeState = callbcak_UpgradeState_Ind; + }else{ + Fota_UpgardeState = Fota_Upgrade_States; // Use the default callback + } + +#ifdef __OCPU_FOTA_BY_FTP__ + if(FTP_IsFtpServer(url)) + { + FOTA_UPGRADE_IND(UP_START,0,retValue); + ret = FTP_FotaMain(contextId, url); + } + else +#endif + +#ifdef __OCPU_FOTA_BY_HTTP__ + if(HTTP_IsHttpServer(url)) + { + FOTA_UPGRADE_IND(UP_START,0,retValue); + ret = HTTP_FotaMain(contextId, url); + } + else +#endif + { + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- The head of the URL string is incorrect or didn't define FOTA in custom_feature_def.h. -->\r\n"); + FOTA_DBG_PRINT("<-- The head of the URL string is incorrect or didn't define FOTA in custom_feature_def.h. -->\r\n"); + + return -1; + } + + return ret; +} + +s32 Ql_FOTA_StopUpgrade(void) +{ + if (UP_CONNECTING == g_FOTA_State || + UP_CONNECTED == g_FOTA_State || + UP_GETTING_FILE == g_FOTA_State || + UP_GET_FILE_OK == g_FOTA_State + ) + { + // Stop upgrading... + } + return QL_RET_OK; +} + +/***************************************************************** +* Function: Fota_Upgrade_States +* +* Description: +* This function is callback function.custom can write it by yourself. and if you want use the callback, the UP_Callbcak pointer must point to it. if don.t need it UP_Callbcak =NULL. +* NOtes: +* the callback function has a return value. when in the UP_SYSTEM_REBOOT state, that means the Firmware is prepare ok, do you want reboot the system immediately. +* if in the 'UP_SYSTEM_REBOOT' case, the callbcak return TRUE, the system will reboot ,and upgrade the firmware. +* if in the 'UP_SYSTEM_REBOOT' case, the callback return FALSE, the system not reboot. +* and you must invoke the Ql_FOTA_Update(void) function before you want to reboot the system for the last step in the whole fota upgrade. +* +* Parameters: +* state: +* the upgrade states, you can refer the Upgrade_State enum +* fileDLPercent: +* the percent of the file download.. +* Return: +*****************************************************************/ +static bool Fota_Upgrade_States(Upgrade_State state, s32 fileDLPercent) +{ + switch(state) + { + case UP_START: + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- Fota start to Upgrade -->\r\n"); + FOTA_DBG_PRINT("<-- Fota start to Upgrade -->\r\n"); + break; + case UP_FOTAINITFAIL: + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- Fota Init failed!! -->\r\n"); + FOTA_DBG_PRINT("<-- Fota Init failed!! -->\r\n"); + break; + case UP_CONNECTING: + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- connecting to the server-->\r\n"); + FOTA_DBG_PRINT("<-- connecting to the server-->\r\n"); + break; + case UP_CONNECTED: + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- conneced to the server now -->\r\n"); + FOTA_DBG_PRINT("<-- conneced to the server now -->\r\n"); + break; + case UP_GETTING_FILE: + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<-- getting the bin file (%d) -->\r\n", fileDLPercent); + FOTA_DBG_PRINT("<-- getting the bin file -->\r\n"); + break; + case UP_GET_FILE_OK: + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--file down OK (%d) -->\r\n", fileDLPercent); + FOTA_DBG_PRINT("<--file down OK -->\r\n"); + break; + case UP_UPGRADFAILED: + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Fota upgrade failed !!!! -->\r\n"); + FOTA_DBG_PRINT("<--Fota upgrade failed !!!! -->\r\n"); + break; + + + case UP_SYSTEM_REBOOT: // If fota upgrade is in this case, this function you can return false or true, Notes: + { + // this case is important. return TRUE or FALSE, you can design by youself. + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Return TRUE, system will reboot, and upgrade -->\r\n"); + UPGRADE_APP_DEBUG(FOTA_DBGBuffer,"<--Return FLASE, you must invoke Ql_FOTA_Update() for upgrade !!!-->\r\n"); + FOTA_DBG_PRINT("<--Return TRUE, system will reboot, and upgrade -->\r\n"); + FOTA_DBG_PRINT("<--Return FLASE, you must invoke Ql_FOTA_Update() for upgrade !!!-->\r\n"); + return TRUE;// if return TRUE the module will reboot ,and fota upgrade complete. + //return FALSE; // if return False, you must invoke Ql_FOTA_Update() function before you want to reboot the system. + } + default: + break; + } + return TRUE; +} + +#endif //__OCPU_FOTA_APP__ diff --git a/cores/opencpu/include/nema_pro.h b/cores/opencpu/include/nema_pro.h new file mode 100644 index 0000000..cac650e --- /dev/null +++ b/cores/opencpu/include/nema_pro.h @@ -0,0 +1,57 @@ +#ifndef __NMEA_PRO_H__ +#define __NMEA_PRO_H__ + +#include "ql_type.h" +#include "ql_stdlib.h" +#define MAX_I2C_BUF_SIZE 255 +#define MAX_NMEA_LEN 255 +#define IIC_DEV_ADDR 0x20 + + +#define MSG_ID_IIC_READ_INDICATION 0x1011 +#define MSG_ID_OUTPUT_INDICATION 0x1012 + +#define TIMERID1 100 +#define INTERVAL500MS 500 +#define INTERVAL5MS 5 +#define NMEA_TX_MAX 2048 + + + + +typedef enum +{ + RXS_DAT_HBD, // receive HBD data + RXS_PRM_HBD2, // receive HBD preamble 2 + RXS_PRM_HBD3, // receive HBD preamble 3 + RXS_DAT, // receive NMEA data + RXS_DAT_DBG, // receive DBG data + RXS_ETX, // End-of-packet +} RX_SYNC_STATE_T; + +typedef struct +{ + s16 inst_id; // 1 - NMEA, 2 - DBG, 3 - HBD + s16 dat_idx; + s16 dat_siz; +}st_queue; + +extern u8 rd_buf[MAX_I2C_BUF_SIZE+1]; +extern u8 tx_buf[NMEA_TX_MAX]; +extern s32 tx_data_len; +extern s32 tx_size; + +bool iop_init_pcrx( void ); +void iop_pcrx_nmea( u8 data ); +void iop_get_inst(s16 idx, s16 size, void *data); +bool iop_inst_avail(s16 *inst_id, s16 *dat_idx, s16 *dat_siz) ; +bool iop_init_pcrx( void ) ; + +void get_nmea(void); +void extract_nmea(void); +bool read_gps_I2C_buffer(void); +s32 IIC_ReadBytes(u32 chnnlNo,u8 slaveAddr,u8 *buf,u32 len) ; +s32 IIC_WriteBytyes(u32 chnnlNo,u8 slaveAddr,u8 *pdata,u32 len); + +#endif + diff --git a/cores/opencpu/include/ql_adc.h b/cores/opencpu/include/ql_adc.h new file mode 100644 index 0000000..5c7f98f --- /dev/null +++ b/cores/opencpu/include/ql_adc.h @@ -0,0 +1,126 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_adc.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module defines the information, and APIs related to the ADC function. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __QL_ADC_H__ +#define __QL_ADC_H__ + +typedef enum +{ + PIN_ADC0, + PIN_ADC_MAX = 2 +}Enum_ADCPin; + +/***************************************************************** +* Function: Ql_ADC_Register +* +* Description: +* This function registers an ADC with the ADC pin name, +* callback function and the customized parameter. +* +* Parameters: +* adcPin: +* ADC pin name, one value of Enum_ADCPin. +* +* callback_adc: +* callback function, which will be invoked when the ADC result comes out. +* +* customParam: +* A customized parameter, which can be used in the ADC interrupt handler. +* It may be NULL if no customized parameter needs to be passed in. +* +* adcValue: +* the average voltage value for the specified sampling times. +* The range is 0~2800mV. Please also see "Ql_ADC_Init". +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input IO is invalid. +* other place. For example this IO has been using as GPIO. +* QL_RET_ERR_ADC_ALREADY_REGISTERED, this ADC pin is registered already +*****************************************************************/ +typedef void (*Callback_ADC)(Enum_ADCPin adcPin, u32 adcValue, void *customParam); +s32 Ql_ADC_Register(Enum_ADCPin adcPin, Callback_ADC callback_adc, void *customParam); + +/***************************************************************** +* Function: Ql_ADC_Init +* +* Description: +* This function configures the sampling parameters, +* including sampling count and the interval. +* +* Note: +* The ADC sampling result will be reported in the period of +* (count * interval)(ms). +* For example, if Ql_ADC_Init(PIN_ADC0, 5, 400), then the +* Callback_ADC function will be triggered in (5*400)ms=2s periodically. +* Parameters: +* adcPin: +* ADC pin name, one value of Enum_ADCPin +* +* count: +* Sampling times for each ADC value, the minimum is 5. +* +* interval: +* Interval of each internal sampling, unit is ms. +* the minimum is 200(ms). +* +* For example, if Ql_ADC_Init(PIN_ADC0, 5, 200), then +* |--200ms--->|--200ms--->|--200ms--->|--200ms--->|--200ms--->|... +* Start---->sample1---->sample2---->sample3---->sample4---->sample5. Then report the average value by callback. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_PARAM, parameter is error. +* QL_RET_ERR_NOSUPPORTPIN, the input pin is invalid. +* QL_RET_ERR_ADC_NOT_REGISTERED, the ADC not registered. +* +*****************************************************************/ +s32 Ql_ADC_Init(Enum_ADCPin adcPin, u32 count, u32 interval); + +/***************************************************************** +* Function: Ql_ADC_Sampling +* +* Description: +* this function switches on/off ADC sample. +* +* Parameters: +* enable: +* sample control, TRUE : start to sample. +* FALSE: stop sampling. +* +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input pin is invalid. +* QL_RET_ERR_ADC_NOT_REGISTERED, the ADC not register +* QL_RET_ERR_ADC_SAMPLING_ALREADY,the ADC sampling has been started already +*****************************************************************/ +s32 Ql_ADC_Sampling(Enum_ADCPin adcPin, bool enable); + +#endif //__QL_ADC_H__ diff --git a/cores/opencpu/include/ql_clock.h b/cores/opencpu/include/ql_clock.h new file mode 100644 index 0000000..e2d1c88 --- /dev/null +++ b/cores/opencpu/include/ql_clock.h @@ -0,0 +1,106 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_clock.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module defines the information, and APIs related to the clock function. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_CLOCK_H__ +#define __QL_CLOCK_H__ + + +typedef enum{ + CLOCKSOURCE_26M= 0, + CLOCKSOURCE_13M, + CLOCKSOURCE_6DOT5M, + CLOCKSOURCE_32K, + END_OF_CLOCKSOURCE +}Enum_ClockSource; + +/***************************************************************** +* Function: Ql_CLK_Init +* +* Description: +* This function Initialization a clock pin. +* +* NOTES: +* The clock can't out immediately after Ql_CLK_Init Initialization +* you must invoke Ql_CLK_Output functinon to control clock on or off +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* Enum_ClockSource: +* source clock , one value of Enum_ClockSource. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input pin is invalid. +* QL_RET_ERR_PINALREADYSUBCRIBE, the pin is in use in +* other place. For example this pin has been using as EINT. +* QL_RET_ERR_NOGPIOMODE, the input pin no clock mode +* QL_RET_ERR_NOSUPPORTSET not support this function +*****************************************************************/ +s32 Ql_CLK_Init(Enum_PinName clkName,Enum_ClockSource clkSrc); + +/***************************************************************** +* Function: Ql_CLK_Uninit +* +* Description: +* This function release a clock pin. +* +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input pin is invalid. +* QL_RET_ERR_BUSSUBBUSY, the PIN not used as clock, +* Maby is used by IIC or SPI,this function can't release it +*****************************************************************/ +s32 Ql_CLK_Uninit(Enum_PinName clkName); + +/***************************************************************** +* Function: Ql_CLK_Output +* +* Description: +* This function control clock on or off +* +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input pin is invalid. +* QL_RET_ERR_NORIGHTOPERATE, the PIN not in clock mode or not init, +* QL_RET_ERR_NOSUPPORTCONTROL not support control +*****************************************************************/ +s32 Ql_CLK_Output(Enum_PinName pinName,bool clkOnOff); + +#endif diff --git a/cores/opencpu/include/ql_common.h b/cores/opencpu/include/ql_common.h new file mode 100644 index 0000000..2e58eab --- /dev/null +++ b/cores/opencpu/include/ql_common.h @@ -0,0 +1,156 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_common.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module defines the information. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_COMMON_H__ +#define __QL_COMMON_H__ +#include "custom_feature_def.h" +#include "ql_type.h" +#include "ql_gpio.h" +#include "ql_trace.h" + +#define SYS_CONFIG_PWRKEY_DATA_SIZE (2) +#define SYS_CONFIG_EMERGOFF_DATA_SIZE (4) +#define SYS_CONFIG_WATCHDOG_DATA_SIZE (8) +#define SYS_CONFIG_APPENABLE_DATA_SIZE (4) +#define SYS_CONFIG_DEBUGMODE_DATA_SIZE (4) +#define SYS_CONFIG_DEBUGSET_DATA_SIZE (4) + + +typedef enum{ + SYS_CONFIG_PWRKEY_DATA_ID, // For PWRKEY pin setting + SYS_CONFIG_EMERGOFF_DATA_ID, // For EMERG_OFF pin setting + SYS_CONFIG_WATCHDOG_DATA_ID, // For external watchdog setting + SYS_CONFIG_APP_ENABLE_ID, // For application enable setting + SYS_CONFIG_DEBUG_MODE_ID, // For serial mode setting + SYS_CONFIG_DEBUG_SET_ID, // For catcher port setting + + SYS_CONFIG_END = 0x7FFFFFFF +}Enum_SysCfgId; + +typedef enum{ + APP_DISABLE = 0, + APP_ENABLE = 1 +}Enum_AppEnable; + +typedef struct{ + void (*proc_taskEntry)(s32 TaskId); // Task Entrance Procedure + s32 TaskId; + u32 TaskStackSize; // The stack size of subtask. Range from 1K to 10K. + u32 rev1; // Reserved parameter, must be DEFAULT_VALUE1. + u32 rev2; // Reserved parameter, must be DEFAULT_VALUE2. +}ST_TaskConfig; + +typedef struct{ + bool autoPowerOn; // If module automatically power on when pressing POWER_KEY + bool autoPowerOff; // If module automatically power off when pressing POWER_KEY +}ST_PowerKeyCfg; + +typedef struct{ + Enum_PinName pinWtd1; // Specify a pin which connects to the external watchdog + Enum_PinName pinWtd2; // Specify another pin for watchdog if needed +}ST_ExtWatchdogCfg; + +typedef struct{ + s32 appEnable; // Specify the working mode of serial debug port (UART2) +}ST_AppEnable; + +typedef struct{ + Enum_DebugMode dbgPortMode; +}ST_DebugPortCfg; + +typedef struct{ + Enum_PortName dbgPort; +}ST_DebugPortSet; + +/**************************************************************************** + * Customized configuration structure + ***************************************************************************/ +typedef struct{ + Enum_SysCfgId itemId; // Data item ID + u32 size; // Size of one record + void* pValue; // Pointer to config data +}ST_SystemConfig; + +#define QL_TRACE_LOG(PORT,BUF,BUF_LEN,...) \ + Ql_memset((char *)(BUF), 0, BUF_LEN); \ + Ql_sprintf((char *)(BUF),__VA_ARGS__); \ + if (UART_PORT2 == (PORT)) \ + {\ + Ql_Debug_Trace(BUF);\ + } else {\ + Ql_UART_Write((Enum_SerialPort)(PORT), (u8*)(BUF), Ql_strlen((const char *)(BUF)));\ + } + +#endif // __QL_COMMON_H__ + + +#if (defined(TASK_FUNC_DECLARATION) && defined(TASK_ID_DEF)) +#error [ Conflict I ] +#endif +#if (defined(TASK_FUNC_DECLARATION) && defined(TASK_DEFINITION)) +#error [ Conflict II ] +#endif +#if (defined(TASK_DEFINITION) && defined(TASK_ID_DEF)) +#error [ Conflict III ] +#endif + + +#undef TASK_DEFINITION_BEGIN +#undef TASK_ITEM +#undef TASK_DEFINITION_END + +#ifdef GPIO_DEFINITION +#define GPIO_DEFINITION_BEGIN const ST_GPIOConfig GpioConfigTbl[] = { +#define GPIO_ITEM(PINNAME, PINDIRECTION, PINLEVEL, PINPULLSEL) {PINNAME, PINDIRECTION, PINLEVEL, PINPULLSEL}, +#define GPIO_DEFINITION_END {PINNAME_END, 0, 0, 0} }; +#endif + + +#if defined( TASK_DEFINITION) +#define TASK_DEFINITION_BEGIN const ST_TaskConfig TaskConfig[] = { +#define TASK_ITEM(EntryFunc,TaskId,TaskStackSize,P1,P2) {EntryFunc, TaskId, TaskStackSize, P1, P2}, +#define TASK_DEFINITION_END {NULL, 0, 0, 0, 0}}; +#elif defined(TASK_ID_DEF) +#define TASK_DEFINITION_BEGIN typedef enum{ +#define TASK_ITEM(EntryFunc,TaskId,TaskStackSize,P1,P2) TaskId, +#define TASK_DEFINITION_END TaskId_End } Enum_TaskId; +#elif defined(TASK_FUNC_DECLARATION) +#define TASK_DEFINITION_BEGIN +#define TASK_ITEM(EntryFunc,TaskId,TaskStackSize,P1,P2) extern void EntryFunc(s32); +#define TASK_DEFINITION_END +#else +#undef TASK_DEFINITION_BEGIN +#undef TASK_ITEM +#undef TASK_DEFINITION_END +#endif diff --git a/cores/opencpu/include/ql_eint.h b/cores/opencpu/include/ql_eint.h new file mode 100644 index 0000000..7f52ea7 --- /dev/null +++ b/cores/opencpu/include/ql_eint.h @@ -0,0 +1,226 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_eint.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * EINT API defines. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_EINT_H__ +#define __QL_EINT_H__ + +#include "ql_gpio.h" + + +typedef enum{ + EINT_EDGE_TRIGGERED = 0, + EINT_LEVEL_TRIGGERED, + EINT_CLOSE +}Enum_EintType; + + +/***************************************************************** +* Description: +* Definition for EINT callback function. +* +* Parameters: +* eintPinName: +* EINT pin name, one value of Enum_PinName, which is registered by +* calling Ql_EINT_Register() or Ql_EINT_RegisterFast(). +* +* pinLevel: +* The EINT level value, one value of Enum_PinLevel. +* +* customParam: +* The customized parameter, which is passed in by calling +* Ql_EINT_Register() or Ql_EINT_RegisterFast(). +*****************************************************************/ +typedef void (*Callback_EINT_Handle)(Enum_PinName eintPinName, Enum_PinLevel pinLevel, void* customParam); + +/***************************************************************** +* Function: Ql_EINT_Register +* +* Description: +* This function registers an EINT I/O, and specifies the +* interrupt handler. +* +* Parameters: +* eintPinName: +* EINT pin name, one value of Enum_PinName that has +* the interrupt function. +* +* callback_eint: +* The interrupt handler, or ISR. +* +* customParam: +* A customized parameter, which can be use in interrupt handler. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input IO is invalid. +* QL_RET_ERR_PINALREADYSUBCRIBE, the IO is in use in +* other place. For example this IO has been using as GPIO. +* Ql_RET_ERR_EINT_ALREADY_REGISTERED, this EINT is registered already +*****************************************************************/ +s32 Ql_EINT_Register(Enum_PinName eintPinName, Callback_EINT_Handle callback_eint, void* customParam); + +/***************************************************************** +* Function: Ql_EINT_RegisterFast +* +* Description: +* This function registers an EINT I/O, and specifies the +* interrupt handler. +* The EINT, that is registered by calling this function, +* is a lower-level interrupt. The response for interrupt +* request is timelier. +* +* IMPORTANT NOTES: +* Please don't add any task schedule in the interrupt +* handler.And the interrupt handler cannot consume much +* CPU time. Or it causes system exception or reset. +* +* Parameters: +* eintPinName: +* EINT pin name, one value of Enum_PinName that has +* the interrupt function. +* +* callback_eint: +* The interrupt handler, or ISR. +* +* customParam: +* A customized parameter, which can be use in interrupt handler. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input IO is invalid. +* QL_RET_ERR_PINALREADYSUBCRIBE, the IO is in use in +* other place. For example this IO has been using as GPIO. +* Ql_RET_ERR_EINT_ALREADY_REGISTERED, this EINT is registered already +*****************************************************************/ +s32 Ql_EINT_RegisterFast(Enum_PinName eintPinName, Callback_EINT_Handle callback_eint, void* customParam); + +/***************************************************************** +* Function: Ql_EINT_Init +* +* Description: +* Initialize an external interrupt function. +* +* Parameters: +* eintPinName: +* EINT pin name, one value of Enum_PinName that has +* the interrupt function. +* +* eintType: +* Interrupt type, level-triggered or edge-triggered. +* Now, only level-triggered interrupt is supported. +* +* hwDebounce: +* Hardware debounce. Unit in 10ms. +* +* swDebounce: +* Software debounce. Unit in 10ms. The minimum value for +* this parameter is 5, which means the minimum software +* debounce time is 5*10ms=50ms. +* automask: +* mask the Eint after the interrupt happened. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input pin is invalid. +* QL_RET_ERR_PINALREADYSUBCRIBE, the pin is in use in +* other place. For example this pin has been using as GPIO. +* QL_RET_ERR_NOSUPPORTMODE this pin not support EINT mode. +* QL_RET_ERR_NOSUPPORTSET do not support this function +*****************************************************************/ +s32 Ql_EINT_Init(Enum_PinName eintPinName, Enum_EintType eintType, u32 hwDebounce, u32 swDebounce, bool automask); + +/***************************************************************** +* Function: Ql_EINT_Uninit +* +* Description: +* This function releases the specified EINT pin that was +* initialized by calling Ql_EINT_Init() previously. +* After releasing, the pin can be used for other purpose. +* Parameters: +* eintPinName: +* EINT pin name, one value of Enum_PinName that has +* the interrupt function. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +* QL_RET_ERR_BUSSUBBUSY, the GPIO not used as GPIO, +* Maby is used by IIC or SPI,this function can't release it +*****************************************************************/ +s32 Ql_EINT_Uninit(Enum_PinName eintPinName); + +/***************************************************************** +* Function: Ql_EINT_GetLevel +* +* Description: +* This function gets the level of the specified EINT pin. +* +* Parameters: +* eintPinName: +* EINT pin name, one value of Enum_PinName that has +* the interrupt function. +* Return: +* The level value of the specified EINT pin, which is +* nonnegative integer. +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +*****************************************************************/ +s32 Ql_EINT_GetLevel(Enum_PinName eintPinName); + +/***************************************************************** +* Function: Ql_EINT_Mask +* +* Description: +* This function masks the specified EINT pin. +* +* Parameters: +* eintPinName: +* EINT pin name, one value of Enum_PinName that has +* the interrupt function. +* Return: +* None. +*****************************************************************/ +void Ql_EINT_Mask(Enum_PinName eintPinName); + +/***************************************************************** +* Function: Ql_EINT_Unmask +* +* Description: +* This function unmasks the specified EINT pin. +* +* Parameters: +* eintPinName: +* EINT pin name, one value of Enum_PinName that has +* the interrupt function. +* Return: +* None. +*****************************************************************/ +void Ql_EINT_Unmask(Enum_PinName eintPinName); + +#endif // __QL_EINT_H__ diff --git a/cores/opencpu/include/ql_error.h b/cores/opencpu/include/ql_error.h new file mode 100644 index 0000000..3a4e70a --- /dev/null +++ b/cores/opencpu/include/ql_error.h @@ -0,0 +1,198 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_error.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * error code defines. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_ERROR_H__ +#define __QL_ERROR_H__ + +/**************************************************************************** + * Error Code Definition + ***************************************************************************/ +enum { + QL_RET_OK = 0, + QL_RET_ERR_PARAM = -1, + QL_RET_ERR_PORT_NOT_OPEN = -2, + QL_RET_ERR_TIMER_FULL = -3, + QL_RET_ERR_INVALID_TIMER = -4, + QL_RET_ERR_FATAL = -5, + QL_RET_ERR_INVALID_OP = -6, + QL_RET_ERR_UART_BUSY = -7, + QL_RET_ERR_INVALID_PORT = -8, + QL_RET_ERR_NOMATCHVERSION = -9, + QL_RET_ERR_NOSUPPORTPIN = -10, + QL_RET_ERR_NOSUPPORTMODE = -11, + QL_RET_ERR_NOSUPPORTEINT = -12, + QL_RET_ERR_NOSUPPORTSET = -13, + QL_RET_ERR_NOSUPPORTGET = -14, + QL_RET_ERR_NOSUPPORTCONTROL = -15, + QL_RET_ERR_PINALREADYSUBCRIBE = -16, + QL_RET_ERR_BUSSUBBUSY = -17, + QL_RET_ERR_NOGPIOMODE = -18, + QL_RET_ERR_NORIGHTOPERATE = -19, + QL_RET_ERR_ALREADYUNSUBCRIBE = -20, + QL_RET_ERR_FULLI2CBUS = -21, + QL_RET_ERR_NOTSUPPORTBYHANDLE = -22, + QL_RET_ERR_INVALIDBUSHANDLE = -23, + QL_RET_ERR_NOEXISTOBJEXT = -24, + QL_RET_ERR_OPERATEOBJEXTFAILED = -25, + QL_RET_ERR_OPENOBJEXTFAILED = -26, + QL_RET_ERR_WRITEOBJEXTFAILED = -27, + QL_RET_ERR_READOBJEXTFAILED = -28, + QL_RET_ERR_FLASHFULLOVER = -29, + QL_RET_ERR_FLASHSPACE = -30, + QL_RET_ERR_DRIVE = -31, + QL_RET_ERR_DRIVEFULLOVER = -32, + QL_RET_ERR_INVALIDFLASHID = -33, + QL_RET_ERR_I2CHWFAILED = -34, + QL_RET_ERR_FILEFAILED = -35, + QL_RET_ERR_FILEOPENFAILED = -36, + QL_RET_ERR_FILENAMETOOLENGTH = -37, + QL_RET_ERR_FILEREADFAILED = -38, + QL_RET_ERR_FILEWRITEFAILED = -39, + QL_RET_ERR_FILESEEKFAILED = -40, + QL_RET_ERR_FILENOTFOUND = -41, + QL_RET_ERR_FILENOMORE = -42, + QL_RET_ERR_FILEDISKFULL = -43, + QL_RET_ERR_INVALID_BAUDRATE = -44, + QL_RET_ERR_API_NO_RESPONSE = -45, + QL_RET_ERR_API_INVALID_RESPONSE = -46, + QL_RET_ERR_SMS_EXCEED_LENGTH =-47, + QL_RET_ERR_SMS_NOT_INIT = -48, + QL_RET_ERR_INVALID_TASK_ID = -49, + QL_RET_ERR_NOT_IN_BASIC_MODE = -50, + QL_RET_ERR_INVALID_PARAMETER = -51, + QL_RET_ERR_PATHNOTFOUND = -52, + QL_RET_ERR_GET_MEM = -53, + QL_RET_ERR_GENERAL_FAILURE = -54, + QL_RET_ERR_FILE_EXISTS = -55, + QL_RET_ERR_SMS_INVALID_FORMAT = -56, + QL_RET_ERR_SMS_GET_FORMAT = -57, + QL_RET_ERR_SMS_INVALID_STORAGE = -58, + QL_RET_ERR_SMS_SET_STORAGE = -59, + QL_RET_ERR_SMS_SEND_AT_CMD = -60, + QL_RET_ERR_API_CMD_BUSY = -61, + + /* AUD -70 ~ -100*/ + QL_RET_ERR_MED_BAD_FORMAT = -70, + QL_RET_ERR_MED_BUSY = -71, + QL_RET_ERR_MED_DISC_FULL = -72, + QL_RET_ERR_MED_OPEN_FILE_FAIL = -73, + QL_RET_ERR_MED_BAD_FILE_EXTENSION = -74, + QL_RET_ERR_MED_WRITE_PROTECTION = -75, + QL_RET_ERR_MED_FILE_EXIST = -76, + QL_RET_ERR_MED_UNSUPPORT_FMT_IN_CALLING = -77, + Ql_RET_ERR_AUD_REC_STOP_FAIL = -78, + QL_RET_ERR_MED_DRIVE_NOT_FOUND = -79, + QL_RET_ERR_MED_NO_CARD = -80, + Ql_RET_ERR_MEM_FULL = -81, + QL_ERR_DTMFSTRING_TOO_LONG = -82, + QL_ERR_WDTMF_PS_BUSY = -83, + QL_ERR_DTMF_BUSY = -84, + QL_ERR_DTMF_NO_CALLING =-85, + /* reserve to -100 */ + QL_RET_ERR_MED_UNKNOWN = -100, + + /* File Append */ + QL_RET_ERR_FILE_NO_CARD = -101, + + QL_RET_ERR_FS_FATAL_ERR1 = 190, // File system fatal error type1, which indicates the file system is corrupted and cannot restored. + // If this value is returned by FS-related APIs, devloper should call Ql_Fs_Format(QL_FS_FAT) to format the file system. + // After formatted the file system, all user files will be deleted. + QL_RET_ERR_FS_FATAL_ERR2 = 191, + + /*reserved to -200 */ + QL_RET_ERR_FILE_UNKNOWN = -200, + + Ql_RET_ERR_EINT_USED =-300, + Ql_RET_ERR_EINT_ALREADY_REGISTERED = -301, + QL_RET_ERR_ADC_ALREADY_REGISTERED = -302, + QL_RET_ERR_ADC_NOT_REGISTERED = -303, + QL_RET_ERR_ADC_SAMPLING_ALREADY = -304, + QL_RET_ERR_CHANNEL_OUTRANGE = -305, + QL_RET_ERR_CHANNEL_USED = -306, + QL_RET_ERR_CHANNEL_NOT_FOUND = -307, + QL_RET_ERR_IIC_SLAVE_NOT_FOUND = -308, + QL_RET_ERR_IIC_SAME_SLAVE_ADDRESS = -309, + QL_RET_ERR_IIC_SLAVE_TOO_MANY = -310, + QL_RET_ERR_IIC_NOT_IIC_CONTROLER = -311, + QL_RET_ERR_FULLSPIBUS = -312, + + + Ql_RET_ERR_SIM_NOT_INSERTED =-400, + Ql_RET_ERR_SIM_TYPE_ERROR =-401, + + /* SMS -500 ~ -550*/ + QL_RET_ERR_SMS_ERROR = -500, + QL_RET_ERR_SMS_NOT_INITIAL = -501, + Ql_RET_ERR_SMS_NOT_READY = -502, + QL_RET_ERR_SMS_INVALID_PARAM = -503, + QL_RET_ERR_SMS_OUT_OF_MEMORY = -504, + QL_RET_ERR_SMS_INCORRECT_DATA_LENGTH = -505, + QL_RET_ERR_SMS_PDU_SYNTEX_ERROR = -506, + QL_RET_ERR_SMS_INVALID_MEM_INDEX = -507, + QL_RET_ERR_SMS_CMD_CONFLICT = -508, + QL_RET_ERR_SMS_MSG_EMPTY = -509, + QL_RET_ERR_SMS_INVALID_NUMBER_STRING = -510, + QL_RET_ERR_SMS_INVALID_TEXT_CONTENT = -511, + QL_RET_ERR_SMS_NOT_SUPPORTED = -512, + QL_RET_ERR_SMS_INCORRECT_FORMAT = -513, + QL_RET_ERR_SMS_STORAGE_FULL = -514, + + /* RIL FTP -600 */ + QL_RET_ERR_RIL_FTP_OPENFAIL = -600, + QL_RET_ERR_RIL_FTP_CLOSEFAIL = -601, + QL_RET_ERR_RIL_FTP_SETPATHFAIL = -602, + QL_RET_ERR_RIL_FTP_SETCFGFAIL = -603, + QL_RET_ERR_RIL_FTP_RENAMEFAIL = -604, + QL_RET_ERR_RIL_FTP_SIZEFAIL = -605, + QL_RET_ERR_RIL_FTP_DELETEFAIL = -606, + QL_RET_ERR_RIL_FTP_MKDIRFAIL = -607, + + Ql_RET_ERR_RAWFLASH_OVERRANGE = -8001, + Ql_RET_ERR_RAWFLASH_UNIITIALIZED = -8002, + Ql_RET_ERR_RAWFLASH_UNKNOW = -8003, + Ql_RET_ERR_RAWFLASH_INVLIDBLOCKID = -8004, + Ql_RET_ERR_RAWFLASH_PARAMETER = -8005, + Ql_RET_ERR_RAWFLASH_ERASEFlASH = -8006, + Ql_RET_ERR_RAWFLASH_WRITEFLASH = -8007, + Ql_RET_ERR_RAWFLASH_READFLASH = -8008, + Ql_RET_ERR_RAWFLASH_MAXLENGATH = -8009, + /* Flash OPT End */ + + Ql_RET_ERR_SYS_NOT_READY = -9998, + Ql_RET_ERR_UNKOWN = -9999, + Ql_RET_NOT_SUPPORT = -10000, +}; + +#endif // End-of QL_ERROR_H + diff --git a/cores/opencpu/include/ql_fota.h b/cores/opencpu/include/ql_fota.h new file mode 100644 index 0000000..facb0a9 --- /dev/null +++ b/cores/opencpu/include/ql_fota.h @@ -0,0 +1,158 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_fota.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * Fota API defines. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_FOTA_H__ +#define __QL_FOTA_H__ + +#include "ql_type.h" + +typedef struct +{ + s16 Q_gpio_pin1; //Watchdog GPIO pin 1, If only use one GPIO,you can set other to -1,it means invalid. + s16 Q_feed_interval1; //gpio1 time interval for feed dog. + s16 Q_gpio_pin2; //Watchdog GPIO pin 2, If only use one GPIO,you can set other to -1,it means invalid. + s16 Q_feed_interval2; //gpio2 time interval for feed dog. + s32 reserved1; //reserve 1 + s32 reserved2; //reserve 2 +}ST_FotaConfig; + + +/***************************************************************** +* Function: Ql_FOTA_Init +* +* Description: Initialize FOTA related functions. +* It a simple API.Programer only need to pass the +* simple parameters to this API. +* +* Parameters: +* pFotaCfg: Initialize fota config include watch dog. +* Return: +* QL_RET_OK indicates this function successes. +* QL_RET_ERR_PARAM indicates parameter error. +* Ql_RET_NOT_SUPPORT indicates not support this function. +* Ql_RET_ERR_RAWFLASH_UNKNOW indicates unknown error. +*****************************************************************/ +s32 Ql_FOTA_Init(ST_FotaConfig * pFotaCfg); + + +/***************************************************************** +* Function: Ql_FOTA_WriteData +* +* Description: +* FOTA write data API. +* 1. This function is used to write data to spare image pool +* 2. This API only allow sequentially writing mechanism +* 3. Authentication mechanism is executed during writing +* Parameters: +* length: the length of writing (Unit: Bytes).recommend 512 bytes +* buffer: point to the start address of buffer +* Return: +* QL_RET_OK indicates this function successes. +* QL_RET_ERR_PARAM indicates parameter error. +* Ql_RET_NOT_SUPPORT indicates not support this function. +* Ql_RET_ERR_UNKOWN indicates unknown error. +* Ql_RET_ERR_RAWFLASH_OVERRANGE indicates over flash range. +* Ql_RET_ERR_RAWFLASH_UNIITIALIZED indicates uninitialized before write or read flash. +* Ql_RET_ERR_RAWFLASH_UNKNOW indicates unknown error. +* Ql_RET_ERR_RAWFLASH_INVLIDBLOCKID indicates block id invalid. +* Ql_RET_ERR_RAWFLASH_PARAMETER indicates parameter error. +* Ql_RET_ERR_RAWFLASH_ERASEFlASH indicates erase flash failure. +* Ql_RET_ERR_RAWFLASH_WRITEFLASH indicates written flash failure. +* Ql_RET_ERR_RAWFLASH_READFLASH indicates read flash failure. +* Ql_RET_ERR_RAWFLASH_MAXLENGATH indicates the data length too large. +*****************************************************************/ +s32 Ql_FOTA_WriteData(s32 length, s8* buffer); + +/***************************************************************** +* Function: Ql_FOTA_Finish +* +* Description: +* FOTA finalization API. +* 1. compare calculated checksum with image checksum in the header after +* whole image is written +* 2. mark the status to UPDATE_NEEDED +* Parameters: +* None +* Return: +* QL_RET_OK indicates this function successes. +* Ql_RET_NOT_SUPPORT indicates not support this function. +* Ql_RET_ERR_UNKOWN indicates unknown error. +* Ql_RET_ERR_RAWFLASH_OVERRANGE indicates over flash range. +* Ql_RET_ERR_RAWFLASH_UNIITIALIZED indicates uninitialized before write or read flash. +* Ql_RET_ERR_RAWFLASH_UNKNOW indicates unknown error. +* Ql_RET_ERR_RAWFLASH_INVLIDBLOCKID indicates block id invalid. +* Ql_RET_ERR_RAWFLASH_PARAMETER indicates parameter error. +* Ql_RET_ERR_RAWFLASH_ERASEFlASH indicates erase flash failure. +* Ql_RET_ERR_RAWFLASH_WRITEFLASH indicates written flash failure. +* Ql_RET_ERR_RAWFLASH_READFLASH indicates read flash failure. +* Ql_RET_ERR_RAWFLASH_MAXLENGATH indicates the data length too large. +*****************************************************************/ +s32 Ql_FOTA_Finish(void); + +/***************************************************************** +* Function: Ql_FOTA_ReadData +* +* Description: +* This function reads data from the data region which +* Ql_FOTA_WriteData writes to. +* If Developer needs to check the whole data package after +* writing, this API can read back the data. +* Parameters: +* offset: the offset value to the data region +* len: the length to read (Unit: Byte).recommend 512 bytes +* pBuffer: point to the buffer to store read data. +* Return: +* QL_RET_ERR_PARAM, indicates parameter error. +* >0, the real read number of bytes. +*****************************************************************/ +s32 Ql_FOTA_ReadData(u32 offset, u32 len, u8* pBuffer); + +/***************************************************************** +* Function: Ql_Fota_Update +* +* Description: +* Starts FOTA Update. +* Parameters: +* None. +* Return: +* QL_RET_OK indicates this function successes. +* QL_RET_ERR_INVALID_OP indicates invalid operation. +* Ql_RET_NOT_SUPPORT indicates not support this function. +* Ql_RET_ERR_RAWFLASH_PARAMETER indicates parameter error. +* Ql_RET_ERR_RAWFLASH_ERASEFlASH indicates erase flash failure. +* Ql_RET_ERR_RAWFLASH_WRITEFLASH indicates written flash failure. +*****************************************************************/ +s32 Ql_FOTA_Update(void); + +#endif // End-of __QL_FOTA_H__ diff --git a/cores/opencpu/include/ql_fs.h b/cores/opencpu/include/ql_fs.h new file mode 100644 index 0000000..a299ecd --- /dev/null +++ b/cores/opencpu/include/ql_fs.h @@ -0,0 +1,722 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_fs.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * File API defines. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_FS_H__ +#define __QL_FS_H__ +#include "ql_type.h" + + +/**************************************************************************** + * Type of file access permitted + ***************************************************************************/ +#define QL_FS_READ_WRITE 0x00000000L +#define QL_FS_READ_ONLY 0x00000100L +#define QL_FS_CREATE 0x00010000L +#define QL_FS_CREATE_ALWAYS 0x00020000L +#define QL_FS_OPEN_SHARED 0x00000200L + + +/**************************************************************************** + * Type of file move permitted + ***************************************************************************/ +#define QL_FS_MOVE_COPY 0x00000001 // Move file|folder by copy +#define QL_FS_MOVE_KILL 0x00000002 // Delete the moved file|folder after moving +#define QL_FS_MOVE_OVERWRITE 0x00010000 // Overwrite the existed file in destination path when move file|folder + + +/**************************************************************************** + * + ***************************************************************************/ +#define QL_FS_FILE_TYPE 0x00000004 +#define QL_FS_DIR_TYPE 0x00000008 +#define QL_FS_RECURSIVE_TYPE 0x00000010 + +/**************************************************************************** + * Constants for File Seek + ***************************************************************************/ +typedef enum +{ + QL_FS_FILE_BEGIN, // Beginning of file + QL_FS_FILE_CURRENT, // Current position of file pointer + QL_FS_FILE_END // End of file +}Enum_FsSeekPos; + +typedef enum +{ + Ql_FS_UFS = 1, + Ql_FS_SD = 2, + Ql_FS_RAM = 3, + QL_FS_FAT = 0xFF +}Enum_FSStorage; + + + +/****************************************************************************** +* Function: Ql_FS_Open +* +* Description: +* Opens or creates a file with a specified name in the UFS or SD card. +* If you want to create a file in the UFS , you only need to use a relative path. +* If you want to create a file in the SD card , you also need to add prefix "SD:" +* in front of the file name. +* +* Parameters: +* lpFileName: +* [in]The name of the file. The name is limited to 252 characters. +* You must use a relative path, such as "filename.ext" or +* "dirname\filename.ext". + +* +* flag: +* [in]A u32 that defines the file's opening and access mode. +* The possible values are shown as follow: +* QL_FS_READ_WRITE, can read and write +* QL_FS_READ_ONLY, can only read +* QL_FS_CREATE, opens the file, if it exists. +* If the file does not exist, the function creates the file +* QL_FS_CREATE_ALWAYS, creates a new file. +* If the file exists, the function overwrites the file +* and clears the existing attributes +* Return: +* If the function succeeds, the return value specifies a file handle. +* If the function fails, the return value is an error codes. +* QL_RET_ERR_FILE_NO_CARD indicates no sd card. +* QL_RET_ERR_PARAM indicates parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH indicates filename too length. +* QL_RET_ERR_FILEOPENFAILED indicates open file failed. +* +* QL_RET_ERR_FS_FATAL_ERR1 indicates some fatal error happens to +* the file system. Develops may call Ql_GetLastErrorCode() to +* retrieve the inner error code. And develops can call Ql_Fs_Format(QL_FS_FAT) +* to format FAT to retore the file system. +******************************************************************************/ +s32 Ql_FS_Open(char* lpFileName, u32 flag); + +/****************************************************************************** +* Function: Ql_FS_OpenRAMFile +* +* Description: +* Opens or creates a file with a specified name in the RAM,you need +* to add prefix "RAM:" in front of the file. You can create at most 15 files. +* +* Parameters: +* lpFileName: +* [in]The name of the file. The name is limited to 252 characters. +* You must use a relative path, such as "RAM:filename.ext". +* + +* +* flag: +* [in]A u32 that defines the file's opening and access mode. +* The possible values are shown as follow: +* QL_FS_READ_WRITE, can read and write +* QL_FS_READ_ONLY, can only read +* QL_FS_CREATE, opens the file, if it exists. +* If the file does not exist, the function creates the file +* QL_FS_CREATE_ALWAYS, creates a new file. +* If the file exists, the function overwrites the file +* and clears the existing attributes +* ramFileSize: +* [in]The size of the specified file which you want to create. +* Return: +* If the function succeeds, the return value specifies a file handle. +* If the function fails, the return value is an error codes. +* QL_RET_ERR_PARAM indicates parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH indicates filename too length. +* QL_RET_ERR_FILEOPENFAILED indicates open file failed. +******************************************************************************/ +s32 Ql_FS_OpenRAMFile(char *lpFileName, u32 flag, u32 ramFileSize); + +/****************************************************************************** +* Function: Ql_FS_Read +* +* Description: +* Reads data from the specified file, starting at the position +* indicated by the file pointer. After the read operation has been +* completed, the file pointer is adjusted by the number of bytes actually read. +* +* Parameters: +* fileHandle: +* [in] A handle to the file to be read, which is the return value +* of the function Ql_FS_Open. +* +* readBuffer: +* [out] Point to the buffer that receives the data read from the file. +* +* numberOfBytesToRead: +* [in] Number of bytes to be read from the file. +* +* numberOfBytesRead: +* [out] The number of bytes has been read. sets this value to zero before +* doing taking action or checking errors. +* Return: +* QL_RET_OK, suceess +* QL_RET_ERR_FILEREADFAILED, read file failed. +******************************************************************************/ +s32 Ql_FS_Read(s32 fileHandle, u8 *readBuffer, u32 numberOfBytesToRead, u32 *numberOfBytesRead); + + +/****************************************************************************** +* Function: Ql_FS_Write +* +* Description: +* This function writes data to a file. Ql_FS_Write starts writing +* data to the file at the position indicated by the file pointer. +* After the write operation has been completed, the file pointer +* is adjusted by the number of bytes actually written. +* +* Parameters: +* fileHandle: +* [in] A handle to the file to be read, which is the return value +* of the function Ql_FS_Open. +* +* writeBuffer: +* [in] Point to the buffer containing the data to be written to the file. +* +* numberOfBytesToWrite: +* [in] Number of bytes to be write to the file. +* +* numberOfBytesWritten: +* [out] The number of bytes has been written. Sets this value to zero +* before doing taking action or checking errors. +* Return: +* QL_RET_OK, suceess +* QL_RET_ERR_FILEDISKFULL, file disk is full. +* QL_RET_ERR_FILEWRITEFAILED, write file failed. +* +* QL_RET_ERR_FS_FATAL_ERR1 indicates some fatal error happens to +* the file system. Develops may call Ql_GetLastErrorCode() to +* retrieve the inner error code. And develops can call Ql_Fs_Format(QL_FS_FAT) +* to format FAT to retore the file system. +******************************************************************************/ +s32 Ql_FS_Write(s32 fileHandle, u8 *writeBuffer, u32 numberOfBytesToWrite, u32 *numberOfBytesWritten); + + +/****************************************************************************** +* Function: Ql_FS_Seek +* +* Description: +* Repositions the pointer in the previously opened file. +* +* Parameters: +* fileHandle: +* [in] A handle to the file to be read, which is the return value +* of the function Ql_FS_Open. +* +* offset: +* [in] Number of bytes to move the file pointer. +* +* whence: +* [in] The file pointer reference position. See Enum_FsSeekPos. +* Return: +* QL_RET_OK, suceess +* QL_RET_ERR_FILESEEKFAILED, file seek failed +******************************************************************************/ +s32 Ql_FS_Seek(s32 fileHandle, s32 offset, u32 whence); + + +/****************************************************************************** +* Function: Ql_FS_GetFilePosition +* +* Description: +* Gets the current value of the file pointer. +* +* Parameters: +* fileHandle: +* [in] A file handle, which was returned by calling 'Ql_FS_Open'. +* +* Return: +* The return value is the current offset from the beginning of the file +* if this function succeeds. Otherwise, the return value is an error code. +* QL_RET_ERR_FILEFAILED, fail to operate file. +******************************************************************************/ +s32 Ql_FS_GetFilePosition(s32 fileHandle); + + +/****************************************************************************** +* Function: Ql_FS_Truncate +* +* Description: +* This function truncates a file to ZERO size. +* +* Parameters: +* fileHandle: +* [in] A file handle, which was returned by calling 'Ql_FS_Open'. +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_FILEFAILED, fail to operate file. +******************************************************************************/ +s32 Ql_FS_Truncate(s32 fileHandle); + + +/****************************************************************************** +* Function: Ql_FS_Flush +* +* Description: +* Forces any data remaining in the file buffer to be written to the file. +* +* Parameters: +* fileHandle: +* [in] A file handle, which was returned by calling 'Ql_FS_Open'. +* Return: +* None +******************************************************************************/ +void Ql_FS_Flush(s32 fileHandle); + + +/****************************************************************************** +* Function: Ql_FS_Close +* +* Description: +* Closes the file associated with the file handle and makes +* the file unavailable for reading or writing. +* +* Parameters: +* fileHandle: +* [in] A file handle, which was returned by calling 'Ql_FS_Open'. +* Return: +* None +******************************************************************************/ +void Ql_FS_Close(s32 fileHandle); + + +/****************************************************************************** +* Function: Ql_FS_GetSize +* +* Description: +* Retrieves the size, in bytes, of the specified file. +* +* Parameters: +* lpFileName: +* [in] The name of the file. +* +* Return: +* The return value is the bytes of the file if this function succeeds. +* Otherwise, the return value is an error code. +* QL_RET_ERR_FILE_NO_CARD, no sd card. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH , filename too length. +* QL_RET_ERR_FILEFAILED, fail to operate file. +******************************************************************************/ +s32 Ql_FS_GetSize(char *lpFileName); + + +/****************************************************************************** +* Function: Ql_FS_Delete +* +* Description: +* This function deletes an existing file. +* +* Parameters: +* lpFileName: +* [in]The name of the file to be deleted. The name is limited +* to 252 characters. You must use a relative path, such as +* "filename.ext" or "dirname\filename.ext". +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_FILE_NO_CARD, no sd card. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH , filename too length. +* QL_RET_ERR_FILEFAILED, fail to operate file. +******************************************************************************/ +s32 Ql_FS_Delete(char *lpFileName); + + +/****************************************************************************** +* Function: Ql_FS_Check +* +* Description: +* Check whether the file exists or not. +* +* Parameters: +* lpFileName: +* [in] The name of the file. The name is limited to 252 characters. +* You must use a relative path, such as "filename.ext" or +* "dirname\filename.ext". +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_FILE_NO_CARD, no sd card. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH , filename too length. +* QL_RET_ERR_FILEFAILED, fail to operate file. +* QL_RET_ERR_FILENOTFOUND, file not found. +******************************************************************************/ +s32 Ql_FS_Check(char *lpFileName); + + +/****************************************************************************** +* Function: Ql_FS_Rename +* +* Description: +* Rename a file. +* +* Parameters: +* lpFileName: +* [in] File to be renamed.The name is limited to 252 characters. +* You must use a relative path, such as "filename.ext" or +* "dirname\filename.ext". +* +* newLpFileName: +* [in] New name of file. The name is limited to 252 characters. +* You must use a relative path, such as "filename.ext" or +* "dirname\filename.ext". +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_FILE_NO_CARD, no sd card. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH , filename too length. +* QL_RET_ERR_FILEFAILED, fail to operate file. +******************************************************************************/ +s32 Ql_FS_Rename(char *lpFileName, char *newLpFileName); + + +/****************************************************************************** +* Function: Ql_FS_CreateDir +* +* Description: +* Creates a directory in the UFS or SD card. +* If you want to create a directory in the UFS , you only need to use a relative path. +* If you want to create a directory in the SD card , you also need to add prefix "SD:" +* in front of the file name. +* +* Parameters: +* lpDirName: +* [in] The name of the directory.The name is limited to 252 characters. +* You must use a relative path,such as "dirname1" or "dirname1\dirname2". +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_FILE_NO_CARD, no sd card. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH , filename too length. +* QL_RET_ERR_FILEFAILED, fail to operate file. +* Notes: +* Don't support to create a directory in the RAM. +* +* QL_RET_ERR_FS_FATAL_ERR1 indicates some fatal error happens to +* the file system. Develops may call Ql_GetLastErrorCode() to +* retrieve the inner error code. And develops can call Ql_Fs_Format(QL_FS_FAT) +* to format FAT to retore the file system. +******************************************************************************/ +s32 Ql_FS_CreateDir(char *lpDirName); + + +/****************************************************************************** +* Function: Ql_FS_DeleteDir +* +* Description: +* Deletes an existing directory. +* +* Parameters: +* lpDirName: +* [in] The name of the directory.The name is limited to 252 characters. +* You must use a relative path,such as "dirname1" or "dirname1\dirname2". +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_FILE_NO_CARD, no sd card. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH , filename too length. +* QL_RET_ERR_FILEFAILED, fail to operate file. +* Notes: +* Don't support to delete a directory in the RAM. +******************************************************************************/ +s32 Ql_FS_DeleteDir(char *lpDirName); + + +/****************************************************************************** +* Function: Ql_FS_CheckDir +* +* Description: +* Check whether the file exists or not. +* +* Parameters: +* lpDirName: +* [in] The name of the directory.The name is limited to 252 characters. +* You must use a relative path,such as "dirname1" or "dirname1\dirname2". +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_FILE_NO_CARD, no sd card. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH , filename too length. +* QL_RET_ERR_FILEFAILED, fail to operate file. +* QL_RET_ERR_FILENOTFOUND, file not found. +* Notes: +* Don't support to check directory in the RAM. +******************************************************************************/ +s32 Ql_FS_CheckDir(char *lpDirName); + + +/****************************************************************************** +* Function: Ql_FS_FindFirst +* +* Description: +* This function searches a directory for a file or subdirectory +* whose name matches the specified file name. +* +* Parameters: +* lpPath: +* [in] Point to a null-terminated string that specifies a valid directory or path. +* +* lpFileName: +* [in] Point to a null-terminated string that specifies a valid file name, +* which can contain wildcard characters, such as * and ?. +* +* fileNameLength: +* [in] The maximum number of bytes to be received of the name. +* +* fileSize: +* [out] A pointer to the variable which represents the size specified by the file. +* +* isDir: +* [out] A pointer to the variable which represents the type specified by the file. +* Return: +* If the function succeeds, the return value is a search handle +* that can be used in a subsequent call to the "Ql_FindNextFile" or "Ql_FindClose" function. +* If the function fails, the return value is an error codes.: +* QL_RET_ERR_FILE_NO_CARD, no sd card. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH , filename too length. +* QL_RET_ERR_FILEFAILED, fail to operate file. +* QL_RET_ERR_FILENOMORE, no more file. +* +* QL_RET_ERR_FS_FATAL_ERR1 indicates some fatal error happens to +* the file system. Develops may call Ql_GetLastErrorCode() to +* retrieve the inner error code. And develops can call Ql_Fs_Format(QL_FS_FAT) +* to format FAT to retore the file system. +******************************************************************************/ +s32 Ql_FS_FindFirst(char *lpPath, char *lpFileName, u32 fileNameLength, u32 *fileSize, bool *isDir); + +/****************************************************************************** +* Function: Ql_FS_FindNext +* +* Description: +* Continues a file search from a previous call to the Ql_FS_FindFirst +* function. +* +* Parameters: +* handle: +* [in] Search handle returned by a previous call to the Ql_FS_FindFirst +* +* lpFileName: +* [in] Point to a null-terminated string that specifies a valid file name, +* which can contain wildcard characters, such as * and ?. +* +* fileNameLength: +* [in] The maximum number of bytes to be received of the name. +* +* fileSize: +* [out] A pointer to the variable which represents the size specified by the file. +* +* isDir: +* [out] A pointer to the variable which represents the type specified by the file. +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILEFAILED, fail to operate file. +* QL_RET_ERR_FILENOMORE, file not found. +* +* QL_RET_ERR_FS_FATAL_ERR1 indicates some fatal error happens to +* the file system. Develops may call Ql_GetLastErrorCode() to +* retrieve the inner error code. And develops can call Ql_Fs_Format(QL_FS_FAT) +* to format FAT to retore the file system. +******************************************************************************/ +s32 Ql_FS_FindNext(s32 handle, char *lpFileName, u32 fileNameLength, u32 *fileSize, bool *isDir); + + +/****************************************************************************** +* Function: Ql_FS_FindClose +* +* Description: +* Closes the specified search handle. +* +* Parameters: +* handle: +* [in] Find handle, +* returned by a previous call of the Ql_FS_FindFirst function. +* Return: +* None +******************************************************************************/ +void Ql_FS_FindClose(s32 handle); + + +/****************************************************************************** +* Function: Ql_FS_XDelete +* +* Description: +* Delete a file or directory. +* +* Parameters: +* lpPath: +* [in] File path to be deleted +* +* flag: +* [in] A u32 that defines the file's opening and access mode. +* The possible values are shown as follow: +* QL_FS_FILE_TYPE, +* QL_FS_DIR_TYPE, +* QL_FS_RECURSIVE_TYPE +* +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH, filename too length. +* QL_RET_ERR_FILENOTFOUND, file not found. +* QL_RET_ERR_PATHNOTFOUND, path not found. +* QL_RET_ERR_GET_MEM, fail to get memory. +* QL_RET_ERR_GENERAL_FAILURE, general failture. +******************************************************************************/ +s32 Ql_FS_XDelete(char* lpPath, u32 flag); + + +/****************************************************************************** +* Function: Ql_FS_XMove +* +* Description: +* This function provides a facility to move/copy a file or folder +* +* Parameters: +* lpSrcPath: +* [in] Source path to be moved/copied +* +* lpDestPath: +* [in] Destination path +* +* flag: +* [in] A u32 that defines the file's opening and access mode. +* The possible values are shown as follow: +* QL_FS_MOVE_COPY, +* QL_FS_MOVE_KILL, +* QL_FS_MOVE_OVERWRITE +* +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH, filename too length. +* QL_RET_ERR_FILENOTFOUND, file not found. +* QL_RET_ERR_PATHNOTFOUND, path not found. +* QL_RET_ERR_GET_MEM, fail to get memory. +* QL_RET_ERR_FILE_EXISTS, file existed. +* QL_RET_ERR_GENERAL_FAILURE, general failture. +******************************************************************************/ +s32 Ql_FS_XMove(char* lpSrcPath, char* lpDestPath, u32 flag); + + +/****************************************************************************** +* Function: Ql_FS_GetFreeSpace +* +* Description: +* This function obtains the amount of free space on Flash or SD card. +* +* Parameters: +* storage: +* [in]The type of storage, which is one value of "Enum_FSStorage". +* typedef enum +* { +* Ql_FS_UFS = 1, +* Ql_FS_SD = 2, +* Ql_FS_RAM = 3, +* } Enum_FSStorage; +* +* Return: +* The return value is the total number of bytes of the free space +* in the specified storage, if this function succeeds. Otherwise, +* the return value is an error code. +* Ql_RET_ERR_UNKOWN, unkown error. +* +* QL_RET_ERR_FS_FATAL_ERR1 indicates some fatal error happens to +* the file system. Develops may call Ql_GetLastErrorCode() to +* retrieve the inner error code. And develops can call Ql_Fs_Format(QL_FS_FAT) +* to format FAT to retore the file system. +******************************************************************************/ +s64 Ql_FS_GetFreeSpace (u32 storage); + + +/****************************************************************************** +* Function: Ql_FS_GetTotalSpace +* +* Description: +* This function obtains the amount of total space on Flash or SD card. +* +* Parameters: +* storage: +* [in]The type of storage, which is one value of "Enum_FSStorage". +* typedef enum +* { +* Ql_FS_UFS = 1, +* Ql_FS_SD = 2, +* Ql_FS_RAM = 3, +* } Enum_FSStorage; +* +* Return: +* The return value is the total number of bytes in the specified +* storage, if this function succeeds. Otherwise, the return value +* is an error code. +* Ql_RET_ERR_UNKOWN, unkown error. +* +* QL_RET_ERR_FS_FATAL_ERR1 indicates some fatal error happens to +* the file system. Develops may call Ql_GetLastErrorCode() to +* retrieve the inner error code. And develops can call Ql_Fs_Format(QL_FS_FAT) +* to format FAT to retore the file system. +******************************************************************************/ +s64 Ql_FS_GetTotalSpace(u32 storage); + + +/****************************************************************************** +* Function: Ql_Fs_Format +* +* Description: +* This function format the SD card or UFS +* +* Parameters: +* storage: +* [in]The type of storage, which is one value of "Enum_FSStorage". +* +* storage: can be one of the following values: +* Ql_FS_UFS, // delete all existing files in UFS +* Ql_FS_SD, // delete all existing data in SD card +* QL_FS_FAT // format the whole file system, which takes tens of seconds. +* +* Return: +* QL_RET_OK, success. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_FILENAMETOOLENGTH, filename too length. +* QL_RET_ERR_FILENOTFOUND, file not found. +* QL_RET_ERR_PATHNOTFOUND, path not found. +* QL_RET_ERR_GET_MEM, fail to get memory. +* QL_RET_ERR_GENERAL_FAILURE, general failture. +* QL_RET_ERR_FILE_NO_CARD, no sd card +* QL_RET_ERR_FILEFAILED, fail to operate file. +******************************************************************************/ +s32 Ql_FS_Format(u8 storage); + +#endif //__QL_FS_H__ diff --git a/cores/opencpu/include/ql_gpio.h b/cores/opencpu/include/ql_gpio.h new file mode 100644 index 0000000..e7c7fc5 --- /dev/null +++ b/cores/opencpu/include/ql_gpio.h @@ -0,0 +1,244 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_gpio.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * GPIO API defines. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_GPIO_H__ +#define __QL_GPIO_H__ + +/**************************************************************************** + * Enumeration for GPIO Pins available. + ***************************************************************************/ +typedef enum{ + PINNAME_NETLIGHT = 0, + PINNAME_DTR, + PINNAME_RI, + PINNAME_DCD, + PINNAME_CTS, + PINNAME_RTS, + PINNAME_RXD_AUX, + PINNAME_TXD_AUX, + PINNAME_PCM_CLK, + PINNAME_PCM_SYNC, + PINNAME_PCM_IN, + PINNAME_PCM_OUT, + PINNAME_RFTXMON, + PINNAME_END +}Enum_PinName; + +typedef enum{ + PINDIRECTION_IN = 0, + PINDIRECTION_OUT = 1 +}Enum_PinDirection; + +typedef enum{ + PINLEVEL_LOW = 0, + PINLEVEL_HIGH = 1 +}Enum_PinLevel; + +typedef enum{ + PINPULLSEL_DISABLE = 0, // Disable pull selection + PINPULLSEL_PULLDOWN = 1, // Pull-down + PINPULLSEL_PULLUP = 2 // Pull-up +}Enum_PinPullSel; + + +/**************************************************************************** + * GPIO Config Items + ***************************************************************************/ +typedef struct{ + Enum_PinName pinName; + Enum_PinDirection pinDirection; + Enum_PinLevel pinLevel; + Enum_PinPullSel pinPullSel; +}ST_GPIOConfig; + +/***************************************************************** +* Function: Ql_GPIO_Init +* +* Description: +* This function enables the GPIO function of the specified pin, +* and initialize the configurations, including direction, +* level and pull selection. +* +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* dir: +* The initial direction of GPIO, one value of Enum_PinDirection. +* level: +* The initial level of GPIO, one value of Enum_PinLevel. +* pullSel: +* Pull selection, one value of Enum_PinPullSel. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +* QL_RET_ERR_PINALREADYSUBCRIBE, the GPIO is in use in +* other place. For example this GPIO has been using as EINT. +*****************************************************************/ +s32 Ql_GPIO_Init(Enum_PinName pinName, + Enum_PinDirection dir, + Enum_PinLevel level, + Enum_PinPullSel pullSel + ); + +/***************************************************************** +* Function: Ql_GPIO_SetLevel +* +* Description: +* This function sets the level of the specified GPIO. +* +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* level: +* The initial level of GPIO, one value of Enum_PinLevel. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +* QL_RET_ERR_NORIGHTOPERATE, can't operate,Maybe the GPIO not Init +* QL_RET_ERR_NOGPIOMODE, the input GPIO is not GPIO mode +*****************************************************************/ +s32 Ql_GPIO_SetLevel(Enum_PinName pinName, Enum_PinLevel level); + +/***************************************************************** +* Function: Ql_GPIO_GetLevel +* +* Description: +* This function gets the level of the specified GPIO. +* +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* Return: +* The level value of the specified GPIO, which is +* nonnegative integer. +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +*****************************************************************/ +s32 Ql_GPIO_GetLevel(Enum_PinName pinName); + +/***************************************************************** +* Function: Ql_GPIO_SetDirection +* +* Description: +* This function sets the direction of the specified GPIO. +* +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* dir: +* The initial direction of GPIO, one value of Enum_PinDirection. +* Return: +* QL_RET_OK indicates this function successes. +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +* QL_RET_ERR_NORIGHTOPERATE, can't operate,Maybe the GPIO not Init +* QL_RET_ERR_NOGPIOMODE, the input GPIO is not GPIO mode +*****************************************************************/ +s32 Ql_GPIO_SetDirection(Enum_PinName pinName, Enum_PinDirection dir); + +/***************************************************************** +* Function: Ql_GPIO_GetDirection +* +* Description: +* This function gets the direction of the specified GPIO. +* +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* Return: +* The direction of the specified GPIO, which is +* nonnegative integer.. +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +* QL_RET_ERR_NORIGHTOPERATE, can't operate,Maybe the GPIO not Init +* QL_RET_ERR_NOGPIOMODE, the input GPIO is not GPIO mode +*****************************************************************/ +s32 Ql_GPIO_GetDirection(Enum_PinName pinName); + +/***************************************************************** +* Function: Ql_GPIO_SetPullSelection +* +* Description: +* This function sets the pull selection of the specified GPIO. +* +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* Enum_PinPullSel: +* Pull selection, one value of Enum_PinPullSel. +* Return: +* QL_RET_OK indicates this function successes. +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +* QL_RET_ERR_NORIGHTOPERATE, can't operate,Maybe the GPIO not Init +* QL_RET_ERR_NOGPIOMODE, the input GPIO is not GPIO mode +*****************************************************************/ +s32 Ql_GPIO_SetPullSelection(Enum_PinName pinName, Enum_PinPullSel pullSel); + +/***************************************************************** +* Function: Ql_GPIO_GetPullSelection +* +* Description: +* This function gets the pull selection of the specified GPIO. +* +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* Enum_PinPullSel: +* Pull selection, one value of Enum_PinPullSel. +* Return: +* The pull selection, which is nonnegative integer. +* if successes return one value of Enum_PinPullSel. +* else return +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +* QL_RET_ERR_NORIGHTOPERATE, can't operate,Maybe the GPIO not Init +* QL_RET_ERR_NOGPIOMODE, the input GPIO is not GPIO mode +*****************************************************************/ +s32 Ql_GPIO_GetPullSelection(Enum_PinName pinName); + +/***************************************************************** +* Function: Ql_GPIO_Uninit +* +* Description: +* This function releases the specified GPIO that was +* initialized by calling Ql_GPIO_Init() previously. +* After releasing, the GPIO can be used for other purpose. +* Parameters: +* pinName: +* Pin name, one value of Enum_PinName. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_NOSUPPORTPIN, the input GPIO is invalid. +* QL_RET_ERR_BUSSUBBUSY, the GPIO not used as GPIO, +* Maby is used by IIC or SPI,this function can't release it +*****************************************************************/ +s32 Ql_GPIO_Uninit(Enum_PinName pinName); + +#endif // __QL_GPIO_H__ diff --git a/cores/opencpu/include/ql_gprs.h b/cores/opencpu/include/ql_gprs.h new file mode 100644 index 0000000..905651e --- /dev/null +++ b/cores/opencpu/include/ql_gprs.h @@ -0,0 +1,600 @@ + +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_gprs.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * GPRS APIs definition. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_GPRS_H__ +#define __QL_GPRS_H__ + +#define MAX_GPRS_USER_NAME_LEN 32 +#define MAX_GPRS_PASSWORD_LEN 32 +#define MAX_GPRS_APN_LEN 100 + + +typedef struct { + void (*Callback_GPRS_Actived)(u8 contexId, s32 errCode, void* customParam); + void (*CallBack_GPRS_Deactived)(u8 contextId, s32 errCode, void* customParam ); +}ST_PDPContxt_Callback; + +typedef struct { + u8 apnName[MAX_GPRS_APN_LEN]; + u8 apnUserId[MAX_GPRS_USER_NAME_LEN]; + u8 apnPasswd[MAX_GPRS_PASSWORD_LEN]; + u8 authtype; // pap or chap + void* Reserved1; // Qos + void* Reserved2; // +} ST_GprsConfig; + + +typedef enum { + GPRS_PDP_SUCCESS = 0, + GPRS_PDP_ERROR = -1, + GPRS_PDP_WOULDBLOCK = -2, + GPRS_PDP_ALREADY = -7, /* operation already in progress */ + GPRS_PDP_INVAL = -10, /* invalid argument */ + GPRS_PDP_BEARER_FAIL = -14, /* bearer is broken */ +} Enum_GPRS_PDPError; + + +/***************************************************************** +* Function: Ql_GPRS_GetPDPContextId +* +* Description: +* This function retrieves an available PDP context Id, +* which can be 0 or 1. +* +* Parameters: +* None. +* Return: +* 0 or 1 is returned if this function succeeds. +* GPRS_PDP_ERROR indicates this function fails, or no +* PDP context Id is available. +*****************************************************************/ +s32 Ql_GPRS_GetPDPContextId(void); + +/***************************************************************** +* Function: Ql_GPRS_Register +* +* Description: +* This function registers the GPRS related callback functions. +* +* Parameters: +* contextId: +* Module supports two PDP-context. It can be 0 or 1. +* User may call Ql_GPRS_GetPDPContextId to get an available PDP context Id. +* Within each PDP context, 6 socket links can be created. +* +* callback_func: +* A group of callback functions, including GPRS activate and deactivate, which +* is implemented by Embedded Application and is invoked by Core System. +* +* customParam: +* A customized parameter, which can be used in the callback function. +* It may be NULL if no customized parameter needs to be passed in. +* Return: +* GPRS_PDP_SUCCESS: +* This function succeeds. +* +* GPRS_PDP_INVAL: +* Invalid argument. +* +* GPRS_PDP_ALREADY: +* The GPRS network is already initialized. +*****************************************************************/ +s32 Ql_GPRS_Register(u8 contextId, ST_PDPContxt_Callback * callback_func, void* customParam); + +/***************************************************************** +* Function: Ql_GPRS_Config +* +* Description: +* This function configures GPRS parameters, including +* APN name, user name, password and authentication type +* for the specified PDP context. +* +* Parameters: +* contextId: +* PDP context id, which can be 0 or 1. +* +* cfg: +* PDP configuration structure. +* +* Return: +* GPRS_PDP_SUCCESS: +* This function succeeds. +* +* GPRS_PDP_INVAL: +* Invalid argument. +*====================== +* Example: +*====================== +* Take "China Mobile" for example, the APN name for public +* subscribers is "CMNET", and the user name and password are +* not necessary. So developer can configure GPRS as below: +* { +* ST_GprsConfig gprsCfg; +* Ql_strcpy(gprsCfg.apnName, "CMNET\0"); +* Ql_memset(gprsCfg.apnUserId, 0x0, sizeof(gprsCfg.apnUserId)); +* Ql_memset(gprsCfg.apnPasswd, 0x0, sizeof(gprsCfg.apnPasswd)); +* gprsCfg.authtype = 0; +* gprsCfg.Reserved1 = 0; +* gprsCfg.Reserved2 = 0; +* Ql_GPRS_Config(0, &gprsCfg); +* } +*****************************************************************/ +s32 Ql_GPRS_Config(u8 contextId, ST_GprsConfig* cfg); + +/***************************************************************** +* Function: Ql_GPRS_Activate +* +* Description: +* This function activates the specified PDP context. +* The maximum possible time for Activating GPRS is 180s. +* Parameters: +* contextId: +* PDP context id, which can be 0 or 1. +* +* Return: +* GPRS_PDP_SUCCESS: +* This function succeeds, and activating GPRS succeeds. +* +* GPRS_PDP_WOULDBLOCK: +* The app should wait, till the callback function is called. +* The app gets the information of success or failure in callback function. +* The maximum possible time for Activating GPRS is 180s. +* +* GPRS_PDP_INVAL: +* Invalid argument. +* +* GPRS_PDP_ALREADY: +* The activating operation is in process. +* +* GPRS_PDP_BEARER_FAIL: +* Bearer is broken. +*====================== +* Example: +*====================== +* The following codes show the activating GPRS processing. +* { +* s32 ret; +* ret = Ql_GPRS_Activate(0); +* if (GPRS_PDP_SUCCESS == ret) +* { +* // Activate GPRS successfully +* } +* else if (GPRS_PDP_WOULDBLOCK == ret) +* { +* // Activating GPRS, need to wait Callback_GPRS_Actived for the result +* } +* else if (GPRS_PDP_ALREADY == ret) +* { +* // GPRS has been activating... +* }else{ +* // Fail to activate GPRS, error code is in "ret". +* // Developer may retry to activate GPRS, and reset the module after 3 successive failures. +* } +* } +*****************************************************************/ +s32 Ql_GPRS_Activate(u8 contextId); + +/***************************************************************** +* Function: Ql_GPRS_ActivateEx +* +* Description: +* This function activates the specified PDP context. +* The maximum possible time for Activating GPRS is 180s. +* +* This function supports two modes: +* 1. non-blocking mode +* When the "isBlocking" is set to FALSE, this function works +* under non-blocking mode. The result will be returned even if +* the operation is not done, and the result will be reported in callback. +* 2. blocking mode +* When the "isBlocking" is set to TRUE, this function works +* under blocking mode. The result will be returned only after the operation is done. +* +* If working under non-blocking mode, this function is same as +* Ql_GPRS_Activate() functionally. +* Parameters: +* contextId: +* PDP context id, which can be 0 or 1. +* +* isBlocking: +* blocking mode. TRUE=blocking mode, FALSE=non-blocking mode. +* +* Return: +* GPRS_PDP_SUCCESS: +* This function succeeds, and activating GPRS succeeds. +* +* GPRS_PDP_INVAL: +* Invalid argument. +* +* GPRS_PDP_ALREADY: +* The activating operation is in process. +* +* GPRS_PDP_BEARER_FAIL: +* Bearer is broken. +*====================== +* Example: +*====================== +* The following codes show the activating GPRS processing. +* { +* s32 ret; +* ret = Ql_GPRS_Activate(0, TRUE); +* if (GPRS_PDP_SUCCESS == ret) +* { +* // Activate GPRS successfully +* } +* else if (GPRS_PDP_ALREADY == ret) +* { +* // GPRS has been activating... +* }else{ +* // Fail to activate GPRS, error code is in "ret". +* // Developer may retry to activate GPRS, and reset the module after 3 successive failures. +* } +* } +*****************************************************************/ +s32 Ql_GPRS_ActivateEx(u8 contextId, bool isBlocking); + +/***************************************************************** +* Function: Ql_GPRS_Deactivate +* +* Description: +* This function deactivates the specified PDP context. +* The maximum possible time for Activating GPRS is 90s. +* +* Parameters: +* contextId: +* PDP context id that is specified when calling Ql_GPRS_Activate, +* which can be 0 or 1. +* +* Return: +* GPRS_PDP_SUCCESS: +* This function succeeds, and deactivating GPRS succeeds. +* +* GPRS_PDP_WOULDBLOCK: +* The app should wait, till the callback function is called. +* The app gets the information of success or failure in callback function. +* The maximum possible time for Activating GPRS is 90s. +* +* GPRS_PDP_INVAL: +* Invalid argument. +* +* GPRS_PDP_ERROR +* GPRS is not in active state, or other error. +* +*====================== +* Example: +*====================== +* The following codes show the deactivating GPRS processing. +* { +* s32 ret; +* ret = Ql_GPRS_Deactivate(0); +* if (GPRS_PDP_SUCCESS == ret) +* { +* // GPRS is deactivated successfully +* } +* else if (GPRS_PDP_WOULDBLOCK == ret) +* { +* // Deactivating GPRS, need to wait Callback_GPRS_Deactived for the result +* }else{ +* // Fail to activate GPRS, error code is in "ret". +* } +* } +*****************************************************************/ +s32 Ql_GPRS_Deactivate(u8 contextId); + + +/***************************************************************** +* Function: Ql_GPRS_DeactivateEx +* +* Description: +* This function deactivates the specified PDP context. +* The maximum possible time for Activating GPRS is 90s. +* +* This function supports two modes: +* 1. non-blocking mode +* When the "isBlocking" is set to FALSE, this function works +* under non-blocking mode. The result will be returned even if +* the operation is not done, and the result will be reported in callback. +* 2. blocking mode +* When the "isBlocking" is set to TRUE, this function works +* under blocking mode. The result will be returned only after the operation is done. +* +* If working under non-blocking mode, this function is same as +* Ql_GPRS_Deactivate() functionally. +* Parameters: +* contextId: +* PDP context id that is specified when calling Ql_GPRS_Activate, +* which can be 0 or 1. +* +* isBlocking: +* blocking mode. TRUE=blocking mode, FALSE=non-blocking mode. +* +* Return: +* GPRS_PDP_SUCCESS: +* This function succeeds, and activating GPRS succeeds. +* +* GPRS_PDP_INVAL: +* Invalid argument. +* +* GPRS_PDP_ALREADY: +* The activating operation is in process. +* +* GPRS_PDP_BEARER_FAIL: +* Bearer is broken. +*====================== +* Example: +*====================== +* The following codes show the deactivating GPRS processing. +* { +* s32 ret; +* ret = Ql_GPRS_Deactivate(0, TRUE); +* if (GPRS_PDP_SUCCESS == ret) +* { +* // GPRS is deactivated successfully +* }else{ +* // Fail to activate GPRS, error code is in "ret". +* } +* } +*****************************************************************/ +s32 Ql_GPRS_DeactivateEx(u8 contextId, bool isBlocking); + +/***************************************************************** +* Function: Ql_GPRS_GetLocalIPAddress +* +* Description: +* This function retrieves local IP corresponding +* to the specified PDP context. +* +* Parameters: +* contextId: +* [in] PDP context id that is specified when calling Ql_GPRS_Activate, +* which can be 0 or 1. +* +* ipAddr: +* [out] Pointer to the buffer that stores the local +* IPv4 address. +* +* Return: +* GPRS_PDP_SUCCESS: +* This function succeeds. +* +* GPRS_PDP_INVAL: +* Invalid argument. +* +* GPRS_PDP_BEARER_FAIL: +* Bearer is broken. +*====================== +* Example: +*====================== +* The following codes show the deactivating GPRS processing. +* { +* s32 ret; +* u8 ip_addr[4]; +* Ql_memset(ip_addr, 0, sizeof(ip_addr)); +* ret = Ql_GPRS_GetLocalIPAddress(0, (u32 *)ip_addr); +* if (GPRS_PDP_SUCCESS == ret) +* { +* Ql_Debug_Trace("<-- Get Local Ip successfully,Local Ip=%d.%d.%d.%d -->\r\n", +* ip_addr[0],ip_addr[1],ip_addr[2],ip_addr[3]); +* }else{ +* // Fail to get Local Ip address. +* } +* } +*****************************************************************/ +s32 Ql_GPRS_GetLocalIPAddress(u8 contextId, u32* ipAddr); + + +/***************************************************************** +* Function: Ql_GPRS_GetDNSAddress +* +* Description: +* This function retrieves the DNS server's IP address. +* +* Parameters: +* contextId: +* [in] PDP context id that is specified when calling Ql_GPRS_Activate, +* which can be 0 or 1. +* +* firstAddr: +* [out] Point to the buffer that stores the primary +* DNS server's IP address. +* +* secondAddr: +* [out] Point to the buffer that stores the secondary +* DNS server's IP address. +* +* Return: +* GPRS_PDP_SUCCESS: +* This function succeeds. +* +* GPRS_PDP_INVAL: +* Invalid argument. +* +* GPRS_PDP_BEARER_FAIL: +* Bearer is broken. +*====================== +* Example: +*====================== +* The following codes show how to get DNS IP address. +* { +* s32 ret; +* u8 ipAddr_1st[4]; +* u8 ipAddr_2st[4]; +* Ql_memset(ip_addr, 0, sizeof(ipAddr_1st)); +* Ql_memset(ip_addr, 0, sizeof(ipAddr_2st)); +* ret = Ql_GPRS_GetDNSAddress(0, (u32*)ipAddr_1st, (u32*)ipAddr_2st); +* if (GPRS_PDP_SUCCESS == ret) +* { +* Ql_Debug_Trace("<-- Get DNS address successfully,first DNS Addr=%d.%d.%d.%d, second DNS Addr=%d.%d.%d.%d -->\r\n", +* ipAddr_1st[0],ipAddr_1st[1],ipAddr_1st[2],ipAddr_1st[3],ipAddr_2st[0],ipAddr_2st[1],ipAddr_2st[2],ipAddr_2st[3]); +* } +* else +* { +* // Fail to get DNS address. +* } +* } +*****************************************************************/ +s32 Ql_GPRS_GetDNSAddress(u8 contextId, u32* firstAddr, u32* secondAddr); + + +/***************************************************************** +* Function: Ql_GPRS_SetDNSAddress +* +* Description: +* This function sets the DNS server's IP address. +* +* Parameters: +* contextId: +* [in] PDP context id that is specified when calling Ql_GPRS_Activate, +* which can be 0 or 1. +* +* firstAddr: +* [in] A u32 integer that stores the IPv4 address of the first DNS server. +* +* secondAddr: +* [in] A u32 integer that stores the IPv4 address of the second DNS server. +* +* Return: +* GPRS_PDP_SUCCESS: +* This function succeeds. +* +* GPRS_PDP_INVAL: +* Invalid argument. +* +* GPRS_PDP_BEARER_FAIL: +* Bearer is broken. +*====================== +* Example: +*====================== +* The following codes show how to set DNS IP address. +* { +* s32 ret; +* u32 ip_dns1[5]; +* u32 ip_dns2[5]; +* u8 ipAddr_1st[4] = {208, 67, 222, 222}; +* u8 ipAddr_2st[4] = {8, 8, 8, 8}; +* +* Ql_memset(ip_dns1,0,5); +* Ql_memset(ip_dns2,0,5); +* Ql_IpHelper_ConvertIpAddr(ipAddr_1st, ip_dns1); +* Ql_IpHelper_ConvertIpAddr(ipAddr_2st, ip_dns2); +* ret = Ql_GPRS_SetDNSAddress(0, ip_dns1, ip_dns2); +* if (GPRS_PDP_SUCCESS == ret) +* { +* // Set DNS IP address successfully +* } +* else +* { +* // Fail to set DNS IP address. +* } +* } +******************************************************************/ +s32 Ql_GPRS_SetDNSAddress(u8 contextId, u32 firstAddr, u32 secondAddr); + +/***************************************************************** +* Function: Callback_GPRS_Active +* +* Description: +* This callback function is invoked by Ql_GPRS_Activate() +* when the return value of Ql_GPRS_Activate() is GPRS_PDP_WOULDBLOCK . +* +* Parameters: +* contextId: +* [out] PDP context id that is specified when calling Ql_GPRS_Activate, +* which can be 0 or 1. +* +* errCode: +* Error code, refer to Enum_GPRS_PDPError. It indicates activating GPRS +* successfully when it's equal to GPRS_PDP_SUCCESS. +* +* customParam: +* The customized parameter, which is passed in by calling Ql_GPRS_Activate(). +* Return: +* None. +*====================== +* Example: +*====================== +* The following code is a possible implementation for Callback_GPRS_Actived. +* void Callback_GPRS_Actived(u8 contexId, s32 errCode, void* customParam) +* { +* if(GPRS_PDP_SUCCESS == errCode) +* { +* // Activate GPRS successfully +* }else{ +* // Fail to activate GPRS +* } +* } +*****************************************************************/ +typedef void (*Callback_GPRS_Active)(u8 contextId, s32 errCode, void* customParam); + + +/***************************************************************** +* Function: CallBack_GPRS_Deactive +* +* Description: +* This callback function is invoked by Ql_GPRS_Deactivate() +* when the return value of Ql_GPRS_Deactivate() is GPRS_PDP_WOULDBLOCK. +* +* Besides, this callback function will be invoked when GPRS drops down. +* +* Parameters: +* contextId: +* [in] OpenCPU supports two PDP-contexts to the destination +* host at a time. This parameter can be 0 or 1. +* +* errCode: +* Error code, refer to Enum_GPRS_PDPError. It indicates activating GPRS +* successfully when it's equal to GPRS_PDP_SUCCESS. +* +* customParam: +* The customized parameter, which is passed in by calling Ql_GPRS_Activate(). +* Return: +* None. +*====================== +* Example: +*====================== +* The following code is a possible implementation for Callback_GPRS_Actived. +* void CallBack_GPRS_Deactived(u8 contexId, s32 errCode, void* customParam) +* { +* if(GPRS_PDP_SUCCESS == errCode) +* { +* // Deactivate GPRS successfully +* }else{ +* // Fail to deactivate GPRS +* } +* } +*****************************************************************/ +typedef void (*CallBack_GPRS_Deactive)(u8 contextId, s32 errCode, void* customParam); + +#endif //__QL_GPRS_H__ diff --git a/cores/opencpu/include/ql_iic.h b/cores/opencpu/include/ql_iic.h new file mode 100644 index 0000000..cef0ab8 --- /dev/null +++ b/cores/opencpu/include/ql_iic.h @@ -0,0 +1,194 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_ii.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * IIC interface APIs defines. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __QL_IIC_H__ +#define __QL_IIC_H__ + + +/***************************************************************** +* Function: Ql_IIC_Init +* +* Description: +* This function initialize the configurations for an IIC channel. +* including the specified pins for IIC, IIC type, and IIC channel No. +* +* Parameters: +* chnnlNo: +* [In] IIC channel No, the range is 0~254 +* pinSCL: +* [In] IIC SCL pin. +* pinSDA: +* [In] IIC SDA pin. +* IICtype: +* [In] IIC type,FALSE means simulate IIC, TRUE means hardware IIC. + +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_CHANNEL_OUTRANGE, the channel No is out of range. +* QL_RET_ERR_CHANNEL_USED, the channel No is be used. +* QL_RET_ERR_FULLI2CBUS, IIC bus is full. +* QL_RET_ERR_NOSUPPORTPIN, the input pin is invalid. +* QL_RET_ERR_PINALREADYSUBCRIBE, the pin is in use in +* other place. For example this pin has been using as EINT or gpio. +* QL_RET_ERR_I2CHWFAILED, Maybe the hardware have something wrong. +* QL_RET_ERR_PARAM, IICtype error , or the IICtype = 1, +* but the pinSCL and pinSDA pins are not IIC contronller pins +*****************************************************************/ +s32 Ql_IIC_Init(u32 chnnlNo, Enum_PinName pinSCL, Enum_PinName pinSDA, bool IICtype); + +/***************************************************************** +* Function: Ql_IIC_Config +* +* Description: +* This function configuration the IIC interface for one slave. +* +* Parameters: +* chnnlNo: +* [In] IIC channel No, the No is specified by Ql_IIC_Init function +* isHost: +* [In] must be ture, just support host mode. +* slaveAddr: +* [In] slave address. +* IicSpeed: +* [In] just used for hardware IIC,and the parameter can be ignored when using simulation IIC. +* For hardware IIC, It supports fast mode and high speed mode. the speed of fast speed mode +* is less than 400 kbps, and the speed of high speed mode is [400..3400] kbps. +* +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_CHANNEL_NOT_FOUND, can't found the IIC channel, make sure it is initialized already. +* QL_RET_ERR_IIC_SAME_SLAVE_ADDRESS,the slave address you want to set is already be set,or the address is be used. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_IIC_SLAVE_TOO_MANY, there too many slave in this channel.(one channel at most support 6 slave) +*****************************************************************/ +s32 Ql_IIC_Config(u32 chnnlNo, bool isHost, u8 slaveAddr, u32 IicSpeed); + + +/***************************************************************** +* Function: Ql_IIC_Write +* +* Description: +* This function write data to specified slave through IIC interface. +* +* Parameters: +* chnnlNo: +* [In] IIC channel No, the No is specified by Ql_IIC_Init function. +* slaveAddr: +* [In] slave address. +* pData: +* [In] Setting value to slave +* len: +* [In] Number of bytes to write. +* if IICtype=1 ,1 rdLen) , the other read buffer data will be set 0xff; +* if (rdLen > wrtLen) , the other write buffer data will be set 0xff; +* Return: +* if no error, return the length of the read data. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_CHANNEL_NOT_FOUND, can't found the SPI channel, make sure it is initialized already. +*****************************************************************/ +s32 Ql_SPI_WriteRead(u32 chnnlNo, u8 *pData, u32 wrtLen, u8 * pBuffer, u32 rdLen); +/***************************************************************** +* Function: Ql_SPI_WriteRead_Ex +* +* Description: +* This function is used for SPI full-duplex communication. +* +* Parameters: +* chnnlNo: +* [In] SPI channel No, the No is specified by Ql_SPI_Init function. +* pData: +* [In] Setting value to slave. +* wrtLen: +* [In] Number of bytes to write. +* pBuffer: +* [Out] read buffer of reading from slave. +* rdLen: +* [In] Number of bytes to read. +* +* Notes: +* if (wrtLen > rdLen) , the other read buffer data will be set 0xff; +* if (rdLen > wrtLen) , the other write buffer data will be set 0xff; +* Return: +* if no error, return 0. +* QL_RET_ERR_PARAM, parameter error. +* QL_RET_ERR_CHANNEL_NOT_FOUND, can't found the SPI channel, make sure it is initialized already. +*****************************************************************/ +s32 Ql_SPI_WriteRead_Ex(u32 chnnlNo, u8 *pData, u32 wrtLen, u8 * pBuffer, u32 rdLen); + +/***************************************************************** +* Function: Ql_SPI_Uninit +* +* Description: +* This function release the SPI pins. +* +* Parameters: +* chnnlNo: +* [In] SPI channel No, the No is specified by Ql_SPI_Init function. + +* Return: +* if no error return the length of the read data. +* QL_RET_ERR_CHANNEL_NOT_FOUND, can't found the SPI channel, make sure it is initialized already. +* QL_RET_ERR_ALREADYUNSUBCRIBE, is released already +*****************************************************************/ +s32 Ql_SPI_Uninit(u32 chnnlNo); + +#endif //__QL_SPI_H__ diff --git a/cores/opencpu/include/ql_stdlib.h b/cores/opencpu/include/ql_stdlib.h new file mode 100644 index 0000000..dd81d73 --- /dev/null +++ b/cores/opencpu/include/ql_stdlib.h @@ -0,0 +1,60 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_stdlib.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * this file provides some Standard library APIs + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_STDLIB_H__ +#define __QL_STDLIB_H__ +#include "ql_type.h" + +s32 Ql_atoi(const char* s); +double Ql_atof(const char* s); +void* Ql_memset(void* dest, u8 value, u32 size); +void* Ql_memcpy(void* dest, const void* src, u32 size); +s32 Ql_memcmp(const void* dest, const void*src, u32 size); +void* Ql_memmove(void* dest, const void* src, u32 size); +char* Ql_strcpy(char* dest, const char* src); +char* Ql_strncpy(char* dest, const char* src, u32 size); +char* Ql_strcat(char* s1, const char* s2); +char* Ql_strncat(char* s1, const char* s2, u32 size); +s32 Ql_strcmp(const char*s1, const char*s2); +s32 Ql_strncmp(const char* s1, const char* s2, u32 size); +char* Ql_strchr(const char* s1, s32 ch); +u32 Ql_strlen(const char* str); +char* Ql_strstr(const char* s1, const char* s2); +s32 Ql_toupper(s32 c); +s32 Ql_tolower(s32 c); +s32 Ql_isdigit(char c); +extern s32 (*Ql_sprintf)(char *, const char *, ...); +extern s32 (*Ql_snprintf)(char *, u32, const char *, ...); +extern s32 (*Ql_sscanf)(const char*, const char*, ...); +#endif // __QL_STDLIB_H__ diff --git a/cores/opencpu/include/ql_system.h b/cores/opencpu/include/ql_system.h new file mode 100644 index 0000000..3055fef --- /dev/null +++ b/cores/opencpu/include/ql_system.h @@ -0,0 +1,769 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_system.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * System related APIs + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_SYSTEM_H__ +#define __QL_SYSTEM_H__ +#include "ql_common.h" +#include "ql_type.h" +#include "ql_memory.h" + + +/************************************************************** + * Message Structure Definition + **************************************************************/ +typedef struct { + u32 message; + u32 param1; + u32 param2; + u32 srcTaskId; +} ST_MSG; + +/************************************************************** + * User Message ID Definition + **************************************************************/ +#define MSG_ID_USER_START 0x1000 +#define MSG_ID_RIL_READY (MSG_ID_USER_START + 1) +#define MSG_ID_URC_INDICATION (MSG_ID_USER_START + 2) + + +typedef enum { + EVENT_FLAG0 = 0x00000001, + EVENT_FLAG1 = 0x00000002, + EVENT_FLAG2 = 0x00000004, + EVENT_FLAG3 = 0x00000008, + EVENT_FLAG4 = 0x00000010, + EVENT_FLAG5 = 0x00000020, + EVENT_FLAG6 = 0x00000040, + EVENT_FLAG7 = 0x00000080, + EVENT_FLAG8 = 0x00000100, + EVENT_FLAG9 = 0x00000200, + EVENT_FLAG_END +}Enum_EventFlag; + +/************************************************************** + * Error Code Definition + **************************************************************/ +typedef enum { + OS_SUCCESS, + OS_ERROR, + OS_Q_FULL, + OS_Q_EMPTY, + OS_SEM_NOT_AVAILABLE, + OS_WOULD_BLOCK, + OS_MESSAGE_TOO_BIG, + OS_INVALID_ID, + OS_NOT_INITIALIZED, + OS_INVALID_LENGHT, + OS_NULL_ADDRESS, + OS_NOT_RECEIVE, + OS_NOT_SEND, + OS_MEMORY_NOT_VALID, + OS_NOT_PRESENT, + OS_MEMORY_NOT_RELEASE +} Enum_OS_ErrCode; + +typedef enum { + SYS_STATE_START = 0, + SYS_STATE_ATOK = 1, + SYS_STATE_PHBOK = 2, + SYS_STATE_SMSOK = 3 +}Enum_SysInitState; + +typedef enum { + CFUN_STATE_0 = 0, + CFUN_STATE_1 = 1, + CFUN_STATE_4 = 4 +}Enum_CfunState; + +typedef enum +{ + INVAID_EXCEPTION = 0, + UNDEF_EXCEPTION = 1, + SWI_EXCEPTION = 2, + PREFETCH_EXCEPTION = 3, + DATAABORT_EXCEPTION = 4, + ASSERT_FAIL_EXCEPTION = 5, + SYS_FATALERR_EXT_TASK_EXCEPTION = 6, + SYS_FATALERR_EXT_BUF_EXCEPTION = 7, + SYS_LOCKUP = 8, + ASSERT_DUMP_EXTENDED_RECORD = 9, + ASSERT_FAIL_NATIVE = 10, + STACKACCESS_EXCEPTION = 11, + NUM_EXCEPTION +} exception_type; + +typedef enum +{ + Healthy = 0, + InternalSRAMCorrupted = 1, + SystemStackCorrupted = 2, + TaskStackCorrupted = 3, + HISRStackCorrupted = 4, + VectorTableCorrupted = 5, + AliceCorrupted = 6 +} EX_DIAGNOSIS_T; + + +/******************************************************************************* + * Data Structure Definition - Common + *******************************************************************************/ + + +#define EX_STACK_DUMP_LEN 10 +#define EX_QUEUE_TRACK 20 +#define EX_UNIT_NAME_LEN 8 +#define EX_TIMING_CHECK_LEN 6 + +/* Exception header, used to track the exception type (4Bytes) */ +typedef struct ex_exception_record_header_t +{ + exception_type ex_type; /* offset: +0x0, length: 1 */ + u8 ex_nvram; /* offset: +0x1, length: 1 */ + u16 ex_serial_num; /* offset: +0x2, length: 2 */ +} EX_HEADER_T; + +/* Duplicate structure definition to meet different platform requirement */ +typedef struct _ex_rtc_struct +{ + u8 rtc_sec; /* offset: +0x11, length: 1 */ /* seconds after the minute */ + u8 rtc_min; /* offset: +0x12, length: 1 */ /* minutes after the hour */ + u8 rtc_hour; /* offset: +0x13, length: 1 */ /* hours after the midnight */ + u8 rtc_day; /* offset: +0x14, length: 1 */ /* day of the month */ + u8 rtc_mon; /* offset: +0x15, length: 1 */ /* months */ + u8 rtc_wday; /* offset: +0x16, length: 1 */ /* days in a week */ + u8 rtc_year; /* offset: +0x17, length: 1 */ /* years */ + u8 rtc_pad; /* offset: +0x18, length: 1 */ /* Padding */ +} ex_rtc_struct; + +/* boot mode enumeration */ +typedef enum +{ + /* factory mode, system boot up to communicate with factory tools */ + FACTORY_BOOT = 0, + /* normal mode */ + NORMAL_BOOT = 1, + /* USB mode, system boot up when USB charger connect */ + USBMS_BOOT = 2, + /* Firmware Update Engine mode, system run inside FUE */ + FUE_BOOT = 3, + /* number of known boot mode */ + NUM_OF_BOOT_MODE, + /* unknown mode */ + UNKNOWN_BOOT_MODE = 0xff +} boot_mode_type; + +/* Environment information */ +typedef struct ex_environment_info_t +{ + boot_mode_type boot_mode; /* offset: +0x10, length: 1 */ + ex_rtc_struct rtc; /* offset: +0x11, length: 8 */ + u8 execution_unit[EX_UNIT_NAME_LEN]; /* offset: +0x19, length: 8 */ + u8 status; /* offset: +0x21, length: 1 */ + u8 pad[2]; /* offset: +0x22, length: 2 */ + u32 stack_ptr; /* offset: +0x24, length: 4 */ + u32 stack_dump[EX_STACK_DUMP_LEN]; /* offset: +0x28, length: 40 */ + u16 ext_queue_pending_cnt; /* offset: +0x50, length: 2 */ + u16 interrupt_mask3; /* offset: +0x52, length: 2 */ + u32 ext_queue_pending[EX_QUEUE_TRACK]; /* offset: +0x54, length: 80 */ + u32 interrupt_mask[2]; /* offset: +0xA4, length: 8 */ + u32 processing_lisr; /* offset: +0xAC, length: 4 */ + u32 lr; /* offset: +0xB0, length: 4 */ +} EX_ENVINFO_T; + +/* Diagnosis information */ +typedef struct ex_diagnosis_info_t +{ + EX_DIAGNOSIS_T diagnosis; /* offset: +0xB4, length: 1 */ + u8 owner[EX_UNIT_NAME_LEN]; /* offset: +0xB5, length: 8 */ + u8 pad[3]; /* offset: +0xBD, length: 3 */ + u32 timing_check[EX_TIMING_CHECK_LEN]; /* offset: +0xC0, length: 24 */ +} EX_DIAGNOSISINFO_T; + + +/******************************************************************************* + * Constant Definition - Common + *******************************************************************************/ + +#define EX_LOG_SIZE 512 +#define EX_HEADER_SIZE sizeof(EX_HEADER_T) +#define EX_SWVER_LEN 12 +#define EX_ENVINFO_SIZE sizeof(EX_ENVINFO_T) +#define EX_DIAGINFO_SIZE sizeof(EX_DIAGNOSISINFO_T) +#define EX_GUARD_LEN 4 +#define EX_FORCEMEMORYDUMP 0x26409001 +#define TOTAL_EXPTR_SIZE EX_LOG_SIZE +#define EX_NATIVE_ASSERT_ID 0x20110410 + + +/******************************************************************************* + * Data Structure Definition - Fatal Error in general + *******************************************************************************/ + +#define EX_FATALERR_DESCRIPTION_PARAM_LEN 16 +#define EX_FATALERR_ANALYSIS_PARAM_LEN 48 +#define EX_FATALERR_GUIDELINE_PARAM_LEN 16 + +/* Special for Fatal Error only! (100Bytes) */ +typedef struct ex_fatalerror_code_t +{ + u32 code1; + u32 code2; +} EX_FATALERR_CODE_T; + +typedef struct ex_description_t +{ + u32 trace; + u8 param[EX_FATALERR_DESCRIPTION_PARAM_LEN]; +} EX_DESCRIPTION_T; + +typedef struct ex_analysis_t +{ + u32 trace; + u8 param[EX_FATALERR_ANALYSIS_PARAM_LEN]; +} EX_ANALYSIS_T; + +typedef struct ex_guideline_t +{ + u32 trace; + u8 param[EX_FATALERR_GUIDELINE_PARAM_LEN]; +} EX_GUIDELINE_T; + + +/******************************************************************************* + * Data Structure Definition - Fatal Error extended + *******************************************************************************/ + +typedef struct +{ + u8 ex_his_owner[8]; /* control buffer owner */ + u8 ex_his_source[16]; /* source file */ + u32 ex_his_line; /* line number */ + u32 ex_his_count; /* number of identical entries */ +} EX_CTRLBUFF_HISTORY_T; + +typedef struct +{ + u32 ex_buf_RTOS_header1; /* NUCLEUS overhead 1, 0: allocated, else next pointer */ + u32 ex_buf_RTOS_header2; /* NUCLEUS overhead 2, pointer to its control block */ + u32 ex_buf_KAL_header1; /* KAL overhead 1, header (0xF1F1F1F1) */ + u32 ex_buf_KAL_header2; /* KAL overhead 2, task ID */ + u32 ex_buf_KAL_header3; /* KAL overhead 3, pointer to its control block) */ + u32 ex_buf_poolID; /* Buffer pointer */ + u32 ex_buf_KAL_footer1; /* KAL footer: 0xF2F2F2F2 */ + u32 ex_buf_KAL_footer2; /* KAL footer appended after size requested */ +} EX_CTRLBUFF_COMMON_T; + +typedef struct +{ + u8 ex_buf_source[12]; /* Source file name */ + u32 ex_buf_line; /* line number */ +} EX_CTRLBUFF_OWNER_T; + +typedef union +{ + EX_CTRLBUFF_HISTORY_T history; /* length: 32 */ + EX_CTRLBUFF_COMMON_T common; /* length: 32 */ +} EX_CTRLBUFF_INFO_T; + +typedef struct +{ + u32 ex_ctrlbuf_size; /* offset: +0x13C, length: 4 */ /* control buffer size per entry */ + u32 ex_ctrlbuf_num; /* offset: +0x140, length: 4 */ /* total number of entries */ + EX_CTRLBUFF_INFO_T ex_ctrlbuf_top; /* offset: +0x144, length: 32 */ /* top occupation history node */ + EX_CTRLBUFF_INFO_T ex_ctrlbuf_second; /* offset: +0x164, length: 32 */ /* second occupation history node */ + EX_CTRLBUFF_INFO_T ex_ctrlbuf_third; /* offset: +0x184, length: 32 */ /* third occupation history node */ + EX_CTRLBUFF_OWNER_T ex_monitor[3]; /* offset: +0x1A4, length: 48 */ + u32 ex_reserved[2]; /* offset: +0x1D4, length: 16 */ /* reserved */ +} EX_CTRLBUFF_T; + +typedef struct +{ + u8 ex_q_src_mod; /* source module ID */ + u8 ex_q_count; /* total number of identical message */ + u16 ex_q_msg_id; /* message ID */ + u16 ex_q_cur_mes_no; /* tatal number of messages left in queue */ + u16 ex_q_config_entry; /* total number of entries */ +} EX_QUEUE_T; + +typedef struct +{ + u8 ex_task_name[8]; /* task name */ + u8 ex_task_stack_gp[8]; /* guard pattern:STACK_END */ + u32 ex_task_cur_status; /* task current status, eg. RUNNING, READY etc */ + EX_QUEUE_T ex_task_external_q; /* task external queue */ + EX_QUEUE_T ex_task_internal_q; /* task internal queue */ + u32 ex_reserved; /* reserved */ +} EX_TASKINFO_T; + +typedef struct +{ + u32 cpsr; /* offset: +0x13C, length: 4 */ + u32 reg[16]; /* offset: +0x140, length: 64 */ +} EX_CPU_REG_T; + +/******************************************************************************* + * Constant Definition and Exported Type - Fatal Error + *******************************************************************************/ + +#define EX_MAX_TASK_DUMP 4 + +typedef struct ex_fatalerror_t +{ + EX_FATALERR_CODE_T error_code; /* offset: +0xD8, length: 8 */ + EX_DESCRIPTION_T description; /* offset: +0xE0, length: 20 */ + EX_ANALYSIS_T analysis; /* offset: +0xF4, length: 52 */ + EX_GUIDELINE_T guideline; /* offset: +0x128, length: 20 */ + union + { + EX_CTRLBUFF_T ctrl_buff; /* offset: +0x13C, length: 136 */ + EX_TASKINFO_T task_info[EX_MAX_TASK_DUMP]; /* offset: +0x13C, length: 160 */ + EX_CPU_REG_T cpu_reg; /* offset: +0x13C, length: 68 */ + } info; +} EX_FATALERR_T; + + +/******************************************************************************* + * Constant Definition and Exported Type - Assert Failure + *******************************************************************************/ + +#define EX_ASSERTFAIL_FILENAME_LEN 24 +#define EX_ASSERTFAIL_SIZE EX_ASSERTFAIL_FILENAME_LEN + \ + sizeof(u32) * 4 + \ + EX_GUARD_LEN +#define EX_ASSERTFAIL_DUMP_LEN EX_LOG_SIZE - (EX_HEADER_SIZE + EX_SWVER_LEN + \ + EX_ENVINFO_SIZE + EX_DIAGINFO_SIZE + EX_ASSERTFAIL_SIZE) + +typedef struct ex_assert_fail_t +{ + u8 filename[EX_ASSERTFAIL_FILENAME_LEN]; /* offset: +0xD8, length: 24 */ + u32 linenumber; /* offset: +0xF0, length: 4 */ + u32 parameters[3]; /* offset: +0xF4, length: 12 */ + u8 dump[EX_ASSERTFAIL_DUMP_LEN]; /* offset: +0x100, length: 252 */ + u8 guard[EX_GUARD_LEN]; /* offset: +0x1FC, length: 4 */ +} EX_ASSERTFAIL_T; + + +/******************************************************************************* + * Globally Exported Data Structure + *******************************************************************************/ + +typedef union +{ + EX_FATALERR_T fatalerr; + EX_ASSERTFAIL_T assert; +} EX_CONTENT_T; + +/* Standard strutcure of an exception log */ +/*==========================================*/ +/* NOTE: The structure is frozen; offset of content should be FIXED. */ +/*==========================================*/ +typedef struct ex_exception_log_t +{ + EX_HEADER_T header; /* offset: +0x0, length: 4 */ + u8 sw_version[EX_SWVER_LEN]; /* offset: +0x4, length: 12 */ + EX_ENVINFO_T envinfo; /* offset: +0x10, length: 164 */ + EX_DIAGNOSISINFO_T diaginfo; /* offset: +0xB4, length: 36 */ + EX_CONTENT_T content; /* offset: +0xD8, length: 292 */ +} EX_LOG_T; + +/***************************************************************** +* Function: Ql_Sleep +* +* Description: +* Suspends the execution of the current task +* until the time-out interval elapses. +* Parameters: +* msec: +* The time interval for which execution is to +* be suspended, in milliseconds. +* Return: +* None +*****************************************************************/ +void Ql_Sleep(u32 msec); + +/***************************************************************** +* Function: Ql_Reset +* +* Description: +* This function resets the system. +* +* Parameters: +* resetType: +* must be 0. +* Return: +* None +*****************************************************************/ +void Ql_Reset(u8 resetType); + +/***************************************************************** +* Function: Ql_GetUID +* +* Description: +* Get the module UID. +* +* Parameters: +* ptrUID: +* [out] Point to the buffer to store the uid. +* Need 20 bytes length of buffer. +* len: +* [in] The length of buffer. +* Return: +* If the uid_buf is null, this function will return +* QL_RET_ERR_INVALID_PARAMETER. +* If this function read the uid successfully, the length +* of UID will be returned. +*****************************************************************/ +s32 Ql_GetUID(u8* ptrUID, u32 len); + +/***************************************************************** +* Function: Ql_GetMsSincePwrOn +* +* Description: +* This function returns the number of milliseconds +* since the device booted. +* +* Parameters: +* None +* Return: +* Number of milliseconds +*****************************************************************/ +u64 Ql_GetMsSincePwrOn(void); + +/***************************************************************** +* Function: Ql_GetCoreVer +* +* Description: +* Get the version ID of the core. +* +* Parameters: +* ptrVer: +* [out] Point to a unsigned char buffer, which is +* the the version ID of the core. +* len: +* [in] It must be equal or greater than the length of version ID. +* Otherwise error code will be returned. +* Return: +* The length of version ID indicates success. +* Negative indicates failure. please see Error Code Definition. +*****************************************************************/ +s32 Ql_GetCoreVer(u8* ptrVer, u32 len); + +/***************************************************************** +* Function: Ql_GetSDKVer +* +* Description: +* Get the version ID of the SDK. +* +* Parameters: +* ptrVer: +* [out] Point to a unsigned char buffer, which is +* the the version ID of the SDK. +* len: +* [in] A number will be compare with the length of version ID. +* +* Return: +* The smaller between len and the length of version ID. +*****************************************************************/ +s32 Ql_GetSDKVer(u8* ptrVer, u32 len); + +/***************************************************************** +* Function: Ql_OS_GetMessage +* +* Description: +* This function retrieves a message from the current task's +* message queue. When there is no message in the task's +* message queue, the task is in the waiting state.. +* Parameters: +* msg: +* A pointer to ST_MSG. +* Return: +* Always return QL_RET_OK. +*****************************************************************/ +s32 Ql_OS_GetMessage(ST_MSG* msg); + +/***************************************************************** +* Function: Ql_OS_SendMessage +* +* Description: +* Send message between tasks. + +* Parameters: +* destTaskId: +* One value of Enum_TaskId. +* msgId: +* User message id, must bigger than 0xFF. +* param1: +* param2: +* Parameters to send to another task. +* Return: +* OS_SUCCESS +* OS_INVALID_ID +* OS_MEMORY_NOT_VALID +* OS_Q_FULL +*****************************************************************/ +s32 Ql_OS_SendMessage(s32 destTaskId, u32 msgId, u32 param1, u32 param2); + +/***************************************************************** +* Function: Ql_OS_CreateMutex +* +* Description: +* Create a mutex with name. + +* Parameters: +* mutexName: Mutex Name +* Return: +* Mutex Id +*****************************************************************/ +u32 Ql_OS_CreateMutex(char* mutexName); + +/***************************************************************** +* Function: Ql_OS_TakeMutex +* +* Description: +* Obtain an instance of the specified MUTEX. + +* Parameters: +* mutexId: Mutex Id +* Return: +* None +*****************************************************************/ +void Ql_OS_TakeMutex(u32 mutexId); + +/***************************************************************** +* Function: Ql_OS_GiveMutex +* +* Description: +* Release the instance of the specified MUTEX. + +* Parameters: +* mutexId: Mutex Id +* Return: +* None +*****************************************************************/ +void Ql_OS_GiveMutex(u32 mutexId); + +/***************************************************************** +* Function: Ql_OS_CreateSemaphore +* +* Description: +* Creates a counting semaphore. +* Parameters: +* semName: +* Name of semaphore +* maxCount: +* Initial value of semaphore +* Return: +* Value of created semaphore +*****************************************************************/ +u32 Ql_OS_CreateSemaphore(char* semName, u32 maxCount); + +/***************************************************************** +* Function: Ql_OS_TakeSemaphore +* +* Description: +* Obtain an instance of the specified semaphore. + +* Parameters: +* semId: Name of semaphore +* wait: [IN] wait mode, specify the behavior when the semaphore is +* not ready immediately, it can be one the the following values: +* TRUE - wait until ownership can be satisfied. +* FALSE - don't wait for other task gives ownership to it. +* Return: +* OS_SUCCESS: the operation is done successfully +* OS_SEM_NOT_AVAILABLE: the semaphore is unavailable immediately. +*****************************************************************/ +u32 Ql_OS_TakeSemaphore(u32 semId, bool wait); + +/***************************************************************** +* Function: Ql_OS_GiveSemaphore +* +* Description: +* Release the instance of the specified semaphore. + +* Parameters: +* semId: Name of semaphore +* Return: +* None +*****************************************************************/ +void Ql_OS_GiveSemaphore(u32 semId); + +/***************************************************************** +* Function: Ql_OS_CreateEvent +* +* Description: +* This function creates an event-flag group with the specified name. +* Each event-flag group contains 10 event flags. +* +* Parameters: +* evtName: +* Event name. +* +* Return: +* An event Id that identify this event uniquely. +*****************************************************************/ +u32 Ql_OS_CreateEvent(char* evtName); + +/***************************************************************** +* Function: Ql_OS_WaitEvent +* +* Description: +* This function waits until the specified type of event is in the signaled +* state. Developers can specify different types of events for purposes. +* The event flags are defined in 'Enum_EventFlag'. +* +* Parameters: +* evtId: +* Event id that is returned by calling Ql_OS_CreateEvent(). +* evtFlag: +* Event flag type. Please refer to Enum_EventFlag. +* +* Return: +* Zero indicates success, an nonzero means failure. +*****************************************************************/ +s32 Ql_OS_WaitEvent(u32 evtId, u32 evtFlag); + +/***************************************************************** +* Function: Ql_OS_SetEvent +* +* Description: +* This function sets the specified event flag. Any task waiting on the +* event, whose event flag request is satisfied, is resumed. +* +* Parameters: +* evtId: +* Event id that is returned by calling Ql_OS_CreateEvent(). +* evtFlag: +* Event flag type. Please refer to Enum_EventFlag. +* +* Return: +* Zero indicates success, an nonzero means failure. +*****************************************************************/ +s32 Ql_OS_SetEvent(u32 evtId, u32 evtFlag); + +/***************************************************************** +* Function: Ql_SetLastErrorCode +* +* Description: +* Set error code + +* Parameters: +* errCode: Error code +* Return: +* True indicates success or failure indicates failure. +*****************************************************************/ +s32 Ql_SetLastErrorCode(s32 errCode); + +/***************************************************************** +* Function: Ql_GetLastErrorCode +* +* Description: +* Retrieves the calling task's last-error code value. + +* Parameters: +* None +* Return: +* The return value is the calling task's last-error code. +*****************************************************************/ +s32 Ql_GetLastErrorCode(void); + +/***************************************************************** +* Function: Ql_OS_GetCurrentTaskPriority +* +* Description: +* Get the priority of the current task + +* Parameters: +* None +* Return: +* Task priority, ranges from 200 to 255. +*****************************************************************/ +u32 Ql_OS_GetCurrentTaskPriority(void); + +/***************************************************************** +* Function: Ql_OS_GetCurrenTaskLeftStackSize +* +* Description: +* Get the left number of bytes in the current task stack +* Parameters: +* None +* Return: +* Number of bytes, ranges from 1024 to 10*1024. +*****************************************************************/ +u32 Ql_OS_GetCurrenTaskLeftStackSize(void); + +/***************************************************************** +* Function: Ql_OS_GetActiveTaskId +* +* Description: +* This function returns the task ID of the current task. +* Parameters: +* None. +* Return: +* The Id number of current task. +*****************************************************************/ +s32 Ql_OS_GetActiveTaskId(void); + +/***************************************************************** +* Function: Ql_GetExceptionRecords +* +* Description: +* Retrieves the exception records in the NVRAM. + +* Parameters: +* exceptionBuf: +* pointer of exception records buffer +* validCnt: +* pointer of count of valid exception records +* rdCnt: +* get count of records +* Return: +* The return the exception records in the NVRAM. +*****************************************************************/ +s32 Ql_GetExceptionRecords (EX_LOG_T *exceptionBuf,u8 *validCnt,u8 rdCnt); + +#ifdef TASK_ENTRYFUNC_DEF +#undef TASK_ENTRYFUNC_DEF +#endif +#ifdef TASK_DEFINITION +#undef TASK_DEFINITION +#endif +#define TASK_ID_DEF +#include "ql_common.h" +TASK_DEFINITION_BEGIN +#include "custom_task_cfg.h" +TASK_DEFINITION_END +#undef TASK_ID_DEF + +#endif // End-of __QL_SYSTEM_H__ diff --git a/cores/opencpu/include/ql_time.h b/cores/opencpu/include/ql_time.h new file mode 100644 index 0000000..dffce9b --- /dev/null +++ b/cores/opencpu/include/ql_time.h @@ -0,0 +1,125 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_time.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * Time related APIs + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_TIME_H__ +#define __QL_TIME_H__ +#include "ql_type.h" + +typedef struct { + s32 year; + s32 month; + s32 day; + s32 hour; + s32 minute; + s32 second; + s32 timezone; // one digit expresses a quarter of an hour, for example: 22 indicates "+5:30" +}ST_Time; + +/***************************************************************** +* Function: Ql_SetLocalTime +* +* Description: +* Set the current local date and time. +* +* Parameters: +* dateTime: +* [in] Point to the ST_Time object +* Return: +* QL_RET_OK indicates this function is executed successesfully. +* QL_RET_ERR_PARAM, indicates the parameter is error. +* +*****************************************************************/ +s32 Ql_SetLocalTime(ST_Time* dateTime); + +/***************************************************************** +* Function: Ql_GetLocalTime +* +* Description: +* Get the current local date and time. +* +* Parameters: +* dateTime: +* [out] Point to the ST_Time object +* Return: +* if succeed,return the current local date and time +* , NULL means get failure. +*****************************************************************/ +ST_Time* Ql_GetLocalTime(ST_Time* dateTime); + +/***************************************************************** +* Function: Ql_Mktime +* +* Description: +* This function get total seconds elapsed +* since 1970.01.01 00:00:00. +* +* Parameters: +* dateTime: +* [in] Point to the ST_Time object +* Return: +* The total seconds +*--------------- +* Usage: +* ST_Time systime; +* Ql_GetLocalTime(&systime); +* seconds = Ql_Mktime(&systime); +*****************************************************************/ +u64 Ql_Mktime(ST_Time* dateTime); + +/***************************************************************** +* Function: Ql_MKTime2CalendarTime +* +* Description: +* This function convert the seconds elapsed since +* 1970.01.01 00:00:00 to local date and time. +* +* Parameters: +* seconds: +* [in] the seconds elapsed since +* 1970.01.01 00:00:00 +* pOutDateTime: +* [out] Point to the ST_Time object +* Return: +* if succeed,return the current local date and time +* , NULL means operation failure. +* +*--------------- +* Usage: +* ST_Time systime; +* systime = Ql_MKTime2CalendarTime(seconds, &systime); +* +*****************************************************************/ +ST_Time* Ql_MKTime2CalendarTime(u64 seconds, ST_Time* pOutDateTime); + +#endif diff --git a/cores/opencpu/include/ql_timer.h b/cores/opencpu/include/ql_timer.h new file mode 100644 index 0000000..a5d5e34 --- /dev/null +++ b/cores/opencpu/include/ql_timer.h @@ -0,0 +1,164 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_timer.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * Timer related APIs + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_TIMER_H__ +#define __QL_TIMER_H__ +#include "ql_type.h" + +/************************************************************** + * User TIMER ID Definition + **************************************************************/ +#define TIMER_ID_USER_START 0x100 + + + +typedef void(*Callback_Timer_OnTimer)(u32 timerId, void* param); + +/***************************************************************** +* Function: Ql_Timer_Register +* +* Description: +* Register stack timer,each task only supports 10 timer. +* +* Parameters: +* timerId: +* [in] The timer id must be bigger than 0xFF.And make sure that the id is +* the only one under opencpu task.Of course, the ID that registered +* by "Ql_Timer_RegisterFast" also cannot be the same with it. +* +* callback_onTimer: +* [out] Notify the application when the time of the timer arrives. +* param: +* [in] Used to pass parameters of customers. +* Return: +* QL_RET_OK indicates register ok; +* QL_RET_ERR_PARAM indicates the param error. +* QL_RET_ERR_INVALID_TIMER indicates that the timer ID is already being used +* or the timer is started or stopped not in the same task with it registered. +* QL_RET_ERR_TIMER_FULL indicates all timers are used up. +* QL_RET_ERR_INVALID_TASK_ID indicates the task invalid. +* Notes: +* If you register a timer Id in an opencpu task, then you can only start or stop +* the timer in the same task.Otherwise,the timer can not be started or stopped. +* +*****************************************************************/ +s32 Ql_Timer_Register(u32 timerId, Callback_Timer_OnTimer callback_onTimer, void* param); + +/***************************************************************** +* Function: Ql_Timer_RegisterFast +* +* Description: +* Register GP timer,only support one timer under opencpu task. +* +* Parameters: +* timerId: +* [in] The timer id must be bigger than 0xFF.And make sure that the id is +* not the same with the ID that registered by "Ql_Timer_Register". +* +* callback_onTimer: +* [out] Notify the application when the time of the timer arrives. +* param: +* [in] Used to pass parameters of customers. +* Return: +* QL_RET_OK indicates register ok; +* QL_RET_ERR_PARAM indicates the param error. +* QL_RET_ERR_INVALID_TIMER indicates that the timer ID is already being used +* or the timer is started or stopped not in the same task with it registered. +* QL_RET_ERR_TIMER_FULL indicates all timers are used up. +* QL_RET_ERR_INVALID_TASK_ID indicates the task invalid. +* Notes: +* If you register a timer Id in an opencpu task, then you can only start or stop +* the timer in the same task.Otherwise,the timer can not be started or stopped. +* +*****************************************************************/ +s32 Ql_Timer_RegisterFast(u32 timerId, Callback_Timer_OnTimer callback_onTimer, void* param); + +/***************************************************************** +* Function: Ql_StartTimer +* +* Description: +* Start up a timer with the specified timer id. +* +* Parameters: +* timerId: +* [in] timer id, bigger than 0xFF,the timer id must be registed. +* interval: +* [in] Set the interval of the timer, unit: ms. +* if you start a stack timer, the interval must be +* greater than or equal to 1ms. +* if you start a GP timer, the interval must be +* an integer multiple of 10ms. +* autoRepeat: +* [in] TRUE indicates that the timer is executed repeatedly. +* FALSE indicates that the timer is executed only once. +* Return: +* QL_RET_OK indicates register ok; +* QL_RET_ERR_PARAM indicates the param error. +* QL_RET_ERR_INVALID_TIMER indicates that the timer ID is already being used +* or the timer is started or stopped not in the same task with it registered. +* QL_RET_ERR_TIMER_FULL indicates all timers are used up. +* QL_RET_ERR_INVALID_TASK_ID indicates the task invalid. +* Notes: +* If you register a timer Id in an opencpu task, then you can only start or stop +* the timer in the same task.Otherwise,the timer can not be started or stopped. +* +*****************************************************************/ +s32 Ql_Timer_Start(u32 timerId, u32 interval, bool autoRepeat); + +/***************************************************************** +* Function: Ql_StopTimer +* +* Description: +* Stop the timer with the specified timer id. +* +* Parameters: +* timerId: +* [in] the timer id. The timer has been started +* by calling Ql_Timer_Start previously. +* Return: +* QL_RET_OK indicates register ok; +* QL_RET_ERR_PARAM indicates the param error. +* QL_RET_ERR_INVALID_TIMER indicates that the timer ID is already being used +* or the timer is started or stopped not in the same task with it registered. +* QL_RET_ERR_TIMER_FULL indicates all timers are used up. +* QL_RET_ERR_INVALID_TASK_ID indicates the task invalid. +* Notes: +* If you register a timer Id in an opencpu task, then you can only start or stop +* the timer in the same task.Otherwise,the timer can not be started or stopped. +* +*****************************************************************/ +s32 Ql_Timer_Stop(u32 timerId); + +#endif // End-of __QL_TIMER_H__ + diff --git a/cores/opencpu/include/ql_trace.h b/cores/opencpu/include/ql_trace.h new file mode 100644 index 0000000..e68c8be --- /dev/null +++ b/cores/opencpu/include/ql_trace.h @@ -0,0 +1,73 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_trace.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * debug trace API + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_TRACE_H__ +#define __QL_TRACE_H__ +#include "ql_type.h" + +typedef enum { + BASIC_MODE, /* In basic mode, debug messages from application will be + output to debug serial port as text. + */ + ADVANCE_MODE /* Default mode. + In advance mode, debug messages from System and application + will be output to debug serial port in special format. Only + the Catcher Tool can capture and display these debug messages + legibly. + */ +} Enum_DebugMode; + +typedef enum{ + PORTNAME_UART1, + PORTNAME_UART2 +}Enum_PortName; + +/***************************************************************** +* Function: Ql_Debug_Trace +* +* Description: +* This function prints formatted output to +* debug serial port. Its function is same to 'sprintf'. +* +* Parameters: +* fmt: +* Pointer to a null-terminated multibyte string +* specifying how to interpret the data. +* The maximum string length is 512 bytes. +* Return: +* Number of characters printed +*****************************************************************/ +extern s32 (*Ql_Debug_Trace)(char* fmt, ...); + +#endif // #end-of __QL_TRACE_H__ diff --git a/cores/opencpu/include/ql_type.h b/cores/opencpu/include/ql_type.h new file mode 100644 index 0000000..173b4d8 --- /dev/null +++ b/cores/opencpu/include/ql_type.h @@ -0,0 +1,68 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_type.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * OpenCPU Type Definitions + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + +#ifndef __QL_TYPE_H__ +#define __QL_TYPE_H__ + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef NULL +#define NULL ((void *)0) +#endif + +/**************************************************************************** + * Type Definitions + ***************************************************************************/ +#ifndef ARDUINO +typedef unsigned char bool; +#else +#include +#endif + +typedef unsigned char u8; +typedef signed char s8; +typedef unsigned short u16; +typedef short s16; +typedef unsigned int u32; +typedef int s32; +typedef unsigned long long u64; +typedef long long s64; +typedef unsigned int ticks; + +#endif // End-of __QL_TYPE_H__ diff --git a/cores/opencpu/include/ql_uart.h b/cores/opencpu/include/ql_uart.h new file mode 100644 index 0000000..654184e --- /dev/null +++ b/cores/opencpu/include/ql_uart.h @@ -0,0 +1,510 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_uart.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * Uart APIs defines. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __QL_UART_H__ +#define __QL_UART_H__ +#include "ql_common.h" +#include "ql_system.h" + +typedef enum { + PORT_START = 0, + VIRTUAL_PORT1 = PORT_START, + VIRTUAL_PORT2, + UART_START = 10, + UART_PORT1 = UART_START, + UART_PORT2, + UART_PORT3, + UART_PORT_END +}Enum_SerialPort; + +typedef enum { + DB_5BIT = 5, + DB_6BIT, + DB_7BIT, + DB_8BIT +} Enum_DataBits; + +typedef enum { + SB_ONE = 1, + SB_TWO, + SB_ONE_DOT_FIVE +} Enum_StopBits; + +typedef enum { + PB_NONE = 0, + PB_ODD, + PB_EVEN, + PB_SPACE, + PB_MARK +} Enum_ParityBits; + +typedef enum { + FC_NONE=1, // None Flow Control + FC_HW, // Hardware Flow Control + FC_SW // Software Flow Control +} Enum_FlowCtrl; + +typedef struct { + u32 baudrate; + Enum_DataBits dataBits; + Enum_StopBits stopBits; + Enum_ParityBits parity; + Enum_FlowCtrl flowCtrl; +}ST_UARTDCB; + +typedef enum { + UART_VFIFO = 0, // read and write, only valid on the physical UART PORT1 and physical UART PORT3 + UART_CLR_FE, // write only, only valid on the physical UART ports + UART_RX_BYTE_AVAIL, // read only, valid both on the physical UART and the virtual UART + UART_RX_BUF_LEFT_ROOM, // read only,only valid on the virtual UART + UART_TX_BUF_LEFT_ROOM, // read only,valid both on the physical UART and the virtual UART + UART_TX_BUF_SEND_OUT // read only, only valid on the physical UART ports +}Enum_UARTOption; + +typedef enum { + UART_PIN_RI = 0, // read only, RI read operator only valid on the virtual UART + UART_PIN_DCD, // read only, DCD read operator only valid on the virtual UART +} Enum_UARTPinType ; + +typedef enum { + EVENT_UART_READY_TO_READ = 0, + EVENT_UART_READY_TO_WRITE, + EVENT_UART_FE_IND, + EVENT_UART_RI_IND, + EVENT_UART_DCD_IND, + EVENT_UART_DTR_IND +} Enum_UARTEventType; + +typedef struct { + u16 txBufDeep; // for physical UART1 and UART3 only, max length 2048 byte + u16 rxBufDeep; // for physical UART1 and UART3 only, max length 3584 byte + u16 txBufAlart; // for physical UART1 and UART3 only , should less than txBufDeep + u16 rxBufAlart; // for physical UART1 and UART3only , should less than rxBufDeep +}ST_UartVfifo; + +/***************************************************************** +* Function: Ql_UART_Register +* +* Description: +* This function registers the callback function for the +* specified serial port. +* UART callback function used for receiving the UART notification from CORE. +* +* Parameters: +* [in]port: +* Port name +* [in]callback_uart: +* The pointer of the UART call back function. +* [in]event: +* indication the event type of UART call back, please reference Enum_UARTEventType. +* [in]pinLevel: +* if the event type is EVENT_UART_RI_IND or EVENT_UART_DCD_IND or EVENT_UART_DTR_IND +* the level indication the relate pin's current level otherwise this parameter has no meaning, just ignore it. +* [in]customizePara: +* Customize parameter, if not use just set to NULL. +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +*****************************************************************/ +typedef void (*CallBack_UART_Notify)( Enum_SerialPort port, Enum_UARTEventType event, bool pinLevel,void *customizePara); +s32 Ql_UART_Register(Enum_SerialPort port, CallBack_UART_Notify callback_uart,void * customizePara); + + +/***************************************************************** +* Function: Ql_UART_Open +* +* Description: +* This function opens a specified UART port with the specified +* flow control mode. +* Which task call this function, which task will own the specified UART port. +* +* Parameters: +* [in]port: +* Port name +* [in]baud: +* The baud rate of the UART to be opened +* for the physical the baud rate support 75,150,300,600,1200,2400,4800,7200, +* 9600,14400,19200,28800,38400,57600,115200,230400,460800 +* for the UART_PORT1 support auto-baud rate, when the baud set to 0. +* +* This parameter don't take,effect on the VIRTUAL_PORT1,VIRTUAL_PORT2,just set to 0 +* +* [in]flowCtrl: +* one value of Enum_FlowCtrl, used for the physical UART's flow control. +* the hardware flow control(FC_HW) only supported on the UART_PORT1, +* other port not support hardware flow control. +* This parameter don't take,effect on the VIRTUAL_PORT1,VIRTUAL_PORT2,just set to FC_NONE +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +*****************************************************************/ +s32 Ql_UART_Open(Enum_SerialPort port,u32 baudrate, Enum_FlowCtrl flowCtrl); + + +/***************************************************************** +* Function: Ql_UART_OpenEx +* +* Description: +* This function opens a specified UART port with the +* specified DCB parameters. +* Which task call this function, which task will own the specified UART port. +* +* Parameters: +* [in]port: +* Port name +* [in]dcb: +* The point to the UART dcb struct. +* Include baud rate,data bits,stop bits,parity,and flow control +* only physical UART1(UART_PORT1) have the hardware flow control +* +* This parameter don't take effect on the VIRTUAL_PORT1,VIRTUAL_PORT2 +* just set to NULL. +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +*****************************************************************/ +s32 Ql_UART_OpenEx(Enum_SerialPort port, ST_UARTDCB *dcb); + +/***************************************************************** +* Function: Ql_UART_RX_Enable +* +* Description: +* Enable specified uart rx func ,module can recieve data from terminals +* +* Parameters: +* [in]port: +* Port name ,limited to physical port ,see Enum_SerialPort +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +* Example: Ql_UART_RX_Enable(UART_PORT1); +* +* +* +*****************************************************************/ +s32 Ql_UART_RX_Enable(Enum_SerialPort port); + + +/***************************************************************** +* Function: Ql_UART_RX_Disable +* +* Description: +* Disable specified uart rx func,module can't recieve data from terminals +* +* Parameters: +* [in]port: +* Port name ,limited to physical port ,see Enum_SerialPort +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +*****************************************************************/ +s32 Ql_UART_RX_Disable(Enum_SerialPort port); + + +/***************************************************************** +* Function: Ql_UART_Write +* +* Description: +* This function is used to send data to the specified UART port. +* +* When the number of bytes actually write data is less than that to send, +* Application should stop sending data, and application will receive an event +* EVENT_UART_READY_TO_WRITE later. +* After receiving this Event Application can continue to send data, +* and previously unsent data should be resend. +* +* NOTE: +* The RX/TX buffer size of VIRTUAL_PORT1 and VIRTUAL_PORT2 both are 1024-byte, +* So the number of bytes to write should generally not more than 1024. +* +* Parameters: +* [in] port: +* Port name +* [in]data: +* Pointer to data to be send +* [in]writeLen: +* The length of the data to be written +* +* Return: +* If >= 0, indicates success, and the return value +* is the length of actual write data length +* If < 0, indicates failure to read +* +*****************************************************************/ +s32 Ql_UART_Write(Enum_SerialPort port, u8* data, u32 writeLen ); + + +/***************************************************************** +* Function: Ql_UART_Read +* +* Description: +* This function read data from the specified UART port. +* When the UART callback is called, and the message type is +* EVENT_UART_READ_TO_READ, +* user need read all of the data in the data buffer +* which means the real read len is less than the to be read len, +* otherwise later the UART data is coming, there will be no such event to notify user get data. +* +* Parameters: +* [in]port: +* Port name +* [out]data: +* Point to the read data +* [in]readLen: +* then length of data want to read +* +* Return: +* If >= 0, indicates success, and the return value +* is the length of actual read data length +* If < 0, indicates failure to read +* +*****************************************************************/ +s32 Ql_UART_Read(Enum_SerialPort port, u8* data, u32 readLen); + + +/***************************************************************** +* Function: Ql_UART_SetDCBConfig +* +* Description: +* This function used for setting the parameter of the UART port, for example the baud rate +* data bits, stop bits, parity,and flow control. +* This function is only effect on the physical port(UART_PORT1 UART_PORT2 UART_PORT3). +* the virtual port(VIRTUAL_PORT1,VIRTUAL_PORT2) don't support this function. +* +* Parameters: +* [in]port: +* Port name +* [in]dcb: +* the DCB struct to be set of the special UART +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +*****************************************************************/ +s32 Ql_UART_SetDCBConfig(Enum_SerialPort port, ST_UARTDCB *dcb); + + +/***************************************************************** +* Function: Ql_UART_GetDCBConfig +* +* Description: +* This function used for getting the parameter of the UART port, for example the baud rata +* data bits, stop bits, parity,and flow control. +* This function is only effect on the physical port(UART_PORT1 UART_PORT2 UART_PORT3). +* the virtual port(VIRTUAL_PORT1,VIRTUAL_PORT2) don't support this function. +* +* Parameters: +* [in]port: +* Port name +* [out]dcb: +* the DCB parameter of the special UART port +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +*****************************************************************/ +s32 Ql_UART_GetDCBConfig(Enum_SerialPort port, ST_UARTDCB *dcb); + + +/***************************************************************** +* Function: Ql_UART_ClrRxBuffer +* +* Description: +* This function clears receive-buffer of specified UART port +* +* Parameters: +* [in]port: +* Port name +* +* Return: +* NONE +* +*****************************************************************/ +void Ql_UART_ClrRxBuffer(Enum_SerialPort port); + + +/***************************************************************** +* Function: Ql_UART_ClrTxBuffer +* +* Description: +* This function clears send-buffer of specified UART port. +* +* Parameters: +* [in]port: +* Port name +* +* Return: +* NONE +* +*****************************************************************/ +void Ql_UART_ClrTxBuffer(Enum_SerialPort port); + + +/***************************************************************** +* Function: Ql_UART_GetOption +* +* Description: +* This function used for getting the UART option, such as physical UART port's vfifo, +* or the send or receive buffer left space on the UART port. +* +* Parameters: +* [in]port: +* Port name +* [in]opt: +* one value of Enum_UARTOption +* the get option of UART_VFIFO is only valid on the UART_PORT1 and UART_PORT3 +* the get option of UART_CLR_FE is only valid on the UART_PORT1 and UART_PORT2 and UART_PORT3 +* the get option of UART_RX_BYTE_AVAIL valid both on the vitual or the physical port +* the get option of UART_RX_BUF_LEFT_ROOM only valid on the vitual port +* the get option of UART_TX_BYTE_AVAIL valid both on the vitual or physical port +* the get option of UART_TX_BUF_SEND_OUT is only valid on the UART_PORT1 and UART_PORT2 and UART_PORT3 +* [out]para: +* if opt is UART_VFIFO, point to a struct of ST_UartVfifo +* if opt is UART_RX_BYTE_AVAIL or UART_RX_BUF_LEFT_ROOM or UART_TX_BUF_LEFT_ROOM +* this parameter should a point of u32 +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +*****************************************************************/ +s32 Ql_UART_GetOption(Enum_SerialPort port,Enum_UARTOption opt, void* para); + + +/***************************************************************** +* Function: Ql_UART_SetOption +* +* Description: +* This function used for setting the UART option, such as physical UART port's vfifo, +* or clear the physical UART's(UART_PORT1 UART_PORT2 and UART_PORT3) frame error. +* +* Parameters: +* [in]port: +* Port name +* [in]opt: +* one value of Enum_UARTOption +* the set option of UART_VFIFO is only valid on the UART_PORT1 and UART_PORT3 +* the set option of UART_CLR_FE is only valid on the UART_PORT1 and UART_PORT2 and UART_PORT3 +* other option don't support set operator. +* [in]para: +* if opt is UART_VFIFO, point to a struct of ST_UartVfifo +* if opt is UART_CLR_FE,this parameter should be set to NULL. +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +*****************************************************************/ +s32 Ql_UART_SetOption(Enum_SerialPort port,Enum_UARTOption opt, void* para); + + +/***************************************************************** +* Function: Ql_UART_GetPinStatus +* +* Description: +* This function gets the pin status (include RI, DCD, DTR) +* of the virtual UART port. It doesn't work for the physical UART ports. +* +* Parameters: +* port: +* [in] virtual UART port. +* pin: +* [in] pin name, one value of Enum_UARTPinType. +* +* Return: +* If >= 0, indicates success, and the return special pin level value +* 0:low level, 1:high level. +* If < 0, indicates failure +* +*****************************************************************/ +s32 Ql_UART_GetPinStatus(Enum_SerialPort port, Enum_UARTPinType pin); + + +/***************************************************************** +* Function: Ql_UART_SetPinStatus +* +* Description: +* This function sets the pin level status of the virtual +* UART port. It doesn't work for the physical UART ports. +* +* Parameters: +* port: +* [in] virtual UART port. +* pin: +* [in] pin name, one value of Enum_UARTPinType. +* +* pinLevel: +* [in] the level value to set. 0:low level, 1:high level. +* Return: +* QL_RET_OK indicates success; otherwise failure. +* +*****************************************************************/ +s32 Ql_UART_SetPinStatus(Enum_SerialPort port, Enum_UARTPinType pin, bool pinLevel); + +/***************************************************************** +* Function: Ql_UART_SendEscap +* +* Description: +* This function notifies the port to quit from Data Mode, and return back to Command Mode. +* This function only supported on the VIRTUAL_PORT1, VIRTUAL_PORT2. +* +* Parameters: +* [in] port: +* Port name +* this function only supported on the VIRTUAL_PORT1, VIRTUAL_PORT2. +* +* Return: +* QL_RET_OK indicates success; otherwise failure. +*****************************************************************/ +s32 Ql_UART_SendEscap(Enum_SerialPort port); + +/***************************************************************** +* Function: Ql_UART_Close +* +* Description: +* This function close a specified UART port. +* Parameters: +* [in] port: +* Port name +* Return: +* NONE +* +*****************************************************************/ +void Ql_UART_Close(Enum_SerialPort port); + +#endif // End-of __QL_UART_H__ + diff --git a/cores/opencpu/include/ql_wtd.h b/cores/opencpu/include/ql_wtd.h new file mode 100644 index 0000000..5e75b95 --- /dev/null +++ b/cores/opencpu/include/ql_wtd.h @@ -0,0 +1,125 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ql_wtd.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * watch dog APIs defines. + * + * + * Attention: + * ------------ + * When calling Ql_WTD_Init to start a GPTimer,module can not enter to sleep mode + * + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + + +#ifndef __WATCHDOG_H__ +#define __WATCHDOG_H__ +#include "ql_type.h" +#include "ql_gpio.h" + + +/***************************************************************** +* Function: Ql_WTD_Init +* +* Description: +* This function starts a base H/W timer, which is responsible for feed the external watchdog. And specify the I/O pin and feeding interval. +* Besides, this function may specify the reset mode (H/W reset or S/W reset) when the watchdog overflows. +* H/W reset means the external watchdog chip resets the module. +* +* Parameters: +* resetMode: +* [in] Must be zero, H/W reset. +* wtdPin: +* [in]I/O pin that connects to the WDI pin of external watchdog chip. +* interval: +* [in]the interval for feeding external watchdog.the min value of interval is 200. Unit in ms. +* +* Example: +* Ql_WTD_Init(0,PINNAME_RI,600);// start an external watchdog,set RI to feed dog within 600ms +* +* +* Return: +* QL_RET_OK indicates success in starting watch dog service. +* QL_RET_ERR_PARAM indicates the param invalid. +*****************************************************************/ +s32 Ql_WTD_Init(s32 resetMode, Enum_PinName wtdPin, u32 interval) ; + + + +/***************************************************************** +* Function: Ql_WTD_Start +* +* Description: +* The function starts an internal watchdog. If needed, every task may call this function to start an interval watchdog service. +* Parameters: +* interval: +* [in]the interval for feeding internal watchdog.the min value of interval is 400. Unit in ms. +* +* +* Example: +* Ql_WTD_Start(2000); +* If not call Ql_WTD_Feed within 2000ms ,the module will automatically reset. +* +* Return: +* Success return Watchdog ID +* QL_RET_ERR_PARAM indicates the param invalid. +*****************************************************************/ +s32 Ql_WTD_Start(u32 interval); + + +/***************************************************************** +* Function: Ql_WTD_Feed +* +* Description: +* This function feeds the watchdog that is started by Ql_WTD_Start(). +* Parameters: +* wtdID: +* [in] watchdog ID, which is returned by Ql_WTD_Start(). +* +* Return: +* None +*****************************************************************/ +void Ql_WTD_Feed(s32 wtdID); + + +/***************************************************************** +* Function: Ql_WTD_Stop +* +* Description: +* This function stops a watchdog that is started by Ql_WTD_Start(). +* Parameters: +* wtdID: +* [in]watchdog ID, which is returned by Ql_WTD_Start(). +* +* Return: +* None +*****************************************************************/ +void Ql_WTD_Stop(s32 wtdID); + +#endif diff --git a/cores/opencpu/interface.c b/cores/opencpu/interface.c new file mode 100644 index 0000000..a039627 --- /dev/null +++ b/cores/opencpu/interface.c @@ -0,0 +1,282 @@ +/* + * interface.c M66 + * + * Created on: 11.07.2018 + * Author: Georgi Angelov + */ + +#include "interface.h" + +/* CPP INIT */ +extern void (*__preinit_array_start[])(void) __attribute__((weak)); +extern void (*__preinit_array_end[])(void) __attribute__((weak)); +extern void (*__init_array_start[])(void) __attribute__((weak)); +extern void (*__init_array_end[])(void) __attribute__((weak)); +extern void (*__fini_array_start[])(void) __attribute__((weak)); +extern void (*__fini_array_end[])(void) __attribute__((weak)); + +extern void _init(void) __attribute__((weak)); +extern void _fini(void) __attribute__((weak)); + +void __libc_init_array(void); +void __libc_fini_array(void); + +void __libc_init_array(void) +{ + size_t count; + size_t i; + count = __preinit_array_end - __preinit_array_start; + for (i = 0; i < count; i++) + __preinit_array_start[i](); + _init(); + count = __init_array_end - __init_array_start; + for (i = 0; i < count; i++) + __init_array_start[i](); +} + +void __libc_fini_array(void) +{ + size_t count; + size_t i; + count = __fini_array_end - __fini_array_start; + for (i = count; i > 0; i--) + __fini_array_start[i - 1](); + _fini(); +} + +inline void abort(void) +{ + while (1) + { + } +} + +void __cxa_finalize(void *handle) {} +void __cxa_pure_virtual(void) +{ + abort(); +} + +void __cxa_deleted_virtual(void) +{ + abort(); +} + +void *realloc(void *mem, size_t newsize) +{ + if (newsize == 0) + { + free(mem); + return NULL; + } + void *p; + p = malloc(newsize); + if (p) + { + if (mem != NULL) + { + memcpy(p, mem, newsize); + free(mem); + } + } + return p; +} + +void *calloc(size_t count, size_t size) +{ + size_t alloc_size = count * size; + void *new = malloc(alloc_size); + if (new) + { + memset(new, 0, alloc_size); + return new; + } + return NULL; +} + +void *memcpy(void *dest, const void *src, size_t len) +{ // need for quectel startup + char *d = dest; + const char *s = src; + while (len--) + *d++ = *s++; + return dest; +} + +void *memset(void *dest, int val, size_t len) +{ // need for quectel startup + unsigned char *ptr = dest; + while (len-- > 0) + *ptr++ = val; + return dest; +} + +void reverse(char *begin, char *end) +{ + char *is = begin; + char *ie = end - 1; + while (is < ie) + { + char tmp = *ie; + *ie = *is; + *is = tmp; + ++is; + --ie; + } +} + +extern long atol(const char *s) +{ + long val = 0; + if (s) + Ql_sscanf(s, "%l", &val); + return val; +} + +static const char *str_digits = "0123456789abcdef"; +extern char *itoa(int value, char *result, int base) +{ + if (result) + { + if (base < 2 || base > 16) + { + *result = 0; + return result; + } + char *out = result; + int quotient = abs(value); + do + { + const int tmp = quotient / base; + *out = str_digits[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while (quotient); + if (value < 0) + *out++ = '-'; + reverse(result, out); + *out = 0; + } + return result; +} + +extern char *ltoa(long value, char *result, int base) +{ + if (result) + { + if (base < 2 || base > 16) + { + *result = 0; + return result; + } + char *out = result; + long quotient = abs(value); + do + { + const long tmp = quotient / base; + *out = str_digits[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while (quotient); + if (value < 0) + *out++ = '-'; + reverse(result, out); + *out = 0; + } + return result; +} + +extern char *utoa(unsigned value, char *result, int base) +{ + if (result) + { + if (base < 2 || base > 16) + { + *result = 0; + return result; + } + char *out = result; + unsigned quotient = value; + do + { + const unsigned tmp = quotient / base; + *out = str_digits[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while (quotient); + reverse(result, out); + *out = 0; + } + return result; +} + +extern char *ultoa(unsigned long value, char *result, int base) +{ + if (result) + { + if (base < 2 || base > 16) + { + *result = 0; + return result; + } + char *out = result; + unsigned long quotient = value; + do + { + const unsigned long tmp = quotient / base; + *out = str_digits[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while (quotient); + reverse(result, out); + *out = 0; + } + return result; +} + +inline int isascii(int c) +{ + return c >= 0 && c < 128; +} + +inline int toascii(int c) +{ + return c & 0177; +} + +inline int isalpha(int c) +{ + return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); +} + +inline int isspace(int c) +{ + return (c == ' ' || c == '\t' || c == '\n' || c == '\12'); +} + +inline int isdigit(int c) +{ + return (c >= '0' && c <= '9'); +} + +inline int isxdigit(int c) +{ + return isdigit(c) || ((unsigned)c | 32) - 'a' < 6; +} + +unsigned int *Ql_convertIP(unsigned int ip) +{ + static char m_ipAddress[4]; + unsigned int *p = (unsigned int *)m_ipAddress; + *p = ip; + return p; +} + +int Ql_inet_aton(const char *cp, uint32_t *ip) +{ + if (!ip || !cp) + return 0; + if (0 == Ql_IpHelper_ConvertIpAddr((u8 *)cp, (u32 *)ip)) + return 1; + return 0; +} \ No newline at end of file diff --git a/cores/opencpu/interface.h b/cores/opencpu/interface.h new file mode 100644 index 0000000..688144c --- /dev/null +++ b/cores/opencpu/interface.h @@ -0,0 +1,170 @@ +/* + * interface.h M66 + * + * Created on: 08.08.2018 + * Author: Georgi Angelov + */ + +#ifndef INTERFACE_H_ +#define INTERFACE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include +#include + +#include "ql_common.h" +#include "ql_type.h" +#include "ql_system.h" +#include "ql_memory.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_error.h" +#include "ql_uart.h" +#include "ql_gpio.h" +#include "ql_adc.h" +#include "ql_pwm.h" +#include "ql_spi.h" +#include "ql_iic.h" +#include "ql_eint.h" +#include "ql_power.h" +#include "ql_time.h" +#include "ql_timer.h" +#include "ql_clock.h" +#include "ql_fota.h" +#include "ql_fs.h" +#include "ql_gprs.h" +#include "ql_socket.h" +#include "ql_wtd.h" +#include "nema_pro.h" + +#include "ril.h" +#include "ril_system.h" +#include "ril_util.h" +#include "ril_sim.h" +#include "ril_telephony.h" +#include "ril_sms.h" +#include "lib_ril_sms.h" +#include "ril_network.h" +#include "ril_location.h" +#include "ril_http.h" +#include "ril_ftp.h" +#include "ril_dtmf.h" +#include "ril_bluetooth.h" +#include "ril_audio.h" +#include "ril_alarm.h" + +#define atoi Ql_atoi +#define atof Ql_atof +#define memcmp Ql_memcmp +#define memmove Ql_memmove +#define strcpy Ql_strcpy +#define strncpy Ql_strncpy +#define strcat Ql_strcat +#define strncat Ql_strncat +#define strcmp Ql_strcmp +#define strncmp Ql_strncmp +#define strchr Ql_strchr +#define strlen Ql_strlen +#define strstr Ql_strstr +#define toupper Ql_toupper +#define tolower Ql_tolower +#define sprintf Ql_sprintf +#define snprintf Ql_snprintf +#define sscanf Ql_sscanf +#define malloc Ql_MEM_Alloc +#define free Ql_MEM_Free + +#include "api.h" + +#define vsnprintf wiz__vsnprintf +#define strtol api_strtol +#define api_strtoul strtoul +#define rand api_rand +#define srand api_srand + +#include "dbg.h" + +#define ARDUINO_TASK_ID 3 /* arduino_task_id */ +#define MSG_PROCESS_MESSAGES 0x100 + void arduinoProcessMessages(unsigned int wait); + + void entry_main(int) __attribute__((weak)); // if exist, OpenCPU style else setup/loop + + void __libc_init_array(void); + void __libc_fini_array(void); + + unsigned int seconds(void); + unsigned int millis(void); + unsigned int micros(void); + void delay(unsigned int); + void delayMicroseconds(unsigned int us); + + long atol(const char *s); + char *itoa(int value, char *result, int base); + char *ltoa(long value, char *result, int base); + char *utoa(unsigned value, char *result, int base); + char *ultoa(unsigned long value, char *result, int base); + + int isascii(int c); + int toascii(int c); + int isalpha(int c); + int isspace(int c); + int isdigit(int c); + int isxdigit(int c); + + uint32_t clockCyclesPerMicrosecond(void); + uint32_t clockCyclesToMicroseconds(uint32_t a); + uint32_t microsecondsToClockCycles(uint32_t a); + + unsigned int *Ql_convertIP(unsigned int ip); + int Ql_inet_aton(const char *cp, uint32_t *ip); + +#ifndef SERIAL_BUFFER_SIZE +#define SERIAL_BUFFER_SIZE 256 +#endif + + // for SPI + __attribute__((always_inline)) static inline uint32_t __RBIT(uint32_t value) + { + uint32_t result; + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return (result); + } + + __attribute__((always_inline)) static inline uint32_t __REV(uint32_t x) + { + return __builtin_bswap32(x); + } + + __attribute__((always_inline)) static inline uint16_t __REV16(uint16_t x) + { + return __builtin_bswap16(x); + } + +#ifdef __cplusplus +} // extern "C" + +void arduinoSetWait(u32 wait); +void delayEx(unsigned int ms); + +#endif //__cplusplus + +#endif /* INTERFACE_H_ */ \ No newline at end of file diff --git a/cores/opencpu/lib_M66FAR01A12BT.a b/cores/opencpu/lib_M66FAR01A12BT.a new file mode 100644 index 0000000..c7dbc49 Binary files /dev/null and b/cores/opencpu/lib_M66FAR01A12BT.a differ diff --git a/cores/opencpu/lib_app_start_m66.a b/cores/opencpu/lib_app_start_m66.a new file mode 100644 index 0000000..6c12439 Binary files /dev/null and b/cores/opencpu/lib_app_start_m66.a differ diff --git a/cores/opencpu/new.cpp b/cores/opencpu/new.cpp new file mode 100644 index 0000000..79b14eb --- /dev/null +++ b/cores/opencpu/new.cpp @@ -0,0 +1,39 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +void * operator new(size_t size) +{ + return malloc(size); +} + +void * operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void *ptr) +{ + free(ptr); +} + +void operator delete[](void *ptr) +{ + free(ptr); +} diff --git a/cores/opencpu/new.h b/cores/opencpu/new.h new file mode 100644 index 0000000..6e1b68f --- /dev/null +++ b/cores/opencpu/new.h @@ -0,0 +1,30 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef NEW_H +#define NEW_H + +#include + +void * operator new(size_t size); +void * operator new[](size_t size); +void operator delete(void * ptr); +void operator delete[](void * ptr); + +#endif + diff --git a/cores/opencpu/pgmspace.h b/cores/opencpu/pgmspace.h new file mode 100644 index 0000000..6c4a4ca --- /dev/null +++ b/cores/opencpu/pgmspace.h @@ -0,0 +1,82 @@ +/* + pgmspace.h - Definitions for compatibility with AVR pgmspace macros + + Copyright (c) 2015 Arduino LLC + + Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE +*/ + +#ifndef __PGMSPACE_H_ +#define __PGMSPACE_H_ 1 + +#include + +#define PROGMEM +#define PGM_P const char * +#define PSTR(str) (str) + +#define _SFR_BYTE(n) (n) + +typedef void prog_void; +typedef char prog_char; +typedef unsigned char prog_uchar; +typedef int8_t prog_int8_t; +typedef uint8_t prog_uint8_t; +typedef int16_t prog_int16_t; +typedef uint16_t prog_uint16_t; +typedef int32_t prog_int32_t; +typedef uint32_t prog_uint32_t; +typedef int64_t prog_int64_t; +typedef uint64_t prog_uint64_t; + +typedef const void* int_farptr_t; +typedef const void* uint_farptr_t; + +#define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) +#define strcpy_P(dest, src) strcpy((dest), (src)) +#define strncpy_P strncpy +#define strcat_P(dest, src) strcat((dest), (src)) +#define strcmp_P(a, b) strcmp((a), (b)) +#define strstr_P(a, b) strstr((a), (b)) +#define strlen_P(a) strlen((a)) +#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) + +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#define pgm_read_float(addr) (*(const float *)(addr)) +#define pgm_read_ptr(addr) (*(const void *)(addr)) + +#define pgm_read_byte_near(addr) pgm_read_byte(addr) +#define pgm_read_word_near(addr) pgm_read_word(addr) +#define pgm_read_dword_near(addr) pgm_read_dword(addr) +#define pgm_read_float_near(addr) pgm_read_float(addr) +#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) + +#define pgm_read_byte_far(addr) pgm_read_byte(addr) +#define pgm_read_word_far(addr) pgm_read_word(addr) +#define pgm_read_dword_far(addr) pgm_read_dword(addr) +#define pgm_read_float_far(addr) pgm_read_float(addr) +#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) + +#define pgm_get_far_address(addr) (&(addr)) + +#endif diff --git a/cores/opencpu/ril/inc/lib_ril_sms.h b/cores/opencpu/ril/inc/lib_ril_sms.h new file mode 100644 index 0000000..bd09574 --- /dev/null +++ b/cores/opencpu/ril/inc/lib_ril_sms.h @@ -0,0 +1,613 @@ +/*========================================================================== + | Quectel OpenCPU -- Library header files + | + | Copyright (c) 2013 Quectel Ltd. + | + |-------------------------------------------------------------------------- + | File Description + | ---------------- + | This file defines interfaces which are used in 'ril_sms.c'. + | NOTE: The interfaces are based on portable codes. Therefore they are not related to platform. + | + |-------------------------------------------------------------------------- + | + | Designed by : Vicent GAO + | Coded by : Vicent GAO + | Tested by : Vicent GAO + |-------------------------------------------------------------------------- + | Revision History + | ---------------- + | 2013/11/23 Vicent GAO Create this file by ROTVG00006-P01 + | 2015/06/03 Vicent GAO Add support for read/send con-sms by ROTVG00006-P05 + | 2015/06/05 Vicent GAO Add support for CharSet: IRA by ROTVG00006-P08 + | 2015/06/06 Vicent GAO Add support for CharSet: 8859-1 by ROTVG00006-P09 + | ------------------------------------------------------------------------ + \=========================================================================*/ + +#ifndef __LIB_RIL_SMS_H__ + +#define __LIB_RIL_SMS_H__ + +/*********************************************************************** + * MACRO CONSTANT DEFINITIONS +************************************************************************/ +//Base characters definition +#define LIB_SMS_CHAR_STAR '*' +#define LIB_SMS_CHAR_POUND '#' +#define LIB_SMS_CHAR_PLUS '+' +#define LIB_SMS_CHAR_MINUS '-' + +#define LIB_SMS_CHAR_QM '?' + +#define LIB_SMS_CHAR_A 'A' +#define LIB_SMS_CHAR_B 'B' +#define LIB_SMS_CHAR_C 'C' +#define LIB_SMS_CHAR_D 'D' +#define LIB_SMS_CHAR_E 'E' +#define LIB_SMS_CHAR_F 'F' + +#define LIB_SMS_CHAR_a 'a' +#define LIB_SMS_CHAR_b 'b' +#define LIB_SMS_CHAR_c 'c' +#define LIB_SMS_CHAR_d 'd' +#define LIB_SMS_CHAR_e 'e' +#define LIB_SMS_CHAR_f 'f' + +#define LIB_SMS_CHAR_0 '0' +#define LIB_SMS_CHAR_1 '1' +#define LIB_SMS_CHAR_2 '2' +#define LIB_SMS_CHAR_3 '3' +#define LIB_SMS_CHAR_4 '4' +#define LIB_SMS_CHAR_5 '5' +#define LIB_SMS_CHAR_6 '6' +#define LIB_SMS_CHAR_7 '7' +#define LIB_SMS_CHAR_8 '8' +#define LIB_SMS_CHAR_9 '9' + +#define LIB_SMS_PHONE_NUMBER_MAX_LEN (20) //Unit is: one character +#define LIB_SMS_USER_DATA_MAX_LEN (160) //Unit is: one character + +#define LIB_SMS_PDU_BUF_MAX_LEN (180) + +#define LIB_SMS_PHONE_NUMBER_TYPE_INTERNATIONAL (0x91) //145 +#define LIB_SMS_PHONE_NUMBER_TYPE_NATIONAL (0xA1) //161 +#define LIB_SMS_PHONE_NUMBER_TYPE_UNKNOWN (0x81) //129 +//<2015/03/23-ROTVG00006-P04-Vicent.Gao,<[SMS] Segment 4==>Fix issues of RIL SMS LIB.> +#define LIB_SMS_PHONE_NUMBER_TYPE_ALPHANUMERIC (0x50) //80 +//>2015/03/23-ROTVG00006-P04-Vicent.Gao + +#define LIB_SMS_PDU_FO_UDHI_BIT_NO_UDH (0) +#define LIB_SMS_PDU_FO_UDHI_BIT_HAS_UDH (1) + +#define LIB_SMS_PDU_DCS_NO_MSG_CLASS (0) +#define LIB_SMS_PDU_DCS_HAS_MSG_CLASS (1) + +#define LIB_SMS_PDU_DEFAULT_PID (0x00) + +#define LIB_SMS_SUBMIT_PDU_FO_SRR_BIT_NO_STATUS_REPORT (0) +#define LIB_SMS_SUBMIT_PDU_FO_SRR_BIT_HAS_STATUS_REPORT (1) + +#define LIB_SMS_SUBMIT_PDU_DEFAULT_VP_RELATIVE (167) + +#define LIB_SMS_UD_TYPE_CON_DEFAULT (LIB_SMS_UD_TYPE_CON_6_BYTE) + +#define LIB_SMS_DEFAULT_FO_IN_SUBMIT_PDU \ +( \ + ((LIB_SMS_PDU_TYPE_SUBMIT) << 0) \ + | ((LIB_SMS_VPF_TYPE_RELATIVE) << 3) \ + | ((LIB_SMS_SUBMIT_PDU_FO_SRR_BIT_NO_STATUS_REPORT) << 5) \ + | ((LIB_SMS_PDU_FO_UDHI_BIT_NO_UDH) << 6) \ +) + +/*********************************************************************** + * ENUM TYPE DEFINITIONS +************************************************************************/ + +//This enum is refer to 'GSM 03.40 Clause 9.2.3.1 TP-Message-Type-Indicator (TP-MTI)' +//Warning: Please NOT-CHANGE this enum! +typedef enum +{ + LIB_SMS_PDU_TYPE_DELIVER = 0x00, + LIB_SMS_PDU_TYPE_SUBMIT = 0x01, + LIB_SMS_PDU_TYPE_STATUS_REPORT = 0x02, + LIB_SMS_PDU_TYPE_RESERVED = 0x03, + + LIB_SMS_PDU_TYPE_INVALID = 0xFF, +} LIB_SMS_PDUTypeEnum; + +//This enum is refer to 'GSM 03.40 Clause 9.2.3.3 TP-Validity-Period-Format (TP-VPF)' +//Warning: Please NOT-CHANGE this enum! +typedef enum +{ + LIB_SMS_VPF_TYPE_NOT_PRESENT = 0x00, + LIB_SMS_VPF_TYPE_RELATIVE = 0x02, + LIB_SMS_VPF_TYPE_ENHANCED = 0x01, + LIB_SMS_VPF_TYPE_ABSOLUTE = 0x03, + + VPF_TYPE_INVALID = 0xFF +} LIB_SMS_VPFTypeEnum; + +typedef enum +{ + LIB_SMS_DCS_ALPHA_DEFAULT = 0, + LIB_SMS_DCS_ALPHA_8BIT_DATA = 1, + LIB_SMS_DCS_ALPHA_UCS2 = 2, + + LIB_SMS_DCS_ALPHA_INVALID = 0xFF +} LIB_SMS_DCSAlphaEnum; + +typedef enum +{ + LIB_SMS_DCS_MSG_CLASS_0 = 0, //PLS NOT CHANGE!! + LIB_SMS_DCS_MSG_CLASS_1 = 1, //PLS NOT CHANGE!! + LIB_SMS_DCS_MSG_CLASS_2 = 2, //PLS NOT CHANGE!! + LIB_SMS_DCS_MSG_CLASS_3 = 3, //PLS NOT CHANGE!! + LIB_SMS_DCS_MSG_CLASS_RESERVED = 4, //PLS NOT CHANGE!! + + MSG_CLASS_TYPE_INVALID = 0xFF, +} LIB_SMS_DCSMsgClassEnum; + +typedef enum +{ + LIB_SMS_DCS_COMP_UNCOMPRESSED = 0x00, //PLS NOT CHANGE!! + LIB_SMS_DCS_COMP_COMPRESSED = 0x01, //PLS NOT CHANGE!! + + LIB_SMS_DCS_COMP_INVALID = 0xFF, +} LIB_SMS_DCSCompressEnum; + +//NOTE: This enum ONLY in send/read/write text message. +typedef enum +{ + LIB_SMS_CHARSET_GSM = 0, //See 3GPP TS 23.038 Clause '6.2.1 GSM 7 bit Default Alphabet' + LIB_SMS_CHARSET_HEX = 1, + LIB_SMS_CHARSET_UCS2 = 2, + LIB_SMS_CHARSET_IRA = 3, + LIB_SMS_CHARSET_8859_1 = 4, + + //==> Warning: Please add new charset upper this line! + LIB_SMS_CHARSET_INVALID = 0xFF +} LIB_SMS_CharSetEnum; + +typedef enum +{ + LIB_SMS_UD_TYPE_NORMAL = 0, + LIB_SMS_UD_TYPE_CON_6_BYTE = 1, + LIB_SMS_UD_TYPE_CON_7_BYTE = 2, + + //==> Waring: Please add new UDH Type upper thils line!! + LIB_SMS_UD_TYPE_INVALID = 0xFF +} LIB_SMS_UDTypeEnum; + +/*********************************************************************** + * STRUCT TYPE DEFINITIONS +************************************************************************/ +typedef struct +{ + u8 uType; + u8 aNumber[LIB_SMS_PHONE_NUMBER_MAX_LEN]; + u8 uLen; +} LIB_SMS_PhoneNumberStruct; + +typedef struct +{ + u8 uYear; + u8 uMonth; + u8 uDay; + u8 uHour; + u8 uMinute; + u8 uSecond; + s8 iTimeZone; +} LIB_SMS_TimeStampStruct; + +typedef struct +{ + u8 uMsgType; //LIB_SMS_UDH_TYPE_CON_8_BIT or LIB_SMS_UDH_TYPE_CON_16_BIT + u16 uMsgRef; + u8 uMsgSeg; + u8 uMsgTot; +} LIB_SMS_ConSMSParamStruct; + +typedef struct +{ + u8 aUserData[LIB_SMS_USER_DATA_MAX_LEN]; + u16 uLen; +} LIB_SMS_UserDataStruct; + +typedef union +{ + u8 uRelative; + LIB_SMS_TimeStampStruct sAbsolute; +} LIB_SMS_ValidityPeriodUnion; + +typedef struct +{ + LIB_SMS_ConSMSParamStruct sConSMSParam; + + LIB_SMS_PhoneNumberStruct sOA; + u8 uPID; + u8 uDCS; + + LIB_SMS_TimeStampStruct sSCTS; + LIB_SMS_UserDataStruct sUserData; +} LIB_SMS_DeliverPDUParamStruct; + +typedef struct +{ + LIB_SMS_ConSMSParamStruct sConSMSParam; + + LIB_SMS_PhoneNumberStruct sDA; + u8 uPID; + u8 uDCS; + + LIB_SMS_ValidityPeriodUnion sVP; + LIB_SMS_UserDataStruct sUserData; +} LIB_SMS_SubmitPDUParamStruct; + +typedef struct +{ + LIB_SMS_PhoneNumberStruct sSCA; + u8 uFO; + + union + { + LIB_SMS_DeliverPDUParamStruct sDeliverParam; + LIB_SMS_SubmitPDUParamStruct sSubmitParam; + } sParam; + +} LIB_SMS_PDUParamStruct; + +typedef struct +{ + u8 aPDUOct[LIB_SMS_PDU_BUF_MAX_LEN]; + u16 uLen; +} LIB_SMS_PDUInfoStruct; + +/*********************************************************************** + * OTHER TYPE DEFINITIONS +************************************************************************/ + + +/*********************************************************************** + * MACRO FUNCTION DEFINITIONS +************************************************************************/ +#define LIB_SMS_SET_POINTER_VAL(p,v) \ + do \ + { \ + if((p) != NULL) \ + { \ + (*(p)) = (v); \ + } \ + } while(0) + +#define LIB_SMS_GET_MSG_TYPE_IN_PDU_FO(FirstOctet) ((FirstOctet) & 0x03) +#define LIB_SMS_GET_UDHI_IN_PDU(FirstOctet) (((FirstOctet) & 0x40) >> 6) +#define LIB_SMS_GET_VPF_IN_SUBMIT_PDU_FO(FirstOctet) (((FirstOctet) & 0x18) >> 3) + +#define LIB_SMS_SET_DEFAULT_DCS_IN_SUBMIT_PDU(CharSet,DCS) \ + do \ + { \ + u8 uAlphaZ = 0; \ + \ + if(LIB_SMS_CHARSET_HEX == (CharSet)) \ + { \ + uAlphaZ = LIB_SMS_DCS_ALPHA_8BIT_DATA; \ + } \ + else if(LIB_SMS_CHARSET_UCS2 == (CharSet)) \ + { \ + uAlphaZ = LIB_SMS_DCS_ALPHA_UCS2; \ + } \ + else if(LIB_SMS_CHARSET_IRA == (CharSet)) \ + { \ + uAlphaZ = LIB_SMS_DCS_ALPHA_DEFAULT; \ + } \ + else if(LIB_SMS_CHARSET_8859_1 == (CharSet)) \ + { \ + uAlphaZ = LIB_SMS_DCS_ALPHA_DEFAULT; \ + } \ + else \ + { \ + uAlphaZ = LIB_SMS_DCS_ALPHA_DEFAULT; \ + } \ + \ + (DCS) = (((uAlphaZ) << 2) | ((LIB_SMS_PDU_DCS_NO_MSG_CLASS) << 4) | ((LIB_SMS_DCS_COMP_UNCOMPRESSED) << 5)); \ + } while(0); + +#define LIB_SMS_GET_ALPHA_IN_PDU_DCS(DataCodeScheme,Alphabet) LIB_SMS_DecodeDCS((DataCodeScheme),NULL,&(Alphabet),NULL,NULL); + +#define LIB_SMS_IS_SUPPORT_CHARSET(CharSet) \ + ( \ + ( \ + (LIB_SMS_CHARSET_GSM == (CharSet)) \ + || (LIB_SMS_CHARSET_HEX == (CharSet)) \ + || (LIB_SMS_CHARSET_UCS2 == (CharSet)) \ + || (LIB_SMS_CHARSET_IRA == (CharSet)) \ + || (LIB_SMS_CHARSET_8859_1 == (CharSet)) \ + ) ? TRUE : FALSE \ + ) + +#define LIB_SMS_CHECK_PDU_STR(PDUStr,PDUStrLen,Result) \ + do \ + { \ + LIB_SMS_PDUParamStruct *pTmpZA = NULL; \ + \ + pTmpZA = (LIB_SMS_PDUParamStruct*)Ql_MEM_Alloc(sizeof(LIB_SMS_PDUParamStruct)); \ + if(NULL == pTmpZA) \ + { \ + (Result) = FALSE; \ + break; \ + } \ + \ + (Result) = LIB_SMS_DecodePDUStr((PDUStr),(PDUStrLen),pTmpZA); \ + Ql_MEM_Free(pTmpZA); \ + (Result) = TRUE; \ + } while(0) + +#define LIB_SMS_CHECK_SUBMIT_PDU_STR_FOR_SEND(PDUStr,PDUStrLen,Result) \ + do \ + { \ + LIB_SMS_PDUParamStruct *pTmpZA = NULL; \ + LIB_SMS_SubmitPDUParamStruct *pSubmitParamZA = NULL; \ + \ + pTmpZA = (LIB_SMS_PDUParamStruct*)Ql_MEM_Alloc(sizeof(LIB_SMS_PDUParamStruct)); \ + if(NULL == pTmpZA) \ + { \ + (Result) = FALSE; \ + break; \ + } \ + \ + (Result) = LIB_SMS_DecodePDUStr((PDUStr),(PDUStrLen),pTmpZA); \ + if(FALSE == (Result)) \ + { \ + Ql_MEM_Free(pTmpZA); \ + break; \ + } \ + \ + if(LIB_SMS_PDU_TYPE_SUBMIT != LIB_SMS_GET_MSG_TYPE_IN_PDU_FO(pTmpZA->uFO)) \ + { \ + Ql_MEM_Free(pTmpZA); \ + (Result) = FALSE; \ + break; \ + } \ + \ + pSubmitParamZA = &((pTmpZA->sParam).sSubmitParam); \ + \ + if(0 == ((pSubmitParamZA->sDA).uLen)) \ + { \ + Ql_MEM_Free(pTmpZA); \ + (Result) = FALSE; \ + break; \ + } \ + \ + Ql_MEM_Free(pTmpZA); \ + (Result) = TRUE; \ + } while(0) + +#define LIB_SMS_IS_VALID_ASCII_NUMBER_CHAR(Char) \ +( \ + ( \ + (((Char) >= LIB_SMS_CHAR_0) && ((Char) <= LIB_SMS_CHAR_9)) \ + || (LIB_SMS_CHAR_STAR == (Char)) \ + || (LIB_SMS_CHAR_POUND == (Char)) \ + || (((Char) >= LIB_SMS_CHAR_A) && ((Char) <= LIB_SMS_CHAR_C)) \ + || (((Char) >= LIB_SMS_CHAR_a) && ((Char) <= LIB_SMS_CHAR_c)) \ + ) ? TRUE : FALSE \ +) + +/*********************************************************************** + * FUNCTION DECLARATIONS +************************************************************************/ +/****************************************************************************** +* Function: LIB_SMS_IsValidHexStr +* +* Description: +* This function is used to Check the hex string is VALID or not. +* +* Parameters: +* : +* [In] The pointer of hex string +* : +* [In] The length of hex string +* +* Return: +* TRUE, This function works SUCCESS. +* FALSE, This function works FAIL! +* +* NOTE: +* 1. This is a library function. +* 2. Please ensure all parameters are VALID. +******************************************************************************/ +extern bool LIB_SMS_IsValidHexStr(char *pHexStr,u16 uHexStrLen); + +/****************************************************************************** +* Function: LIB_SMS_ConvHexOctToHexStr +* +* Description: +* This function is used to convert hex octet to hex string. +* +* Parameters: +* : +* [In] The pointer of source buffer +* : +* [In] The length of source buffer +* : +* [In] The pointer of destination buffer +* : +* [In] The length of destination buffer +* +* Return: +* TRUE, This function works SUCCESS. +* FALSE, This function works FAIL! +* +* NOTE: +* 1. This is a library function. +* 2. Please ensure all parameters are VALID. +* 3. Warning: Before call this function,MUST set <*pDestLen> to a value which specify the rest bytes of buffer. +* 4. If this function works SUCCESS,<*pDestLen> will return the bytes of buffer that has been written. +******************************************************************************/ +extern bool LIB_SMS_ConvHexOctToHexStr(const u8 *pSrc,u16 uSrcLen, char *pDest, u16 *pDestLen); + +/****************************************************************************** +* Function: LIB_SMS_ConvHexStrToHexOct +* +* Description: +* This function is used to convert hex string to hex octet. +* +* Parameters: +* : +* [In] The pointer of source buffer +* : +* [In] The length of source buffer +* : +* [In] The pointer of destination buffer +* : +* [In] The length of destination buffer +* +* Return: +* TRUE, This function works SUCCESS. +* FALSE, This function works FAIL! +* +* NOTE: +* 1. This is a library function. +* 2. Please ensure all parameters are VALID. +* 3. Warning: Before call this function,MUST set <*pDestLen> to a value which specify the rest bytes of buffer. +* 4. If this function works SUCCESS,<*pDestLen> will return the bytes of buffer that has been written. +******************************************************************************/ +extern bool LIB_SMS_ConvHexStrToHexOct(const char *pSrc,u16 uSrcLen, u8 *pDest, u16 *pDestLen); + +/****************************************************************************** +* Function: LIB_SMS_ConvCharSetToAlpha +* +* Description: +* This function is used to convert 'LIB_SMS_CharSetEnum' data to 'LIB_SMS_DCSAlphaEnum' data. +* +* Parameters: +* +* [In] Character set,It's value is in 'LIB_SMS_CharSetEnum' +* : +* [In] The pointer of source data +* +* [In] The length of source data +* : +* [In] element in TPDU +* +* [In] The length of destination data +* +* [In] The length of destination length +* Return: +* TRUE, This function works SUCCESS. +* FALSE, This function works FAIL! +* +* NOTE: +* 1. This is a library function. +* 2. Please ensure all parameters are VALID. +* 3. Warning: Before call this function,MUST set <*pDestLen> to a value which specify the rest bytes of buffer. +* 4. If this function works SUCCESS,<*pDestLen> will return the bytes of buffer that has been written. +******************************************************************************/ +extern bool LIB_SMS_ConvCharSetToAlpha(LIB_SMS_CharSetEnum eCharSet,u8 *pSrc,u16 uSrcLen,u8 uDCS,u8 *pDest,u16 *pDestLen); + +/****************************************************************************** +* Function: LIB_SMS_ConvAlphaToCharSet +* +* Description: +* This function is used to convert 'LIB_SMS_DCSAlphaEnum' data to 'LIB_SMS_CharSetEnum' data. +* +* Parameters: +* : +* [In] element in TPDU +* : +* [In] The pointer of source data +* +* [In] The length of source data +* +* [In] Character set,It's value is in 'LIB_SMS_CharSetEnum' +* +* [In] The length of destination data +* +* [In] The length of destination length +* Return: +* TRUE, This function works SUCCESS. +* FALSE, This function works FAIL! +* +* NOTE: +* 1. This is a library function. +* 2. Please ensure all parameters are VALID. +* 3. Warning: Before call this function,MUST set <*pDestLen> to a value which specify the rest bytes of buffer. +* 4. If this function works SUCCESS,<*pDestLen> will return the bytes of buffer that has been written. +******************************************************************************/ +extern bool LIB_SMS_ConvAlphaToCharSet(u8 uDCS,u8 *pSrc,u16 uSrcLen,LIB_SMS_CharSetEnum eCharSet,u8 *pDest,u16 *pDestLen); + +/****************************************************************************** +* Function: LIB_SMS_DecodePDUStr +* +* Description: +* This function is used to decode PDU string to 'LIB_SMS_PDUParamStruct' data. +* +* Parameters: +* : +* [In] The pointer of PDU string +* : +* [In] The length of PDU string +* +* [In] The pointer of 'LIB_SMS_PDUParamStruct' data +* +* Return: +* TRUE, This function works SUCCESS. +* FALSE, This function works FAIL! +* +* NOTE: +* 1. This is a library function. +* 2. Please ensure all parameters are VALID. +******************************************************************************/ +extern bool LIB_SMS_DecodePDUStr(char *pPDUStr,u16 uPDUStrLen,LIB_SMS_PDUParamStruct *pParam); + +/****************************************************************************** +* Function: LIB_SMS_DecodeDCS +* +* Description: +* This function is used to decode in TPDU +* +* Parameters: +* : +* [In] element in TPDU +* : +* [In] The pointer of message type which is same as 'DCSMsgTypeEnum' +* +* [In] The pointer of alphabet which is same as 'LIB_SMS_DCSAlphaEnum' +* +* [In] The pointer of message class which is same as 'DCSMsgClassEnum' +* +* [In] The pointer of compress flag which is same as 'DCSCompressEnum' +* Return: +* TRUE, This function works SUCCESS. +* FALSE, This function works FAIL! +* +* NOTE: +* 1. This is a library function. +* 2. Please ensure all parameters are VALID. +* 3. If you DONOT want to get certain parameter's value,please set it to NULL. +******************************************************************************/ +extern void LIB_SMS_DecodeDCS(u8 uDCS,u8 *pMsgType,u8 *pAlpha,u8 *pMsgClass,u8 *pCompress); + +/****************************************************************************** +* Function: LIB_SMS_EncodeSubmitPDU +* +* Description: +* This function is used to encode SUBMIT-PDU according to given parameters +* +* Parameters: +* : +* [In] The pointer of 'LIB_SMS_PDUParamStruct' data +* : +* [In] The pointer of 'LIB_SMS_PDUInfoStruct' data +* +* Return: +* TRUE, This function works SUCCESS. +* FALSE, This function works FAIL! +* +* NOTE: +* 1. This is a library function. +* 2. Please ensure all parameters are VALID. +******************************************************************************/ +extern bool LIB_SMS_EncodeSubmitPDU(LIB_SMS_PDUParamStruct *pParam,LIB_SMS_PDUInfoStruct *pInfo); + +#endif //#ifndef __LIB_RIL_SMS_H__ diff --git a/cores/opencpu/ril/inc/ril.h b/cores/opencpu/ril/inc/ril.h new file mode 100644 index 0000000..11d8610 --- /dev/null +++ b/cores/opencpu/ril/inc/ril.h @@ -0,0 +1,239 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file intends for OpenCPU RIL. Declare the APIs for RIL initialization, + * send AT command and register URC callback. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_H__ +#define __RIL_H__ +#include "ql_type.h" + +/****************************************************************************** +* Module URC definition +******************************************************************************/ +typedef enum { + /****************************************/ + /* System URC definition begin */ + /****************************************/ + URC_SYS_BEGIN = 0, + URC_SYS_INIT_STATE_IND, // Indication for module initialization state during boot stage, see also "Enum_SysInitState". + URC_SIM_CARD_STATE_IND, // Indication for SIM card state (state change), see also "Enum_SIMState". + URC_GSM_NW_STATE_IND, // Indication for GSM network state (state change), see also "Enum_NetworkState". + URC_GPRS_NW_STATE_IND, // Indication for GPRS network state (state change), see also "Enum_NetworkState". + URC_CFUN_STATE_IND, // Indication for CFUN state, see also "Enum_CfunState". + URC_COMING_CALL_IND, // Indication for coming call. + URC_CALL_STATE_IND, // Indication for call state (state change), see also "Enum_CallState". + URC_NEW_SMS_IND, // Indication for new short message. + URC_MODULE_VOLTAGE_IND, // Indication for abnormal voltage of module supply power. + URC_ALARM_RING_IND, // Indication for clock alarm + URC_SYS_END = 100, + /*****************************************/ + /* System URC definition end */ + /*****************************************/ + URC_END +}Enum_URCType; + +/****************************************************************************** +* Define URC struct +******************************************************************************/ +typedef struct { + u32 urcType; + void* urcResult; +}ST_URC, *PST_URC; + +/****************************************************************************** +* Define URC Handle struct +******************************************************************************/ +#define RIL_MAX_URC_PREFIX_LEN 50 + +typedef struct { + char keyword[RIL_MAX_URC_PREFIX_LEN]; + void (* handler)(const char* strURC, void* reserved); +}ST_URC_HDLENTRY; + +/****************************************************************************** +* Define the return value of AT callback function. +* RIL_ATRSP_FAILED, means that the AT command executed failed. +* RIL_ATRSP_SUCCESS, means that the AT command executed successfully. +* RIL_ATRSP_CONTINUE,means that continue to wait for the response of AT command. +* if return RIL_ATRSP_CONTINUE,the "Ql_RIL_SendATCmd" function will be blocked, +* until you return to RIL_ATRSP_FAILED or RIL_ATRSP_SUCCESS. +******************************************************************************/ +typedef enum { + RIL_ATRSP_FAILED = -1, + RIL_ATRSP_SUCCESS = 0, + RIL_ATRSP_CONTINUE = 1, +}Enum_ATRspError; + +/****************************************************************************** +* Define the return value of Ql_RIL_SendATCmd. +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +typedef enum { + RIL_AT_SUCCESS = 0, + RIL_AT_FAILED = -1, + RIL_AT_TIMEOUT = -2, + RIL_AT_BUSY = -3, + RIL_AT_INVALID_PARAM = -4, + RIL_AT_UNINITIALIZED = -5, +}Enum_ATSndError; + + +/****************************************************************************** +* Function: Ql_RIL_Initialize +* +* Description: +* This function initializes RIl-related functions. +* Set the initial AT commands, please refer to "m_InitCmds". +* Parameters: +* None. +* Return: +* None. +******************************************************************************/ +extern void Ql_RIL_Initialize(void); + + +/****************************************************************************** +* Function: Ql_RIL_SendATCmd +* +* Description: +* This function implements sending AT command with the result +* being returned synchronously.The response of the AT command +* will be reported to the callback function,you can get the results +* you want in it. +* +* Parameters: +* atCmd: +* [in]AT command string. +* atCmdLen: +* [in]The length of AT command string. +* atRsp_callBack: +* [in]Callback function for handle the response of the AT command. +* userData: +* [out]Used to transfer the customer's parameter. +* timeOut: +* [in]Timeout for the AT command, unit in ms. If set it to 0, +* RIL uses the default timeout time (3min). +* +* Return: +* RIL_AT_SUCCESS,succeed in executing AT command, and the response is OK. +* RIL_AT_FAILED, fail to execute AT command, or the response is ERROR. +* you may call Ql_RIL_AT_GetErrCode() to get the +* specific error code. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +typedef s32 (*Callback_ATResponse)(char* line, u32 len, void* userData); +extern s32 Ql_RIL_SendATCmd(char* atCmd, u32 atCmdLen, Callback_ATResponse atRsp_callBack, void* userData, u32 timeOut); + + +/****************************************************************************** +* Function: Ql_RIL_AT_GetErrCode +* +* Description: +* This function retrieves the specific error code after executing AT failed. +* +* Parameters: +* None. +* +* Return: +* 0, succeed in executing AT +* -1, fails to execute AT +* other value indicates the specific error code when executing AT failed. +* you can usually find the meaning of error code in ATC document. +******************************************************************************/ +extern s32 Ql_RIL_AT_GetErrCode(void); + + +/***************************************************************** +* Function: Ql_RIL_WriteDataToCore +* +* Description: +* This function is used to send data to the core system. +* Parameters: +* [in]data: +* Pointer to data to be send +* [in]writeLen: +* The length of the data to be written +* +* Return: +* If >= 0, indicates success, and the return value +* is the length of actual write data length +* If < 0, indicates failure to write +* +*****************************************************************/ +extern s32 Ql_RIL_WriteDataToCore (u8* data, u32 writeLen); + +/***************************************************************** +* Function: Ql_RIL_RcvDataFrmCore +* +* Description: +* This function is used to receive data from the core +* system when programing some AT commands that need to +* response with much data, such as "AT+QHTTPREAD". +* +* This function is implemented in ril_custom.c. Developer +* don't need to call this function. Under mode, this function +* will be invoken when data coming automatically. +* +* The CB_RIL_RcvDataFrmCore is defined for ustomer to define +* the callback function for each AT command. +* Parameters: +* [in]ptrData: +* Pointer to the data to be received. +* +* [in]dataLen: +* The length to be received. +* +* [in]reserved: +* Not used. +* +* Return: +* None. +* +*****************************************************************/ +typedef void (*CB_RIL_RcvDataFrmCore)(u8* ptrData, u32 dataLen, void* reserved); +void Ql_RIL_RcvDataFrmCore(u8* ptrData, u32 dataLen, void* reserved); + + +#define NUM_ELEMS(x) (sizeof(x)/sizeof(x[0])) +#define FREE_MEM(x) {if (x) {void* ptr = (void*)(x); Ql_MEM_Free(ptr); ptr = NULL;}} + +#endif //__RIL_H__ + diff --git a/cores/opencpu/ril/inc/ril_alarm.h b/cores/opencpu/ril/inc/ril_alarm.h new file mode 100644 index 0000000..4e3f3c9 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_alarm.h @@ -0,0 +1,87 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2014 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_alarm.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module declares RTC alarm related APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_ALARM_H__ +#define __RIL_ALARM_H__ +#include "ql_time.h" + +/***************************************************************** +* Function: RIL_Alarm_Create +* +* Description: +* Set and start the alarm with the specified date and time. +* +* Parameters: +* dateTime: [in] Pointer to the ST_Time +* mode:[in] +* 0: start alarm only one time. +* 1: repeat alarm every day. +* 2: repeat alarm every week. +* 3: repeat alarm every month. +* Return: +* QL_RET_OK indicates this function successes. +* QL_RET_ERR_PARAM indicates parameter error. +* QL_RET_ERR_INVALID_TIMER indicates invalid timer. +*****************************************************************/ +s32 RIL_Alarm_Create(ST_Time* dateTime, u8 mode); + +/***************************************************************** +* Function: RIL_Alarm_Query +* +* Description: +* Query the current setting of the clock alarm. +* +* Parameters: +* dateTime: [out] Pointer to the ST_Time +* Return: +* QL_RET_OK indicates this function successes. +* QL_RET_ERR_PARAM indicates parameter error. +* QL_RET_ERR_INVALID_TIMER indicates invalid timer. +*****************************************************************/ +s32 RIL_Alarm_Query(ST_Time* dateTime); + +/***************************************************************** +* Function: RIL_Alarm_Remove +* +* Description: +* Remove the alarm. +* +* Parameters: +* dateTime: [out] Pointer to the ST_Time +* +* Return: +* QL_RET_OK indicates this function successes. +* QL_RET_ERR_PARAM indicates this function fail. +*****************************************************************/ +s32 RIL_Alarm_Remove(ST_Time* dateTime); + +#endif //__RIL_ALARM_H__ diff --git a/cores/opencpu/ril/inc/ril_audio.h b/cores/opencpu/ril/inc/ril_audio.h new file mode 100644 index 0000000..f6f38af --- /dev/null +++ b/cores/opencpu/ril/inc/ril_audio.h @@ -0,0 +1,280 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2014 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_aud.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file is for OpenCPU RIL sytem definitions and APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_AUD_H__ +#define __RIL_AUD_H__ + +typedef enum +{ + AUD_CHANNEL_NORMAL= 0, + AUD_CHANNEL_HEADSET, + AUD_CHANNEL_LOUD_SPEAKER +} Enum_AudChannel; + +typedef enum { + AUD_DATA_FMT_MP3 = 1, + AUD_DATA_FMT_AMR = 2, + AUD_DATA_FMT_WAV = 3, + AUD_DATA_FMT_END +}Enum_AudDataFormat; + +typedef enum +{ + AUD_RECORD_FORMAT_AMR = 0, + AUD_RECORD_FORMAT_WAV_PCM16, + AUD_RECORD_FORMAT_WAV_ALAW, + AUD_RECORD_FORMAT_WAV_ULAW, + AUD_RECORD_FORMAT_WAV_ADPCM +} Enum_AudRecordFormat; + +/* Define volume type.*/ +typedef enum { + VOL_TYPE_MIC , /* microphone attribute */ + VOL_TYPE_SPH , /* MMI can apply to associate volume; speech sound attribute */ + VOL_TYPE_MEDIA , /* MMI can apply to associate volume; As MP3, Wave,... attribute */ + VOL_TYPE_SID , //side tone attribute + MAX_VOL_TYPE +}Enum_VolumeType; + + +typedef enum{ + AUD_PLAY_IND_OK = 5, // Playing finished normally + AUD_PLAY_IND_INTERRUPT = 6, // Interrupted by other audio tasks + AUD_PLAY_IND_UNKNOWN_ERROR = 9 // Unknown error +}Enum_AudPlayInd; + +/***************************************************************************** + * FUNCTION + * RIL_AUD_RegisterPlayCB + * + * DESCRIPTION + * This function registers a callback function that will be invoked to + * indicate the playing result. + * + * If you want to get a feedback (end indication or error code) for playing + * when calling APIs "RIL_AUD_PlayFile" and "RIL_AUD_PlayMem". You can call + * this API to reguster a callback function before calling playing API. + * + * PARAMETERS + * errCode :[OUT] error code for audio playing, which is defined in + * "AT+QAUDPLAY". + * RETURNS + * QL_RET_OK, this function succeeds. + * QL_RET_ERR_INVALID_PARAMETER, invlid paramter. + *****************************************************************************/ +typedef void (*RIL_AUD_PLAY_IND)(s32 errCode); +s32 RIL_AUD_RegisterPlayCB(RIL_AUD_PLAY_IND audCB); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_PlayFile + * DESCRIPTION + * This function is used to play audio file. + * PARAMETERS + * filePath :[in]source file name with filepath + * isRepeated :[in]repeat play mode + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_PlayFile(char* filePath, bool isRepeated); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_StopPlay + * DESCRIPTION + * This function is used to stop play audio file. + * PARAMETERS + * void + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_StopPlay(void); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_StartRecord + * DESCRIPTION + * This function is used to start record audio. + * PARAMETERS + * fileName :[in]source file name + * format :[in]source file format,see Enum_AudRecordFormat + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_StartRecord(char* fileName, Enum_AudRecordFormat format); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_StopRecord + * DESCRIPTION + * This function is used to stop record audio. + * PARAMETERS + * void + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_StopRecord(void); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_GetRecordState + * DESCRIPTION + * This function is used to get audio record state. + * PARAMETERS + * 0 Module is not in recording + * 1 Module is in recording + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_GetRecordState(u8* pState); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_SetVolume + * DESCRIPTION + * This function is used to set the volume level according to the specified volume type. + * PARAMETERS + * volType :[in] volume type,see Enum_VolumeType + * pvolLevel :[in] volume level. + * RETURNS + * s32 QL_RET_OK means AT execute suceess,see 'Error Code Definition' + *****************************************************************************/ +s32 RIL_AUD_SetVolume(Enum_VolumeType volType, u8 volLevel); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_GetVolume + * DESCRIPTION + * This function is used to get the volume level according to the specified volume type. + * PARAMETERS + * volType :[in] volume type,see Enum_VolumeType + * pVolLevel :[out] volume level. + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_GetVolume(Enum_VolumeType volType, u8* pVolLevel); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_GetChannel + * DESCRIPTION + * This function is used to get the audio channel. + * PARAMETERS + * pChannel :[out] audio channel,see Enum_AudChannel + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_GetChannel(Enum_AudChannel *pChannel); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_SetChannel + * DESCRIPTION + * This function is used to set the audio channel. + * PARAMETERS + * audChannel :[out] audio channel,see Enum_AudChannel + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_SetChannel(Enum_AudChannel audChannel); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_PlayMem + * DESCRIPTION + * This function plays audio resource data with the specified address(hex) + * through the current audio channel. + * + * PARAMETERS + * mem_addr :[in] address in memory of audio data + * mem_size :[in] size of audio data + * aud_format :[in] audio data format + * repeat :[in] once play or infinite + * + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_PlayMem(u32 mem_addr, u32 mem_size, u8 aud_format, bool repeat); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_StopPlayMem + * DESCRIPTION + * This function is used stop play memory audio file. + * PARAMETERS + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_StopPlayMem(void); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_PlayMemBg + * DESCRIPTION + * This function plays audio resource data with the specified address(hex) IN CALL + * through the current audio channel. + * + * PARAMETERS + * mem_addr :[in] address in memory of audio data + * mem_size :[in] size of audio data + * aud_format :[in] audio data format + * vol_ul :[in] volume level for uplink + * vol_dl :[in] volume level for downlink + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_PlayMemBg(u32 mem_addr, u32 mem_size, u8 aud_format, u8 vol_ul, u8 vol_dl); + +/***************************************************************************** + * FUNCTION + * RIL_AUD_StopPlayMemBg + * DESCRIPTION + * This function stops playing memory audio data in call. + * PARAMETERS + * RETURNS + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. + *****************************************************************************/ +s32 RIL_AUD_StopPlayMemBg(void); + +#endif //__RIL_AUD_H__ diff --git a/cores/opencpu/ril/inc/ril_bluetooth.h b/cores/opencpu/ril/inc/ril_bluetooth.h new file mode 100644 index 0000000..2900e45 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_bluetooth.h @@ -0,0 +1,725 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2015 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_bluetooth.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The API functions defined in this file are used for managing Bluetooth + * devices and services. + * + * Author: + * ------- + * ------- + * Designed by : Stanley YONG + * Coded by : Stanley YONG + * Tested by : + + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_BLUETOOTH_H__ +#define __RIL_BLUETOOTH_H__ + +#define BT_OFF (0) +#define BT_ON (1) +#define BT_NAME_LEN 56 /* 18 * 3 + 2 */ +#define BT_ADDR_LEN 13 +#define BT_PIN_LEN 7 +#define MAX_BT_DEV_CNT 30 +#define MAX_BT_SCAN_CNT 20 +#define MAX_BT_SCAN_COD 255 +#define MAX_BT_SCAN_TIMEOUT 255 +#define MAX_BT_PAIRED_CNT 10 + + + + +// SPP connection mode +typedef enum{ + BT_SPP_CONN_MODE_AT = 0, // AT command mode + BT_SPP_CONN_MODE_BUF, // Buffer Access Mode (default mode) + BT_SPP_CONN_MODE_TRANS // Transparent Access Mode +}Enum_BT_SPP_ConnMode; + +// Bluetooth profile Id +typedef enum{ + BT_PROFILE_SPP = 0, + BT_PROFILE_OBEX_PBA_CLIENT, + BT_PROFILE_OBEX_PBA_PROFILE, + BT_PROFILE_OBEX_OBJECT_PUSH_SERVICE, + BT_PROFILE_OBEX_OBJECT_PUSH_CLIENT, + BT_PROFILE_HF_PROFILE, + BT_PROFILE_HFG_PROFILE, + BT_PROFILE_END +}Enum_BTProfileId; + + +typedef enum{ + BT_INVISIBLE= 0, + BT_VISIBLE_FOREVER, + BT_VISIBLE_TIMEOUT, + BT_VISIBLE_END + +}Enum_VisibleMode; + + +// Definitions for Bluetooth device status +typedef enum{ + BT_STATUS_INITIAL, // 0 Initial on + BT_STATUS_DEACTIVATING, // 1 Deactivating + BT_STATUS_ACTIVATING, // 2 Activating + BT_STATUS_IDLE = 5, // 5 Idle + BT_STATUS_SCANNING, //6 Scanning + BT_STATUS_SCANRESINDICATE,// 7 Scan result indicate + BT_STATUS_CANCELSCAN, // 8 Scan cancelling + BT_STATUS_INITPAIRING, // 9 Initiate pairing + BT_STATUS_CONNECTING = 12, //12 Connecting + BT_STATUS_UNPAIRING, // 13 Un-pairing + BT_STATUS_DELPAIRED, // 14 Deleting paired device + BT_STATUS_DELALL, // 15 Deleting all + BT_STATUS_DISCONNECT, // 16 Disconnecting + BT_STATUS_NUMERICCONFIRM = 19, //19 Numeric Confirm + BT_STATUS_NUMERICCONFIRMRSP, //20 Numeric Confirm Response + BT_STATUS_CONACCEPTCONFIRMIND = 25, //25 connect accept confirm indication + BT_STATUS_SERVICEREFRESHING, //26 service refreshing + BT_STATUS_DEVICENAMESET, //29 device name setting + BT_STATUS_AUTHSET,//30 authentication setting + BT_STATUS_RELEASEALLCONN,//31 release all connection + BT_STATUS_ACTIVATEPROFILE = 36 ,//activating profiles + DEV_STATE_END +}Enum_BTDevStatus; + +typedef enum{ + MSG_NONE = 0, + MSG_BT_SCAN_IND, // Scanning indication + MSG_BT_PAIR_IND, + MSG_BT_PAIR_CNF_IND, + MSG_BT_RECV_IND, + + MSG_BT_PAIR_REQ, + MSG_BT_CONN_REQ, + MSG_BT_DISCONN_IND, + + MSG_BT_SPP_CONN_IND, + MSG_BT_VISIBLE_IND, + +}Enum_BTMsg; + + +/* Bluetooth device address struct */ +typedef struct +{ + u32 lap; /* Lower Address Part 00..23 */ + u8 uap; /* upper Address Part 24..31 */ + u16 nap; /* Non-significant 32..47 */ +} ST_BT_Addr; + + +typedef unsigned int BT_DEV_HDL; + +typedef struct{ + BT_DEV_HDL devHdl; + char name[BT_NAME_LEN]; + char addr[BT_ADDR_LEN]; +}ST_BT_BasicInfo; + +// for internal use +typedef struct{ + ST_BT_BasicInfo btDevice; + s32 devId; + s32 pairId; // -1, not paired + s32 connId; // -1, not connected + s32 profileId; //-1,no profile + s32 reserved; +}ST_BT_DevInfo; + +typedef enum{ + BT_ERROR_NONE = 0, + BT_ERROR_VISIBLE_TIMEOUT, + BT_ERROR_SCAN, + BT_ERROR_END +}Enum_BT_ErrorCode; + + +typedef enum{ + URC_BT_NONE = 0, + URC_BT_INVISIBLE, + URC_BT_SCAN_FINISHED, + URC_BT_SCAN_FOUND, + URC_BT_NEED_PASSKEY, + URC_BT_NO_NEED_PASSKEY, + URC_BT_PAIR_CNF_SUCCESS, + URC_BT_PAIR_CNF_FAIL, + URC_BT_CONN_SUCCESS, + URC_BT_CONN_FAIL, + URC_BT_CONN_REQ, + URC_BT_DISCONNECT_PASSIVE, + URC_BT_DISCONNECT_POSITIVE, + URC_BT_DATA_RECIEVE, + URC_BT_END +}Enum_BT_URCCode; + + + + + + + + + +typedef void (*CALLBACK_BT_IND)(s32 event, s32 errCode, void* param1, void* param2); + +//below apis can be used to manage the table +s32 BT_DevMngmt_GetDeviceId(const u32 hdl); +s32 BT_DevMngmt_GetPairedId(const u32 hdl); +s32 BT_DevMngmt_GetConnId(const u32 hdl); +s32 BT_DevMngmt_GetProfileId(const u32 hdl); +char * BT_DevMngmt_GetDevName(const u32 hdl); +char * BT_DevMngmt_GetDevAddr(const u32 hdl); + + + + + + + + + + + + +/***************************************************************** +* Function: RIL_BT_Switch +* +* Description: +* Turn on /off bluetooth +* +* Parameters: +* on_off [in] : 0 --- off ,1 ----- on +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_Switch(u8 on_off); + +/***************************************************************** +* Function: RIL_BT_GetPwrState +* +* Description: +* query current bluetooth power state +* +* Parameters: +* p_on_off [out] : 0 --- off ,1 ----- on +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_GetPwrState(s32 *p_on_off); + + +/***************************************************************** +* Function: RIL_BT_Initialize +* +* Description: +* bluetooth initialization after power on ,register callback and update paired info +* +* Parameters: +* cb: callback to be registered +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_Initialize(CALLBACK_BT_IND cb); + + + +/***************************************************************** +* Function: RIL_BT_SetName +* +* Description: +* set the name of bluetooth +* +* Parameters: +* name [in] : bluetooth name to set +* len [in] : length of bluetooth name,max length 56 bytes +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_SetName(char *name,u8 len); + + +/***************************************************************** +* Function: RIL_BT_GetName +* +* Description: +* get the name of bluetooth +* +* Parameters: +* name [out] : bluetooth name to get + len [in] : sizeof of param 1 +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_GetName(char *name/*char addr[BT_NAME_LEN]*/,u8 len); + + + + + + +/***************************************************************** +* Function: RIL_BT_GetLocalAddr +* +* Description: +* get the device address of bluetooth +* +* Parameters: +* ptrAddr [out] : bluetooth addr to get ,length is fixed 13 bytes including '\0' + len [in] : sizeof param 1 +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + +s32 RIL_BT_GetLocalAddr(char* ptrAddr/*char addr[BT_ADDR_LEN]*/,u8 len); + + + + +/***************************************************************** +* Function: RIL_BT_SetVisble +* +* Description: +* set the bluetooth to be viewed or not +* +* Parameters: +* mode [in] : visible mode 0 :invisble 1: visible forever 2.visibility temporary on ,see Enum_VisibleMode +* timeout [in] : when mode is set to 2 ,this param decide during which time bluetooth can be found by others +* unit second,can be 1-255 ,after timout ,MSG_BT_INVISIBLE will be triggered,other mode is ignored +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + +s32 RIL_BT_SetVisble(Enum_VisibleMode mode,u8 timeout); + + + +/***************************************************************** +* Function: RIL_BT_GetVisble +* +* Description: +* get the current bluetooth visble mode +* +* Parameters: +* mode [out] : visible mode 0 :invisble 1: visible forever 2.visibility temporary on ,see Enum_VisibleMode +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + +s32 RIL_BT_GetVisble(s32 *mode); + + + + + +/***************************************************************** +* Function: RIL_BT_StartScan +* +* Description: +* start scan the around bt devices +* +* Parameters: +* +* @maxDevCount: 0-20, default 20 +* @CoD: 0-255, default 0 +* @timeout: unit in second. 1-255, default 60s +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + +s32 RIL_BT_StartScan(u16 maxDevCount, u16 CoD, u16 timeout); + + +/***************************************************************** +* Function: RIL_BT_GetDevListInfo +* +* Description: +* get current bt devices info + + ADDR DEVID HANDLER PAIRID CONNID PROFILE NAME +* +* Parameters: +* +* void +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + +s32 RIL_BT_GetDevListInfo(void); + + +/***************************************************************** +* Function: RIL_BT_GetDevListPointer +* +* Description: +* get the dev list pointer ,then you can use it to get items of the list + before you use the pointer ,RIL_BT_GetDevListInfo can help you see valid + items to operate +* +* Parameters: +* +* void +* Return: +* the pointer to dev list + ST_BT_DevInfo ** ptr; + ptr = RIL_BT_GetDevListPointer(); + ptr[i]->btDevice.devHdl + +*****************************************************************/ + +ST_BT_DevInfo ** RIL_BT_GetDevListPointer(void); + + +/***************************************************************** +* Function: RIL_BT_StopScan +* +* Description: +* stop the scan process +* +* Parameters: +* void +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_StopScan(void); + + +/***************************************************************** +* Function: RIL_BT_QueryState +* +* Description: +* query current bluetooth state and update paired items +* +* Parameters: +* status [out] : current BT status see Enum_BTDevStatus +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_QueryState(s32 *status); + + + +/***************************************************************** +* Function: RIL_BT_PairReq +* +* Description: +* request to pair a bt device ,for paired items ,ignore this step ,directly to connect +* +* Parameters: +* hdlDevice :[in] the bt handler to pair +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_PairReq(BT_DEV_HDL hdlDevice); + + + +/***************************************************************** +* Function: RIL_BT_PairConfirm +* +* Description: +* confirm to pair +* +* Parameters: +* accept :[in] whether to accpect the pair request--- 0 :reject 1:accept +* pincode :[in] the passkey used to pair +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_PairConfirm(bool accept, char* pinCode); + + + + +/***************************************************************** +* Function: RIL_BT_Unpair +* +* Description: +* unpair a paired bt device +* +* Parameters: +* hdlDevice :[in] the bt handler to unpair +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_Unpair(BT_DEV_HDL hdlDevice); + + + +/***************************************************************** +* Function: RIL_BT_GetSupportedProfile +* +* Description: +* returns the profiles suppoerted both by the local device and the other side device,for paired items +* +* Parameters: +* hdlDevice :[in] the bt handler to get support profile + profile_support :[out] the supported profile get for both sides ,see Enum_BTProfileId + len :[in] the array length +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_GetSupportedProfile(BT_DEV_HDL hdlDevice,s32 *profile_support,u8 len); + + + + + +/***************************************************************** +* Function: RIL_BT_ConnReq +* +* Description: +* request to connect a paired bt device +* +* Parameters: +* hdlDevice :[in] the bt handler to connect +* profileId :[in] profile type when connect ,see Enum_BTProfileId +* mode :[in] connect type ,see Enum_BT_SPP_ConnMode +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_ConnReq(BT_DEV_HDL hdlDevice, u8 profileId, u8 mode); + + +/***************************************************************** +* Function: RIL_BT_SPP_DirectConn +* +* Description: +* use addr to make a direct connect ,so you don't need to scan or concern the paring process +* only support SPP connection +* +* Parameters: +* btMacAddr :[in] the bt addr to connect +* mode :[in] connect type ,see Enum_BT_SPP_ConnMode +* pinCode : [in] pairkey + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_SPP_DirectConn(char* btMacAddr, u8 mode, char* pinCode); + + +/***************************************************************** +* Function: RIL_BT_ConnAccept +* +* Description: +* accept to connect +* +* Parameters: +* accept :[in] 0--reject 1---accept + mode :[in] connect type ,see Enum_BT_SPP_ConnMode + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_ConnAccept(bool accept , u8 mode); + + +/***************************************************************** +* Function: RIL_BT_Disconnect +* +* Description: +* disconnect a bt connection +* +* Parameters: +* hdlDevice :[in] the handler to disconnect + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_Disconnect(BT_DEV_HDL hdlDevice); + + +/***************************************************************** +* Function: RIL_BT_SPP_Send +* +* Description: +* send data in SPP mode +* +* Parameters: +* hdlDevice :[in] the handler to send + ptrData :[in] the ptr to data to be sent + lenToSend :[in] the length of data to be sent + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + s32 RIL_BT_SPP_Send(BT_DEV_HDL hdlDevice, u8* ptrData, u32 lenToSend,u32* actualSend); + + + +/***************************************************************** +* Function: RIL_BT_SPP_Read +* +* Description: +* read data in SPP mode +* +* Parameters: +* hdlDevice :[in] the handler to read + ptrBuffer :[in] the ptr to store the readed data + lenToRead :[in] the length of data to read + actualReadlen: [out] the actually length readed + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_SPP_Read(BT_DEV_HDL hdlDevice, u8* ptrBuffer, u32 lenToRead ,u32 *actualReadlen); + + + + +#endif //__RIL_BLUETOOTH_H__ + diff --git a/cores/opencpu/ril/inc/ril_dtmf.h b/cores/opencpu/ril/inc/ril_dtmf.h new file mode 100644 index 0000000..3b9fc35 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_dtmf.h @@ -0,0 +1,203 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** +* +* Filename: +* --------- +* ril_dtmf.h +* +* Project: +* -------- +* OpenCPU +* +* Description: +* ------------ +* The module defines the information, and APIs related to DTMF. +* +* Author: +* ------- +* ------- +* +*============================================================================ +* HISTORY +*---------------------------------------------------------------------------- +* +****************************************************************************/ +#ifndef __RIL_DTMF_H__ +#define __RIL_DTMF_H__ + +#include "ql_type.h" + +/*********************************************************************** + * ENUM TYPE DEFINITIONS +************************************************************************/ +typedef enum +{ + RIL_DETThreshold_Min = 1, + RIL_DETThreshold_100MS, // Configure 1400Hz or 2300Hz detection threshold, duration of which is 100ms + RIL_DETThreshold_400MS, // Configure 1400Hz and 2300Hz 400ms detection threshold + RIL_DETThreshold_DTMF, // Configure DTMF detection threshold + RIL_DETThreshold_Max = 5 +} Enum_ToneDet_Mode; + +typedef enum +{ + RIL_WDTMF_VOLUME0 = 0, // uplink or downlink channel of the volume + RIL_WDTMF_VOLUME1, + RIL_WDTMF_VOLUME2, + RIL_WDTMF_VOLUME3, + RIL_WDTMF_VOLUME4, + RIL_WDTMF_VOLUME5, + RIL_WDTMF_VOLUME6, + RIL_WDTMF_VOLUME7 +} Enum_WDTMF_Vomume; + + +/**************************************************** +* DTMF detection function definition +****************************************************/ +/***************************************************************** +* Function: RIL_ToneDet_Open +* +* Description: +* This function is used to Open DTMF detect. +* +* Parameters: +* cb_ToneDet_hdl: +* [IN] call back function to handle DTMF detected. +* dtmfCode: +* [OUT] detected DTMF tone code corresponding ASSCII. +* timems: +* [OUT] persistence time of the tone, unit is ms. +* only when is 69(1400Hz) or 70(1400Hz) is available, otherwise it will always be -1. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +typedef void (* CB_ToneDet)( s32 dtmfCode, s32 timems ); +s32 RIL_ToneDet_Open( CB_ToneDet cb_ToneDet_hdl ); + +/***************************************************************** +* Function: RIL_ToneDet_Close +* +* Description: +* The function is used to close DTMF detect. +* +* Parameters: +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_ToneDet_Close( void ); + +/***************************************************************** +* Function: RIL_ToneDet_Set +* +* Description: +* This function is used to set DTMF detection. +* +* Parameters: +* : +* [IN] 2-4, select which threshold to set. +* : +* [IN] prefix pause number. +* : +* [IN] low threshold value. +* : +* [IN] high threshold value. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_ToneDet_Set( Enum_ToneDet_Mode mode, u32 pause, u32 low, u32 high ); + +/***************************************************************** +* Function: RIL_ToneDet_Get +* +* Description: +* This function is used to get settings of DTMF detection. +* +* Parameters: +* : +* [IN] 2-4, select which threshold to get. +* : +* [IN] low threshold value. +* : +* [IN] high threshold value. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_ToneDet_Get( Enum_ToneDet_Mode mode, u32 *low, u32 *high ); + +/**************************************************** +* DTMF send functions definition +****************************************************/ +/***************************************************************** +* Function: RIL_WDTMF_Send +* +* Description: +* This function is used to play DTMF tone during the call. +* +* Parameters: +* ul_volume: +* [IN] 0-7, uplink channel of the volume. +* dl_volume: +* [IN] 0-7, downlink channel of the volume, recommended to be set as 0. +* dtmfStr: +* [IN] this string consists of DTMF tone strings, Duration of each DTMF tone(unit is ms) and Mute time (unit is ms). +* example: "0A5,50,50,3,100,50"-->0A5 is DTMF tone strings, continuancetime 50ms, mute time 50ms; +* The rest of the three Numbers is the same meaning as before. the total lenth of dtmfStr must be less than 400. +* cb_WDTMF_hdl: +* [IN] callback function for QWDTMF URC handle. +* result: +* [OUT] Indicate status of sending DTMF. +* If is 5, it means sending DTMF successfully; +* If is not 5, it means sending DTMF unsuccessfully; +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +typedef void (* CB_WDTMF)( s32 result ); +s32 RIL_WDTMF_Send( Enum_WDTMF_Vomume ul_volume, Enum_WDTMF_Vomume dl_volume, u8 *dtmfStr, CB_WDTMF cb_WDTMF_hdl ); + + +#endif //__RIL_DTMF_H__ + diff --git a/cores/opencpu/ril/inc/ril_ftp.h b/cores/opencpu/ril/inc/ril_ftp.h new file mode 100644 index 0000000..cc868cb --- /dev/null +++ b/cores/opencpu/ril/inc/ril_ftp.h @@ -0,0 +1,86 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_ftp.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file is for OpenCPU RIL sytem definitions and APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_SYSTEM_H__ +#define __RIL_FTP_H__ + +typedef void (*CallBack_Ftp_Upload)(s32 result,s32 size); +typedef void (*CallBack_Ftp_Download)(s32 result,s32 size); + +typedef struct{ +char *prefix; +s32 data; +}ST_AT_ftpParam; + +typedef enum +{ + FTP_STATUS_IDLE = 0, //No FTP service. + FTP_STATUS_OPENING, //Opening an FTP service. + FTP_STATUS_OPENED, //The FTP service is opened and idle. + FTP_STATUS_WORKING, //Sending FTP commands to the FTP server and receiving response from the FTP server to start data transfer. + FTP_STATUS_TRANSFER, //Transferring data between the module and the FTP server. + FTP_STATUS_CLOSING, //Closing the FTP service. + FTP_STATUS_CLOSED //The FTP service is closed + +}ENUM_FTP_STATUS; + +s32 RIL_FTP_QFTPOPEN(u8* hostName, u32 port,u8* userName,u8* password, bool mode); + +s32 RIL_FTP_QFTPCLOSE(void); + +s32 RIL_FTP_QFTPPUT(u8* fileName, u32 fileSize, u32 timeOut, CallBack_Ftp_Upload ftpPut_CB); + +s32 RIL_FTP_QFTPGET(u8* fileName, u32 fileSize,CallBack_Ftp_Download ftpGet_CB); + +s32 RIL_FTP_QFTPPATH(u8* pathName); + +s32 RIL_FTP_QFTPCFG(u8 type, u8* value); + +s32 RIL_FTP_QFTPSTAT(s32* state); + +s32 RIL_FTP_QFTPLEN(s32* len); + +s32 RIL_FTP_QFTPRENAME(u8* sourcName, u8* targetName); + +s32 RIL_FTP_QFTPSIZE(u8* fileName, u32* fileSize); + +s32 RIL_FTP_QFTPDELETE(u8* fileName); + +s32 RIL_FTP_QFTPMKDIR(u8* pathName); + +s32 RIL_FTP_QFTPRMDIR(u8* pathName); + +s32 RIL_FTP_QIDEACT(void); + +#endif + + diff --git a/cores/opencpu/ril/inc/ril_http.h b/cores/opencpu/ril/inc/ril_http.h new file mode 100644 index 0000000..8f97a49 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_http.h @@ -0,0 +1,33 @@ +#ifndef __RIL_HTTP_H__ +#define __RIL_HTTP_H__ + +typedef enum{ + HTTP_ACTION_IDLE = 0, + HTTP_ACTION_SETRUL, + HTTP_ACTION_GET_REQ, + HTTP_ACTION_POST_REQ, + HTTP_ACTION_READ_RSP, + HTTP_ACTION_DOWNLOAD_FILE +}Enum_HTTP_Ation; + +// +// +// Set http server URL address. +s32 RIL_HTTP_SetServerURL(char* strURL, u16 len); +// +// Send http-get request. +s32 RIL_HTTP_RequestToGet(u32 timeout); +// +// Send http-post request. +s32 RIL_HTTP_RequestToPost(char* strPostMsg, u16 len); +// +// Read response from HTTP server. +s32 RIL_HTTP_ReadResponse(u32 timeout, CB_RIL_RcvDataFrmCore cb_rcvData); +// +// Downlaod the file from http server to a local file. +// The http file is specified by the url when calling RIL_HTTP_SetServerURL(). +typedef void (*CB_HTTP_DwnldFile)(u32 dllSize, u32 cntntLen, s32 errCode); +s32 RIL_HTTP_DownloadFile(char* filePath, u32 size, CB_HTTP_DwnldFile cb); + +#endif //__RIL_HTTP_H__ + diff --git a/cores/opencpu/ril/inc/ril_location.h b/cores/opencpu/ril/inc/ril_location.h new file mode 100644 index 0000000..b9fc8c3 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_location.h @@ -0,0 +1,63 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** +* +* Filename: +* --------- +* ril_location.h +* +* Project: +* -------- +* OpenCPU +* +* Description: +* ------------ +* +* +* Author: +* ------- +* ------- +* +*============================================================================ +* HISTORY +*---------------------------------------------------------------------------- +* +****************************************************************************/ +#ifndef __RIL_LOCATION_H__ +#define __RIL_LOCATION_H__ + +#include "ql_type.h" + + +// Cell info +typedef struct { + u16 mcc; + u16 mnc; + u32 lac; + s32 cellId; + s16 rssi; + u16 timeAd; +}ST_CellInfo; + +// Location info +typedef struct{ + float longitude; + float latitude; + //u16 reserved; +}ST_LocInfo; + +typedef void(*CB_LocInfo)(s32 result,ST_LocInfo* loc_info); + +s32 RIL_GetLocation(CB_LocInfo cb_loc); +s32 RIL_GetLocation_Ex(ST_LocInfo* locinfo); +s32 RIL_GetLocationByCell(ST_CellInfo* cell, CB_LocInfo cb_loc); + +#endif //__RIL_LOCATION_H__ + diff --git a/cores/opencpu/ril/inc/ril_network.h b/cores/opencpu/ril/inc/ril_network.h new file mode 100644 index 0000000..f64707b --- /dev/null +++ b/cores/opencpu/ril/inc/ril_network.h @@ -0,0 +1,252 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_network.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file declares some API functions, which are related to network, including + * SIM state, GSM/GPRS network state and signal strength, and so forth. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_NETWORK_H__ +#define __RIL_NETWORK_H__ +#include "ql_type.h" +#include "ril_sim.h" + + +/**************************************************************************** + * Definition for network State + ***************************************************************************/ +typedef enum { + NW_STAT_NOT_REGISTERED = 0, // Not register to network + NW_STAT_REGISTERED, // The normal network state + NW_STAT_SEARCHING, // Searching network + NW_STAT_REG_DENIED, // The register request is denied + NW_STAT_UNKNOWN, + NW_STAT_REGISTERED_ROAMING //Registered and Roaming state +}Enum_NetworkState; + +typedef enum { + IP_INITIAL=0, + IP_START, + IP_CONFIG, + IP_IND, + IP_GPRSACT, + IP_STATUS, + TCP_PROCESSING, + UDP_PROCESSING=TCP_PROCESSING, + IP_CLOSE, + CONNECT_OK, + GPRS_CONTEXT_DEACT, + IP_STATUS_END +}Enum_ContextIPState; + +typedef struct{ + int rssi; + int ber; +}ST_CSQ_Reponse; + + +/****************************************************************************** +* Function: RIL_NW_GetGSMState +* +* Description: +* This function gets the GSM network register state. +* +* Parameters: +* stat: +* [out]GSM State. +* Return: +* One value of Enum_NetworkState: network register state code. +* -1 : fail to get the network state. +******************************************************************************/ +s32 RIL_NW_GetGSMState(s32 *stat); + +/****************************************************************************** +* Function: RIL_NW_GetGPRSState +* +* Description: +* This function gets the GPRS network register state. +* +* Parameters: +* stat: +* [out]GPRS State. +* Return: +* One value of Enum_NetworkState: network register state code. +* -1 : fail to get the network state. +******************************************************************************/ +s32 RIL_NW_GetGPRSState(s32 *stat); + +/****************************************************************************** +* Function: RIL_NW_GetSignalQuality +* +* Description: +* This function gets the signal quality level and bit error rate. +* +* Parameters: +* rssi: +* [out] Signal quality level, 0~31 or 99. 99 indicates module +* doesn't register to GSM network. +* +* ber: +* [out] The bit error code of signal. +* Return: +* QL_RET_OK indicates success. +* QL_RET_ERR_INVALID_PARAMETER indicates something wrong for input parameters. +******************************************************************************/ +s32 RIL_NW_GetSignalQuality(u32* rssi, u32* ber); + +/****************************************************************************** +* Function: RIL_NW_SetGPRSContext +* +* Description: +* This function select a context as foreground context +* +* Parameters: +* foregroundContext: +* [IN] Anumeric indicates which context will be set as foreground context.The range is 0-1. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_NW_SetGPRSContext(u8 foregroundContext); + +/****************************************************************************** +* Function: RIL_NW_SetAPN +* +* Description: +* This function sets the APN for the current context. +* +* Parameters: +* mode: +* [in] wireless connection mode. +* 0=CSD, not supported. +* 1=GPRS +* apn: +* [in] pointer to the APN name. +* +* userName: +* [in] pointer to the user name. +* +* pw: +* [in] pointer to the password. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_NW_SetAPN(u8 mode, char* apn, char* userName, char* pw); + +/****************************************************************************** +* Function: RIL_NW_GetIPStatus +* +* Description: +* This function the status of IP protocol stack. +* +* Parameters: +* None. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_NW_GetIPStatus(void); + +/****************************************************************************** +* Function: RIL_NW_OpenPDPContext +* +* Description: +* This function opens/activates the GPRS PDP context. The PDP +* context id is specified by RIL_NW_SetGPRSContext(). +* +* Parameters: +* None. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_NW_OpenPDPContext(void); + +/****************************************************************************** +* Function: RIL_NW_ClosePDPContext +* +* Description: +* This function closes/deactivates the GPRS PDP context.The PDP +* context id is specified by RIL_NW_SetGPRSContext(). +* +* Parameters: +* None. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_NW_ClosePDPContext(void); + +/****************************************************************************** +* Function: RIL_NW_GetOperator +* +* Description: +* This function gets the network operator that module registered. +* +* Parameters: +* operator: +* [out] a string with max 16 characters, which indicates the +* network operator that module registered. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_NW_GetOperator(char*); + +#endif // __RIL_NETWORK_H__ diff --git a/cores/opencpu/ril/inc/ril_ntp.h b/cores/opencpu/ril/inc/ril_ntp.h new file mode 100644 index 0000000..587a197 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_ntp.h @@ -0,0 +1,62 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2014 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_ntp.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements NTP related APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_NTP_H__ +#define __RIL_NTP_H__ + +#include "ql_type.h" + + +/***************************************************************** +* Function: RIL_NTP_START +* +* Description: +* This function is used to synchronize time with NTP server. +* +* Parameters: +* : [IN] point to the string which indicates NTP server address. +* : [IN] the NTP server port. +* : [IN] callback function for NTP URC handle. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +typedef void (* CB_NTPCMD)(char *strURC); +s32 RIL_NTP_START(u8 *server_addr, u16 server_port, CB_NTPCMD cb_NTPCMD_hdl); + +#endif //__RIL_NTP_H__ + diff --git a/cores/opencpu/ril/inc/ril_sim.h b/cores/opencpu/ril/inc/ril_sim.h new file mode 100644 index 0000000..ca47af4 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_sim.h @@ -0,0 +1,112 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_network.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file declares some API functions, which are related to SIM card, including + * SIM state, IMSI and CCID. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_SIM_H__ +#define __RIL_SIM_H__ +#include "ql_type.h" + + +/**************************************************************************** + * Definition for SIM Card State + ***************************************************************************/ +typedef enum { + SIM_STAT_NOT_INSERTED = 0, + SIM_STAT_READY, + SIM_STAT_PIN_REQ, + SIM_STAT_PUK_REQ, + SIM_STAT_PH_PIN_REQ, + SIM_STAT_PH_PUK_REQ, + SIM_STAT_PIN2_REQ, + SIM_STAT_PUK2_REQ, + SIM_STAT_BUSY, + SIM_STAT_NOT_READY, + SIM_STAT_UNSPECIFIED + }Enum_SIMState; + + +/****************************************************************************** +* Function: RIL_SIM_GetSimState +* +* Description: +* This function gets the state of SIM card. +* +* Related AT: +* "AT+CPIN?". +* +* Parameters: +* stat: +* [out]SIM card State code, one value of Enum_SIMState. +* Return: + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. +******************************************************************************/ +s32 RIL_SIM_GetSimState(s32* state); + +/****************************************************************************** +* Function: RIL_SIM_GetIMSI +* +* Description: +* This function gets the state of SIM card. +* +* Related AT: +* "AT+CIMI". +* +* Parameters: +* imsi: +* [out]IMSI number, a string of 15-byte. +* Return: + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. +******************************************************************************/ +s32 RIL_SIM_GetIMSI(char* imsi); + +/****************************************************************************** +* Function: RIL_SIM_GetCCID +* +* Description: +* This function gets the CCID of SIM card. +* +* Related AT: +* "AT+CCID". +* +* Parameters: +* ccid: +* [out] CCID number, a string of 20-byte. +* Return: + * RIL_AT_SUCCESS, this function succeeds. + * Or, please see the definition of Enum_ATSndError. +******************************************************************************/ +s32 RIL_SIM_GetCCID(char* ccid); + +#endif //__RIL_SIM_H__ + diff --git a/cores/opencpu/ril/inc/ril_sms.h b/cores/opencpu/ril/inc/ril_sms.h new file mode 100644 index 0000000..7cd281c --- /dev/null +++ b/cores/opencpu/ril/inc/ril_sms.h @@ -0,0 +1,380 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_sms.h + * + * Project: + * -------- + * OpenCPU SDK + * + * Description: + * ------------ + * The file is for SMS RIL function. All APIs depend on OpenCPU RIL feature. + * + * Author: + * ------- + * ------- + * Designed by : Vicent GAO + * Coded by : Vicent GAO + * Tested by : Vicent GAO + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * 2013/11/19 Vicent GAO This file is created by ROTVG00006-P01 + * 2015/06/02 Vicent GAO Add support for read/send con-sms by ROTVG00006-P05 + ****************************************************************************/ +#ifndef __RIL_SMS_H__ +#define __RIL_SMS_H__ + +#include "Lib_ril_sms.h" + +/*********************************************************************** + * MACRO CONSTANT DEFINITIONS +************************************************************************/ +#define SMS_MEM_CHAR_LEN 4 + +#define RIL_SMS_PHONE_NUMBER_MAX_LEN (LIB_SMS_PHONE_NUMBER_MAX_LEN + 2) //It may contain '+' at the first position and will contain '\0' at the end. +#define RIL_SMS_TEXT_DATA_MAX_LEN (4 * LIB_SMS_USER_DATA_MAX_LEN) +#define RIL_SMS_TIME_STAMP_STR_MAX_LEN (22) //It will contain '\0' at the end. + +/*********************************************************************** + * ENUM TYPE DEFINITIONS +************************************************************************/ +//Warning:Please NOT-CHANGE this enum's value +typedef enum { + RIL_SMS_STORAGE_TYPE_SM = 0, + RIL_SMS_STORAGE_TYPE_ME = 1, + RIL_SMS_STORAGE_TYPE_MT = 2, +} Enum_RIL_SMS_StorageType; + +//Warning:Please NOT-CHANGE this enum's value +typedef enum +{ + RIL_SMS_DEL_INDEXED_MSG = 0, /* Single message by index */ + RIL_SMS_DEL_READ_MSG = 1, /* Already read messages */ + RIL_SMS_DEL_READ_SENT_MSG = 2, /* Read and sent messages */ + RIL_SMS_DEL_READ_SENT_UNSENT_MSG = 3, /* Read ,sent and unsent messages */ + RIL_SMS_DEL_ALL_MSG = 4,/* All messages in current storage */ +} Enum_RIL_SMS_DeleteFlag; + +typedef enum +{ + RIL_SMS_STATUS_TYPE_REC_UNREAD = 0, + RIL_SMS_STATUS_TYPE_REC_READ = 1, + RIL_SMS_STATUS_TYPE_STO_UNSENT = 2, + RIL_SMS_STATUS_TYPE_STO_SENT = 3, + + RIL_SMS_STATUS_TYPE_INVALID = 0xFF +} Enum_RIL_SMS_StatusType; + +/*********************************************************************** + * STRUCT TYPE DEFINITIONS +************************************************************************/ +typedef struct +{ + u8 msgType; + u16 msgRef; + u8 msgSeg; + u8 msgTot; +} ST_RIL_SMS_Con; + +typedef struct +{ + bool conPres; //FALSE: This is a normal SMS. TRUE: This is a concatenate SMS + ST_RIL_SMS_Con con; +} ST_RIL_SMS_SendExt; + +typedef struct +{ + u8 alpha; //It's value is same as 'LIB_SMS_DCSAlphaEnum' + char oa[RIL_SMS_PHONE_NUMBER_MAX_LEN]; + char scts[RIL_SMS_TIME_STAMP_STR_MAX_LEN]; + + bool conPres; //FALSE: This is a normal SMS. TRUE: This is a concatenate SMS + ST_RIL_SMS_Con con; + + u8 data[RIL_SMS_TEXT_DATA_MAX_LEN]; + u32 length; +} ST_RIL_SMS_DeliverParam; + +typedef struct +{ + u8 alpha; //It's value is same as 'LIB_SMS_DCSAlphaEnum' + char da[RIL_SMS_PHONE_NUMBER_MAX_LEN]; + + bool conPres; //FALSE: This is a normal SMS. TRUE: This is a concatenate SMS + ST_RIL_SMS_Con con; + + u8 data[RIL_SMS_TEXT_DATA_MAX_LEN]; + u32 length; +} ST_RIL_SMS_SubmitParam; + +typedef struct +{ + u8 mr; + char ra[RIL_SMS_PHONE_NUMBER_MAX_LEN]; + char scts[RIL_SMS_TIME_STAMP_STR_MAX_LEN]; + char dt[RIL_SMS_TIME_STAMP_STR_MAX_LEN]; +} ST_RIL_SMS_StatusReportParam; + +typedef struct { + u8 status; // It's value is same as 'Enum_RIL_SMS_StatusType' + u8 type; // It's value is same as 'LIB_SMS_PDUTypeEnum' + + char sca[RIL_SMS_PHONE_NUMBER_MAX_LEN]; + + union + { + ST_RIL_SMS_DeliverParam deliverParam; //Parameters for MSG_TYPE_DELIVER + ST_RIL_SMS_SubmitParam submitParam; //Parameters for MSG_TYPE_SUBMIT + ST_RIL_SMS_StatusReportParam statusReportParam; //Parameters for MSG_TYPE_STATUS_REPORT + } param; +} ST_RIL_SMS_TextInfo; + +typedef struct { + u8 status; // It's value is same as 'Enum_RIL_SMS_StatusType' + u32 length; + char data[LIB_SMS_PDU_BUF_MAX_LEN * 2]; // The PDU string +} ST_RIL_SMS_PDUInfo; + +typedef struct +{ + char* pduString; + u32 pduLen; + u32 mr; +}ST_RIL_SMS_SendPDUInfo; + +/*********************************************************************** + * OTHER TYPE DEFINITIONS +************************************************************************/ + +/*********************************************************************** + * RIL SMS API define +************************************************************************/ + +/****************************************************************************** +* Function: RIL_SMS_GetStorage +* +* Description: +* Get SMS storage info +* +* Parameters: +* : +* [In] The pointer of current SMS storage type,same as: 'Enum_RIL_SMS_SMSStorage' +* : +* [In] The pointer of used count in SMS storage +* +* [In] The pointer of total count in SMS storage +* +* Return: +* RIL_ATRSP_CONTINUE: Need to wait later AT response +* RIL_ATRSP_SUCCESS: AT command run SUCCESS. +* RIL_ATRSP_FAILED: AT command run FAIL! +* OTHER VALUES: This function works FAIL! +* NOTE: +* 1. If you DONOT want to get ,pTotal value,please set it to NULL. +******************************************************************************/ +extern s32 RIL_SMS_GetStorage(u8* pCurrMem, u32* pUsed,u32* pTotal); + +/****************************************************************************** +* Function: RIL_SMS_SetStorage +* +* Description: +* Set SMS storage +* +* Parameters: +* : +* [In] SMS storage,same as 'Enum_RIL_SMS_SMSStorage' +* +* Return: +* RIL_ATRSP_SUCCESS: This function works SUCCESS. +* RIL_ATRSP_CONTINUE: Need to wait later AT response +* RIL_ATRSP_SUCCESS: AT command run SUCCESS. +* RIL_ATRSP_FAILED: AT command run FAIL! +* OTHER VALUES: This function works FAIL! +* NOTE: +* 1. If you DONOT want to get ,pTotal value,please set it to NULL. +******************************************************************************/ +extern s32 RIL_SMS_SetStorage(Enum_RIL_SMS_StorageType eStorage,u32* pUsed,u32* pTotal); + +/****************************************************************************** +* Function: RIL_SMS_ReadSMS_PDU +* +* Description: +* Read a PDU SMS +* +* Parameters: +* : +* [In] The SMS index in current SMS storage +* : +* [In] The pointer of 'ST_RIL_SMS_PDUInfo' data +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +extern s32 RIL_SMS_ReadSMS_PDU(u32 uIndex, ST_RIL_SMS_PDUInfo* pPDUInfo); + +/****************************************************************************** +* Function: RIL_SMS_ReadSMS_Text +* +* Description: +* Read a TEXT SMS +* +* Parameters: +* : +* [In] The SMS index in current SMS storage +* : +* [In] Character set enum value +* +* [In] The pointer of TEXT SMS info +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +extern s32 RIL_SMS_ReadSMS_Text(u32 uIndex, LIB_SMS_CharSetEnum eCharset,ST_RIL_SMS_TextInfo* pTextInfo); + +/****************************************************************************** +* Function: RIL_SMS_SendSMS_PDU +* +* Description: +* This function is used to send PDU message +* +* Parameters: +* : +* [In] The pointer of PDU string +* : +* [In] The length of PDU string +* +* [Out] The pointer of message reference number +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +* Note: +* 1. If you DONOT want to get value,please set it to NULL. +******************************************************************************/ +extern s32 RIL_SMS_SendSMS_PDU(char* pPDUStr,u32 uPDUStrLen,u32 *pMsgRef); + +/****************************************************************************** +* Function: RIL_SMS_SendSMS_Text +* +* Description: +* This function is used to send TEXT message +* +* Parameters: +* : +* [In] The pointer of phone number +* : +* [In] The length of phone number +* +* [In] CharSet,it's value is same as 'LIB_SMS_CharSetEnum' +* +* [In] The pointer of message content +* +* [In] The length of message content +* +* [Out] The pointer of message reference number +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +* Note: +* 1. If you DONOT want to get value,please set it to NULL. +******************************************************************************/ +extern s32 RIL_SMS_SendSMS_Text(char* pNumber, u8 uNumberLen, LIB_SMS_CharSetEnum eCharset, u8* pMsg, u32 uMsgLen,u32 *pMsgRef); + +/****************************************************************************** +* Function: RIL_SMS_SendSMS_Text_Ext +* +* Description: +* This function is used to send TEXT message witch external info +* +* Parameters: +* : +* [In] The pointer of phone number +* : +* [In] The length of phone number +* +* [In] CharSet,it's value is same as 'LIB_SMS_CharSetEnum' +* +* [In] The pointer of message content +* +* [In] The length of message content +* +* [Out] The pointer of message reference number +* +* [In] The pointer of 'ST_RIL_SMS_SendExt' data +* + conPres con-SMS present or not +* + con 'ST_RIL_SMS_Con' data +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +* Note: +* 1. If you DONOT want to get value,please set it to NULL. +* 2. If you want to send normal SMS, you can set to NULL. +******************************************************************************/ +extern s32 RIL_SMS_SendSMS_Text_Ext(char* pNumber, u8 uNumberLen, LIB_SMS_CharSetEnum eCharset, u8* pMsg, u32 uMsgLen,u32 *pMsgRef,ST_RIL_SMS_SendExt *pExt); + +/****************************************************************************** +* Function: RIL_SMS_DeleteSMS +* +* Description: +* This function deletes SMS messages in current SMS storage. +* +* Parameters: +* index: +* [In] The index number of SMS message. +* flag: +* [In] Delete flag , which is one value of 'Enum_RIL_SMS_DeleteFlag'. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +extern s32 RIL_SMS_DeleteSMS(u32 uIndex,Enum_RIL_SMS_DeleteFlag eDelFlag); + +#endif //#ifndef __RIL_SMS_H__ + diff --git a/cores/opencpu/ril/inc/ril_system.h b/cores/opencpu/ril/inc/ril_system.h new file mode 100644 index 0000000..26cf781 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_system.h @@ -0,0 +1,174 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_system.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file is for OpenCPU RIL sytem definitions and APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_SYSTEM_H__ +#define __RIL_SYSTEM_H__ + + + +typedef struct +{ + s32 capacity; + s32 voltage; +}ST_SysPower; + +/***************************************************************** +* Function: RIL_QuerySysInitStatus +* +* Description: +* Queries the initializing status of module. +* +* Parameters: +* SysInitStatus +* [Out] system init status. +* 0/1/2/3, the init status value, one value of "Enum_SysInitState". +* Please refer to "AT+QINISTAT" in ATC document for the meanings. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_QuerySysInitStatus(s32* SysInitStatus); + +/***************************************************************** +* Function: RIL_GetPowerSupply +* +* Description: +* This function queries the battery balance, and the battery voltage. +* +* Parameters: +* capacity: +* [out] battery balance, a percent, ranges from 1 to 100. +* +* voltage: +* [out] battery voltage, unit in mV +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_GetPowerSupply(u32* capacity, u32* voltage); + +/***************************************************************** +* Function: Ql_SecureData_Store +* +* Description: +* This function can be used to store some critical user data +* to prevent them from losing. +* +* Note: +* 1. +* OpenCPU has designed 13 blocks of system storage space to +* backup critical user data. Developer may specify the first +* parameter index [1-13] to specify different storage block. +* Among the storage blocks, 1~8 blocks can store 50 bytes for +* each block, 9~12 blocks can store 100 bytes for each block, +* and the 13th block can store 500 bytes. +* +* 2. +* User should not call this API function frequently, which is not +* good for life cycle of flash. +* +* Parameters: +* index: +* [in] the index of the secure data block. The range is: 1~13. +* +* pData: +* [in] The data to be backed up. In 1~8 groups, every group can +* save 50 bytes at most. In 9~12 groups, every group can save +* 100 bytes at most. If index is 13, the user data can save 500 bytes at most. +* +* len: +* [in] The length of the user data. When the index is (1~8), +* then len<=50. When the index is (9~12), then len<=100. +* When the index is 13, then len<=500. +* Return: +* QL_RET_OK, this function succeeds. +* QL_RET_ERR_PARAM, invalid paramter. +* QL_RET_ERR_GET_MEM, the heap memory is no enough. +* ...... +*****************************************************************/ +s32 Ql_SecureData_Store(u8 index , u8* pData, u32 len); + +/***************************************************************** +* Function: Ql_SecureData_Read +* +* Description: +* This functin reads secure data which is previously +* stored by Ql_SecureData_Store. +* Parameters: +* index: +* [in] The index of the secure data block. The range is: 1~13. +* +* len: +* [in] The length of the user data. When the index is (1~8), +* then len<=50. When the index is (9~12), then len<=100. +* When the index is 13, then len<=500. +* Return: +* If this function succeeds, the real read length is returned. +* QL_RET_ERR_PARAM, invalid paramter. +* QL_RET_ERR_GET_MEM, the heap memory is no enough. +* Ql_RET_ERR_UNKOWN, unknown error. +*****************************************************************/ +s32 Ql_SecureData_Read(u8 index, u8* pBuffer, u32 len); + +/***************************************************************** +* Function: RIL_GetIMEI +* +* Description: +* Retrieves the IMEI number of module. +* +* Parameters: +* imei: +* [Out] buffer to store the imei number. The length +* of buffer should be at least 15-byte. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_GetIMEI(char* imei); + +#endif //__RIL_SYSTEM_H__ + diff --git a/cores/opencpu/ril/inc/ril_telephony.h b/cores/opencpu/ril/inc/ril_telephony.h new file mode 100644 index 0000000..b17e457 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_telephony.h @@ -0,0 +1,124 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_telephony.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file is for telephony. All APIs depend on OpenCPU RIL feature. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_TELEPHONY_H__ +#define __RIL_TELEPHONY_H__ +#include "ql_type.h" + +#define PHONE_NUMBER_MAX_LEN 41 +typedef struct { + s32 type; + char phoneNumber[PHONE_NUMBER_MAX_LEN]; +}ST_ComingCall; + +typedef struct { + u32 ringCnt; + ST_ComingCall comingCall[6]; +}ST_ComingCallInfo; + +typedef enum { + CALL_STATE_ERROR = -1, + CALL_STATE_OK = 0, + CALL_STATE_BUSY, + CALL_STATE_NO_ANSWER, + CALL_STATE_NO_CARRIER, + CALL_STATE_NO_DIALTONE, + CALL_STATE_END +}Enum_CallState; + +/****************************************************************************** +* Function: RIL_Telephony_Dial +* +* Description: +* This function dials the specified phone number, only support voice call. +* +* Parameters: +* type: +* [In] Must be 0 , just support voice call. +* phoneNumber: +* [In] Phone number, null-terminated string. +* result: +* [Out] Result for dial, one value of Enum_CallState. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_Telephony_Dial(u8 type, char* phoneNumber, s32* result); + +/****************************************************************************** +* Function: RIL_Telephony_Dial +* +* Description: +* This function answers a coming call. +* +* Parameters: +* result: +* [Out] Delete flag , which is one value of 'Enum_SMSDeleteFlag'. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_Telephony_Answer(s32 *result); + +/****************************************************************************** +* Function: RIL_Telephony_Dial +* +* Description: +* This function answers a call. +* +* Parameters: +* None +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_Telephony_Hangup(void); + +#endif diff --git a/cores/opencpu/ril/inc/ril_util.h b/cores/opencpu/ril/inc/ril_util.h new file mode 100644 index 0000000..4189fd7 --- /dev/null +++ b/cores/opencpu/ril/inc/ril_util.h @@ -0,0 +1,94 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_tuil.h + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The file is for some useful definitions and APIs in common. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#ifndef __RIL_UTIL_H__ +#define __RIL_UTIL_H__ +#include "ql_type.h" + +typedef enum { + CHAR_0 = '0', + CHAR_9 = '9', + CHAR_A = 'A', + CHAR_F = 'F', + END_OF_STR = '\0' +}Enum_Char; +#define IS_NUMBER(alpha_char) \ + (((alpha_char >= CHAR_0) && (alpha_char <= CHAR_9) ) ? 1 : 0) + +extern s32 Ql_StrPrefixMatch(const char* str, const char *prefix); +extern bool Ql_HexStrToInt(u8 *str, u32 *val); +extern char* Ql_StrToUpper(char* str); +/****************************************************************************** +* Function: Ql_RIL_FindString +* +* Description: +* This function is used to match string within a specified length. +* This function is very much like strstr. +* +* Parameters: +* line: +* [in]The address of the string. +* len: +* [in]The length of the string. +* str: +* [in]The specified item which you want to look for in the string. +* +* Return: + The function returns a pointer to the located string, + or a null pointer if the specified string is not found. +******************************************************************************/ +extern char* Ql_RIL_FindString(char *line, u32 len,char *str); + +/****************************************************************************** +* Function: Ql_RIL_FindLine +* +* Description: +* This function is used to find the specified character line by line. +* for example,if you want to find "OK", In fact, we think that you are +* looking for OK,OK or OK. +* +* +* Parameters: +* line: +* [in]The address of the string. +* len: +* [in]The length of the string. +* str: +* [in]The specified item which you want to look for in the string. +* +* Return: + The function returns a pointer to the located string, + or a null pointer if the specified string is not found. +******************************************************************************/ +extern char* Ql_RIL_FindLine(char *line, u32 len,char *str); + +#endif diff --git a/cores/opencpu/ril/src/ril_alarm.c b/cores/opencpu/ril/src/ril_alarm.c new file mode 100644 index 0000000..6cc61bf --- /dev/null +++ b/cores/opencpu/ril/src/ril_alarm.c @@ -0,0 +1,204 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2014 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_alarm.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements RTC alarm related APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "ril_alarm.h" +#include "ril.h" +#include "ril_util.h" +#include "ql_common.h" +#include "ql_stdlib.h" +#include "ql_error.h" + +static s32 ATResponse_QALARM_Handler(char* line, u32 len, void* userData); + + +s32 RIL_Alarm_Create(ST_Time* dateTime, u8 mode) +{ + char strAT[50] = {"\0"}; + u16 atLength = 0; + char strTimeZone[10]; + + if (NULL == dateTime) + { + return QL_RET_ERR_INVALID_PARAMETER; + } + Ql_memset(strAT, 0x0, sizeof(strAT)); + if (dateTime->timezone >= 0) + { + Ql_sprintf(strTimeZone, "+%02d\0", dateTime->timezone); + } else { + Ql_sprintf(strTimeZone, "-%02d\0", dateTime->timezone); + } + atLength = Ql_sprintf(strAT, "AT+QALARM=1,\"%02d/%02d/%02d,%02d:%02d:%02d%s\",%d,0", + dateTime->year, dateTime->month, dateTime->day, dateTime->hour, dateTime->minute, dateTime->second, strTimeZone, mode); + //Ql_Debug_Trace("%s\r\n", strAT); + return Ql_RIL_SendATCmd(strAT, atLength, NULL, NULL,0); +} + +s32 RIL_Alarm_Query(ST_Time* dateTime) +{ + char strAT[] = "AT+QALARM?\0"; + if (NULL == dateTime) + { + return QL_RET_ERR_INVALID_PARAMETER; + } + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATResponse_QALARM_Handler, dateTime, 0); +} + +s32 RIL_Alarm_Remove(ST_Time* dateTime) +{ + s32 retRes = 0; + { + char strAT[50] = {"\0"}; + char strTimeZone[10]; + + if (NULL == dateTime) + { + return QL_RET_ERR_INVALID_PARAMETER; + } + Ql_memset(strAT, 0x0, sizeof(strAT)); + if (dateTime->timezone >= 0) + { + Ql_sprintf(strTimeZone, "+%02d\0", dateTime->timezone); + } else { + Ql_sprintf(strTimeZone, "-%02d\0", dateTime->timezone); + } + Ql_sprintf(strAT, "AT+QALARM=0,\"%02d/%02d/%02d,%02d:%02d:%02d%s\",0,0", + dateTime->year, dateTime->month, dateTime->day, dateTime->hour, dateTime->minute, dateTime->second, strTimeZone); + //Ql_Debug_Trace("%s\r\n", strAT); + retRes = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL,0); + } + return retRes; +} + +static s32 ATResponse_QALARM_Handler(char* line, u32 len, void* userData) +{ + char* p1 = NULL; + char* p2 = NULL; + ST_Time* pDT = (ST_Time*)userData; + char* head = Ql_RIL_FindString(line, len, "+QALARM:"); //continue wait + char strTmp[10]; + + //Ql_Debug_Trace("Line%d:%s, ", __LINE__, line); + + if (head) + { + p1 = Ql_strstr(head, ","); + if (p1) + { + // year + p1 += 2; + p2 = Ql_strstr(p1, "/"); + if (p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_strncpy(strTmp, p1, 2); + pDT->year = Ql_atoi(strTmp); + } + + // month + p1 = p2 + 1; + p2 = Ql_strstr(p1, "/"); + if (p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_strncpy(strTmp, p1, 2); + pDT->month = Ql_atoi(strTmp); + } + + // day + p1 = p2 + 1; + p2 = Ql_strstr(p1, ","); + if (p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_strncpy(strTmp, p1, 2); + pDT->day = Ql_atoi(strTmp); + } + + // hour + p1 = p2 + 1; + p2 = Ql_strstr(p1, ":"); + if (p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_strncpy(strTmp, p1, 2); + pDT->hour = Ql_atoi(strTmp); + } + + // minute + p1 = p2 + 1; + p2 = Ql_strstr(p1, ":"); + if (p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_strncpy(strTmp, p1, 2); + pDT->minute = Ql_atoi(strTmp); + } + + // second + p1 = p2 + 1; + p2 = Ql_strstr(p1, "+"); + if (p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_strncpy(strTmp, p1, 2); + pDT->second = Ql_atoi(strTmp); + } + + // time zone + p1 = p2 + 1; + p2 = Ql_strstr(p1, ","); + if (p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_strncpy(strTmp, p1, 2); + pDT->timezone = Ql_atoi(strTmp); + } + } + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (head) + { + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if(head) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + diff --git a/cores/opencpu/ril/src/ril_atResponse.c b/cores/opencpu/ril/src/ril_atResponse.c new file mode 100644 index 0000000..fc8ce61 --- /dev/null +++ b/cores/opencpu/ril/src/ril_atResponse.c @@ -0,0 +1,95 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_atResponse.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module handles the AT response in RIL. + * Developer may reprogram to cover some special AT commands according to the requirements. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ril.h " +#include "ril_util.h" +#include "ql_stdlib.h" +#include "ql_trace.h" + +#ifdef __OCPU_RIL_SUPPORT__ + +static s32 m_iErrCode = 0; // Is used to record the specific error code + // 0 indicates success in executing AT + // -1 indicats failure in executing AT + // other value indicates the specific error code after executing AT failed. + // you can usually find the meaning of error code in ATC document. +s32 Ql_RIL_AT_GetErrCode(void) {return m_iErrCode;} +// +// Developer can call this API to set the error code when resolving the response for AT. +s32 Ql_RIL_AT_SetErrCode(s32 errCode) {m_iErrCode = errCode;} + +/****************************************************************************** +* Function: Default_atRsp_callback +* +* Description: +* If you set the callback parameter of Ql_RIL_SendATCmd to NULL, +* we will provide you with a default callback function.But we need +* to clarify that this callback function can only handle simple +* response of the AT command.The response of AT command only is +* OK or error. +* +* Parameters: +* line: +* [in]The address of the string. +* len: +* [in]The length of the string. +* userdata: +* [out]Used to transfer the customer's parameter. +* Return: +* RIL_ATRSP_SUCCESS : AT command executed successfully. +* RIL_ATRSP_FAILED : AT command executed failed. +******************************************************************************/ +s32 Default_atRsp_callback(char* line, u32 len, void* userdata) +{ + if (Ql_RIL_FindLine(line, len, "OK"))// find OK,OK, OK£¬OK + { + m_iErrCode = RIL_ATRSP_SUCCESS; + return RIL_ATRSP_SUCCESS; + } + else if (Ql_RIL_FindLine(line, len, "ERROR")) // find ERROR, ERROR£¬ERROR + { + m_iErrCode = RIL_ATRSP_FAILED; + return RIL_ATRSP_FAILED; + } + else if (Ql_RIL_FindString(line, len, "+CME ERROR:") || + Ql_RIL_FindString(line, len, "+CMS ERROR:")) + { + Ql_sscanf(line, "%*[^:]: %d\r\n", &m_iErrCode); + return RIL_ATRSP_FAILED; + } + return RIL_ATRSP_CONTINUE; //continue wait +} + +#endif //__OCPU_RIL_SUPPORT__ + diff --git a/cores/opencpu/ril/src/ril_audio.c b/cores/opencpu/ril/src/ril_audio.c new file mode 100644 index 0000000..98cd7cc --- /dev/null +++ b/cores/opencpu/ril/src/ril_audio.c @@ -0,0 +1,435 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2014 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_audio.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The APIs are used to afford the audio related operations,based on RIL. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ + +#include "custom_feature_def.h" +#include "ql_type.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_error.h" +#include "ql_common.h" +#include "ql_system.h" +#include "ql_uart.h" +#include "ril.h" +#include "ril_util.h" +#include "ril_audio.h" + + +#ifdef __OCPU_RIL_SUPPORT__ + +#define IS_SUPPORT_AUD_CHANNEL(audChannel) \ +( \ + ( \ + (AUD_CHANNEL_NORMAL == (audChannel)) \ + || (AUD_CHANNEL_HEADSET == (audChannel)) \ + || (AUD_CHANNEL_LOUD_SPEAKER == (audChannel)) \ + ) ? TRUE : FALSE \ +) + +#define IS_SUPPORT_VOLUME_TYPE(volume_type) \ +( \ + ( \ + (VOL_TYPE_CTN == (volume_type)) \ + || (VOL_TYPE_GMI == (volume_type)) \ + || (VOL_TYPE_KEY == (volume_type)) \ + || (VOL_TYPE_MEDIA == (volume_type)) \ + || (VOL_TYPE_MIC == (volume_type)) \ + || (VOL_TYPE_SID == (volume_type)) \ + || (VOL_TYPE_SPH == (volume_type)) \ + ) ? TRUE : FALSE \ +) +static Enum_AudChannel s_channel_qmic = AUD_CHANNEL_HEADSET; +static s32 ATResponse_AUD_handler(char* line, u32 len, void* userdata); + + +/* ++QAUDCH: 0 + +*/ +s32 RIL_AUD_GetChannel(Enum_AudChannel *pchannel) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[20]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QAUDCH?\r\n"); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_AUD_handler,pchannel,0); + return ret; +} + +s32 RIL_AUD_SetChannel(Enum_AudChannel audChannel) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[20]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QAUDCH=%d\r\n",(char)audChannel); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + return ret; + +} + +s32 RIL_AUD_SetVolume(Enum_VolumeType volType, u8 volLevel) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[40]; + Enum_AudChannel channel ; + + Ql_memset(strAT, 0, sizeof(strAT)); + switch(volType) + { + case VOL_TYPE_SPH: + { + Ql_sprintf(strAT, "AT+CLVL=%d\r\n",(char)volLevel); + } + break; + case VOL_TYPE_MIC: + { + //level :0-15 + if(RIL_AT_SUCCESS != (ret = RIL_AUD_GetChannel(&channel))) + { + return ret; + } + Ql_sprintf(strAT, "AT+QMIC=%d,%d\r\n",channel,(char)volLevel); + } + break; + case VOL_TYPE_MEDIA: + { + Ql_sprintf(strAT, "AT+QMEDVL=%d\r\n",(char)volLevel); + } + break; + default: + { + return RIL_AT_INVALID_PARAM; + } + break; + } + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + + return ret; +} +s32 RIL_AUD_GetVolume(Enum_VolumeType volType,u8* pVolLevel) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[20]; + + Ql_memset(strAT, 0, sizeof(strAT)); + switch(volType) + { + case VOL_TYPE_SPH: + { + Ql_sprintf(strAT, "AT+CLVL?\r\n"); + } + break; + case VOL_TYPE_MIC: + { + if(RIL_AT_SUCCESS != (ret = RIL_AUD_GetChannel(&s_channel_qmic))) + { + return ret; + } + Ql_sprintf(strAT, "AT+QMIC?\r\n"); + + } + break; + case VOL_TYPE_MEDIA: + { + Ql_sprintf(strAT, "AT+QMEDVL?\r\n"); + + } + break; + default: + { + return RIL_AT_INVALID_PARAM; + } + break; + } + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_AUD_handler,pVolLevel,0); + + return ret; +} + +/* +File suffix can be AMR,WAV or MP3 +*/ +s32 RIL_AUD_PlayFile(char* filePath, bool isRepeated) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[255]; + char repeat = 0; + u8 vol_level = 0; + Enum_AudChannel channel; + (isRepeated)?(repeat = 1):(repeat = 0); + if(RIL_AT_SUCCESS != (ret=RIL_AUD_GetVolume(VOL_TYPE_MEDIA, &vol_level))) + { + return ret; + } + if(RIL_AT_SUCCESS != (ret=RIL_AUD_GetChannel(&channel))) + { + return ret; + } + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QAUDPLAY=\"%s\",%d,%d,%d\r\n",filePath,repeat,vol_level,channel); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_AUD_handler,NULL,0); + return ret; +} + +s32 RIL_AUD_StopPlay(void) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[20]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QAUDSTOP\r\n"); + + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_AUD_handler,NULL,0); + return ret; +} + +/* +reference to file :GSM_Recording_AT_Commands_Manual_V3.0.pdf + AMR = 3, + WAV_PCM16 =13, + WAV_ALAW, 14 + WAV_ULAW, 15 + WAV_ADPCM 16 +*/ +static u8 tool_convert_format(Enum_AudRecordFormat format) +{ + u8 real=255; + if(AUD_RECORD_FORMAT_AMR==format) + { + real = 3; + } + else if(AUD_RECORD_FORMAT_WAV_PCM16 == format) + { + real = 13; + } + else if(AUD_RECORD_FORMAT_WAV_ALAW == format) + { + real = 14; + } + else if(AUD_RECORD_FORMAT_WAV_ULAW == format) + { + real = 15; + } + else if(AUD_RECORD_FORMAT_WAV_ADPCM == format) + { + real = 16; + } + return real; +} + +/* +start record audio, use the func tool_convert_format to convert the num + */ +s32 RIL_AUD_StartRecord(char* fileName, Enum_AudRecordFormat format) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[255]; + u8 real_format = tool_convert_format(format); + + if(real_format == 255) + { + return RIL_AT_INVALID_PARAM; + } + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QAUDRD=1,\"%s\",%d\r\n",fileName,real_format); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_AUD_handler,NULL,0); + + return ret; +} +s32 RIL_AUD_StopRecord(void) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[20]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QAUDRD=0\r\n"); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_AUD_handler,NULL,0); + return ret; +} + +s32 RIL_AUD_PlayMem(u32 mem_addr, u32 mem_size, u8 aud_format, bool repeat) +{ + s32 at_result = RIL_AT_SUCCESS; + char strAT[60]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QPLAYMEM=0x%x,%d,%d,%d",mem_addr,mem_size,aud_format,repeat); + at_result = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_AUD_handler,NULL,0); + + return at_result; +} + +s32 RIL_AUD_StopPlayMem(void) +{ + char strAT[20]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QSTOPRES"); + return Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_AUD_handler,NULL,0); +} + +s32 RIL_AUD_PlayMemBg(u32 mem_addr, u32 mem_size, u8 aud_format, u8 vol_ul, u8 vol_dl) +{ + char strAT[60]; + u32 atLen; + + // AT+QPMEMBG=<1>,,,,, + // format: 1 - mp3, 2 - amr, 3 - wav + // ex.: AT+QPMEMBG=1,0x102C706C,88836,2,5,5 (request to play amr audio data) + // OK + // +QPRESBG: 0,5 (when finished) + Ql_memset(strAT, 0, sizeof(strAT)); + atLen =Ql_sprintf(strAT, "AT+QPMEMBG=1,0x%x,%d,%d,%d,%d",mem_addr,mem_size,aud_format,vol_ul,vol_dl); + return Ql_RIL_SendATCmd(strAT, atLen, ATResponse_AUD_handler, NULL, 0); +} + +s32 RIL_AUD_StopPlayMemBg(void) +{ + char strAT[20]; + u32 atLen; + + Ql_memset(strAT, 0, sizeof(strAT)); + atLen = Ql_sprintf(strAT, "AT+QPMEMBG=0"); + return Ql_RIL_SendATCmd(strAT, atLen, ATResponse_AUD_handler, NULL, 0); +} + +s32 RIL_AUD_GetRecordState(u8* pState) +{ + s32 at_result = RIL_AT_SUCCESS; + char strAT[20]; + u8 state = 0; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QAUDRD?\r\n"); + at_result = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_AUD_handler,&state,0); + if(at_result == RIL_ATRSP_SUCCESS) + { + *pState = state; + } + return at_result; +} +static u8 parse_cmd_qmic(char *pcmd,u8 channel) +{ + char strTmp[10]; + char* phead = NULL; + char* ptail= NULL; + u8 temp1 =0,temp2=0,temp3=0; + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + if(NULL == (phead = Ql_strstr(pcmd, ":"))) + goto error; + phead +=2; + if(NULL == (ptail = Ql_strstr(phead, ","))) + goto error; + Ql_memcpy(strTmp, phead, ptail - phead); + temp1 = Ql_atoi(strTmp); + + phead = ptail+1; + if(NULL == (ptail = Ql_strstr(phead , ","))) + goto error; + Ql_memcpy(strTmp, phead, ptail - phead); + temp2 = Ql_atoi(strTmp); + + phead = ptail+1; + if(NULL == (ptail = Ql_strstr(phead, "\r\n"))) + goto error; + Ql_memcpy(strTmp, phead, ptail - phead); + temp3 = Ql_atoi(strTmp); + + if(channel == 0)return temp1; + else if(1 == channel) return temp2; + else if(2 == channel) return temp3; + +error: + return 255; +} +static s32 ATResponse_AUD_handler(char* line, u32 len, void* userdata) +{ + char *head = NULL; + + if((head =Ql_RIL_FindString(line, len, "+QAUDCH:")) || \ + (head =Ql_RIL_FindString(line, len, "+QMEDVL:")) || (head =Ql_RIL_FindString(line, len, "+CLVL:")) || \ + (head =Ql_RIL_FindString(line, len, "+QSIDET:")) || (head =Ql_RIL_FindString(line, len, "+QAUDRD:")) ) + { + char strTmp[10]; + char* p1 = NULL; + char* p2 = NULL; + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + p1 = Ql_strstr(head, ":"); + p2 = Ql_strstr(p1 + 1, "\r\n"); + if (p1 && p2) + { + Ql_memcpy(strTmp, p1 + 2, p2 - p1 - 2); + *(u8* )userdata = Ql_atoi(strTmp); + } + return RIL_ATRSP_CONTINUE; + } + else if(head =Ql_RIL_FindString(line, len, "+QMIC:")) + { + *(u8* )userdata = parse_cmd_qmic(head,(u8)s_channel_qmic); + return RIL_ATRSP_CONTINUE; + } + + head = Ql_RIL_FindLine(line, len, "OK"); + if(head) + { + return RIL_ATRSP_SUCCESS; + } + head = Ql_RIL_FindLine(line, len, "ERROR"); + if(head) + { + return RIL_ATRSP_FAILED; + } + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +RIL_AUD_PLAY_IND cb_aud_play = NULL; +s32 RIL_AUD_RegisterPlayCB(RIL_AUD_PLAY_IND audCB) +{ + if (NULL == audCB) + { + return QL_RET_ERR_INVALID_PARAMETER; + } + cb_aud_play = audCB; + return QL_RET_OK; +} + +#endif + diff --git a/cores/opencpu/ril/src/ril_bluetooth.c b/cores/opencpu/ril/src/ril_bluetooth.c new file mode 100644 index 0000000..c694338 --- /dev/null +++ b/cores/opencpu/ril/src/ril_bluetooth.c @@ -0,0 +1,2122 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2015 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_bluetooth.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements bluetooth related APIs. + * + * Author: + * ------- + * ------- + * Designed by : Stanley YONG + * Coded by : Stanley YONG + * Tested by : + + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#ifdef __OCPU_RIL_BT_SUPPORT__ +#include "ql_type.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_error.h" +#include "ql_common.h" +#include "ql_system.h" +#include "ril.h" +#include "ril_util.h" +#include "ril_bluetooth.h" + +static ST_BT_DevInfo* m_arrBTDev[MAX_BT_DEV_CNT] = {NULL}; +static CALLBACK_BT_IND callback_bt = NULL; +static u8* m_ptrSppData = NULL; +static u32 m_nSppDataLenToSnd = 0; +static u8* m_ptrSppDataBuf = NULL; +static u32 m_nSppDataLenToRd = 0; +static u32 m_nSppRealReadLen = 0; +static char *pf_name[]={"SPP","OBEX_PBA_PROFILE_CLIENT","OBEX_PBA_PROFILE","OBEX_OBJECT_PUSH_SERVICE",\ + "OBEX_OBJECT_PUSH_CLIENT","HF_PROFILE","HFG_PROFILE",NULL}; + + + + +static s32 ATRsp_QBTPWR_Hdlr(char* line, u32 len, void* param); +static s32 ATRsp_QBTADDR_Hdlr(char* line, u32 len, void* param); +static s32 ATRsp_QBTSTATE_Hdlr(char* line, u32 len, void* param); +static s32 ATRsp_QBTSPPREAD_Hdlr(char* line, u32 len, void* param); +static s32 ATRsp_QBTSPPSEND_Hdlr(char* line, u32 len, void* param); +static s32 ATRsp_QBTVISB_Hdlr(char* line, u32 len, void* param); +static s32 ATRsp_QBTNAME_Hdlr(char* line, u32 len, void* param); +static s32 AtRsp_QBTCONND_Hdlr(char* line, u32 len, void* userData); +static s32 ATRsp_QBTGPROF_Hdlr(char* line, u32 len, void* param); + + +extern u32 Ql_GenHash(char* strSrc, u32 len); + + + +// Clean the scanned bt devices +static void BT_DevMngmt_Clean(void) +{ + u16 i; + + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (m_arrBTDev[i] != NULL) + { + Ql_MEM_Free((void *)m_arrBTDev[i]); + m_arrBTDev[i] = NULL; + } + } +} +// +// Append a bt device +static void BT_DevMngmt_Append(ST_BT_DevInfo* pstBtDev) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (NULL == m_arrBTDev[i]) + { + m_arrBTDev[i] = pstBtDev; + break; + } + } +} + + + +static bool BT_DevMngmt_isFull(void) +{ + u16 i; + u16 count = 0 ; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (NULL != m_arrBTDev[i]) + { + count++; + } + } + + if(count >= MAX_BT_DEV_CNT) + { + return TRUE; + } + else + { + return FALSE; + } +} + +// + + +static bool BT_PairUpdateConfirm(const s32 pairid,BT_DEV_HDL devHdl,const char *name) +{ + u16 i; + + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (NULL != m_arrBTDev[i]) + { + if(devHdl == m_arrBTDev[i]->btDevice.devHdl) + { + m_arrBTDev[i]->pairId = pairid; + Ql_memset(m_arrBTDev[i]->btDevice.name,0,BT_NAME_LEN); + Ql_strcpy(m_arrBTDev[i]->btDevice.name,name); + return TRUE; + } + + } + } + return FALSE; + +} + + +static bool BT_ConnectUpdateConfirm(const s32 connid,const s32 profileId,BT_DEV_HDL devHdl,const char *name) +{ + u16 i; + + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (NULL != m_arrBTDev[i]) + { + if(devHdl == m_arrBTDev[i]->btDevice.devHdl) + { + m_arrBTDev[i]->connId = connid; + m_arrBTDev[i]->profileId = profileId; + Ql_memset(m_arrBTDev[i]->btDevice.name,0,BT_NAME_LEN); + Ql_strcpy(m_arrBTDev[i]->btDevice.name,name); + return TRUE; + } + + } + } + return FALSE; + +} + + +static bool BT_ScanUpdateConfirm(BT_DEV_HDL devHdl,const s32 devid,const char *name) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (NULL != m_arrBTDev[i]) + { + if(devHdl == m_arrBTDev[i]->btDevice.devHdl) + { + m_arrBTDev[i]->devId = devid; + Ql_memset(m_arrBTDev[i]->btDevice.name,0,BT_NAME_LEN); + Ql_strcpy(m_arrBTDev[i]->btDevice.name,name); + return TRUE; + } + + } + } + return FALSE; + +} + + + +// +// Update pair id +static void BT_DevMngmt_UpdatePairId(const u32 hdl, const s32 pairId) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (hdl == m_arrBTDev[i]->btDevice.devHdl) + { + m_arrBTDev[i]->pairId= pairId; + break; + } + } +} +// +// Update connect id +static void BT_DevMngmt_UpdateConnId(const u32 hdl, const s32 connId) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (hdl == m_arrBTDev[i]->btDevice.devHdl) + { + m_arrBTDev[i]->connId= connId; + break; + } + } +} + +static void BT_DevMngmt_UpdateProfileId(const u32 hdl, const s32 profileId) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (hdl == m_arrBTDev[i]->btDevice.devHdl) + { + m_arrBTDev[i]->profileId= profileId; + break; + } + } +} + + + +static s32 BT_DevMngmt_ProfileNameToId(const char *profile_name) +{ + u16 i = 0; + + if(NULL == profile_name) + { + return -1; + } + + while (pf_name[i] != NULL) + { + if(0 == Ql_strncmp(profile_name,pf_name[i],Ql_strlen(profile_name))) + { + return i ; + } + i++; + } + + return -1; + + +} + + + + +static BT_DEV_HDL BT_DevMngmt_GetDevHdl(const s32 connId) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (connId == m_arrBTDev[i]->connId) + { + return m_arrBTDev[i]->btDevice.devHdl; + } + } + return 0; +} + + +s32 BT_DevMngmt_GetDeviceId(const u32 hdl) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (hdl == m_arrBTDev[i]->btDevice.devHdl) + { + return m_arrBTDev[i]->devId; + } + } + return 0; +} + + +s32 BT_DevMngmt_GetPairedId(const u32 hdl) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (hdl == m_arrBTDev[i]->btDevice.devHdl) + { + return m_arrBTDev[i]->pairId; + } + } + return 0; +} +s32 BT_DevMngmt_GetConnId(const u32 hdl) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (hdl == m_arrBTDev[i]->btDevice.devHdl) + { + return m_arrBTDev[i]->connId; + } + } + return 0; +} + +s32 BT_DevMngmt_GetProfileId(const u32 hdl) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (hdl == m_arrBTDev[i]->btDevice.devHdl) + { + return m_arrBTDev[i]->profileId; + } + } + return 0; +} + +char *BT_DevMngmt_GetDevName(const u32 hdl) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (hdl == m_arrBTDev[i]->btDevice.devHdl) + { + return m_arrBTDev[i]->btDevice.name; + } + } + return NULL; +} + + +char * BT_DevMngmt_GetDevAddr(const u32 hdl) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (hdl == m_arrBTDev[i]->btDevice.devHdl) + { + return m_arrBTDev[i]->btDevice.addr; + } + } + return NULL; +} + + +/***************************************************************** +* Function: RIL_BT_Switch +* +* Description: +* Turn on /off bluetooth +* +* Parameters: +* on_off [in] : 0 --- off ,1 ----- on +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_Switch(u8 on_off) +{ + char strAT[20]; + + if (on_off < BT_OFF || on_off > BT_ON) + { + return RIL_AT_INVALID_PARAM; + } + + Ql_memset(strAT, 0x0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QBTPWR=%d", on_off); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); +} + + +/***************************************************************** +* Function: RIL_BT_GetPwrState +* +* Description: +* query current bluetooth power state +* +* Parameters: +* p_on_off [out] : 0 --- off ,1 ----- on +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_GetPwrState(s32 *p_on_off) +{ + char strAT[] = "AT+QBTPWR?\0"; + + if (NULL == p_on_off) + { + return RIL_AT_INVALID_PARAM; + } + + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QBTPWR_Hdlr, (void*)p_on_off, 0); +} + + +/***************************************************************** +* Function: RIL_BT_Initialize +* +* Description: +* bluetooth initialization after power on ,register callback and update paired info +* +* Parameters: +* cb: callback to be registered +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_Initialize(CALLBACK_BT_IND cb) +{ + + if (!cb) + { + return RIL_AT_INVALID_PARAM; + } + + BT_DevMngmt_Clean(); + + callback_bt = cb; + + RIL_BT_QueryState(NULL); //update paired items + + return RIL_AT_SUCCESS; +} + + + +/***************************************************************** +* Function: RIL_BT_SetName +* +* Description: +* set the name of bluetooth +* +* Parameters: +* name [in] : bluetooth name to set +* len [in] : length of bluetooth name,max length 56 bytes (18 * 3+2) +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_SetName(char *name,u8 len) +{ + char strAT[80]; + + if(NULL == name || (len > BT_NAME_LEN - 2)) + { + return RIL_AT_INVALID_PARAM ; + } + + Ql_memset(strAT, 0x0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QBTNAME=\"%s\"", name); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); +} + + +/***************************************************************** +* Function: RIL_BT_GetName +* +* Description: +* get the name of bluetooth +* +* Parameters: +* name [out] : bluetooth name to get + len [in] : sizeof of param 1 +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_GetName(char *name/*char addr[BT_NAME_LEN]*/,u8 len) + +{ + char strAT[20]="AT+QBTNAME?\0"; + s32 ret = RIL_AT_SUCCESS; + char in_name[BT_NAME_LEN] = {0}; + + + if(NULL == name ) + { + return RIL_AT_INVALID_PARAM ; + } + + Ql_memset(name,0,len); + + ret = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QBTNAME_Hdlr,(void *)in_name, 0); + + if(ret == RIL_AT_SUCCESS) + { + if(len < Ql_strlen(in_name)) + { + Ql_strncpy(name,in_name,len-1); + } + else + { + Ql_strncpy(name,in_name,Ql_strlen(in_name)); + } + } + + return ret; +} + + + +/***************************************************************** +* Function: RIL_BT_GetLocalAddr +* +* Description: +* get the device address of bluetooth +* +* Parameters: +* ptrAddr [out] : bluetooth addr to get ,length is fixed 13 bytes including '\0' + len [in] : sizeof param 1 +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + +s32 RIL_BT_GetLocalAddr(char* ptrAddr/*char addr[BT_ADDR_LEN]*/,u8 len) +{ + char strAT[] = "AT+QBTADDR?\0"; + s32 ret = RIL_AT_SUCCESS; + char in_addr[BT_ADDR_LEN] = {0}; + + if (NULL == ptrAddr) + { + return RIL_AT_INVALID_PARAM; + } + + Ql_memset(ptrAddr,0,len); + + ret = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QBTADDR_Hdlr,(void *)in_addr, 0); + + if(ret == RIL_AT_SUCCESS) + { + if(len < Ql_strlen(in_addr)) + { + Ql_strncpy(ptrAddr,in_addr,len-1); + } + else + { + Ql_strncpy(ptrAddr,in_addr,Ql_strlen(in_addr)); + } + } + + return ret; +} + + + +/***************************************************************** +* Function: RIL_BT_SetVisble +* +* Description: +* set the bluetooth to be viewed or not +* +* Parameters: +* mode [in] : visible mode 0 :invisble 1: visible forever 2.visibility temporary on,see Enum_VisibleMode +* timeout [in] : when mode is set to 2 ,this param decide during which time bluetooth can be found by others +* unit second,can be 1-255,after timout,MSG_BT_INVISIBLE will be triggered ,other mode is ignored +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + +s32 RIL_BT_SetVisble(Enum_VisibleMode mode,u8 timeout) +{ + char strAT[30]; + + if(mode < BT_INVISIBLE || mode >= BT_VISIBLE_END) + { + return RIL_AT_INVALID_PARAM; + } + + Ql_memset(strAT, 0x0, sizeof(strAT)); + + if(BT_INVISIBLE == mode || BT_VISIBLE_FOREVER == mode) + { + Ql_sprintf(strAT, "AT+QBTVISB=%d", mode); + } + else + { + Ql_sprintf(strAT, "AT+QBTVISB=%d,%d", mode,timeout); + } + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); + +} + + +void OnURCHandler_BTVisible(const char* strURC, void* reserved) +{ + s32 err_code = 0; + char urcHead[30]; + + if(callback_bt == NULL) + { + return; + } + + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d\r\n",&err_code); + if(0 == err_code) + { + callback_bt(MSG_BT_VISIBLE_IND, URC_BT_INVISIBLE, NULL, NULL); + } + else + { + callback_bt(MSG_BT_VISIBLE_IND, err_code, NULL, NULL); + } + return; + } + Ql_strcpy(urcHead, "+CME ERROR:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d\r\n", &err_code); + callback_bt(MSG_BT_VISIBLE_IND, err_code, NULL, NULL); + return; + } +} + + + +/***************************************************************** +* Function: RIL_BT_GetVisble +* +* Description: +* get the current bluetooth visble mode +* +* Parameters: +* mode [out] : visible mode 0 :invisble 1: visible forever 2.visibility temporary on ,see Enum_VisibleMode +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_GetVisble(s32 *mode) + +{ + + char strAT[] = "AT+QBTVISB?\0"; + + if(NULL == mode) + { + return RIL_AT_INVALID_PARAM; + } + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QBTVISB_Hdlr, (void*)mode, 0); +} + + + +/***************************************************************** +* Function: RIL_BT_StartScan +* +* Description: +* start scan the around bt devices +* +* Parameters: +* +* @maxDevCount: 0-20, default 20 +* @CoD: 0-255, default 0 +* @timeout: unit in second. 1-255, default 60s +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + +s32 RIL_BT_StartScan(u16 maxDevCount, u16 CoD, u16 timeout) +{ + char strAT[20]; + + if(maxDevCount < 0 || maxDevCount > MAX_BT_SCAN_CNT) + { + return RIL_AT_INVALID_PARAM ; + } + + if(CoD < 0 || CoD > MAX_BT_SCAN_COD) + { + return RIL_AT_INVALID_PARAM ; + } + + if(timeout < 1 || timeout > MAX_BT_SCAN_TIMEOUT) + { + return RIL_AT_INVALID_PARAM ; + } + + BT_DevMngmt_Clean(); + + RIL_BT_QueryState(NULL); + + // Start to scan bt devices + Ql_memset(strAT, 0x0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QBTSCAN=%d,%d,%d", timeout, maxDevCount, CoD); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); +} + + +void OnURCHandler_BTScan(const char* strURC, void* reserved) +{ + // +QBTSCAN:3,"M26-test",397D0D816261 + // +QBTSCAN:0 + char urcHead[] = "\r\n+QBTSCAN:\0"; + s32 deviceId = 0; + ST_BT_DevInfo* pstrNewBtDev = NULL; + bool ret = FALSE; + s32 err_code = 0; + + if(callback_bt == NULL) + { + return; + } + + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d%*[^\r\n]\r\n",&deviceId); + + if (0 == deviceId) // scan finished + { + callback_bt(MSG_BT_SCAN_IND,URC_BT_SCAN_FINISHED, NULL, NULL); + + }else{ // scan new bt device + // Create a new bt device + pstrNewBtDev = (ST_BT_DevInfo*)Ql_MEM_Alloc(sizeof(ST_BT_DevInfo)); + Ql_memset(pstrNewBtDev, 0x0, sizeof(ST_BT_DevInfo)); + pstrNewBtDev->devId = deviceId; + pstrNewBtDev->pairId = -1; + pstrNewBtDev->connId = -1; + pstrNewBtDev->profileId = -1; + + Ql_sscanf(strURC, "%*[^\"]\"%[^\"]%*[^\r\n]\r\n",pstrNewBtDev->btDevice.name); + Ql_sscanf(strURC, "%*[^,],%*[^,],%[^\r\n]\r\n",pstrNewBtDev->btDevice.addr); + pstrNewBtDev->btDevice.devHdl = Ql_GenHash(pstrNewBtDev->btDevice.addr, Ql_strlen(pstrNewBtDev->btDevice.addr)); + ret = BT_ScanUpdateConfirm(pstrNewBtDev->btDevice.devHdl,pstrNewBtDev->devId,pstrNewBtDev->btDevice.name); + callback_bt(MSG_BT_SCAN_IND,URC_BT_SCAN_FOUND,&(pstrNewBtDev->btDevice), NULL);//customer own management + if(ret == FALSE) + { + if(!BT_DevMngmt_isFull()) + { + BT_DevMngmt_Append(pstrNewBtDev); + } + else + { + Ql_MEM_Free(pstrNewBtDev); + } + } + else + { + Ql_MEM_Free(pstrNewBtDev); + } + + + } + return; + } + + Ql_strcpy(urcHead, "+CME ERROR:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d\r\n", &err_code); + callback_bt(MSG_BT_SCAN_IND, err_code, NULL, NULL); + return; + } +} + + +/***************************************************************** +* Function: RIL_BT_GetDevListInfo +* +* Description: +* get current bt devices info + + ADDR DEVID HANDLER PAIRID CONNID PROFILE NAME +* +* Parameters: +* +* void +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ + +s32 RIL_BT_GetDevListInfo(void) +{ + u16 i; + for (i = 0; i < MAX_BT_DEV_CNT; i++) + { + if (NULL != m_arrBTDev[i]) + { + Ql_Debug_Trace("%s %2d 0x%08x %2d %2d %2d %s\r\n",m_arrBTDev[i]->btDevice.addr,m_arrBTDev[i]->devId,\ + m_arrBTDev[i]->btDevice.devHdl,m_arrBTDev[i]->pairId,m_arrBTDev[i]->connId,m_arrBTDev[i]->profileId,m_arrBTDev[i]->btDevice.name); + } + } + return RIL_AT_SUCCESS; +} + + +/***************************************************************** +* Function: RIL_BT_GetDevListPointer +* +* Description: +* get the dev list pointer ,then you can use it to get items of the list + before you use the pointer ,RIL_BT_GetDevListInfo can help you see valid + items to operate +* +* Parameters: +* +* void +* Return: +* the pointer to dev list + ST_BT_DevInfo ** ptr; + ptr = RIL_BT_GetDevListPointer(); + ptr[i]->btDevice.devHdl +*****************************************************************/ + +ST_BT_DevInfo ** RIL_BT_GetDevListPointer(void) +{ + return m_arrBTDev; +} + + + + +/***************************************************************** +* Function: RIL_BT_StopScan +* +* Description: +* stop the scan process +* +* Parameters: +* void +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_StopScan(void) +{ + char strAT[] = "AT+QBTSCANC\0"; + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); +} + + +/***************************************************************** +* Function: RIL_BT_QueryState +* +* Description: +* query current bluetooth state and update paired items +* +* Parameters: +* status [out] : current BT status see Enum_BTDevStatus +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_QueryState(s32 *status) +{ + char strAT[] = "AT+QBTSTATE\0"; + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QBTSTATE_Hdlr, (void *)status, 0); +} + + + +/***************************************************************** +* Function: RIL_BT_PairReq +* +* Description: +* request to pair a bt device ,for paired items ,ignore this step ,directly to connect +* if passive pair ,see +QBTIND +* +* Parameters: +* hdlDevice :[in] the bt handler to pair +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_PairReq(BT_DEV_HDL hdlDevice) +{ + char strAT[20]; + s32 devId ; + + devId = BT_DevMngmt_GetDeviceId(hdlDevice); + if(devId == 0) + { + return RIL_AT_INVALID_PARAM; + } + Ql_sprintf(strAT, "AT+QBTPAIR=%d", devId); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); +} + + + + +void OnURCHandler_BTPair(const char* strURC, void* reserved) +{ + s32 err_code = 0; + char urcHead[30]; + char pinCode[BT_PIN_LEN] = {0}; + ST_BT_BasicInfo bt_dev; + char temp[30]={0}; + + Ql_memset(&bt_dev, 0x0, sizeof(ST_BT_BasicInfo)); + Ql_memset(pinCode, 0x0, sizeof(pinCode)); + + if(callback_bt == NULL) + { + return; + } + + // +QBTPAIR: "H60-L01",F4E3FBE47920,724242 + + + Ql_strcpy(urcHead, "\r\n+QBTPAIR:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^\"]\"%[^\"]%*[^\r\n]\r\n", bt_dev.name); + Ql_sscanf(strURC, "%*[^,],%[^\r\n]\r\n", temp); + + if(Ql_strlen(temp) == (BT_ADDR_LEN - 1)) + { + Ql_sscanf(strURC, "%*[^,],%[^\r\n]\r\n", bt_dev.addr); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + callback_bt(MSG_BT_PAIR_IND, URC_BT_NEED_PASSKEY, &bt_dev, NULL); // need paaskey + } + else + { + Ql_sscanf(strURC, "%*[^,],%[^,]%*[^\r\n]\r\n",bt_dev.addr); + Ql_sscanf(strURC, "%*[^,],%*[^,],%[^\r\n]\r\n",pinCode); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + callback_bt(MSG_BT_PAIR_IND, URC_BT_NO_NEED_PASSKEY, &bt_dev, pinCode); //direct confirm + } + return; + } + + Ql_strcpy(urcHead, "+CME ERROR:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d\r\n", &err_code); + callback_bt(MSG_BT_PAIR_IND, err_code, NULL, NULL); + return; + } + +} + + + + +/***************************************************************** +* Function: RIL_BT_PairConfirm +* +* Description: +* confirm to pair +* +* Parameters: +* accept :[in] whether to accpect the pair request--- 0 :reject 1:accept +* pincode :[in] the passkey used to pair,4bytes +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_PairConfirm(bool accept, char* pinCode) +{ + char strAT[20] = {0}; + + if(accept != 0 && accept != 1) + { + return RIL_AT_INVALID_PARAM; + } + + if (NULL != pinCode)//not numeric code ,is passkey(4bit digits) + { + Ql_sprintf(strAT, "AT+QBTPAIRCNF=%d,\"%s\"", (u8)accept, pinCode); + }else{ + Ql_sprintf(strAT, "AT+QBTPAIRCNF=%d", (u8)accept); + } + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); +} + + +void OnURCHandler_BTPairCnf(const char* strURC, void* reserved) +{ + s32 err_code = 0; + s32 pairedId; + s32 is1stPaired; + char urcHead[30]; + ST_BT_BasicInfo bt_dev; + + Ql_memset(&bt_dev, 0x0, sizeof(ST_BT_BasicInfo)); + + if(callback_bt == NULL) + { + return; + } + + + // +QBTPAIRCNF:1,1,1,"H60-L01",F4E3FBE47920 + Ql_strcpy(urcHead, "\r\n+QBTPAIRCNF:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d%*[^\r\n]\r\n", &err_code); + if (err_code > 0) + { + Ql_sscanf(strURC, "%*[^,],%d%*[^\r\n]\r\n",&pairedId); + Ql_sscanf(strURC, "%*[^,]%*[^,],%d%*[^\r\n]\r\n",&is1stPaired); + Ql_sscanf(strURC, "%*[^\"]\"%[^\"]%*[^\r\n]\r\n",bt_dev.name); + Ql_sscanf(strURC, "%*[^\"]\"%*[^\"]\",%[^\r\n]\r\n",bt_dev.addr); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + RIL_BT_QueryState(NULL); + callback_bt(MSG_BT_PAIR_CNF_IND, URC_BT_PAIR_CNF_SUCCESS, &bt_dev, NULL); + }else{ + Ql_sscanf(strURC, "%*[^,],%[^\r\n]\r\n",bt_dev.addr); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + BT_DevMngmt_UpdatePairId(bt_dev.devHdl,-1); + callback_bt(MSG_BT_PAIR_CNF_IND, URC_BT_PAIR_CNF_FAIL, NULL, NULL); + } + + return; + } + + Ql_strcpy(urcHead, "+CME ERROR:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d[^\r\n]", &err_code); + callback_bt(MSG_BT_PAIR_CNF_IND, err_code, NULL, NULL); + return; + } +} + + +/***************************************************************** +* Function: RIL_BT_Unpair +* +* Description: +* unpair a paired bt device +* +* Parameters: +* hdlDevice :[in] the bt handler to unpair +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_Unpair(BT_DEV_HDL hdlDevice) +{ + char strAT[20]; + s32 pairedId = -1 ; + s32 ret = RIL_AT_SUCCESS ; + + pairedId = BT_DevMngmt_GetPairedId(hdlDevice); + + if(pairedId <=0 || pairedId >MAX_BT_PAIRED_CNT) + { + return RIL_AT_INVALID_PARAM; + } + + Ql_sprintf(strAT, "AT+QBTUNPAIR=%d", pairedId); + ret = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); + + + if(RIL_AT_SUCCESS == ret) + { + BT_DevMngmt_UpdatePairId(hdlDevice,-1); + BT_DevMngmt_UpdateConnId(hdlDevice,-1); + BT_DevMngmt_UpdateProfileId(hdlDevice,-1); + } + + return ret ; +} + + + +/***************************************************************** +* Function: RIL_BT_GetSupportedProfile +* +* Description: +* returns the profiles suppoerted both by the local device and the other side device,for paired items +* +* Parameters: +* hdlDevice :[in] the bt handler to get support profile + profile_support :[out] the supported profile get for both sides ,see Enum_BTProfileId + len :[in] the array length +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_GetSupportedProfile(BT_DEV_HDL hdlDevice,s32 *profile_support,u8 len) +{ + char strAT[20]; + s32 pairedId = -1 ; + s32 ret; + s32 in_profile_get[BT_PROFILE_END] = {-1}; + + pairedId = BT_DevMngmt_GetPairedId(hdlDevice); + + if(pairedId <= 0 || pairedId > MAX_BT_PAIRED_CNT || NULL == profile_support || len <= 0 ) + { + return RIL_AT_INVALID_PARAM; + } + + Ql_memset(profile_support,0,len*sizeof(profile_support[0])); + + Ql_sprintf(strAT, "AT+QBTGPROF=%d", pairedId); + ret = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QBTGPROF_Hdlr, (void *)in_profile_get, 0); + + if(RIL_AT_SUCCESS == ret) + { + if(len < BT_PROFILE_END) + { + Ql_memcpy(profile_support,in_profile_get,len*sizeof(in_profile_get[0])); + } + else + { + Ql_memcpy(profile_support,in_profile_get,BT_PROFILE_END*sizeof(in_profile_get[0])); + } + } + return ret; +} + + + + +/***************************************************************** +* Function: RIL_BT_ConnReq +* +* Description: +* request to connect a paired bt device +* +* Parameters: +* hdlDevice :[in] the bt handler to connect +* profileId :[in] profile type when connect ,see Enum_BTProfileId +* mode :[in] connect type ,see Enum_BT_SPP_ConnMode +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_ConnReq(BT_DEV_HDL hdlDevice, u8 profileId, u8 mode) +{ + char strAT[20]; + s32 pairedId; + + if (profileId < BT_PROFILE_SPP || profileId >= BT_PROFILE_END) + { + return RIL_AT_INVALID_PARAM; + } + + if(mode < BT_SPP_CONN_MODE_AT || mode > BT_SPP_CONN_MODE_TRANS) + { + return RIL_AT_INVALID_PARAM; + } + + pairedId = BT_DevMngmt_GetPairedId(hdlDevice); + + if(pairedId <= 0 || pairedId > MAX_BT_PAIRED_CNT) + { + return RIL_AT_INVALID_PARAM; + } + + Ql_sprintf(strAT, "AT+QBTCONN=%d,%d,%d", pairedId, profileId, mode); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); + +} + +void OnURCHandler_BTConn(const char* strURC, void* reserved) +{ + s32 err_code = 0; + s32 connId; + char profile_name[40] = {0}; + char urcHead[30]; + ST_BT_BasicInfo bt_dev; + + Ql_memset(&bt_dev, 0x0, sizeof(ST_BT_BasicInfo)); + + if(callback_bt == NULL) + { + return ; + } + + + //+QBTCONN:1,1,H60-L01,F4E3FBE47920,SPP + //+QBTDISC:F4E3FBE47920,SPP + //+QBTCONN:0 + Ql_strcpy(urcHead, "\r\n+QBTCONN:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d%*[^\r\n]\r\n", &err_code); + if (err_code > 0) + { + //+QBTCONN:1,1,H30-T00,786A89ECCEC7,HF_PROFILE + Ql_sscanf(strURC, "%*[^,],%d%*[^\r\n]\r\n",&connId); + Ql_sscanf(strURC, "%*[^\"]\"%[^\"]%*[^\r\n]\r\n",bt_dev.name); + Ql_sscanf(strURC, "%*[^,],%*[^,],%*[^,],%[^,]%*[^\r\n]\r\n",bt_dev.addr); + Ql_sscanf(strURC, "%*[^,],%*[^,],%*[^,],%*[^,],\"%[^\"]%*[^\r\n]\r\n",profile_name); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + RIL_BT_QueryState(NULL); + callback_bt(MSG_BT_SPP_CONN_IND, URC_BT_CONN_SUCCESS, &bt_dev, NULL); + }else{ + Ql_sscanf(strURC, "%*[^,],%*[^,],%*[^,],%[^,]%*[^\r\n]\r\n",bt_dev.addr); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + BT_DevMngmt_UpdateConnId(bt_dev.devHdl, -1); + BT_DevMngmt_UpdateProfileId(bt_dev.devHdl,-1); + callback_bt(MSG_BT_SPP_CONN_IND, URC_BT_CONN_FAIL, NULL, NULL); + } + return; + } + + Ql_strcpy(urcHead, "+CME ERROR:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d\r\n", err_code); + callback_bt(MSG_BT_SPP_CONN_IND, err_code, NULL, NULL); + return; + } +} + + +/***************************************************************** +* Function: RIL_BT_SPP_DirectConn +* +* Description: +* use addr to make a direct connect ,so you don't need to scan or concern the paring process +* only support SPP connection +* +* Parameters: +* btMacAddr :[in] the bt addr to connect +* mode :[in] connect type ,see Enum_BT_SPP_ConnMode +* pinCode : [in] pairkey + + + AT+QBTCONND=F4E3FBE47920,0,"0000" + + OK + + +QBTIND: "pair",H60-L01,F4E3FBE47920,339056 + + +QBTPAIRCNF:1,1,1,"H60-L01",F4E3FBE47920 + + +QBTCONN:1,1,H60-L01,F4E3FBE47920,SPP + + + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_SPP_DirectConn(char* btMacAddr, u8 mode, char* pinCode) +{ + + char strAT[20]; + + if(NULL == btMacAddr) + { + return RIL_AT_INVALID_PARAM; + } + + if(mode < BT_SPP_CONN_MODE_AT || mode > BT_SPP_CONN_MODE_TRANS) + { + return RIL_AT_INVALID_PARAM; + } + + Ql_sprintf(strAT, "AT+QBTCONND=%s,%d,\"%s\"", btMacAddr, mode, pinCode); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), AtRsp_QBTCONND_Hdlr, NULL, 0); +} + +static s32 AtRsp_QBTCONND_Hdlr(char* line, u32 len, void* userData) +{ + if (Ql_RIL_FindLine(line, len, "OK")) + { + return RIL_ATRSP_SUCCESS; + }else{ + //todo + return RIL_ATRSP_CONTINUE; + } +} + + +/***************************************************************** +* Function: RIL_BT_ConnAccept +* +* Description: +* accept to connect +* +* Parameters: +* accept :[in] 0--reject 1---accept + mode :[in] connect type ,see Enum_BT_SPP_ConnMode + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_ConnAccept(bool accept , u8 mode) +{ + char strAT[20]; + + if(accept != 0 && accept != 1) + { + return RIL_AT_INVALID_PARAM; + } + + if(mode < BT_SPP_CONN_MODE_AT || mode > BT_SPP_CONN_MODE_TRANS) + { + return RIL_AT_INVALID_PARAM; + } + + if(1 == accept) + { + Ql_sprintf(strAT, "AT+QBTACPT=1,%d", mode); + } + else + { + Ql_sprintf(strAT, "AT+QBTACPT=0", mode); + } + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); +} + + +void OnURCHandler_BTConnCnf(const char* strURC, void* reserved) +{ + s32 err_code = 0; + s32 connId; + char urcHead[30]; + char profile_name[40] = {0}; + //s32 profileId; + ST_BT_BasicInfo bt_dev; + + Ql_memset(&bt_dev, 0x0, sizeof(ST_BT_BasicInfo)); + + if(callback_bt == NULL) + { + return ; + } + + + // AT+QBTACPT=1 + //+QBTACPT:1,2,H60-L01,F4E3FBE47920,SPP + // + // AT+QBTACPT=0 + //+QBTDISC:F4E3FBE47920,SPP + Ql_strcpy(urcHead, "\r\n+QBTACPT:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + {// Response for succeeding in connecting + Ql_sscanf(strURC, "%*[^:]: %d[^\r\n]\r\n", &err_code); + if (err_code > 0) + { + Ql_sscanf(strURC, "%*[^,],%d%*[^\r\n]\r\n",&connId); + Ql_sscanf(strURC, "%*[^\"]%[^\"]%*[^\r\n]\r\n",bt_dev.name); + Ql_sscanf(strURC, "%*[^,],%*[^,],%*[^,],%[^,]%*[^\r\n]\r\n",bt_dev.addr); + Ql_sscanf(strURC, "%*[^,],%*[^,],%*[^,],%*[^,],\"%[^\"]%*[^\r\n]\r\n",profile_name); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + RIL_BT_QueryState(NULL); + callback_bt(MSG_BT_SPP_CONN_IND, URC_BT_CONN_SUCCESS, &bt_dev, NULL); + }else{ + Ql_sscanf(strURC, "%*[^,],%*[^,],%*[^,],%[^,]%*[^\r\n]\r\n",bt_dev.addr); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + BT_DevMngmt_UpdateConnId(bt_dev.devHdl, -1); + BT_DevMngmt_UpdateProfileId(bt_dev.devHdl,-1); + callback_bt(MSG_BT_SPP_CONN_IND, URC_BT_CONN_FAIL, NULL, NULL); + } + return; + } + Ql_strcpy(urcHead, "\r\n+QBTDISC:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + {// Fail to connect or reject connection req + Ql_sscanf(strURC, "%*[^:]: %[^,]%*[^\r\n]\r\n",bt_dev.addr); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + BT_DevMngmt_UpdateConnId(bt_dev.devHdl, -1); + BT_DevMngmt_UpdateProfileId(bt_dev.devHdl,-1); + callback_bt(MSG_BT_SPP_CONN_IND, URC_BT_CONN_FAIL, NULL, NULL); + return; + } + + Ql_strcpy(urcHead, "+CME ERROR:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d\r\n", err_code); + callback_bt(MSG_BT_SPP_CONN_IND, err_code, NULL, NULL); + return; + } +} + + +/***************************************************************** +* Function: RIL_BT_Disconnect +* +* Description: +* disconnect a bt connection +* +* Parameters: +* hdlDevice :[in] the handler to disconnect + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_Disconnect(BT_DEV_HDL hdlDevice) +{ + char strAT[20]; + s32 connId ; + + connId = BT_DevMngmt_GetConnId(hdlDevice); + + if(-1 == connId) + { + return RIL_AT_INVALID_PARAM ; + } + + Ql_sprintf(strAT, "AT+QBTDISCONN=%d", connId); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); +} + +void OnURCHandler_BTDisconn(const char* strURC, void* reserved) +{ + // +QBTDISCONN:2,2,H60-L01,F4E3FBE47920,SPP + // +CME ERROR: 3518 + ST_BT_BasicInfo bt_dev; + char urcHead[30]; + s32 connId; + s32 pairedId; + s32 profileId; + s32 err_code = 0; + char profile_name[40] = {0}; + + Ql_memset(&bt_dev, 0x0, sizeof(ST_BT_BasicInfo)); + if(callback_bt == NULL) + { + return ; + } + + Ql_strcpy(urcHead, "\r\n+QBTDISCONN:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^:]: %d,%d%*[^\r\n]\r\n", &connId,&pairedId); + Ql_sscanf(strURC, "%*[^,],%*[^,],\"%[^\"]%*[^\r\n]\r\n",bt_dev.name); + Ql_sscanf(strURC, "%*[^,],%*[^,],%*[^,],%[^,]%*[^\r\n]\r\n",bt_dev.addr); + Ql_sscanf(strURC, "%*[^,],%*[^,],%*[^,],%*[^,],\"%[^\"]%*[^\r\n]\r\n",profile_name); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + //Ql_Debug_Trace("connid = %d pairid = %d name = %s addr = %s ,handle = 0x%08x\r\n",connId,pairedId,bt_dev.name,bt_dev.addr,bt_dev.devHdl); + BT_DevMngmt_UpdateConnId(bt_dev.devHdl, -1); + BT_DevMngmt_UpdateProfileId(bt_dev.devHdl,-1); + + callback_bt(MSG_BT_DISCONN_IND, URC_BT_DISCONNECT_POSITIVE, &bt_dev, NULL); + return; + } + + Ql_strcpy(urcHead, "\r\n+CME ERROR: \0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + Ql_sscanf(strURC, "%*[^: ]: %d\r\n", &err_code); + callback_bt(MSG_BT_DISCONN_IND, err_code, &bt_dev, NULL); + return; + } +} + + +/***************************************************************** +* Function: RIL_BT_SPP_Send +* +* Description: +* send data in SPP mode +* +* Parameters: +* hdlDevice :[in] the handler to send + ptrData :[in] the ptr to data to be sent + lenToSend :[in] the length of data to be sent + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_SPP_Send(BT_DEV_HDL hdlDevice, u8* ptrData, u32 lenToSend,u32* actualSend) +{ + char strAT[20]; + s32 connId ; + + if(NULL == ptrData || lenToSend < 0) + { + return RIL_AT_INVALID_PARAM; + } + + connId = BT_DevMngmt_GetConnId(hdlDevice); + + if(-1 == connId) + { + return RIL_AT_INVALID_PARAM; + } + + m_ptrSppData = ptrData; + m_nSppDataLenToSnd = lenToSend; + Ql_sprintf(strAT, "AT+QSPPSEND=%d,%d", connId, lenToSend); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QBTSPPSEND_Hdlr,(void *)actualSend, 0); +} + + +/***************************************************************** +* Function: RIL_BT_SPP_Read +* +* Description: +* read data in SPP mode +* +* Parameters: +* hdlDevice :[in] the handler to read + ptrBuffer :[in] the ptr to store the readed data + lenToRead :[in] the length of data to read + actualReadlen: [out] the actually length readed + +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +*****************************************************************/ +s32 RIL_BT_SPP_Read(BT_DEV_HDL hdlDevice, u8* ptrBuffer, u32 lenToRead ,u32 *actualReadlen) +{ + char strAT[20]; + s32 connId; + + if(NULL == ptrBuffer || lenToRead < 0) + { + return RIL_AT_INVALID_PARAM; + } + + connId = BT_DevMngmt_GetConnId(hdlDevice); + + + if(-1 == connId) + { + return RIL_AT_INVALID_PARAM; + } + + m_ptrSppDataBuf = ptrBuffer; + m_nSppDataLenToRd = lenToRead; + m_nSppRealReadLen = 0; + Ql_sprintf(strAT, "AT+QSPPREAD=%d,%d", connId, lenToRead); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QBTSPPREAD_Hdlr, (void *)actualReadlen, 0); +} + + + + +void OnURCHandler_BTIndication(const char* strURC, void* reserved) +{ + // +QBTIND: "pair",H60-L01,F4E3FBE47920,760429 + // +QBTIND: "conn","H60-L01",F4E3FBE47920,"SPP" + // +QBTIND: "disc",2,"H60-L01",F4E3FBE47920,"SPP" + char urcHead[30]; + char urcType[10]; + char pinCode[BT_PIN_LEN]={0}; + ST_BT_BasicInfo bt_dev; + s32 connId; + char temp[30]={0}; + + + Ql_memset(&bt_dev, 0x0, sizeof(ST_BT_BasicInfo)); + Ql_memset(urcType, 0x0, sizeof(urcType)); + + if(callback_bt == NULL) + { + return; + } + + + Ql_strcpy(urcHead, "\r\n+QBTIND:\0"); + if (Ql_StrPrefixMatch(strURC, urcHead)) + { + // +QBTIND: "pair",H60-L01,F4E3FBE47920,760429 + Ql_sscanf(strURC, "%*[^\"]\"%[^\"]%*[^\r\n]\r\n", urcType); + if (Ql_strcmp(urcType, "pair") == 0) + { + Ql_sscanf(strURC, "%*[^,],%*[^,],%[^\r\n]\r\n", temp); + if(Ql_strlen(temp) == (BT_ADDR_LEN - 1)) + { + Ql_sscanf(strURC, "%*[^,],%*[^,],%[^\r\n]\r\n", bt_dev.addr); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + callback_bt(MSG_BT_PAIR_REQ, URC_BT_NEED_PASSKEY, &bt_dev, NULL); // need paaskey + } + else + { + Ql_sscanf(strURC, "%*[^,],%*[^,],%[^,]%*[^\r\n]\r\n",bt_dev.addr); + Ql_sscanf(strURC, "%*[^,],%*[^,],%*[^,],%[^\r\n]\r\n",pinCode); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + callback_bt(MSG_BT_PAIR_REQ, URC_BT_NO_NEED_PASSKEY, &bt_dev, pinCode); //direct confirm + } + } + else if (Ql_strcmp(urcType, "conn") == 0) + { + // +QBTIND: "conn","H60-L01",F4E3FBE47920,"SPP" + Ql_sscanf(strURC, "%*[^,],\"%[^\"]%*[^\r\n]\r\n",bt_dev.name); + Ql_sscanf(strURC, "%*[^,],%*[^,],%[^,]%*[^\r\n]\r\n",bt_dev.addr); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + callback_bt(MSG_BT_CONN_REQ,URC_BT_CONN_REQ ,&bt_dev, NULL); + } + else if (Ql_strcmp(urcType, "disc") == 0) + { + // +QBTIND: "disc",2,2,"H60-L01",F4E3FBE47920,"SPP" + Ql_sscanf(strURC, "%*[^,],%*[^\"]\"%*[^,],%[^,]%*[^\r\n]\r\n",bt_dev.addr); + Ql_sscanf(strURC, "%*[^,],%*[^\"]\"%[^\"]%*[^\r\n]\r\n",bt_dev.name); + bt_dev.devHdl = Ql_GenHash(bt_dev.addr, Ql_strlen(bt_dev.addr)); + BT_DevMngmt_UpdateConnId(bt_dev.devHdl, -1); + BT_DevMngmt_UpdateProfileId(bt_dev.devHdl, -1); + callback_bt(MSG_BT_DISCONN_IND, URC_BT_DISCONNECT_PASSIVE, &bt_dev, NULL); + }else if (Ql_strcmp(urcType, "recv") == 0) + { + + Ql_sscanf(strURC, "%*[^,],%d\r\n",&connId); + bt_dev.devHdl = BT_DevMngmt_GetDevHdl(connId); + callback_bt(MSG_BT_RECV_IND, URC_BT_DATA_RECIEVE, &connId, &bt_dev); + } + }else{ + // error + } +} + +static s32 ATRsp_QBTADDR_Hdlr(char* line, u32 len, void* param) +{ + char* pHead = Ql_RIL_FindString(line, len, "\r\n+QBTADDR:"); + + if (pHead) + { + // +QBTADDR: 1488CD1F6261 + Ql_sscanf(line, "%*[^:]: %[^\r\n]\r\n", (char*)param); + return RIL_ATRSP_CONTINUE; + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_FAILED; //not supported +} +static s32 ATRsp_QBTSPPREAD_Hdlr(char* line, u32 len, void* param) +{ + // +CME ERROR: 8021 + // +QSPPREAD: 0 + // +QSPPREAD: 20 + // + // OK + static bool sppReadMode = FALSE; + char* pHead = NULL; + + + // The coming data is spp data + if (sppReadMode) + { + Ql_memcpy((void*)(m_ptrSppDataBuf), (const void*)line, m_nSppRealReadLen); + if(NULL != param) + { + *(u32 *)param = m_nSppRealReadLen ; + } + + sppReadMode = FALSE; + if(len>m_nSppRealReadLen) + { + pHead = Ql_RIL_FindLine(line+m_nSppRealReadLen, len-m_nSppRealReadLen, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + } + + return RIL_ATRSP_CONTINUE; + + } + + pHead = Ql_RIL_FindString(line, len, "\r\n+QSPPREAD: "); + if (pHead) + { + Ql_sscanf(line, "%*[^:]: %d", &m_nSppRealReadLen); + if (m_nSppRealReadLen > 0) + { + sppReadMode = TRUE; + }else{ // no more data + sppReadMode = FALSE; + // do nothing, just wait for "OK" + } + return RIL_ATRSP_CONTINUE; + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_FAILED; //not supported +} +static s32 ATRsp_QBTSPPSEND_Hdlr(char* line, u32 len, void* param) +{ + + char* pHead = Ql_RIL_FindString(line, len, ">\r\n"); + u32 ret = 0; + + if (pHead) + { + + ret = Ql_RIL_WriteDataToCore(m_ptrSppData, m_nSppDataLenToSnd); + + if(NULL != param && ret >= 0 ) + { + *(u32 *)param = ret ; + } + return RIL_ATRSP_CONTINUE; + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +static s32 ATRsp_QBTSTATE_Hdlr(char* line, u32 len, void* param) +{ + char* pHead = Ql_RIL_FindString(line, len, "+QBTSTATE:"); //continue wait + bool ret = FALSE ; + char profile_name[40] = {0}; + static bool is_first_prompt = TRUE; + s32 status = -1; + ST_BT_DevInfo* pstrNewBtDev = NULL; + + if (pHead) + { + // +QBTSTATE:0,1,"H60-L01",F4E3FBE47920 + // +QBTSTATE:1,2,"H60-L01",F4E3FBE47920,SPP + + if(is_first_prompt) + { + if(NULL != param) + { + Ql_sscanf(pHead, "%*[^:]: %d\r\n", (s32 *)param); + } + is_first_prompt = FALSE; + } + else + { + Ql_sscanf(pHead, "%*[^:]: %d%*[^\r\n]\r\n", &status); + } + + if (0 == status) + { + // paired device + pstrNewBtDev = (ST_BT_DevInfo*)Ql_MEM_Alloc(sizeof(ST_BT_DevInfo)); + Ql_memset(pstrNewBtDev, 0x0, sizeof(ST_BT_DevInfo)); + pstrNewBtDev->pairId = -1; + pstrNewBtDev->connId = -1; + pstrNewBtDev->profileId = -1; + Ql_sscanf(line, "%*[^,],%d%*[^\r\n]\r\n",&(pstrNewBtDev->pairId)); + Ql_sscanf(line, "%*[^\"]\"%[^\"]%*[^\r\n]\r\n",pstrNewBtDev->btDevice.name); + Ql_sscanf(line, "%*[^\"]\"%*[^,],%[^\r\n]\r\n",pstrNewBtDev->btDevice.addr); + pstrNewBtDev->btDevice.devHdl = Ql_GenHash(pstrNewBtDev->btDevice.addr, Ql_strlen(pstrNewBtDev->btDevice.addr)); + ret = BT_PairUpdateConfirm(pstrNewBtDev->pairId,pstrNewBtDev->btDevice.devHdl,pstrNewBtDev->btDevice.name); + if(FALSE == ret) + { + if(!BT_DevMngmt_isFull()) + { + BT_DevMngmt_Append(pstrNewBtDev); + } + else + { + Ql_MEM_Free (pstrNewBtDev); + } + } + else + { + Ql_MEM_Free (pstrNewBtDev); + } + + } + else if (1 == status) + { + // connected device +QBTSTATE:1,2,"H60-L01",F4E3FBE47920,SPP + pstrNewBtDev = (ST_BT_DevInfo*)Ql_MEM_Alloc(sizeof(ST_BT_DevInfo)); + Ql_memset(pstrNewBtDev, 0x0, sizeof(ST_BT_DevInfo)); + pstrNewBtDev->pairId = -1; + pstrNewBtDev->connId = -1; + pstrNewBtDev->profileId = -1; + Ql_sscanf(line, "%*[^,],%d%*[^\r\n]\r\n",&(pstrNewBtDev->connId)); + Ql_sscanf(line, "%*[^\"]\"%[^\"]%*[^\r\n]\r\n",pstrNewBtDev->btDevice.name); + Ql_sscanf(line, "%*[^\"]\"%*[^,],%[^,]%*[^\r\n]\r\n",pstrNewBtDev->btDevice.addr); + Ql_sscanf(line, "%*[^\"]\"%*[^\"]\"%*[^\"]\"%[^\"]%*[^\r\n]\r\n",profile_name); + pstrNewBtDev->profileId = BT_DevMngmt_ProfileNameToId(profile_name); + pstrNewBtDev->btDevice.devHdl = Ql_GenHash(pstrNewBtDev->btDevice.addr, Ql_strlen(pstrNewBtDev->btDevice.addr)); + ret = BT_ConnectUpdateConfirm(pstrNewBtDev->connId,pstrNewBtDev->profileId,pstrNewBtDev->btDevice.devHdl,pstrNewBtDev->btDevice.name); + if(FALSE == ret) + { + if(!BT_DevMngmt_isFull()) + { + BT_DevMngmt_Append(pstrNewBtDev); + + } + else + { + Ql_MEM_Free (pstrNewBtDev); + } + } + else + { + Ql_MEM_Free (pstrNewBtDev); + } + } + + return RIL_ATRSP_CONTINUE; + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + is_first_prompt = TRUE; + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + + +static s32 ATRsp_QBTPWR_Hdlr(char* line, u32 len, void* param) +{ + + char* pHead = Ql_RIL_FindString(line, len, "\r\n+QBTPWR:"); + + if (pHead) + { + Ql_sscanf(line, "%*[^:]: %d\r\n", (s32*)param); + + return RIL_ATRSP_CONTINUE; + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_FAILED; //not supported +} + + + +static s32 ATRsp_QBTNAME_Hdlr(char* line, u32 len, void* param) +{ + + char* pHead = Ql_RIL_FindString(line, len, "\r\n+QBTNAME:"); + + if (pHead) + { + Ql_sscanf(line, "%*[^\"]\"%[^\"]%*[^\r\n]\r\n", (char*)param); + + return RIL_ATRSP_CONTINUE; + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_FAILED; //not supported +} + + +static s32 ATRsp_QBTVISB_Hdlr(char* line, u32 len, void* param) +{ + + char* pHead = Ql_RIL_FindString(line, len, "\r\n+QBTVISB:"); + + if (pHead) + { + Ql_sscanf(line, "%*[^:]: %d\r\n", (s32 *)param); + + return RIL_ATRSP_CONTINUE; + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_FAILED; //not supported +} + + +static s32 ATRsp_QBTGPROF_Hdlr(char* line, u32 len, void* param) +{ + char* pHead = Ql_RIL_FindString(line, len, "\r\n+QBTGPROF:"); + static u8 index = 0 ; + + if (pHead) + { + Ql_sscanf(line, "%*[^:]: %d[^\r\n]\r\n", (s32 *)(param)+index); + + return RIL_ATRSP_CONTINUE; + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + index = 0 ; + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + + + +#endif //__OCPU_RIL_BT_SUPPORT__ + diff --git a/cores/opencpu/ril/src/ril_custom.c b/cores/opencpu/ril/src/ril_custom.c new file mode 100644 index 0000000..0a56739 --- /dev/null +++ b/cores/opencpu/ril/src/ril_custom.c @@ -0,0 +1,86 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_custom.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module has been designed for customer to develop new API functions over RIL. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ril.h" +#include "ril_util.h" +#include "ql_stdlib.h" + + +#if defined(__OCPU_RIL_SUPPORT__) + +/***************************************************************** +* Function: Ql_RIL_RcvDataFrmCore +* +* Description: +* This function is used to receive data from the core +* system when programing some AT commands that need to +* response with much data, such as "AT+QHTTPREAD". +* +* This function is implemented in ril_custom.c. Developer +* don't need to call this function. Under mode, this function +* will be invoken when data coming automatically. +* +* The CB_RIL_RcvDataFrmCore is defined for ustomer to define +* the callback function for each AT command. +* Parameters: +* [in]ptrData: +* Pointer to the data to be received. +* +* [in]dataLen: +* The length to be received. +* +* [in]reserved: +* Not used. +* +* Return: +* None. +* +*****************************************************************/ +CB_RIL_RcvDataFrmCore cb_rcvCoreData = NULL; +void Ql_RIL_RcvDataFrmCore(u8* ptrData, u32 dataLen, void* reserved) +{ + if (cb_rcvCoreData != NULL) + { + cb_rcvCoreData(ptrData, dataLen, reserved); + } +} + +// +// Customer may add new API functions definition here. +// +// +// +// +// +#endif + diff --git a/cores/opencpu/ril/src/ril_dtmf.c b/cores/opencpu/ril/src/ril_dtmf.c new file mode 100644 index 0000000..a2ac6d2 --- /dev/null +++ b/cores/opencpu/ril/src/ril_dtmf.c @@ -0,0 +1,397 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_dtmf.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module defines the information, and APIs related to DTMF. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "ril_dtmf.h" +#include "ril.h" +#include "ril_util.h" +#include "ql_common.h" +#include "ql_uart.h" +#include "ql_stdlib.h" +#include "ql_error.h" + + +#define RIL_DTMF_DEBUG_ENABLE 0 +#if RIL_DTMF_DEBUG_ENABLE > 0 +#define RIL_DTMF_DEBUG_PORT UART_PORT2 +static char DBG_Buffer[100]; +#define RIL_DTMF_DEBUG(BUF,...) QL_TRACE_LOG(RIL_DTMF_DEBUG_PORT,BUF,100,__VA_ARGS__) +#else +#define RIL_DTMF_DEBUG(BUF,...) +#endif + +static CB_ToneDet callback_ToneDet = NULL; // get callback funtion pointer for TONEDET URC handle +static CB_WDTMF callback_WDTMF = NULL; // get callback funtion pointer for WDTMF URC handle +static u32 *g_low_thresholdPtr = NULL; // get pointer of low threshold +static u32 *g_high_thresholdPtr = NULL; // get pointer of high threshold + +static s32 ATResponse_Handler(char* line, u32 len, void* userData); + +/**************************************************** +* DTMF detection +****************************************************/ +/***************************************************************** +* Function: RIL_ToneDet_Open +* +* Description: +* This function is used to Open DTMF detect. +* +* Parameters: +* cb_ToneDet_hdl: +* [IN] call back function to handle DTMF detected. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_ToneDet_Open( CB_ToneDet cb_ToneDet_hdl ) +{ + s32 ret = RIL_AT_FAILED; + char strAT[200]; + + callback_ToneDet = cb_ToneDet_hdl; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QTONEDET=1\r\n"); + ret = Ql_RIL_SendATCmd( strAT, Ql_strlen(strAT), NULL, NULL, 300 ) ; + + RIL_DTMF_DEBUG( DBG_Buffer, "<-- Send AT:%s, ret = %d -->\r\n", strAT, ret ); + + return ret; +} + +/***************************************************************** +* Function: RIL_ToneDet_Close +* +* Description: +* The function is used to close DTMF detect. +* +* Parameters: +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_ToneDet_Close( void ) +{ + s32 ret = RIL_AT_FAILED; + char strAT[200]; + + Ql_memset( strAT, 0, sizeof(strAT) ); + Ql_sprintf( strAT, "AT+QTONEDET=0\r\n" ); + ret = Ql_RIL_SendATCmd( strAT, Ql_strlen(strAT), NULL, NULL, 300 ) ; + + RIL_DTMF_DEBUG( DBG_Buffer, "<-- Send AT:%s, ret = %d -->\r\n", strAT, ret ); + + return ret; +} + +/***************************************************************** +* Function: RIL_ToneDet_Set +* +* Description: +* This function is used to set DTMF detection. +* +* Parameters: +* : +* [IN] 2-4, select which threshold to set. +* : +* [IN] prefix pause number. +* : +* [IN] low threshold value. +* : +* [IN] high threshold value. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_ToneDet_Set( Enum_ToneDet_Mode mode, u32 pause, u32 low, u32 high ) +{ + s32 ret = RIL_AT_FAILED; + char strAT[200]; + + if ( mode <= RIL_DETThreshold_Min || mode >= RIL_DETThreshold_Max ) + { + RIL_DTMF_DEBUG( DBG_Buffer, "<-- ToneDet Set Fail, INVALID PARAM: mode=%d -->\r\n", mode ); + return RIL_AT_INVALID_PARAM; + } + + Ql_memset( strAT, 0, sizeof(strAT) ); + Ql_sprintf( strAT, "AT+QTONEDET=%d,1,%d,%d,%d", mode, pause, low, high ); + ret = Ql_RIL_SendATCmd( strAT, Ql_strlen(strAT), NULL, NULL, 300 ) ; + + RIL_DTMF_DEBUG( DBG_Buffer, "<-- Send AT:%s, ret = %d -->\r\n", strAT, ret ); + + return ret; +} + +/***************************************************************** +* Function: RIL_ToneDet_Get +* +* Description: +* This function is used to get settings of DTMF detection. +* +* Parameters: +* : +* [IN] 2-4, select which threshold to get. +* : +* [IN] low threshold value. +* : +* [IN] high threshold value. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_ToneDet_Get( Enum_ToneDet_Mode mode, u32 *low, u32 *high ) +{ + s32 ret = RIL_AT_FAILED; + char strAT[200]; + + if ( mode < RIL_DETThreshold_Min || mode > RIL_DETThreshold_Max + || NULL == low + || NULL == high ) + { + RIL_DTMF_DEBUG( DBG_Buffer, "<-- ToneDet Set Fail, INVALID PARAM: mode=%d. -->\r\n", mode ); + return RIL_AT_INVALID_PARAM; + } + + g_low_thresholdPtr = low; + g_high_thresholdPtr = high; + + Ql_memset( strAT, 0, sizeof(strAT) ); + Ql_sprintf( strAT, "AT+QTONEDET=%d,0", mode ); + ret = Ql_RIL_SendATCmd( strAT, Ql_strlen(strAT), ATResponse_Handler, NULL, 300 ) ; + + RIL_DTMF_DEBUG( DBG_Buffer, "<-- Send AT:%s, ret = %d -->\r\n", strAT, ret ); + + return ret; +} + +/***************************************************************** +* Function: ATResponse_Handler +* +* Description: +* Call back function for handle response of the AT command. +* +* Parameters: +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +static s32 ATResponse_Handler(char* line, u32 len, void* userData) +{ + // get TONEDET threshold + if ( Ql_strstr(line, "+QTONEDET:") ) + { + if ( NULL != g_low_thresholdPtr && NULL != g_high_thresholdPtr ) + { + Ql_sscanf( line, "%*[^,],%*[^,],%d,%d", g_low_thresholdPtr, g_high_thresholdPtr ); + RIL_DTMF_DEBUG( DBG_Buffer, "<-- ATResponse_Handler: low=%d, high=%d -->\r\n", *g_low_thresholdPtr, *g_high_thresholdPtr ); + } + } + + + if (Ql_RIL_FindLine(line, len, "OK")) + { + return RIL_ATRSP_SUCCESS; + } + else if (Ql_RIL_FindLine(line, len, "ERROR")) + { + return RIL_ATRSP_FAILED; + } + else if (Ql_RIL_FindString(line, len, "+CME ERROR")) + { + return RIL_ATRSP_FAILED; + } + else if (Ql_RIL_FindString(line, len, "+CMS ERROR:")) + { + return RIL_ATRSP_FAILED; + } + return RIL_ATRSP_CONTINUE; //continue wait +} + +/***************************************************************** +* Function: OnURCHandler +* +* Description: +* This function is the entrance for Unsolicited Result Code (URC) Handler. +* +* Parameters: +* strURC: +* [IN] a URC string terminated by '\0'. +* +* reserved: +* reserved, can be NULL. +* Return: +* +*****************************************************************/ +void OnURCHandler_QToneDet( const char* strURC, void* reserved ) +{ + char buff[30]; + s32 dtmfCode = -1; + s32 timems = -1; + + if ( NULL != callback_ToneDet ) + { + Ql_strcpy( buff, "\r\n+QTONEDET:\0" ); + if( Ql_StrPrefixMatch(strURC, buff) ) + { + Ql_sscanf(strURC,"%*[^:]: %[^,]",buff); + dtmfCode = Ql_atof(buff); + if ( dtmfCode < 48 || dtmfCode > 70 ) + { + return; // not dtmfCode return. + } + else if ( 69 == dtmfCode || 70 == dtmfCode ) + { + Ql_sscanf( strURC, "%*[^,],%[^\r\n]", buff ); + timems = Ql_atof( buff ); + } + + callback_ToneDet( dtmfCode, timems ); + } + } +} + +/**************************************************** +* DTMF send +****************************************************/ +/***************************************************************** +* Function: RIL_WDTMF_Send +* +* Description: +* This function is used to play DTMF tone during the call. +* +* Parameters: +* : +* [IN] 0-7, uplink channel of the volume. +* : +* [IN] 0-7, downlink channel of the volume, recommended to be set as 0. +* : +* [IN] this string consists of DTMF tone strings, Duration of each DTMF tone(unit is ms) and Mute time (unit is ms). +* example: "0A5,50,50,3,100,50"-->0A5 is DTMF tone strings, continuancetime 50ms, mute time 50ms; +* The remaining three as before. the total lenth of dtmfStr must be less than 400. +* : +* [IN] callback function for QWDTMF URC handle. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +*****************************************************************/ +s32 RIL_WDTMF_Send( Enum_WDTMF_Vomume ul_volume, Enum_WDTMF_Vomume dl_volume, u8 *dtmfStr, CB_WDTMF cb_WDTMF_hdl ) +{ + s32 ret = RIL_AT_FAILED; + char strAT[200]; + + if ( ( ul_volume < RIL_WDTMF_VOLUME0 || ul_volume > RIL_WDTMF_VOLUME7 ) + || ( dl_volume < RIL_WDTMF_VOLUME0 || dl_volume > RIL_WDTMF_VOLUME7 ) + || ( NULL == dtmfStr ) ) + { + RIL_DTMF_DEBUG( DBG_Buffer, "<-- WDTMF Send Fail, INVALID PARAM. -->\r\n"); + return RIL_AT_INVALID_PARAM; + } + + callback_WDTMF = cb_WDTMF_hdl; + + Ql_memset( strAT, 0, sizeof(strAT) ); + Ql_sprintf( strAT, "AT+QWDTMF=%d,%d,\"%s\"\r\n", ul_volume, dl_volume, dtmfStr ); + ret = Ql_RIL_SendATCmd( strAT, Ql_strlen(strAT), NULL, NULL, 0 ) ; + + RIL_DTMF_DEBUG( DBG_Buffer, "<-- Send AT:%s, ret = %d -->\r\n", strAT, ret ); + + return ret; +} + +/***************************************************************** +* Function: OnURCHandler +* +* Description: +* This function is the entrance for Unsolicited Result Code (URC) Handler. +* +* Parameters: +* strURC: +* [IN] a URC string terminated by '\0'. +* +* reserved: +* reserved, can be NULL. +* Return: +* +*****************************************************************/ +void OnURCHandler_QWDTMF( const char* strURC, void* reserved ) +{ + char buff[30]; + s32 result = -1; + + if ( NULL != callback_WDTMF ) + { + Ql_strcpy( buff, "\r\n+QWDTMF:\0" ); + if( Ql_StrPrefixMatch(strURC, buff) ) + { + Ql_sscanf( strURC, "%*[^:]: %[^\r\n]", buff ); + result = Ql_atof( buff ); + + callback_WDTMF( result ); + } + } +} \ No newline at end of file diff --git a/cores/opencpu/ril/src/ril_ftp.c b/cores/opencpu/ril/src/ril_ftp.c new file mode 100644 index 0000000..86cfcb0 --- /dev/null +++ b/cores/opencpu/ril/src/ril_ftp.c @@ -0,0 +1,613 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_ftp.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module defines the information, and APIs related to RIL. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ql_type.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_error.h" +#include "ql_common.h" +#include "ql_system.h" +#include "ql_uart.h" +#include "ril.h" +#include "ril_util.h" +#include "ril_ftp.h" +#include "ril_network.h" + +#ifdef __OCPU_RIL_SUPPORT__ + +#define RIL_FTP_DEBUG_ENABLE 0 +#if RIL_FTP_DEBUG_ENABLE > 0 +#define RIL_FTP_DEBUG_PORT UART_PORT1 +static char DBG_Buffer[100]; +#define RIL_FTP_DEBUG(BUF,...) QL_TRACE_LOG(RIL_FTP_DEBUG_PORT,BUF,100,__VA_ARGS__) +#else +#define RIL_FTP_DEBUG(BUF,...) +#endif + + +extern CallBack_Ftp_Upload FtpPut_IND_CB; +extern CallBack_Ftp_Download FtpGet_IND_CB; +static s32 ATResponse_FTP_handler_Common(char* line, u32 len, void* userdata) +{ + ST_AT_ftpParam *ftpParam = (ST_AT_ftpParam *)userdata; + char *head = Ql_RIL_FindString(line, len, ftpParam->prefix); //continue wait + if(head) + { + char strTmp[10]; + char* p1 = NULL; + char* p2 = NULL; + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + p1 = Ql_strstr(head, ":"); + p2 = Ql_strstr(p1 + 1, "\r\n"); + if (p1 && p2) + { + //Ql_memcpy(strTmp, p1 + 2, p2 - p1 - 2); + Ql_memcpy(strTmp, p1 + 1, p2 - p1 - 1); + ftpParam->data= Ql_atoi(strTmp); + } + return RIL_ATRSP_SUCCESS; + } + head = Ql_RIL_FindLine(line, len, "OK"); + if(head) + { + return RIL_ATRSP_CONTINUE; + } + head = Ql_RIL_FindLine(line, len, "ERROR"); + if(head) + { + return RIL_ATRSP_FAILED; + } + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + head = Ql_RIL_FindString(line, len, "+CMS ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + return RIL_ATRSP_CONTINUE; //continue wait +} + +s32 RIL_FTP_QFTPOPEN(u8* hostName, u32 port,u8* userName,u8* password, bool mode) +{ + s32 ret = RIL_AT_SUCCESS; + ST_AT_ftpParam ftpParam; + char strAT[200]; + + if(NULL != userName) + { + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPUSER=\"%s\"\n", userName); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if (RIL_AT_SUCCESS != ret) + { + return ret; + } + } + + if(NULL != password) + { + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPPASS=\"%s\"\n", password); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if (RIL_AT_SUCCESS != ret) + { + return ret; + } + } + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPCFG=1,%d\n", mode); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if (RIL_AT_SUCCESS != ret) + { + return ret; + } + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPCFG=6,1\n"); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if (RIL_AT_SUCCESS != ret) + { + return ret; + } + +#if 1 //AT+QIREGAPP is not necessary in RDA platform, just verify QISTAT + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QIREGAPP\n"); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if (RIL_AT_SUCCESS != ret) + { + return ret; + } +#else +{ + u8 attempts = 0; + // 3 attempts for query QISTAT + do + { + ret = RIL_NW_GetIPStatus(); + RIL_FTP_DEBUG(DBG_Buffer, "<-- IP status: %d -->\r\n", ret); + if (IP_INITIAL == ret) + { + break; + } + attempts++; + Ql_Sleep(500); + } while (attempts < 3); +} +#endif + Ql_Sleep(100); + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QIACT\n", mode); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if (RIL_AT_SUCCESS != ret) + { + return ret; + } + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPOPEN=\"%s\",\"%d\"\n", hostName, port); + ftpParam.prefix="+QFTPOPEN:"; + ftpParam.data = 255; + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_FTP_handler_Common,(void* )&ftpParam,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send AT command failure -->\r\n"); + return ret; + } + else if(0 != ftpParam.data) // ftp open failed!!! + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- FTP OPEN SET failure, =-%d -->\r\n", ftpParam.data); + return QL_RET_ERR_RIL_FTP_OPENFAIL; + } + + return ret; + +} + + +s32 RIL_FTP_QFTPCLOSE(void) +{ + s32 ret = RIL_AT_SUCCESS; + ST_AT_ftpParam ftpParam; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPCLOSE\n"); + ftpParam.prefix = "+QFTPCLOSE:"; + ftpParam.data = 255; + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_FTP_handler_Common,(void* )&ftpParam,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if (RIL_AT_SUCCESS != ret) + { + return ret; + } + else if(0 != ftpParam.data) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- FTP CLOSE failure, =-%d -->\r\n", ftpParam.data); + return QL_RET_ERR_RIL_FTP_CLOSEFAIL; + } + return ret; +} + +s32 RIL_FTP_QFTPPUT(u8* fileName, u32 fileSize, u32 timeOut, CallBack_Ftp_Upload ftpPut_CB) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + if(0 == timeOut) + { + Ql_sprintf(strAT, "AT+QFTPPUT=\"%s\",%d\n",fileName,fileSize);// time out use the default value + } + else + { + Ql_sprintf(strAT, "AT+QFTPPUT=\"%s\",%d,%d\n",fileName,fileSize,timeOut); + } + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_ATRSP_SUCCESS == ret) + { + FtpPut_IND_CB = ftpPut_CB; + } + return ret; +} + +s32 RIL_FTP_QFTPGET(u8* fileName, u32 fileSize,CallBack_Ftp_Download ftpGet_CB) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + if(0 == fileSize) + { + Ql_sprintf(strAT, "AT+QFTPGET=\"%s\"\n",fileName); + } + else + { + Ql_sprintf(strAT, "AT+QFTPGET=\"%s\",%d\n",fileName,fileSize); + } + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_ATRSP_SUCCESS == ret) + { + FtpGet_IND_CB = ftpGet_CB; + } + return ret; +} + +s32 RIL_FTP_QFTPPATH(u8* pathName) +{ + s32 ret = RIL_AT_SUCCESS; + ST_AT_ftpParam ftpParam; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPPATH=\"%s\"\n",pathName); + ftpParam.prefix = "+QFTPPATH:"; + ftpParam.data = 255; + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_FTP_handler_Common,(void *)&ftpParam,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send FTP PATH command failure -->\r\n"); + return ret; + } + else if(0 != ftpParam.data) // ftp open failed!!! + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- FTP PATH failure, =-%d -->\r\n", ftpParam.data); + return QL_RET_ERR_RIL_FTP_SETPATHFAIL; + } + return ret; +} + +s32 RIL_FTP_QFTPCFG(u8 type, u8* value) +{ + s32 ret = RIL_AT_SUCCESS; + ST_AT_ftpParam ftpParam; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPCFG=%d,\"/%s/\"\n",type,value); + ftpParam.prefix = "+QFTPCFG:"; + ftpParam.data = 255; + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_FTP_handler_Common,(void *)&ftpParam,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send QFTPCFG command failure -->\r\n"); + return ret; + } + else if(0 != ftpParam.data) // ftp CFG failed!!! + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- FTP QFTPCFG failure, =-%d -->\r\n", ftpParam.data); + return QL_RET_ERR_RIL_FTP_SETCFGFAIL; + } + return ret; +} + +static s32 ATResponse_QFTPSTAT_handler(char* line, u32 len, void* userdata) +{ + char *head = Ql_RIL_FindString(line, len, "+QFTPSTAT:"); //continue wait + if(head) + { + if(NULL != Ql_strstr(line,"+QFTPSTAT:IDLE")) + { + *(s32*) userdata = FTP_STATUS_IDLE; + } + else if(NULL != Ql_strstr(line,"+QFTPSTAT:OPENING")) + { + *(s32*) userdata = FTP_STATUS_OPENING; + } + else if(NULL != Ql_strstr(line,"+QFTPSTAT:OPENED")) + { + *(s32*) userdata = FTP_STATUS_OPENED; + } + else if(NULL != Ql_strstr(line,"+QFTPSTAT:WORKING")) + { + *(s32*) userdata = FTP_STATUS_WORKING; + } + else if(NULL != Ql_strstr(line,"+QFTPSTAT:TRANSFER")) + { + *(s32*) userdata = FTP_STATUS_TRANSFER; + } + else if(NULL != Ql_strstr(line,"+QFTPSTAT:CLOSING")) + { + *(s32*) userdata = FTP_STATUS_CLOSING; + } + else if(NULL != Ql_strstr(line,"+QFTPSTAT:CLOSED")) + { + *(s32*) userdata = FTP_STATUS_CLOSED; + } + + return RIL_ATRSP_CONTINUE; + } + head = Ql_RIL_FindLine(line, len, "OK"); + if(head) + { + return RIL_ATRSP_SUCCESS; + } + head = Ql_RIL_FindLine(line, len, "ERROR"); + if(head) + { + return RIL_ATRSP_FAILED; + } + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + head = Ql_RIL_FindString(line, len, "+CMS ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + return RIL_ATRSP_CONTINUE; //continue wait +} + + s32 RIL_FTP_QFTPSTAT(s32* state) + { + s32 ret = RIL_AT_SUCCESS; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPSTAT\n"); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_QFTPSTAT_handler,(void *)&state,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send QFTPSTAT command failure =%d -->\r\n",ret); + *state = -1; // if the AT command set fail ,the state is Invalied + return ret; + } + return ret; +} + +static s32 ATResponse_QFTPLEN_handler(char* line, u32 len, void* userdata) +{ + char *head = Ql_RIL_FindString(line, len, "+QFTPLEN:"); //continue wait + if(head) + { + char strTmp[10]; + char* p1 = NULL; + char* p2 = NULL; + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + p1 = Ql_strstr(head, ":"); + p2 = Ql_strstr(p1 + 1, "\r\n"); + if (p1 && p2) + { + Ql_memcpy(strTmp, p1 + 2, p2 - p1 - 2); + *(s32* )userdata = Ql_atoi(strTmp); + } + return RIL_ATRSP_CONTINUE; + } + head = Ql_RIL_FindLine(line, len, "OK"); + if(head) + { + return RIL_ATRSP_SUCCESS; + } + head = Ql_RIL_FindLine(line, len, "ERROR"); + if(head) + { + return RIL_ATRSP_FAILED; + } + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + head = Ql_RIL_FindString(line, len, "+CMS ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + return RIL_ATRSP_CONTINUE; //continue wait +} +s32 RIL_FTP_QFTPLEN(s32* len) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPLEN\n"); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_QFTPLEN_handler,(void *)&len,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send QFTPLEN command failure =%d -->\r\n",ret); + *len = -1; // if the AT command set fail ,the state is Invalied + return ret; + } + return ret; +} + + s32 RIL_FTP_QFTPRENAME(u8* sourcName, u8* targetName) + { + s32 ret = RIL_AT_SUCCESS; + ST_AT_ftpParam ftpParam; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPRENAME=\"%s\",\"%s\"\n",sourcName,targetName); + ftpParam.prefix = "+QFTPRENAME:"; + ftpParam.data = 255; + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_FTP_handler_Common,(void *)&ftpParam,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send QFTPRENAME command failure -->\r\n"); + return ret; + } + else if(0 != ftpParam.data ) // ftp CFG failed!!! + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- FTP QFTPCFG failure, =-%d -->\r\n", ftpParam.data ); + return QL_RET_ERR_RIL_FTP_RENAMEFAIL; + } + return ret; +} + +s32 RIL_FTP_QFTPSIZE(u8* fileName, u32* fileSize) +{ + s32 ret = RIL_AT_SUCCESS; + ST_AT_ftpParam ftpParam; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPSIZE=\"%s\"\n",fileName); + ftpParam.prefix = "+QFTPSIZE:"; + ftpParam.data = -1; + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_FTP_handler_Common,(void *)&ftpParam,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send QFTPSIZE command failure -->\r\n"); + fileSize = 0; + return ret; + } + else if(0 > ftpParam.data) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- +QFTPSIZE failure %d-->\r\n", ftpParam.data); + fileSize = 0; + return QL_RET_ERR_RIL_FTP_SIZEFAIL; + } + *fileSize = ftpParam.data; + + return ret; +} + +s32 RIL_FTP_QFTPDELETE(u8* fileName) +{ + s32 ret = RIL_AT_SUCCESS; + ST_AT_ftpParam ftpParam; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPDELETE=\"%s\"\n",fileName); + ftpParam.prefix = "+QFTPDELETE:"; + ftpParam.data = 255; + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_FTP_handler_Common,(void *)&ftpParam,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send QFTPDELETE command failure -->\r\n"); + return ret; + } + else if(0 != ftpParam.data) // ftp QFTPDELETE failed!!! + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- FTP +QFTPDELETE failure, =-%d -->\r\n", ftpParam.data); + return QL_RET_ERR_RIL_FTP_DELETEFAIL; + } + return ret; +} + +s32 RIL_FTP_QFTPMKDIR(u8* pathName) +{ + s32 ret = RIL_AT_SUCCESS; + ST_AT_ftpParam ftpParam; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPMKDIR=\"%s\"\n",pathName); + ftpParam.prefix = "+QFTPMKDIR:"; + ftpParam.data = 255; + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_FTP_handler_Common,(void *)&ftpParam,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send QFTPMKDIR command failure -->\r\n"); + return ret; + } + else if(0 != ftpParam.data) // ftp QFTPMKDIR failed!!! + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- FTP +QFTPMKDIR failure, =-%d -->\r\n", ftpParam.data); + return QL_RET_ERR_RIL_FTP_MKDIRFAIL; + } + return ret; +} + + s32 RIL_FTP_QFTPRMDIR(u8* pathName) + { + s32 ret = RIL_AT_SUCCESS; + ST_AT_ftpParam ftpParam; + char strAT[200]; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QFTPMKDIR=\"%s\"\n",pathName); + ftpParam.prefix = "+QFTPMKDIR:"; + ftpParam.data = 255; + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_FTP_handler_Common,(void *)&ftpParam,0); + RIL_FTP_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if(RIL_AT_SUCCESS != ret) + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- send QFTPRMDIR command failure -->\r\n"); + return ret; + } + else if(0 != ftpParam.data) // + { + RIL_FTP_DEBUG(DBG_Buffer,"\r\n<-- FTP +QFTPRMDIR failure, =-%d -->\r\n", ftpParam.data); + return QL_RET_ERR_RIL_FTP_MKDIRFAIL; + } + return ret; +} + +static s32 Callback_QIDEACT(char* line, u32 len, void* userData) +{ + if (Ql_RIL_FindLine(line, len, "DEACT OK")) + { + return RIL_ATRSP_SUCCESS; + } + else if (Ql_RIL_FindLine(line, len, "ERROR")) + { + return RIL_ATRSP_FAILED; + } + return RIL_ATRSP_CONTINUE; //continue wait +} + +s32 RIL_FTP_QIDEACT(void) +{ + return Ql_RIL_SendATCmd("AT+QIDEACT\n", 11, Callback_QIDEACT, NULL, 0); +} + +#endif + + diff --git a/cores/opencpu/ril/src/ril_http.c b/cores/opencpu/ril/src/ril_http.c new file mode 100644 index 0000000..13f4520 --- /dev/null +++ b/cores/opencpu/ril/src/ril_http.c @@ -0,0 +1,232 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2015 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_ftp.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements HTTP related APIs. + * + * Author: + * ------- + * Created by: Stanley.YONG 24Jun2015 + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ql_type.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_error.h" +#include "ql_common.h" +#include "ql_system.h" +#include "ql_memory.h" +#include "ql_uart.h" +#include "ril.h" +#include "ril_util.h" +#include "ril_network.h" +#include "ril_http.h" + +#ifdef __OCPU_RIL_SUPPORT__ + +#define RIL_HTTP_DEBUG_ENABLE 0 +#if RIL_HTTP_DEBUG_ENABLE > 0 +#define RIL_HTTP_DEBUG_PORT UART_PORT2 +static char DBG_Buffer[100]; +#define RIL_HTTP_DEBUG(BUF,...) QL_TRACE_LOG(RIL_HTTP_DEBUG_PORT,BUF,100,__VA_ARGS__) +#else +#define RIL_HTTP_DEBUG(BUF,...) +#endif + +static Enum_HTTP_Ation m_httpAction = HTTP_ACTION_IDLE; +static s32 ATRsp_QHTTP_Handler(char* line, u32 len, void* param); + +char* http_url_addr = NULL; +u16 http_url_addr_len = 0; +s32 RIL_HTTP_SetServerURL(char* strURL, u16 len) +{ + s32 retRes; + s32 errCode = RIL_AT_FAILED; + char strAT[30]; + + if (!strURL) + { + return RIL_AT_INVALID_PARAM; + } + http_url_addr = strURL; + http_url_addr_len = len; + m_httpAction = HTTP_ACTION_SETRUL; + Ql_sprintf(strAT, "AT+QHTTPURL=%d,%d\0", len, 120); + retRes = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QHTTP_Handler, &errCode, 0); + if (retRes != RIL_AT_SUCCESS) + { + if (RIL_AT_FAILED == errCode) + { + return retRes; + } else { + return errCode; + } + } + return retRes; +} + +s32 RIL_HTTP_RequestToGet(u32 timeout) +{ + s32 retRes; + s32 errCode = RIL_AT_FAILED; + char strAT[30]; + + m_httpAction = HTTP_ACTION_GET_REQ; + Ql_sprintf(strAT, "AT+QHTTPGET=%d\0", timeout); + retRes = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QHTTP_Handler, &errCode, 0); + if (retRes != RIL_AT_SUCCESS) + { + if (RIL_AT_FAILED == errCode) + { + return retRes; + } else { + return errCode; + } + } + return retRes; +} + +char* http_post_msg = NULL; +u16 http_post_msg_len = 0; +s32 RIL_HTTP_RequestToPost(char* strPostMsg, u16 len) +{ + s32 retRes; + s32 errCode = RIL_AT_FAILED; + char strAT[30]; + + if (!strPostMsg) + { + return RIL_AT_INVALID_PARAM; + } + http_post_msg = strPostMsg; + http_post_msg_len = len; + m_httpAction = HTTP_ACTION_POST_REQ; + Ql_sprintf(strAT, "AT+QHTTPPOST=%d,120,120\0", len); + retRes = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QHTTP_Handler, &errCode, 0); + if (retRes != RIL_AT_SUCCESS) + { + if (RIL_AT_FAILED == errCode) + { + return retRes; + } else { + return errCode; + } + } + return retRes; +} + +s32 RIL_HTTP_ReadResponse(u32 timeout, CB_RIL_RcvDataFrmCore cb_rcvData) +{ + s32 retRes; + s32 errCode = RIL_AT_FAILED; + char strAT[30]; + extern CB_RIL_RcvDataFrmCore cb_rcvCoreData; + + if (!cb_rcvData) + { + return RIL_AT_INVALID_PARAM; + } + cb_rcvCoreData = cb_rcvData; + m_httpAction = HTTP_ACTION_READ_RSP; + Ql_sprintf(strAT, "AT+QHTTPREAD=%d\0", timeout); + retRes = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_QHTTP_Handler, &errCode, 0); + if (retRes != RIL_AT_SUCCESS) + { + if (RIL_AT_FAILED == errCode) + { + return retRes; + } else { + return errCode; + } + } + return retRes; +} + +CB_HTTP_DwnldFile callback_http_dwnld = NULL; +s32 RIL_HTTP_DownloadFile(char* filePath, u32 size, CB_HTTP_DwnldFile cb) +{ + s32 retRes; + char* strAT = NULL; + + callback_http_dwnld = cb; + m_httpAction = HTTP_ACTION_DOWNLOAD_FILE; + strAT = (char*)Ql_MEM_Alloc(Ql_strlen(filePath) + 20); + Ql_sprintf(strAT, "AT+QHTTPDL=\"%s\",%d\0", filePath, size); + retRes = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), NULL, NULL, 0); + Ql_MEM_Free(strAT); + return retRes; +} + +static s32 ATRsp_QHTTP_Handler(char* line, u32 len, void* param) +{ + char* pHead = NULL; + RIL_HTTP_DEBUG(DBG_Buffer, "RCV:%s, len:%d, m_httpAction:%d\r\n", line, len, m_httpAction); + pHead = Ql_RIL_FindLine(line, len, "CONNECT"); + if (pHead) + { + if (HTTP_ACTION_SETRUL == m_httpAction) + { + Ql_RIL_WriteDataToCore((u8*)http_url_addr, http_url_addr_len); + } + else if (HTTP_ACTION_POST_REQ == m_httpAction) + { + RIL_HTTP_DEBUG(DBG_Buffer, "Post msg:len=%d, msg:%s\r\n", http_post_msg_len, http_post_msg); + Ql_RIL_WriteDataToCore((u8*)http_post_msg, http_post_msg_len); + } + else if (HTTP_ACTION_READ_RSP == m_httpAction) + { + RIL_HTTP_DEBUG(DBG_Buffer, "\r\n"); + } + return RIL_ATRSP_CONTINUE; // wait for OK + } + pHead = Ql_RIL_FindLine(line, len, "OK"); + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + pHead = Ql_RIL_FindLine(line, len, "ERROR"); + if (pHead) + { + if (param != NULL) + { + *((s32*)param) = RIL_AT_FAILED; + } + return RIL_ATRSP_FAILED; + } + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:"); + if (pHead) + { + if (param != NULL) + { + Ql_sscanf(line, "%*[^: ]: %d[^\r\n]", (s32*)param); + } + return RIL_ATRSP_FAILED; + } + return RIL_ATRSP_CONTINUE; // Just wait for the specified results above +} + +#endif //__OCPU_RIL_SUPPORT__ + diff --git a/cores/opencpu/ril/src/ril_init.c b/cores/opencpu/ril/src/ril_init.c new file mode 100644 index 0000000..054f9f1 --- /dev/null +++ b/cores/opencpu/ril/src/ril_init.c @@ -0,0 +1,77 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_init.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * This file is used for customer to inital RIL interface. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ril.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_error.h" +#include "ql_system.h" + +#ifdef __OCPU_RIL_SUPPORT__ + +/*********************************************************************** +* Initial commands for RIL. g_InitCmds[] will be used by Ql_RIL_Initialize function. +* Now RIL is implemented based on the following AT commands. +************************************************************************/ +const char* g_InitCmds[] = { + //"ATE0Q0V1\r", // verbose result codes + "AT+CMEE=1\r", // Extended errors. This item is necessary. + "ATS0=0\r", // No auto-answer. If customer want auto answer the incoming call , must change this string as "ATS0=n\r" (n=1~255). + "AT+CREG=1\r", // GSM registration events . + "AT+CGREG=1\r", // GPRS registration events + "AT+CLIP=1\r", // Display RING number + "AT+COLP=0\r" // no connected line identification + +//...... More customization setting can add here +}; + +u32 RIL_GetInitCmdCnt(void) +{ + return NUM_ELEMS(g_InitCmds); +} + +/*********************************************************************** +* Limited commands for RIL. +* Now RIL is implemented based on the opposite functions of the +* following AT commands. +************************************************************************/ +const char* g_LimitedCmds[] = { + "AT+CMEE=0", + "AT+CLIP", +}; +u32 RIL_GetLimitedCmdCnt(void) +{ + return NUM_ELEMS(g_LimitedCmds); +} + +#endif //__OCPU_RIL_SUPPORT__ diff --git a/cores/opencpu/ril/src/ril_location.c b/cores/opencpu/ril/src/ril_location.c new file mode 100644 index 0000000..0bffb8b --- /dev/null +++ b/cores/opencpu/ril/src/ril_location.c @@ -0,0 +1,208 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_location.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module defines the information, and APIs related to RIL. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "ril_location.h" +#include "ril.h" +#include "ril_util.h" +#include "ql_common.h" +#include "ql_uart.h" +#include "ql_stdlib.h" +#include "ql_error.h" + + +#define RIL_LOC_DEBUG_ENABLE 0 +#if RIL_LOC_DEBUG_ENABLE > 0 +#define RIL_LOC_DEBUG_PORT UART_PORT2 +static char DBG_Buffer[100]; +#define RIL_LOC_DEBUG(BUF,...) QL_TRACE_LOG(RIL_LOC_DEBUG_PORT,BUF,100,__VA_ARGS__) +#else +#define RIL_LOC_DEBUG(BUF,...) +#endif + +static CB_LocInfo callback_loc = NULL; +static s32 ATResponse_GetLocation_Ex_Handler(char* line, u32 len, void* userdata); + +s32 RIL_GetLocation(CB_LocInfo cb_loc) +{ + s32 ret = RIL_AT_FAILED; + char strAT[200]; + callback_loc = cb_loc; + + Ql_memset(strAT, 0, sizeof(strAT)); + //The third parameter default value is 0.When set to 1, get location error will return "+QCELLLOC: ". + Ql_sprintf(strAT, "AT+QLOCCFG=\"ASYNCH\",1,1\r\n"); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_LOC_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + if (RIL_AT_SUCCESS == ret) + { + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QCELLLOC=1\r\n"); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + RIL_LOC_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + } + return ret; +} + +static s32 ATResponse_GetLocation_Ex_Handler(char* line, u32 len, void* userdata) +{ + char* p1 = NULL; + char* p2 = NULL; + char buff[30]; + + ST_LocInfo *loclnfo = (ST_LocInfo *)userdata ; + + Ql_memset(buff , 0, 30); + char* head = Ql_RIL_FindString(line, len, "+QCELLLOC:"); //continue wait + if(head) + { + Ql_sscanf(head,"%*[^:]: %[^,]",buff); + loclnfo->longitude = Ql_atof(buff); + + Ql_sscanf(head,"%*[^,],%[^\r\n]",buff); + loclnfo->latitude = Ql_atof(buff); + + return RIL_ATRSP_CONTINUE; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");// find ERROR, ERROR£¬ERROR + if(head) + { + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if(head) + { + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if(head) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +s32 RIL_GetLocation_Ex(ST_LocInfo* locinfo) +{ + s32 ret = RIL_AT_FAILED; + char strAT[200]; + ST_LocInfo Locinfo; + + Ql_memset(strAT, 0, sizeof(strAT)); + //The third parameter default value is 0.When set to 1, get location error will return "+QCELLLOC: ". + Ql_sprintf(strAT, "AT+QLOCCFG=\"ASYNCH\",0,0\r\n"); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + if (RIL_AT_SUCCESS == ret) + { + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QCELLLOC=1\r\n"); + RIL_LOC_DEBUG(DBG_Buffer,"<-- Send AT:%s, ret = %d -->\r\n",strAT, ret); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),ATResponse_GetLocation_Ex_Handler,(void*)&Locinfo,0); + if(RIL_ATRSP_SUCCESS == ret) + { + locinfo->latitude = Locinfo.latitude; + locinfo->longitude = Locinfo.longitude; + RIL_LOC_DEBUG(DBG_Buffer,"<-- lat:%f,long:%f ret = %d -->\r\n",locinfo->latitude,locinfo->longitude, ret); + } + else + { + locinfo->latitude = 0; + locinfo->longitude = 0; + } + } + + return ret; +} + +s32 RIL_GetLocationByCell(ST_CellInfo* cell, CB_LocInfo cb_loc) +{ + s32 ret = RIL_AT_SUCCESS; + char strAT[200]; + callback_loc = cb_loc; + + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QLOCCFG=\"ASYNCH\",1\r\n"); + Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + if (RIL_AT_SUCCESS == ret) + { + Ql_memset(strAT, 0, sizeof(strAT)); + Ql_sprintf(strAT, "AT+QCELLLOC=3,%d,%d,%d,%d,%d,%d\n",cell->cellId,cell->lac,cell->mnc,cell->mcc,cell->rssi,cell->timeAd); + ret = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT),NULL,NULL,0); + } + return ret; +} + +void OnURCHandler_QCELLLocation(const char* strURC,void* reserved) +{ + char buff[30]; + ST_LocInfo loclnfo; + s32 result; + u8* p = NULL; + + if (NULL != callback_loc) + { + p = strURC; + if(Ql_strstr(p, ",") != NULL) + { + Ql_strcpy(buff,"\r\n+QCELLLOC:\0"); + if(Ql_StrPrefixMatch(strURC,buff)) + { + Ql_sscanf(strURC,"%*[^:]: %[^,]",buff); + loclnfo.longitude = Ql_atof(buff); + + Ql_sscanf(strURC,"%*[^,],%[^\r\n]",buff); + loclnfo.latitude = Ql_atof(buff); + + callback_loc(0,&loclnfo); + + } + } + else + { + Ql_strcpy(buff,"\r\n+QCELLLOC:\0"); + if(Ql_StrPrefixMatch(strURC,buff)) + { + Ql_sscanf(strURC,"%*[^:]: %[^\r\n]",buff); + RIL_LOC_DEBUG(DBG_Buffer,"<-- +QCELLLOC: %s-->\r\n",buff); + result = Ql_atoi(buff); + loclnfo.longitude = 0; + loclnfo.latitude = 0; + callback_loc(result,&loclnfo); + } + } + } +} + + diff --git a/cores/opencpu/ril/src/ril_network.c b/cores/opencpu/ril/src/ril_network.c new file mode 100644 index 0000000..3696ecc --- /dev/null +++ b/cores/opencpu/ril/src/ril_network.c @@ -0,0 +1,555 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_network.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements network related APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ril_network.h" +#include "ril.h" +#include "ril_util.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_error.h" +#include "ql_system.h" +#include "ql_trace.h" + +#ifdef __OCPU_RIL_SUPPORT__ + +/****************************************************************************** +* Function: ATResponse_CREG_Handler +* +* Description: +* This function is used to deal with the response of the AT+CREG command. +* +* Parameters: +* line: +* [in]The address of the string. +* len: +* [in]The length of the string. +* userdata: +* [out]Used to transfer the customer's parameter. +* +* Return: +* RIL_ATRSP_SUCCESS, indicates AT executed successfully.. +* RIL_ATRSP_FAILED, indicates AT executed failed. +* RIL_ATRSP_CONTINUE,indicates continue to wait for the response +* of the AT command. +* Notes: +* 1.Can't send any new AT commands in this function. +* 2.RIL handle the AT response line by line, so this function may +* be called multiple times. +******************************************************************************/ +static s32 ATResponse_CREG_Handler(char* line, u32 len, void* userdata) +{ + char *head = Ql_RIL_FindString(line, len, "+CREG:"); //continue wait + if(head) + { + s32 n = 0; + s32 *state = (s32 *)userdata; + Ql_sscanf(head,"%*[^ ]%d,%d,%[^\r\n]",&n,state); + return RIL_ATRSP_CONTINUE; + } + + head = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if(head) + { + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if(head) + { + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +/****************************************************************************** +* Function: RIL_NW_GetGSMState +* +* Description: +* This function gets the GSM network register state. +* +* Parameters: +* stat: +* [out]GPRS State. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_NW_GetGSMState(s32 *stat) +{ + s32 retRes = -1; + s32 nStat = 0; + char strAT[] = "AT+CREG?\0"; + + retRes = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATResponse_CREG_Handler, &nStat, 0); + if(RIL_AT_SUCCESS == retRes) + { + *stat = nStat; + } + return retRes; +} + +/****************************************************************************** +* Function: ATResponse_CGREG_Handler +* +* Description: +* This function is used to deal with the response of the AT+CGREG command. +* +* Parameters: +* line: +* [in]The address of the string. +* len: +* [in]The length of the string. +* userdata: +* [out]Used to transfer the customer's parameter. +* +* Return: +* RIL_ATRSP_SUCCESS, indicates AT executed successfully.. +* RIL_ATRSP_FAILED, indicates AT executed failed. +* RIL_ATRSP_CONTINUE,indicates continue to wait for the response +* of the AT command. +* Notes: +* 1.Can't send any new AT commands in this function. +* 2.RIL handle the AT response line by line, so this function may +* be called multiple times. +******************************************************************************/ +static s32 ATResponse_CGREG_Handler(char* line, u32 len, void* userdata) +{ + char *head = Ql_RIL_FindString(line, len, "+CGREG:"); //continue wait + if(head) + { + s32 n = 0; + s32 *state = (s32 *)userdata; + Ql_sscanf(head,"%*[^ ]%d,%d,%[^\r\n]",&n,state); + return RIL_ATRSP_CONTINUE; + } + + head = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if(head) + { + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if(head) + { + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +/****************************************************************************** +* Function: RIL_NW_GetGPRSState +* +* Description: +* This function gets the GPRS network register state. +* +* Parameters: +* stat: +* [out]GPRS State. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_NW_GetGPRSState(s32 *stat) +{ + s32 retRes = -1; + s32 nStat = 0; + char strAT[] = "AT+CGREG?\0"; + + retRes = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATResponse_CGREG_Handler, &nStat, 0); + if(RIL_AT_SUCCESS == retRes) + { + *stat = nStat; + } + return retRes; +} + + +/****************************************************************************** +* Function: ATResponse_CSQ_Handler +* +* Description: +* This function is used to deal with the response of the AT+CSQ command. +* +* Parameters: +* line: +* [in]The address of the string. +* len: +* [in]The length of the string. +* userdata: +* [out]Used to transfer the customer's parameter. +* +* Return: +* RIL_ATRSP_SUCCESS, indicates AT executed successfully.. +* RIL_ATRSP_FAILED, indicates AT executed failed. +* RIL_ATRSP_CONTINUE,indicates continue to wait for the response +* of the AT command. +* Notes: +* 1.Can't send any new AT commands in this function. +* 2.RIL handle the AT response line by line, so this function may +* be called multiple times. +******************************************************************************/ +static s32 ATResponse_CSQ_Handler(char* line, u32 len, void* userdata) +{ + ST_CSQ_Reponse *CSQ_Reponse = (ST_CSQ_Reponse*)userdata; + + char *head = Ql_RIL_FindString(line, len, "+CSQ:"); //continue wait + if(head) + { + Ql_sscanf(head,"%*[^ ]%d,%d,%[^\r\n]",&CSQ_Reponse->rssi,&CSQ_Reponse->ber); + return RIL_ATRSP_CONTINUE; + } + + head = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if(head) + { + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if(head) + { + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +/****************************************************************************** +* Function: RIL_NW_GetSignalQuality +* +* Description: +* This function gets the signal quality level and bit error rate. +* +* Parameters: +* rssi: +* [out] Signal quality level, 0~31 or 99. 99 indicates module +* doesn't register to GSM network. +* +* ber: +* [out] The bit error code of signal. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_NW_GetSignalQuality(u32* rssi, u32* ber) +{ + s32 retRes = 0; + char strAT[] = "AT+CSQ\0"; + ST_CSQ_Reponse pCSQ_Reponse; + Ql_memset(&pCSQ_Reponse,0, sizeof(pCSQ_Reponse)); + retRes = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT), ATResponse_CSQ_Handler,(void*)&pCSQ_Reponse,0); + if(RIL_AT_SUCCESS == retRes) + { + *rssi = pCSQ_Reponse.rssi; + *ber = pCSQ_Reponse.ber; + } + + return retRes; +} + +s32 RIL_NW_SetGPRSContext(u8 foregroundContext) +{ + s32 retRes = 0; + char strAT[20] ; + + Ql_memset(strAT,0x00, sizeof(strAT)); + Ql_sprintf(strAT,"AT+QIFGCNT=%d",foregroundContext); + retRes = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT), NULL,NULL,0); + return retRes; +} + +s32 RIL_NW_SetAPN(u8 mode, char* apn, char* userName, char* pw) +{ + s32 retRes = 0; + char strAT[200] ; + + Ql_memset(strAT,0x00, sizeof(strAT)); + if((NULL != apn) && (NULL != userName) && (NULL != pw)) + { + Ql_sprintf(strAT,"AT+QICSGP=%d,\"%s\"",mode,apn,userName,pw); + } + else if((NULL != apn) && (NULL != userName)) + { + Ql_sprintf(strAT,"AT+QICSGP=%d,\"%s\"",mode,apn,userName); + } + else if(NULL != apn) + { + Ql_sprintf(strAT,"AT+QICSGP=%d,\"%s\"",mode,apn); + } + else + { + Ql_sprintf(strAT,"AT+QICSGP=%d",mode); + } + + retRes = Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT), NULL,NULL,0); + return retRes; + +} + +s32 RIL_NW_GetIpStatusByName(char* ipStsStr, u32 len) +{ + s32 ipSts = IP_INITIAL; + if (Ql_strncmp(ipStsStr, "IP INITIAL", len) == 0) + { + ipSts = IP_INITIAL; + } + else if (Ql_strncmp(ipStsStr, "IP START", len) == 0) + { + ipSts = IP_START; + } + else if (Ql_strncmp(ipStsStr, "IP CONFIG", len) == 0) + { + ipSts = IP_CONFIG; + } + else if (Ql_strncmp(ipStsStr, "IP IND", len) == 0) + { + ipSts = IP_IND; + } + else if (Ql_strncmp(ipStsStr, "IP GPRSACT", len) == 0) + { + ipSts = IP_GPRSACT; + } + else if (Ql_strncmp(ipStsStr, "IP STATUS", len) == 0) + { + ipSts = IP_STATUS; + } + else if (Ql_strncmp(ipStsStr, "TCP CONNECTING", len) == 0) + { + ipSts = TCP_PROCESSING; + } + else if (Ql_strncmp(ipStsStr, "UDP CONNECTING", len) == 0) + { + ipSts = UDP_PROCESSING; + } + else if (Ql_strncmp(ipStsStr, "IP CLOSE", len) == 0) + { + ipSts = IP_CLOSE; + } + else if (Ql_strncmp(ipStsStr, "CONNECT OK", len) == 0) + { + ipSts = CONNECT_OK; + } + else if (Ql_strncmp(ipStsStr, "PDP DEACT", len) == 0) + { + ipSts = GPRS_CONTEXT_DEACT; + } + return ipSts; +} +static s32 ATResponse_IPStatus_Handler(char* line, u32 len, void* userdata) +{ + s32 *result = (s32 *)userdata; + char *head = Ql_RIL_FindString(line, len, "\r\nSTATE:"); //continue wait + if(head) + { + char str[30] = {0}; + char *p = NULL; + char *q = NULL; + p = head + Ql_strlen("\r\nSTATE:"); + q = Ql_strstr(p,"\r\n"); + if (p) + { + Ql_memcpy(str, p, q - p); + } + + *result = RIL_NW_GetIpStatusByName(str, Ql_strlen(str)); + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if(head) + { + return RIL_ATRSP_CONTINUE; + } + + head = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if(head) + { + *result = IP_INITIAL; + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_FAILED; //not supported +} + +s32 RIL_NW_GetIPStatus(void) +{ + s32 retRes; + s32 ip_status = IP_INITIAL; + retRes = Ql_RIL_SendATCmd("AT+QISTAT\0", 10, ATResponse_IPStatus_Handler, &ip_status, 0); + if (RIL_AT_SUCCESS == retRes) + { + return ip_status; + }else{ + return retRes; + } +} +// +// This function activates pdp context for AT command mode. +s32 RIL_NW_OpenPDPContext(void) +{ + s32 retRes; + char strAT[20]; + u32 strATLen; + + strATLen = Ql_sprintf(strAT, "AT+QIREGAPP\0"); + retRes = Ql_RIL_SendATCmd(strAT, strATLen ,NULL, NULL, 0); + if (RIL_AT_SUCCESS != retRes) + { + return retRes; + } + + Ql_Sleep(100); // Wait for the QISTAT state changing to "IP start" + + // AT+QIACT + Ql_memset(strAT, 0, sizeof(strAT)); + strATLen = Ql_sprintf(strAT, "AT+QIACT\0"); + retRes = Ql_RIL_SendATCmd(strAT, strATLen, NULL, NULL, 0); + return retRes; +} + +static s32 ATRsp_QIDEACT_Hdlr(char* line, u32 len, void* userData) +{ + if (Ql_RIL_FindLine(line, len, "DEACT OK")) + { + return RIL_ATRSP_SUCCESS; + } + else if (Ql_RIL_FindLine(line, len, "ERROR")) + { + return RIL_ATRSP_FAILED; + } + return RIL_ATRSP_CONTINUE; //continue wait +} + +s32 RIL_NW_ClosePDPContext(void) +{ + char strAT[20] = "AT+QIDEACT\0"; + return Ql_RIL_SendATCmd("AT+QIDEACT\n", Ql_strlen(strAT), ATRsp_QIDEACT_Hdlr, NULL, 0); +} + +static s32 ATRsp_COPS_Handler(char* line, u32 len, void* param) +{ + char* pStr = (char *)param; + char* pHead = Ql_RIL_FindString(line, len, "+COPS:"); //continue wait + if (pHead) + { + char str[100] = {0}; + char *p = NULL; + char *q = NULL; + p = pHead + Ql_strlen("+COPS: "); + q = Ql_strstr(p, "\""); + if (p) + {// the response is like: +COPS: 0,0,"CHINA MOBILE" + p = q + 1; + q = Ql_strstr(p, "\""); + if (q != NULL) + { + Ql_memcpy(pStr, p, q - p); + pStr[q - p] = '\0'; + } + } + else + {// the response is like +COPS: 0 + *pStr = '\0'; + } + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +s32 RIL_NW_GetOperator(char* operator) +{ + char strAT[] = "AT+COPS?\0"; + if (NULL == operator) + { + return RIL_AT_INVALID_PARAM; + } + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_COPS_Handler,(void*)operator, 0); +} + +#endif //__OCPU_RIL_SUPPORT__ + diff --git a/cores/opencpu/ril/src/ril_ntp.c b/cores/opencpu/ril/src/ril_ntp.c new file mode 100644 index 0000000..4b09394 --- /dev/null +++ b/cores/opencpu/ril/src/ril_ntp.c @@ -0,0 +1,74 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2014 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_ntp.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements NTP related APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "ril_ntp.h" +#include "ril.h" +#include "ril_util.h" +#include "ql_stdlib.h" +#include "ql_error.h" +#include "ql_trace.h" + +static CB_NTPCMD callback_NTPCMD = NULL; + +void OnURCHandler_NTPCMD(const char* strURC, void* reserved) +{ + char urcHead[] = "\r\n+QNTP:\0"; + + if ( NULL != callback_NTPCMD ) + { + if( Ql_StrPrefixMatch(strURC, urcHead) ) + { + callback_NTPCMD(strURC); + } + } +} + +s32 RIL_NTP_START(u8 *server_addr, u16 server_port, CB_NTPCMD cb_NTPCMD_hdl) +{ + s32 ret = RIL_AT_FAILED; + char strAT[200]; + + if (server_addr == NULL) + { + return RIL_AT_INVALID_PARAM; + } + + callback_NTPCMD = cb_NTPCMD_hdl; + + Ql_memset( strAT, 0, sizeof(strAT) ); + Ql_sprintf( strAT, "AT+QNTP=\"%s\",%d\r\n", server_addr, server_port); + ret = Ql_RIL_SendATCmd( strAT, Ql_strlen(strAT), NULL, NULL, 0 ) ; + + return ret; +} + + diff --git a/cores/opencpu/ril/src/ril_sim.c b/cores/opencpu/ril/src/ril_sim.c new file mode 100644 index 0000000..8a80340 --- /dev/null +++ b/cores/opencpu/ril/src/ril_sim.c @@ -0,0 +1,300 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_network.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements sim card related APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ril.h" +#include "ril_util.h" +#include "ril_sim.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_error.h" +#include "ql_system.h" +#include "ql_trace.h" + +#ifdef __OCPU_RIL_SUPPORT__ + +s32 RIL_SIM_GetSimStateByName(char* simStat, u32 len) +{ + s32 ss = SIM_STAT_UNSPECIFIED; + if (Ql_strncmp(simStat, "READY", len) == 0) + { + ss = SIM_STAT_READY; + } + else if (Ql_strncmp(simStat, "NOT INSERTED", len) == 0) + { + ss = SIM_STAT_NOT_INSERTED; + } + else if (Ql_strncmp(simStat, "SIM PIN", len) == 0) + { + ss = SIM_STAT_PIN_REQ; + } + else if (Ql_strncmp(simStat, "SIM PUK", len) == 0) + { + ss = SIM_STAT_PUK_REQ; + } + else if (Ql_strncmp(simStat, "PH-SIM PIN", len) == 0) + { + ss = SIM_STAT_PH_PIN_REQ; + } + else if (Ql_strncmp(simStat, "PH-SIM PUK", len) == 0) + { + ss = SIM_STAT_PH_PUK_REQ; + } + else if (Ql_strncmp(simStat, "SIM PIN2", len) == 0) + { + ss = SIM_STAT_PIN2_REQ; + } + else if (Ql_strncmp(simStat, "SIM PUK2", len) == 0) + { + ss = SIM_STAT_PUK2_REQ; + } + else if (Ql_strncmp(simStat, "SIM BUSY", len) == 0) + { + ss = SIM_STAT_BUSY; + } + else if (Ql_strncmp(simStat, "NOT READY", len) == 0) + { + ss = SIM_STAT_NOT_READY; + } + return ss; +} +static s32 RIL_SIM_GetSimStateByErrCode(s32 errCode) +{ + s32 ss; + switch (errCode) + { + case 10: + ss = SIM_STAT_NOT_INSERTED; + break; + case 11: + ss = SIM_STAT_PIN_REQ; + break; + case 12: + ss = SIM_STAT_PUK_REQ; + break; + case 13: + case 15: + case 16: + ss = SIM_STAT_UNSPECIFIED; + break; + case 14: + ss = SIM_STAT_BUSY; + break; + case 17: + ss = SIM_STAT_PIN2_REQ; + break; + case 18: + ss = SIM_STAT_PUK2_REQ; + break; + default: + ss = SIM_STAT_UNSPECIFIED; + break; + } + return ss; +} + + +/****************************************************************************** +* Function: ATResponse_CPIN_Handler +* +* Description: +* This function is used to deal with the response of the AT+CPIN command. +* +* Parameters: +* line: +* [in]The address of the string. +* len: +* [in]The length of the string. +* userdata: +* [out]Used to transfer the customer's parameter. +* +* Return: +* RIL_ATRSP_SUCCESS, indicates AT executed successfully.. +* RIL_ATRSP_FAILED, indicates AT executed failed. +* RIL_ATRSP_CONTINUE,indicates continue to wait for the response +* of the AT command. +* Notes: +* 1.Can't send any new AT commands in this function. +* 2.RIL handle the AT response line by line, so this function may +* be called multiple times. +******************************************************************************/ +static s32 ATResponse_CPIN_Handler(char* line, u32 len, void* userdata) +{ + s32 *result = (s32 *)userdata; + char *head = Ql_RIL_FindString(line, len, "+CPIN:"); //continue wait + if(head) + { + char str[100] = {0}; + char *p = NULL; + char *q = NULL; + p = head + Ql_strlen("+CPIN: "); + q = Ql_strstr(p,"\r\n"); + if (p) + { + Ql_memcpy(str, p, q - p); + } + + *result = RIL_SIM_GetSimStateByName(str,Ql_strlen(str)); + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if(head) + { + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if(head) + { + *result = SIM_STAT_UNSPECIFIED; + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + s32 err = 0; + Ql_sscanf(head,"%*[^ ]%d,%[^\r\n]",&err); + *result = RIL_SIM_GetSimStateByErrCode(err); + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +/****************************************************************************** +* Function: RIL_SIM_GetSimState +* +* Description: +* This function gets the state of SIM card. +* +* Parameters: +* stat: +* [out]SIM card State. +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_SIM_GetSimState(s32 *stat) +{ + s32 retRes = -1; + s32 nStat = 0; + char strAT[] = "AT+CPIN?\0"; + + retRes = Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATResponse_CPIN_Handler, &nStat, 0); + if(RIL_AT_SUCCESS == retRes) + { + *stat = nStat; + } + return retRes; +} + +static s32 ATRsp_IMSI_Handler(char* line, u32 len, void* param) +{ + char* pHead = NULL; + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + Ql_memcpy((char*)param, line+2, len - 4); // \r\n + return RIL_ATRSP_CONTINUE; //continue wait +} +s32 RIL_SIM_GetIMSI(char* imsi) +{ + char strAT[] = "AT+CIMI\0"; + if (NULL == imsi) + { + return RIL_AT_INVALID_PARAM; + } + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_IMSI_Handler,(void*)imsi, 0); +} + +static s32 ATRsp_CCID_Handler(char* line, u32 len, void* param) +{ + char* pHead = Ql_RIL_FindString(line, len, "+CCID:"); + if (pHead) + { + Ql_sscanf(pHead,"%*[^: \"]: \"%[^\"\r\n]", (char*)param); + return RIL_ATRSP_CONTINUE; // wait for OK + } + + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} +s32 RIL_SIM_GetCCID(char* ccid) +{ + char strAT[] = "AT+CCID\0"; + if (NULL == ccid) + { + return RIL_AT_INVALID_PARAM; + } + return Ql_RIL_SendATCmd(strAT,Ql_strlen(strAT), ATRsp_CCID_Handler,(void*)ccid, 0); +} + +#endif //__OCPU_RIL_SUPPORT__ + diff --git a/cores/opencpu/ril/src/ril_sms.c b/cores/opencpu/ril/src/ril_sms.c new file mode 100644 index 0000000..9279224 --- /dev/null +++ b/cores/opencpu/ril/src/ril_sms.c @@ -0,0 +1,2330 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_sms.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements SMS related APIs. + * + * Author: + * ------- + * ------- + * Designed by : Vicent GAO + * Coded by : Vicent GAO + * Tested by : Vicent GAO + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * 2013/11/19 Vicent GAO This file is created by ROTVG00006-P01 + * 2015/06/02 Vicent GAO Add support for read/send con-sms by ROTVG00006-P05 + * 2015/06/04 Vicent GAO Remove useless codes by ROTVG00006-P07 + ****************************************************************************/ +#include "custom_feature_def.h" + +#if (defined(__OCPU_RIL_SUPPORT__) && defined(__OCPU_RIL_SMS_SUPPORT__)) + +#include "ril.h" +#include "ril_sms.h" +#include "lib_ril_sms.h" +#include "ril_util.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_uart.h" + +/*********************************************************************** + * MACRO CONSTANT DEFINITIONS +************************************************************************/ +#define DBG_SWITCH (FALSE) +#define DBG_PORT (UART_PORT2) //NOTE: Only DBG_SWITCH set to TRUE,this macro can be VALID. +#define DBG_BUF_MAX_LEN (512) + +#define SMS_CMD_MAX_LEN (30) + +#define CPMS_KEY_STR "+CPMS: " //Warning: Please NOT-CHANGE this value!! +#define CMGR_KEY_STR "+CMGR: " //Warning: Please NOT-CHANGE this value!! +#define CMGS_KEY_STR "+CMGS: " //Warning: Please NOT-CHANGE this value!! + +#define STR_CMGS_HINT "\r\n>" +#define STR_CR_LF "\r\n" +#define STR_COMMA "," + +#define CHARSET_GSM_INSTEAD_0X1B_CHAR_FLAG (0x80) +#define CHARSET_GSM_INSTEAD_0X1A_CHAR_FLAG (0x81) + +/*********************************************************************** + * ENUM TYPE DEFINITIONS +************************************************************************/ +typedef enum +{ + HDLR_TYPE_CPMS_READ_CMD = 0, + HDLR_TYPE_CPMS_SET_CMD = 1, + HDLR_TYPE_CMGR_PDU_CMD = 2, + HDLR_TYPE_CMGS_PDU_CMD = 3, + + //==> Warning: Please add new Handler Type upper this line. + HDLR_TYPE_INVALID = 0xFFFFFFFF +} Enum_HdlrType; + +/*********************************************************************** + * STRUCT TYPE DEFINITIONS +************************************************************************/ +typedef struct +{ + u32 uHdlrType; + void *pUserData; +} ST_SMS_HdlrUserData; + +typedef struct + { + u8 storage; + u32 used; + u32 total; +}ST_SMSStorage; + +/*********************************************************************** + * OTHER TYPE DEFINITIONS +************************************************************************/ + +/*********************************************************************** + * GLOBAL DATA DEFINITIONS +************************************************************************/ + +/*********************************************************************** + * FUNCTION DECLARATIONS --> Adapter layer functions + * NOTE: If you get this RIL SMS to another platform, you MAY need to recode these functions +************************************************************************/ +static u32 ADP_SMS_ConvIdxToCoreIdx(u8 uStoType,u32 uRILIdx, u32 uRILMaxIdx); + +/*********************************************************************** + * FUNCTION DECLARATIONS --> Internal functions + * NOTE: These functions are ONLY used in this file. +************************************************************************/ +static bool IsValidConParam(ST_RIL_SMS_Con *pCon); +static bool ConvStringToPhoneNumber(char *pString,u32 uStrLen,LIB_SMS_PhoneNumberStruct *pNumber); +static bool ConvPhoneNumberToString(LIB_SMS_PhoneNumberStruct *pNumber,char *pString,u32 uStrLen); +static bool ConvTimeStampToString(LIB_SMS_TimeStampStruct *pTimeStamp,char *pString,u32 uStrLen); +static bool ConvDeliverSMSParamToTextInfo(LIB_SMS_DeliverPDUParamStruct *pSMSParam,ST_RIL_SMS_DeliverParam *pTextInfo); +static bool ConvSubmitSMSParamToTextInfo(LIB_SMS_SubmitPDUParamStruct *pSMSParam,ST_RIL_SMS_SubmitParam *pTextInfo); +static bool ConvSMSParamToTextInfo(u8 uCharSet,LIB_SMS_PDUParamStruct *pSMSParam,ST_RIL_SMS_TextInfo* pTextInfo); + +static bool GetStorageType(char *pStr,u8 *pType); + +static char* HdlrGetStorageInfo(char *pLine,u32 uLen,ST_SMSStorage *pInfo); +static char* HdlrSetStorage(char *pLine,u32 uLen,ST_SMSStorage *pInfo); +static char* HdlrReadPDUMsg(char *pLine,u32 uLen,ST_RIL_SMS_PDUInfo *pPDU); +static char* HdlrSendPDUMsg(char *pLine,u32 uLen,ST_RIL_SMS_SendPDUInfo *pInfo); + +static s32 SMS_CMD_GeneralHandler(char* pLine, u32 uLen, void* pUserData); + +static s32 CmdGetStorageInfo(u8* pCurrMem, u32* pUsed,u32* pTotal); +static s32 CmdSetStorageInfo(u8 uStoType,u32* pUsed,u32* pTotal); +static s32 CmdReadPDUMsg(u32 uIndex, ST_RIL_SMS_PDUInfo* pPDU); +static s32 CmdSendPDUMsg(char* pPDUStr,u32 uPDUStrLen,u32 *pMsgRef); + +/*********************************************************************** + * MACRO FUNCTION DEFINITIONS --> ADPATER LAYER USE + * NOTE: If you get this RIL SMS to another platform, you MAY need to recode these macro functions +************************************************************************/ +#define ADP_IS_SUPPORT_STORAGE_TYPE(StorageType) \ +( \ + ( \ + (RIL_SMS_STORAGE_TYPE_SM == (StorageType)) \ + ) ? TRUE : FALSE \ +) + +/*********************************************************************** + * MACRO FUNCTION DEFINITIONS --> INTERNAL USE + * NOTE: These functions are ONLY used in this file. +************************************************************************/ + +#if DBG_SWITCH == (TRUE) + +static char sg_aDbgBuf[DBG_BUF_MAX_LEN]; + +#define DBG_TRACE(Buffer,...) \ + do \ + { \ + Ql_memset((Buffer), 0, sizeof(Buffer)); \ + Ql_snprintf((char *)(Buffer),DBG_BUF_MAX_LEN,__VA_ARGS__); \ + \ + if(UART_PORT2 == DBG_PORT) \ + { \ + Ql_Debug_Trace((char*)(Buffer)); \ + Ql_Debug_Trace((char*)(STR_CR_LF)); \ + } \ + else \ + { \ + Ql_UART_Write(DBG_PORT,(u8*)(Buffer),Ql_strlen((char*)(Buffer))); \ + Ql_UART_Write(DBG_PORT,(u8*)(STR_CR_LF),Ql_strlen((char*)(STR_CR_LF))); \ + } \ + } while(0) + +#define DBG_NO_CRLF_TRACE(Buffer,...) \ + do \ + { \ + Ql_memset((Buffer), 0, sizeof(Buffer)); \ + Ql_snprintf((char *)(Buffer),sizeof(Buffer),__VA_ARGS__); \ + \ + if (UART_DEBUG_PORT == DBG_PORT) \ + {\ + Ql_Debug_Trace("%s", (char*)Buffer);\ + } else {\ + Ql_UART_Write(DBG_PORT,(u8*)(Buffer),Ql_strlen((char*)(Buffer))); \ + }\ + } while(0) + +#define DBG_BIN_TRACE(Data,DataLen) \ + do \ + { \ + Ql_UART_Write(DBG_PORT,(u8*)(Data),(DataLen)); \ + Ql_UART_Write(DBG_PORT,(u8*)"\r\n",2); \ + } while(0) + +#define DBG_BIN_NO_CRLF_TRACE(Data,DataLen) \ + do \ + { \ + Ql_UART_Write(DBG_PORT,(u8*)(Data),(DataLen)); \ + } while(0) + +#else //#if DBG_SWITCH == (TRUE) + +#define DBG_TRACE(Buffer,...) +#define DBG_NO_CRLF_TRACE(Buffer,...) +#define DBG_BIN_TRACE(Data,DataLen) +#define DBG_BIN_NO_CRLF_TRACE(Data,DataLen) + +#endif //#if DBG_SWITCH == (TRUE) + +#define IS_VALID_PDU_INFO(PDUInfo) \ +( \ + ( \ + ((((ST_RIL_SMS_PDUInfo*)(PDUInfo))->status) <= RIL_SMS_STATUS_TYPE_STO_SENT) \ + && ((((ST_RIL_SMS_PDUInfo*)(PDUInfo))->length) <= sizeof(((ST_RIL_SMS_PDUInfo*)(PDUInfo))->data)) \ + ) ? TRUE : FALSE \ +) + +#define CONV_STRING_TO_INTEGER(pStr,uLen,uVal) \ + do \ + { \ + char aBufTmpZ[40] = {0,}; \ + \ + Ql_memcpy(aBufTmpZ,pStr,uLen); \ + uVal = Ql_atoi(aBufTmpZ); \ + } while(0) + +#define SMS_SET_INVALID_PDU_INFO(PDUInfo) \ + do \ + { \ + Ql_memset(((ST_RIL_SMS_PDUInfo*)(PDUInfo)),0x00,sizeof(ST_RIL_SMS_PDUInfo)); \ + \ + (((ST_RIL_SMS_PDUInfo*)(PDUInfo))->status) = RIL_SMS_STATUS_TYPE_INVALID; \ + } while(0) + +#define SMS_SET_INVALID_TEXT_INFO(TextInfo) \ + do \ + { \ + Ql_memset(((ST_RIL_SMS_TextInfo*)(TextInfo)),0x00,sizeof(ST_RIL_SMS_TextInfo)); \ + \ + (((ST_RIL_SMS_TextInfo*)(TextInfo))->status) = RIL_SMS_STATUS_TYPE_INVALID; \ + } while(0) + +#define SMS_SET_PDU_MODE(ErrCode,DbgFunName) \ + do \ + { \ + (ErrCode) = Ql_RIL_SendATCmd("AT+CMGF=0",Ql_strlen("AT+CMGF=0"),NULL,NULL,0); \ + if(RIL_ATRSP_SUCCESS != (ErrCode)) \ + { \ + DBG_TRACE(sg_aDbgBuf,"Enter " DbgFunName ",FAIL! AT+CMGF=0 execute error! Code:%d\r\n",(ErrCode)); \ + return (ErrCode); \ + } \ + } while(0) + +#define SMS_HDLR_CHECK_ERROR(pLine,uLen,DbgFunName) \ + do \ + { \ + if(NULL != Ql_RIL_FindLine((pLine),(uLen),"OK")) \ + { \ + DBG_TRACE(sg_aDbgBuf,"Enter " DbgFunName ",SUCCESS. Find string: \"OK\"\r\n"); \ + return RIL_ATRSP_SUCCESS; \ + } \ + \ + if(NULL != Ql_RIL_FindLine((pLine), (uLen), "ERROR")) \ + { \ + DBG_TRACE(sg_aDbgBuf,"Enter " DbgFunName ",SUCCESS. Find string: \"ERROR\"\r\n"); \ + return RIL_ATRSP_FAILED; \ + } \ + \ + if(NULL != Ql_RIL_FindString((pLine), (uLen), "+CME ERROR:")) \ + { \ + DBG_TRACE(sg_aDbgBuf,"Enter " DbgFunName ",SUCCESS. Find string: \"+CME ERROR:\"\r\n"); \ + return RIL_ATRSP_FAILED; \ + } \ + \ + if(NULL != Ql_RIL_FindString((pLine), (uLen), "+CMS ERROR:")) \ + { \ + DBG_TRACE(sg_aDbgBuf,"Enter " DbgFunName ",SUCCESS. Find string: \"+CMS ERROR:\"\r\n"); \ + return RIL_ATRSP_FAILED; \ + } \ + } while(0); + +#define SMS_GET_STORAGE_NAME(StorageType,StorageName) \ + do \ + { \ + if(RIL_SMS_STORAGE_TYPE_MT == (StorageType)) \ + { \ + Ql_strcpy((StorageName),"MT"); \ + } \ + else if(RIL_SMS_STORAGE_TYPE_ME == (StorageType)) \ + { \ + Ql_strcpy((StorageName),"ME"); \ + } \ + else \ + { \ + Ql_strcpy((StorageName),"SM"); \ + } \ + } while(0) + +/*********************************************************************** + * FUNCTION DEFINITIONS --> Adapter layer functions + * NOTE: If you get this RIL SMS to another platform, you MAY need to recode these functions +************************************************************************/ + +/****************************************************************************** +* Function: ADP_SMS_ConvIdxToCoreIdx +* +* Description: +* Covert RIL SMS index to core SMS index +* +* Parameters: +* : +* [In] SMS storage type,same as: 'Enum_RIL_SMS_SMSStorage' +* : +* [In] The given RIL SMS index +* +* [In] The maximum valid RIL SMS index +* +* Return: +* 0: This function works FAIL! +* OTHER VALUE: This function works SUCCESS. And this value is the core SMS index. +* +* NOTE: +* 1. This is an Adapter function. +******************************************************************************/ +static u32 ADP_SMS_ConvIdxToCoreIdx(u8 uStoType,u32 uRILIdx, u32 uRILMaxIdx) +{ + u32 uCoreIdx = 0; + + if(FALSE == ADP_IS_SUPPORT_STORAGE_TYPE(uStoType)) + { + DBG_TRACE(sg_aDbgBuf,"Enter ADP_SMS_ConvIdxToCoreIdx,FAIL! ADP_IS_SUPPORT_STORAGE_TYPE FAIL! uStoType:%u",uStoType); + return 0; + } + + if((uRILIdx < 1) || (uRILIdx > uRILMaxIdx)) + { + DBG_TRACE(sg_aDbgBuf,"Enter ADP_SMS_ConvIdxToCoreIdx,FAIL! uRILIdx:%u,uRILMaxIdx:%u\r\n",uRILIdx,uRILMaxIdx); + return 0; + } + + uCoreIdx = uRILIdx; + + DBG_TRACE(sg_aDbgBuf,"Enter ADP_SMS_ConvIdxToCoreIdx,SUCCESS. uRILIdx:%u,uRILMaxIdx:%u,uCoreIdx:%u\r\n",uRILIdx,uRILMaxIdx,uCoreIdx); + + return uCoreIdx; +} + +/*********************************************************************** + * FUNCTION DEFINITIONS --> Internal functions + * NOTE: These functions are ONLY used in this file. +************************************************************************/ + +/****************************************************************************** +* Function: IsValidConParam +* +* Description: +* Check 'pCon' is valid or not +* +* Parameters: +* : +* [In] 'ST_RIL_SMS_Con' data +* + msgType Con-SMS type,valid value list: LIB_SMS_UD_TYPE_CON_6_BYTE,LIB_SMS_UD_TYPE_CON_7_BYTE +* + msgRef Con-SMS reference value +* + msgSeg Con-SMS current segment +* + msgTot Con-SMS total segment +* +* Return: +* TRUE: This function works SUCCESS. +* FALSE: This function works FAIL! +* +* NOTE: +* 1. This function ONLY used in AT handler function. +******************************************************************************/ +static bool IsValidConParam(ST_RIL_SMS_Con *pCon) +{ + if(NULL == pCon) + { + DBG_TRACE(sg_aDbgBuf,"Enter IsValidConParam,FAIL! Parameter is NULL."); + return FALSE; + } + + if( ((pCon->msgType) != LIB_SMS_UD_TYPE_CON_6_BYTE) + && ((pCon->msgType) != LIB_SMS_UD_TYPE_CON_7_BYTE) + ) + { + DBG_TRACE(sg_aDbgBuf,"Enter IsValidConParam,FAIL! msgType:%d is INVALID.",pCon->msgType); + return FALSE; + } + + if( ((pCon->msgSeg) < 1) + || ((pCon->msgSeg) > (pCon->msgTot)) + ) + { + DBG_TRACE(sg_aDbgBuf,"Enter IsValidConParam,FAIL! msgSeg:%d or msgTot: %d INVALID.",pCon->msgSeg,pCon->msgTot); + return FALSE; + } + + return TRUE; +} + +/****************************************************************************** +* Function: ConvStringToPhoneNumber +* +* Description: +* Get storage type refer to given string. +* +* Parameters: +* : +* [In] The pointer of number string +* +* [In] The length of number string +* : +* [In] The pointer of 'LIB_SMS_PhoneNumberStruct' data +* +* Return: +* TRUE: This function works SUCCESS. +* FALSE: This function works FAIL! +* +* NOTE: +* 1. This function ONLY used in AT handler function. +******************************************************************************/ +static bool ConvStringToPhoneNumber(char *pString,u32 uStrLen,LIB_SMS_PhoneNumberStruct *pNumber) +{ + u8 uType = 0; + char *pTmp = NULL; + u32 i = 0; + + if((NULL == pString) || (NULL == pNumber)) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvStringToPhoneNumber,FAIL! Parameter is NULL."); + return FALSE; + } + + if(0 == uStrLen) //Not given number string + { + Ql_memset(pNumber,0x00,sizeof(LIB_SMS_PhoneNumberStruct)); + (pNumber->uType) = LIB_SMS_PHONE_NUMBER_TYPE_UNKNOWN; + + DBG_TRACE(sg_aDbgBuf,"Enter ConvStringToPhoneNumber,SUCCESS. NOTE: uStrLen is 0."); + return TRUE; + } + + //Initialize + pTmp = pString; + + if(LIB_SMS_CHAR_PLUS == (*pTmp)) + { + uType = LIB_SMS_PHONE_NUMBER_TYPE_INTERNATIONAL; + pTmp += 1; + } + else + { + uType = LIB_SMS_PHONE_NUMBER_TYPE_NATIONAL; + } + + if((uStrLen - (pTmp - pString)) > LIB_SMS_PHONE_NUMBER_MAX_LEN) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvStringToPhoneNumber,FAIL! Phone number is too long. LIB_SMS_PHONE_NUMBER_MAX_LEN:%d,Now:%d",LIB_SMS_PHONE_NUMBER_MAX_LEN,(uStrLen - (pTmp - pString))); + return FALSE; + } + + //Check the given number's validity + for(i = 0; i < (uStrLen - (pTmp - pString)); i++) + { + if(FALSE == LIB_SMS_IS_VALID_ASCII_NUMBER_CHAR(pTmp[i])) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvStringToPhoneNumber,FAIL! LIB_SMS_IS_VALID_ASCII_NUMBER_CHAR FAIL! Char[%d]:0x%x",i,pTmp[i]); + return FALSE; + } + } + + pNumber->uType = uType; + (pNumber->uLen) = (uStrLen - (pTmp - pString)); + Ql_memcpy((pNumber->aNumber), pTmp, (pNumber->uLen)); + + DBG_TRACE(sg_aDbgBuf,"Enter ConvStringToPhoneNumber,SUCCESS. uLen:%d,uType:%d",(pNumber->uLen),uType); + + return TRUE; +} + +/****************************************************************************** +* Function: ConvPhoneNumberToString +* +* Description: +* Convert 'LIB_SMS_PhoneNumberStruct' data to string. +* +* Parameters: +* : +* [In] The pointer of phone number +* +* [In] The pointer of string +* +* [In] The maximum length of string +* +* Return: +* TRUE: This function works SUCCESS. +* FALSE: This function works FAIL! +******************************************************************************/ +static bool ConvPhoneNumberToString(LIB_SMS_PhoneNumberStruct *pNumber,char *pString,u32 uStrLen) +{ + u32 uLimitLen = 0; + char *pTmp = NULL; + + if((NULL == pNumber) || (NULL == pString) || (0 == uStrLen)) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvPhoneNumberToString,FAIL! Parameter is NULL."); + return FALSE; + } + + if(0 == (pNumber->uLen)) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvPhoneNumberToString,SUCCESS. NOTE: Number length is 0."); + + Ql_memset(pString,0x00,uStrLen); + return TRUE; + } + + //Check is VALID or not + if(LIB_SMS_PHONE_NUMBER_TYPE_INTERNATIONAL == (pNumber->uType)) + { + uLimitLen = ((pNumber->uLen) + 1 + 1); //It will add '+' at the first position,'\0' at the end position. + } + else if(LIB_SMS_PHONE_NUMBER_TYPE_NATIONAL == (pNumber->uType)) + { + uLimitLen = ((pNumber->uLen) + 1); //It will add '\0' at the end position. + } + else if(LIB_SMS_PHONE_NUMBER_TYPE_UNKNOWN == (pNumber->uType)) + { + uLimitLen = ((pNumber->uLen) + 1); //It will add '\0' at the end position. + } + //<2015/03/23-ROTVG00006-P04-Vicent.Gao,<[SMS] Segment 4==>Fix issues of RIL SMS LIB.> + else if(LIB_SMS_PHONE_NUMBER_TYPE_ALPHANUMERIC == (pNumber->uType)) + { + uLimitLen = ((pNumber->uLen) + 1); //It will add '\0' at the end position. + } + //>2015/03/23-ROTVG00006-P04-Vicent.Gao + else + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvPhoneNumberToString,FAIL! Number type is INVALID. uType:%u",(pNumber->uType)); + return FALSE; + } + + if(uStrLen < uLimitLen) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvPhoneNumberToString,FAIL! uStrLen is less than uLimitLen. uStrLen:%u,uLimitLen:%u",uStrLen,uLimitLen); + return FALSE; + } + + //Initialize + Ql_memset(pString,0x00,uStrLen); + pTmp = pString; + + if((LIB_SMS_PHONE_NUMBER_TYPE_INTERNATIONAL == (pNumber->uType))) + { + pTmp[0] = LIB_SMS_CHAR_PLUS; + pTmp += 1; + } + + Ql_memcpy(pTmp,(pNumber->aNumber),(pNumber->uLen)); + + DBG_TRACE(sg_aDbgBuf,"Enter ConvPhoneNumberToString,SUCCESS. pString: %s",pString); + + return TRUE; +} + +/****************************************************************************** +* Function: ConvTimeStampToString +* +* Description: +* Convert 'LIB_SMS_TimeStampStruct' data to string. +* +* Parameters: +* : +* [In] The pointer of 'LIB_SMS_TimeStampStruct' data +* +* [In] The pointer of string +* +* [In] The maximum length of string +* +* Return: +* TRUE: This function works SUCCESS. +* FALSE: This function works FAIL! +******************************************************************************/ +static bool ConvTimeStampToString(LIB_SMS_TimeStampStruct *pTimeStamp,char *pString,u32 uStrLen) +{ + s32 iLen = 0; + s32 iTimeZone = 0; + + if((NULL == pTimeStamp) || (NULL == pString)) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvTimeStampToString,FAIL! Parameter is NULL."); + return FALSE; + } + + if(uStrLen < RIL_SMS_TIME_STAMP_STR_MAX_LEN) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvTimeStampToString,FAIL! uStrLen is too less. uStrLen:%u,RIL_SMS_TIME_STAMP_STR_MAX_LEN:%u",uStrLen,RIL_SMS_TIME_STAMP_STR_MAX_LEN); + return FALSE; + } + + iLen = Ql_sprintf(pString,"%02u/%02u/%02u,%02u:%02u:%02u", + (pTimeStamp->uYear), + (pTimeStamp->uMonth), + (pTimeStamp->uDay), + (pTimeStamp->uHour), + (pTimeStamp->uMinute), + (pTimeStamp->uSecond) + ); + + iTimeZone = (pTimeStamp->iTimeZone); + if(iTimeZone < 0) + { + Ql_sprintf((pString+iLen),"%02d",iTimeZone); + } + else + { + Ql_sprintf((pString+iLen),"+%02d",iTimeZone); + } + + DBG_TRACE(sg_aDbgBuf,"Enter ConvTimeStampToString,SUCCESS. pString:%s",pString); + + return TRUE; +} + +/****************************************************************************** +* Function: ConvDeliverSMSParamToTextInfo +* +* Description: +* Convert 'LIB_SMS_DeliverPDUParamStruct' data to 'ST_RIL_SMS_DeliverParam' data. +* +* Parameters: +* : +* [In] The pointer of SMS parameter +* +* [In] The pointer of TEXT SMS info +* +* Return: +* TRUE: This function works SUCCESS. +* FALSE: This function works FAIL! +******************************************************************************/ +static bool ConvDeliverSMSParamToTextInfo(LIB_SMS_DeliverPDUParamStruct *pSMSParam,ST_RIL_SMS_DeliverParam *pTextInfo) +{ + bool bResult = FALSE; + + if((NULL == pSMSParam) || (NULL == pTextInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvDeliverSMSParamToTextInfo,FAIL! Parameter is NULL."); + return FALSE; + } + + LIB_SMS_GET_ALPHA_IN_PDU_DCS((pSMSParam->uDCS),(pTextInfo->alpha)); + + bResult = ConvPhoneNumberToString(&(pSMSParam->sOA),(pTextInfo->oa),sizeof(pTextInfo->oa)); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvDeliverSMSParamToTextInfo,FAIL! ConvPhoneNumberToString FAIL!"); + return FALSE; + } + + bResult = ConvTimeStampToString(&(pSMSParam->sSCTS),(pTextInfo->scts),sizeof(pTextInfo->scts)); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvDeliverSMSParamToTextInfo,FAIL! ConvTimeStampToString FAIL!"); + return FALSE; + } + + DBG_TRACE(sg_aDbgBuf,"Enter ConvDeliverSMSParamToTextInfo,SUCCESS. alpha:%u,oa:%s,scts:%s",(pTextInfo->alpha),(pTextInfo->oa),(pTextInfo->scts)); + + return TRUE; +} + +/****************************************************************************** +* Function: ConvSubmitSMSParamToTextInfo +* +* Description: +* Convert 'LIB_SMS_SubmitPDUParamStruct' data to 'ST_RIL_SMS_SubmitParam' data. +* +* Parameters: +* : +* [In] The pointer of SMS parameter +* +* [In] The pointer of TEXT SMS info +* +* Return: +* TRUE: This function works SUCCESS. +* FALSE: This function works FAIL! +******************************************************************************/ +static bool ConvSubmitSMSParamToTextInfo(LIB_SMS_SubmitPDUParamStruct *pSMSParam,ST_RIL_SMS_SubmitParam *pTextInfo) +{ + bool bResult = FALSE; + + if((NULL == pSMSParam) || (NULL == pTextInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvSubmitSMSParamToTextInfo,FAIL! Parameter is NULL."); + return FALSE; + } + + LIB_SMS_GET_ALPHA_IN_PDU_DCS((pSMSParam->uDCS),(pTextInfo->alpha)); + + bResult = ConvPhoneNumberToString(&(pSMSParam->sDA),(pTextInfo->da),sizeof(pTextInfo->da)); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvSubmitSMSParamToTextInfo,FAIL! ConvPhoneNumberToString FAIL!"); + return FALSE; + } + + DBG_TRACE(sg_aDbgBuf,"Enter ConvSubmitSMSParamToTextInfo,SUCCESS. alpha:%u,da:%s",(pTextInfo->alpha),(pTextInfo->da)); + + return TRUE; +} + +/****************************************************************************** +* Function: ConvSMSParamToTextInfo +* +* Description: +* Convert 'LIB_SMS_PDUParamStruct' data to 'ST_RIL_SMS_TextInfo' data +* +* Parameters: +* +* [In] CharSet,It's value is in 'LIB_SMS_CharSetEnum' +* : +* [In] The pointer of SMS parameters +* +* [In] The pointer of TEXT SMS info +* +* Return: +* RIL_ATRSP_SUCCESS: This function works SUCCESS. +* OTHER VALUES: This function works FAIL! +******************************************************************************/ +static bool ConvSMSParamToTextInfo(u8 uCharSet,LIB_SMS_PDUParamStruct *pSMSParam,ST_RIL_SMS_TextInfo* pTextInfo) +{ + bool bResult = FALSE; + ST_RIL_SMS_DeliverParam *pDeliverTextInfo = NULL; + ST_RIL_SMS_SubmitParam *pSubmitTextInfo = NULL; + + if((NULL == pSMSParam) || (NULL == pTextInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvSMSParamToTextInfo,FAIL! Parameter is NULL."); + return FALSE; + } + + bResult = ConvPhoneNumberToString(&(pSMSParam->sSCA),(pTextInfo->sca),sizeof(pTextInfo->sca)); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvSMSParamToTextInfo,FAIL! ConvPhoneNumberToString FAIL!"); + return FALSE; + } + + (pTextInfo->type) = LIB_SMS_GET_MSG_TYPE_IN_PDU_FO(pSMSParam->uFO); + if(LIB_SMS_PDU_TYPE_DELIVER == (pTextInfo->type)) + { + pDeliverTextInfo = &((pTextInfo->param).deliverParam); + + if((pSMSParam->uFO) & 0x40) //Concatenate SMS + { + pDeliverTextInfo->conPres = TRUE; + pDeliverTextInfo->con.msgType = pSMSParam->sParam.sDeliverParam.sConSMSParam.uMsgType; + pDeliverTextInfo->con.msgRef = pSMSParam->sParam.sDeliverParam.sConSMSParam.uMsgRef; + pDeliverTextInfo->con.msgSeg = pSMSParam->sParam.sDeliverParam.sConSMSParam.uMsgSeg; + pDeliverTextInfo->con.msgTot= pSMSParam->sParam.sDeliverParam.sConSMSParam.uMsgTot; + } + + bResult = ConvDeliverSMSParamToTextInfo(&((pSMSParam->sParam).sDeliverParam),pDeliverTextInfo); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvSMSParamToTextInfo,FAIL! ConvDeliverSMSParamToTextInfo FAIL!"); + return FALSE; + } + + (pDeliverTextInfo->length) = sizeof(pDeliverTextInfo->data); + + bResult = LIB_SMS_ConvAlphaToCharSet( + ((pSMSParam->sParam).sDeliverParam.uDCS), + ((pSMSParam->sParam).sDeliverParam.sUserData.aUserData), + ((pSMSParam->sParam).sDeliverParam.sUserData.uLen), + uCharSet, + (pDeliverTextInfo->data), + (u16*)&(pDeliverTextInfo->length) + ); + + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvSMSParamToTextInfo,FAIL! LIB_SMS_ConvAlphaToCharSet FAIL!"); + return FALSE; + } + } + else if(LIB_SMS_PDU_TYPE_SUBMIT == (pTextInfo->type)) + { + pSubmitTextInfo = &((pTextInfo->param).submitParam); + + if((pSMSParam->uFO) & 0x40) //Concatenate SMS + { + pSubmitTextInfo->conPres = TRUE; + pSubmitTextInfo->con.msgType = pSMSParam->sParam.sSubmitParam.sConSMSParam.uMsgType; + pSubmitTextInfo->con.msgRef = pSMSParam->sParam.sSubmitParam.sConSMSParam.uMsgRef; + pSubmitTextInfo->con.msgSeg = pSMSParam->sParam.sSubmitParam.sConSMSParam.uMsgSeg; + pSubmitTextInfo->con.msgTot= pSMSParam->sParam.sSubmitParam.sConSMSParam.uMsgTot; + } + + bResult = ConvSubmitSMSParamToTextInfo(&((pSMSParam->sParam).sSubmitParam),pSubmitTextInfo); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvSMSParamToTextInfo,FAIL! ConvSubmitSMSParamToTextInfo FAIL!"); + return FALSE; + } + + (pSubmitTextInfo->length) = sizeof(pSubmitTextInfo->data); + + bResult = LIB_SMS_ConvAlphaToCharSet( + ((pSMSParam->sParam).sSubmitParam.uDCS), + ((pSMSParam->sParam).sSubmitParam.sUserData.aUserData), + ((pSMSParam->sParam).sSubmitParam.sUserData.uLen), + uCharSet, + (pSubmitTextInfo->data), + (u16*)&(pSubmitTextInfo->length) + ); + + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvSMSParamToTextInfo,FAIL! LIB_SMS_ConvAlphaToCharSet FAIL!"); + return FALSE; + } + } + else + { + DBG_TRACE(sg_aDbgBuf,"Enter ConvSMSParamToTextInfo,FAIL! Msg type is INVALID. type:%d",(pTextInfo->type)); + return FALSE; + } + + DBG_TRACE(sg_aDbgBuf,"Enter ConvSMSParamToTextInfo,SUCCESS. bResult:%d",bResult); + + return bResult; +} + +/****************************************************************************** +* Function: GetStorageType +* +* Description: +* Get storage type refer to given string. +* +* Parameters: +* : +* [In] The pointer of a string +* : +* [In] The type of SMS storage,same as 'Enum_RIL_SMS_SMSStorage' +* +* Return: +* TRUE: This function works SUCCESS. +* FALSE: This function works FAIL! +* +* NOTE: +* 1. This function ONLY used in AT handler function. +******************************************************************************/ +static bool GetStorageType(char *pStr,u8 *pType) +{ + #define SMS_TYPE_STR_LEN (4) //As: "SM" "ME" + + char aBuf[SMS_TYPE_STR_LEN+1] = {0,}; + + if((NULL == pStr) || (NULL == pType)) + { + DBG_TRACE(sg_aDbgBuf,"Enter GetStorageType FAIL! Parameter is NULL."); + return FALSE; + } + + Ql_strncpy(aBuf,pStr,SMS_TYPE_STR_LEN); + + if(0 == Ql_strcmp(aBuf,"\"SM\"")) + { + (*pType) = RIL_SMS_STORAGE_TYPE_SM; + } + else if(0 == Ql_strcmp(aBuf,"\"ME\"")) + { + (*pType) = RIL_SMS_STORAGE_TYPE_ME; + } + else if(0 == Ql_strcmp(aBuf,"\"MT\"")) + { + (*pType) = RIL_SMS_STORAGE_TYPE_MT; + } + else + { + DBG_TRACE(sg_aDbgBuf,"Enter GetStorageType FAIL! Storage type is INVALID. aBuf:%s",aBuf); + return FALSE; + } + + DBG_TRACE(sg_aDbgBuf,"Enter GetStorageType SUCCESS. aBuf:%s,*pType:%d",aBuf,(*pType)); + + return TRUE; +} + +/****************************************************************************** +* Function: HdlrGetStorageInfo +* +* Description: +* Get storage info refer to given string. +* +* Parameters: +* : +* [In] The pointer of a string +* +* [In] The length of a string +* : +* [In] The pointer of SMS storage info data +* +* Return: +* NULL: This function works FAIL! +* OTHER VALUE: This function works SUCCESS +* +* NOTE: +* 1. This function ONLY used in AT handler function. +******************************************************************************/ +static char* HdlrGetStorageInfo(char *pLine,u32 uLen,ST_SMSStorage *pInfo) +{ + char *pHead = NULL; + char *pTail = NULL; + + if((NULL == pLine) || (0 == uLen) || (NULL == pInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrGetStorageInfo FAIL! Parameter is NULL."); + return NULL; + } + + pHead = Ql_RIL_FindString(pLine,uLen,CPMS_KEY_STR); + if(NULL == pHead) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrGetStorageInfo FAIL! NOT find \"" CPMS_KEY_STR "\""); + return NULL; + } + + //Get of +CPMS + pHead += Ql_strlen(CPMS_KEY_STR); + if(FALSE == GetStorageType(pHead,&(pInfo->storage))) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrGetStorageInfo FAIL! GetStorageType FAIL! string:%c%c%c%c",pHead[0],pHead[1],pHead[2],pHead[3]); + return NULL; + } + + //Get of +CPMS + pHead = Ql_strstr(pHead, STR_COMMA); + if(NULL == pHead) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrGetStorageInfo FAIL! Ql_strstr FAIL! NOT find comma."); + return NULL; + } + + pTail = Ql_strstr((pHead+1), STR_COMMA); + if(NULL == pTail) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrGetStorageInfo FAIL! Ql_strstr FAIL! NOT find comma."); + return NULL; + } + + CONV_STRING_TO_INTEGER((pHead+1),(pTail-(pHead+1)),(pInfo->used)); + + //Get of +CPMS + pHead = pTail; + pTail = Ql_strstr((pHead+1), STR_COMMA); + if(NULL == pTail) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrGetStorageInfo FAIL! Ql_strstr FAIL! NOT find comma."); + return NULL; + } + + CONV_STRING_TO_INTEGER((pHead+1),(pTail-(pHead+1)),(pInfo->total)); + + DBG_TRACE(sg_aDbgBuf,"Enter HdlrGetStorageInfo SUCCESS. storage:%u,used:%u,total:%u",(pInfo->storage),(pInfo->used),(pInfo->total)); + + return pLine; +} + +/****************************************************************************** +* Function: HdlrSetStorage +* +* Description: +* Set storage and get useful parameters. +* +* Parameters: +* : +* [In] The pointer of a string +* +* [In] The length of a string +* : +* [In] The pointer of SMS storage info data +* +* Return: +* NULL: This function works FAIL! +* OTHER VALUE: This function works SUCCESS +* +* NOTE: +* 1. This function ONLY used in AT handler function. +******************************************************************************/ +static char* HdlrSetStorage(char *pLine,u32 uLen,ST_SMSStorage *pInfo) +{ + char *pHead = NULL; + char *pTail = NULL; + + if((NULL == pLine) || (0 == uLen) || (NULL == pInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrSetStorage FAIL! Parameter is NULL."); + return NULL; + } + + pHead = Ql_RIL_FindString(pLine,uLen,CPMS_KEY_STR); + if(NULL == pHead) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrSetStorage FAIL! NOT find \"" CPMS_KEY_STR "\""); + return NULL; + } + + //Get of +CPMS + pHead += Ql_strlen(CPMS_KEY_STR); + pTail = Ql_strstr(pHead, STR_COMMA); + if(NULL == pTail) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrSetStorage FAIL! Ql_strstr FAIL! NOT find comma."); + return NULL; + } + + CONV_STRING_TO_INTEGER(pHead,(pTail-pHead),(pInfo->used)); + + pHead = pTail; + pTail = Ql_strstr((pHead+1), STR_COMMA); + if(NULL == pTail) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrSetStorage FAIL! Ql_strstr FAIL! NOT find comma."); + return NULL; + } + + CONV_STRING_TO_INTEGER((pHead+1),(pTail-(pHead+1)),(pInfo->total)); + + DBG_TRACE(sg_aDbgBuf,"Enter HdlrSetStorage SUCCESS. used:%u,total:%u",(pInfo->used),(pInfo->total)); + + return pLine; +} + +/****************************************************************************** +* Function: HdlrReadPDUMsg +* +* Description: +* Handler of read PDU message. +* +* Parameters: +* : +* [In] The pointer of a string +* +* [In] The length of a string +* : +* [In] The pointer of 'ST_RIL_SMS_PDUInfo' data +* +* Return: +* NULL: This function works FAIL! +* OTHER VALUE: This function works SUCCESS +* +* NOTE: +* 1. This function ONLY used in AT handler function. +******************************************************************************/ +static char* HdlrReadPDUMsg(char *pLine,u32 uLen,ST_RIL_SMS_PDUInfo *pPDU) +{ + char *pHead = NULL; + char *pTail = NULL; + u32 uDataLen = 0; + + static bool s_bSMSReadContentFlag = FALSE; //FALSE: NOT read SMS content. TRUE: Read SMS content. + + if((NULL == pLine) || (0 == uLen) || (NULL == pPDU)) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrReadPDUMsg,FAIL! Parameter is NULL."); + return NULL; + } + + //Read SMS PDU content + if(TRUE == s_bSMSReadContentFlag) + { + //Initialize + Ql_memset((pPDU->data),0x00,sizeof(pPDU->data)); + + uDataLen = (((uLen - 2) < (LIB_SMS_PDU_BUF_MAX_LEN * 2)) ? (uLen - 2) : (LIB_SMS_PDU_BUF_MAX_LEN * 2)); + Ql_memcpy((pPDU->data), pLine, uDataLen); + + (pPDU->length) = uDataLen; //Get the count of characters in PDU string. + + s_bSMSReadContentFlag = FALSE; + + DBG_TRACE(sg_aDbgBuf,"Enter HdlrReadPDUMsg,SUCCESS. status:%u,length:%u,s_bSMSReadContentFlag:%d",(pPDU->status),(pPDU->length),s_bSMSReadContentFlag); + + return pLine; + } + + //Read SMS PDU header info + pHead = Ql_RIL_FindString(pLine,uLen,CMGR_KEY_STR); + if(NULL == pHead) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrReadPDUMsg FAIL! NOT find \"" CMGR_KEY_STR "\""); + return NULL; + } + + s_bSMSReadContentFlag = TRUE; //Set flag + + //Get of +CMGR + pHead += Ql_strlen(CMGR_KEY_STR); + pTail = Ql_strstr(pHead, STR_COMMA); + if(NULL == pTail) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrReadPDUMsg FAIL! Ql_strstr FAIL! NOT find comma."); + return NULL; + } + + CONV_STRING_TO_INTEGER(pHead,(pTail-pHead),(pPDU->status)); + + DBG_TRACE(sg_aDbgBuf,"Enter HdlrReadPDUMsg SUCCESS. status:%u,s_bSMSReadContentFlag:%d",(pPDU->status),s_bSMSReadContentFlag); + + return pLine; +} + +/****************************************************************************** +* Function: HdlrSendPDUMsg +* +* Description: +* Handler of read PDU message. +* +* Parameters: +* : +* [In] The pointer of a string +* +* [In] The length of a string +* : +* [In] The pointer of 'ST_RIL_SMS_SendPDUInfo' data +* +* Return: +* NULL: This function works FAIL! +* OTHER VALUE: This function works SUCCESS +* +* NOTE: +* 1. This function ONLY used in AT handler function. +******************************************************************************/ +static char* HdlrSendPDUMsg(char *pLine,u32 uLen,ST_RIL_SMS_SendPDUInfo *pInfo) +{ + char *pHead = NULL; + char *pTail = NULL; + u8 uCtrlZ = 0x1A; + + if((NULL == pLine) || (0 == uLen) || (NULL == pInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrSendPDUMsg FAIL! Parameter is NULL."); + return NULL; + } + + pHead = Ql_RIL_FindString(pLine, uLen, STR_CMGS_HINT); + if(NULL != pHead) + { + Ql_RIL_WriteDataToCore((u8*)(pInfo->pduString),(pInfo->pduLen)); + Ql_RIL_WriteDataToCore(&uCtrlZ,1); + + return pLine; + } + + pHead = Ql_RIL_FindString(pLine, uLen, CMGS_KEY_STR); + if(NULL == pHead) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrSendPDUMsg FAIL! NOT find \"" CMGS_KEY_STR "\""); + return NULL; + } + + pHead += Ql_strlen(CMGR_KEY_STR); + pTail = Ql_strstr(pHead, STR_CR_LF); + if(NULL == pTail) + { + DBG_TRACE(sg_aDbgBuf,"Enter HdlrSendPDUMsg FAIL! NOT find \"" CMGS_KEY_STR "\""); + return NULL; + } + + CONV_STRING_TO_INTEGER(pHead,(pTail-pHead),(pInfo->mr)); + + DBG_TRACE(sg_aDbgBuf,"Enter HdlrSendPDUMsg SUCCESS. mr:%u",(pInfo->mr)); + + return pLine; +} + +/****************************************************************************** +* Function: SMS_CMD_GeneralHandler +* +* Description: +* The general handler for RIL SMS AT Command +* +* Parameters: +* : +* [In] The pointer of a line string +* : +* [In] The length of a line string +* +* [In] The pointer of 'ST_SMS_HdlrUserData' data +* +* Return: +* RIL_ATRSP_CONTINUE: Need to wait later AT response +* RIL_ATRSP_SUCCESS: AT command run SUCCESS. +* RIL_ATRSP_FAILED: AT command run FAIL! +* OTHER VALUES: This function works FAIL! +******************************************************************************/ +static s32 SMS_CMD_GeneralHandler(char* pLine, u32 uLen, void* pUserData) +{ + u32 uType = 0; + ST_SMS_HdlrUserData *pParam = (ST_SMS_HdlrUserData*)pUserData; + + if((NULL == pLine) || (0 == uLen) || (NULL == pUserData)) + { + DBG_TRACE(sg_aDbgBuf,"Enter SMS_CMD_GeneralHandler,FAIL! Parameter is NULL."); + return RIL_AT_INVALID_PARAM; + } + + uType = (pParam->uHdlrType); + + switch(uType) + { + case HDLR_TYPE_CPMS_READ_CMD: + { + ST_SMSStorage *pInfo = (ST_SMSStorage*)(pParam->pUserData); + + if(NULL != HdlrGetStorageInfo(pLine, uLen, pInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter SMS_CMD_GeneralHandler,SUCCESS. uType:HDLR_TYPE_CPMS_READ_CMD,storage:%u,used:%u,total:%u",(pInfo->storage),(pInfo->used),(pInfo->total)); + return RIL_ATRSP_CONTINUE; + } + } + break; + + case HDLR_TYPE_CPMS_SET_CMD: + { + ST_SMSStorage *pInfo = (ST_SMSStorage*)(pParam->pUserData); + + if(NULL != HdlrSetStorage(pLine, uLen, pInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter SMS_CMD_GeneralHandler,SUCCESS. uType:HDLR_TYPE_CPMS_SET_CMD,used:%u,total:%u",(pInfo->used),(pInfo->total)); + return RIL_ATRSP_CONTINUE; + } + } + break; + + case HDLR_TYPE_CMGR_PDU_CMD: + { + ST_RIL_SMS_PDUInfo *pInfo = (ST_RIL_SMS_PDUInfo*)(pParam->pUserData); + + if(NULL != HdlrReadPDUMsg(pLine, uLen, pInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter SMS_CMD_GeneralHandler,SUCCESS. uType:HDLR_TYPE_CMGR_PDU_CMD,status:%u,length:%u",(pInfo->status),(pInfo->length)); + return RIL_ATRSP_CONTINUE; + } + } + break; + + case HDLR_TYPE_CMGS_PDU_CMD: + { + ST_RIL_SMS_SendPDUInfo *pInfo = (ST_RIL_SMS_SendPDUInfo*)(pParam->pUserData); + + if(NULL != HdlrSendPDUMsg(pLine, uLen, pInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter SMS_CMD_GeneralHandler,SUCCESS. uType:HDLR_TYPE_CMGS_PDU_CMD,length:%u",(pInfo->pduLen)); + return RIL_ATRSP_CONTINUE; + } + } + break; + + default: + { + DBG_TRACE(sg_aDbgBuf,"Enter SMS_CMD_GeneralHandler,SUCCESS. Warning: NOT support type! uType:%u",uType); + } + break; + } + + SMS_HDLR_CHECK_ERROR(pLine,uLen,"SMS_CMD_GeneralHandler"); + + DBG_TRACE(sg_aDbgBuf,"Enter SMS_CMD_GeneralHandler,SUCCESS. uType:%u",uType); + + return RIL_ATRSP_CONTINUE; //continue wait +} + +/****************************************************************************** +* Function: CmdGetStorageInfo +* +* Description: +* Get SMS storage info +* +* Parameters: +* : +* [In] The pointer of current SMS storage type,same as: 'Enum_RIL_SMS_SMSStorage' +* : +* [In] The pointer of used count in SMS storage +* +* [In] The pointer of total count in SMS storage +* +* Return: +* RIL_ATRSP_CONTINUE: Need to wait later AT response +* RIL_ATRSP_SUCCESS: AT command run SUCCESS. +* RIL_ATRSP_FAILED: AT command run FAIL! +* OTHER VALUES: This function works FAIL! +* +* NOTE: +* 1. This function ONLY used in send AT command. +* 2. If you DONOT want to get certain parameter,please set it to NULL. +******************************************************************************/ +static s32 CmdGetStorageInfo(u8* pCurrMem, u32* pUsed,u32* pTotal) +{ + s32 iResult = 0; + char aCmd[SMS_CMD_MAX_LEN] = {0,}; + ST_SMSStorage sInfo; + ST_SMS_HdlrUserData sUserData; + + //Initialize + Ql_memset(&sInfo,0x00,sizeof(sInfo)); + Ql_memset(&sUserData,0x00,sizeof(sUserData)); + + Ql_strcpy(aCmd,"AT+CPMS?"); + + (sUserData.uHdlrType) = HDLR_TYPE_CPMS_READ_CMD; + (sUserData.pUserData) = (void*)(&sInfo); + + iResult = Ql_RIL_SendATCmd(aCmd, Ql_strlen(aCmd), SMS_CMD_GeneralHandler,&sUserData, 0); + if(RIL_ATRSP_SUCCESS != iResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdSetStorageInfo,FAIL! AT+CPMS? execute error! Code:%d\r\n",iResult); + return iResult; + } + + LIB_SMS_SET_POINTER_VAL(pCurrMem,(sInfo.storage)); + LIB_SMS_SET_POINTER_VAL(pUsed,(sInfo.used)); + LIB_SMS_SET_POINTER_VAL(pTotal,(sInfo.total)); + + DBG_TRACE(sg_aDbgBuf,"Enter CmdGetStorageInfo,SUCCESS. storage:%d,used:%d,total:%d",(sInfo.storage),(sInfo.used),(sInfo.total)); + + return RIL_ATRSP_SUCCESS; +} + +/****************************************************************************** +* Function: CmdSetStorageInfo +* +* Description: +* Set SMS storage type and get SMS storage info. +* +* Parameters: +* : +* [In] SMS storage type,same as: 'Enum_RIL_SMS_SMSStorage' +* : +* [In] The pointer of used count in SMS storage +* +* [In] The pointer of total count in SMS storage +* +* Return: +* RIL_ATRSP_CONTINUE: Need to wait later AT response +* RIL_ATRSP_SUCCESS: AT command run SUCCESS. +* RIL_ATRSP_FAILED: AT command run FAIL! +* OTHER VALUES: This function works FAIL! +* +* NOTE: +* 1. This function ONLY used in send AT command. +******************************************************************************/ +static s32 CmdSetStorageInfo(u8 uStoType,u32* pUsed,u32* pTotal) +{ + char aCmd[SMS_CMD_MAX_LEN] = {0,}; + char aStoName[4] = {0}; //SMS storage name + s32 iLen = 0; + s32 iResult = 0; + + ST_SMSStorage sInfo; + ST_SMS_HdlrUserData sUserData; + + //Initialize + Ql_memset(&sInfo,0x00,sizeof(sInfo)); + Ql_memset(&sUserData,0x00,sizeof(sUserData)); + + //Check SMS storage type is valid or not + if(FALSE == ADP_IS_SUPPORT_STORAGE_TYPE(uStoType)) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdSetStorageInfo,FAIL! ADP_IS_SUPPORT_STORAGE_TYPE FAIL!"); + return RIL_AT_INVALID_PARAM; + } + + //Get SMS storage's name refer to + SMS_GET_STORAGE_NAME(uStoType,aStoName); + + iLen = Ql_sprintf(aCmd, "AT+CPMS=\"%s\",\"%s\",\"%s\"", aStoName, aStoName, aStoName); + + (sUserData.uHdlrType) = HDLR_TYPE_CPMS_SET_CMD; + (sUserData.pUserData) = (void*)(&sInfo); + + iResult = Ql_RIL_SendATCmd(aCmd, iLen, SMS_CMD_GeneralHandler,&sUserData, 0); + if(RIL_ATRSP_SUCCESS != iResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdSetStorageInfo,FAIL! AT+CPMS? execute error! iResult:%d\r\n",iResult); + return iResult; + } + + LIB_SMS_SET_POINTER_VAL(pUsed,(sInfo.used)); + LIB_SMS_SET_POINTER_VAL(pTotal,(sInfo.total)); + + DBG_TRACE(sg_aDbgBuf,"Enter CmdGetStorageInfo,SUCCESS. uStoType:%d,used:%d,total:%d",uStoType,(sInfo.used),(sInfo.total)); + + return RIL_ATRSP_SUCCESS; +} + +/****************************************************************************** +* Function: CmdReadPDUMsg +* +* Description: +* Read a PDU SMS. +* +* Parameters: +* : +* [In] The SMS index in current SMS storage +* : +* [In] The pointer of ST_PDU_SMS data +* +* Return: +* RIL_ATRSP_CONTINUE: Need to wait later AT response +* RIL_ATRSP_SUCCESS: AT command run SUCCESS. +* RIL_ATRSP_FAILED: AT command run FAIL! +* OTHER VALUES: This function works FAIL! +* +* NOTE: +* 1. This function ONLY used in send AT command. +******************************************************************************/ +static s32 CmdReadPDUMsg(u32 uIndex, ST_RIL_SMS_PDUInfo* pPDU) +{ + char aCmd[SMS_CMD_MAX_LEN] = {0,}; + s32 iResult = 0; + u8 uStoType = 0; + u32 uStoTot = 0; + s32 iLen = 0; + u32 uCoreIdx = 0; + + ST_SMS_HdlrUserData sUserData; + + if(NULL == pPDU) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdReadPDUMsg,FAIL! Parameter is NULL."); + return RIL_AT_INVALID_PARAM; + } + + //Initialize + Ql_memset(&sUserData,0x00,sizeof(sUserData)); + + //Check parameter + iResult = CmdGetStorageInfo(&uStoType,NULL,&uStoTot); + if(RIL_ATRSP_SUCCESS != iResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdReadPDUMsg,FAIL! iResult:%d",iResult); + return iResult; + } + + if((uIndex < 1) || (uIndex > uStoTot)) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdReadPDUMsg,FAIL! uIndex is INVALID. uIndex:%d",uIndex); + return RIL_AT_INVALID_PARAM; + } + + uCoreIdx = ADP_SMS_ConvIdxToCoreIdx(uStoType,uIndex,uStoTot); + if(0 == uCoreIdx) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdReadPDUMsg,FAIL! ADP_SMS_ConvIdxToCoreIdx FAIL! uStoType:%u,index:%u,uStoTot:%u", uStoType,uIndex,uStoTot); + return RIL_AT_INVALID_PARAM; + } + + //Set to PDU mode + SMS_SET_PDU_MODE(iResult,"CmdReadPDUMsg"); + + (sUserData.uHdlrType) = HDLR_TYPE_CMGR_PDU_CMD; + (sUserData.pUserData) = pPDU; + + iLen = Ql_sprintf(aCmd, "AT+CMGR=%u", uCoreIdx); + iResult = Ql_RIL_SendATCmd(aCmd, iLen, SMS_CMD_GeneralHandler, &sUserData, 0); + if(iResult != RIL_ATRSP_SUCCESS) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdReadPDUMsg,FAIL! CMD: %s execute FAIL!",aCmd); + return iResult; + } + + DBG_TRACE(sg_aDbgBuf,"Enter CmdReadPDUMsg,SUCCESS. CMD: %s,uStoType:%u,uStoTot:%u,index:%u,length:%u", aCmd,uStoType,uStoTot,uIndex,(pPDU->length)); + + return iResult; +} + +/****************************************************************************** +* Function: CmdSendPDUMsg +* +* Description: +* This function is used to send PDU message +* +* Parameters: +* : +* [In] The pointer of PDU string +* : +* [In] The length of PDU string +* +* [Out] The pointer of message reference number +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +* Note: +* 1. If you DONOT want to get value,please set it to NULL. +******************************************************************************/ +static s32 CmdSendPDUMsg(char* pPDUStr,u32 uPDUStrLen,u32 *pMsgRef) +{ + char aCmd[SMS_CMD_MAX_LEN] = {0,}; + u32 uTPDULen = 0; + u32 uSCALen = 0; + bool bResult = FALSE; + s32 iResult = 0; + s32 iLen = 0; + ST_RIL_SMS_SendPDUInfo sInfo; + ST_SMS_HdlrUserData sUserData; + + //Initialize + Ql_memset(&sInfo,0x00,sizeof(sInfo)); + Ql_memset(&sUserData,0x00,sizeof(sUserData)); + + if((NULL == pPDUStr) || (0 == uPDUStrLen)) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdSendPDUMsg,FAIL! Parameter is NULL."); + return RIL_AT_INVALID_PARAM; + } + + bResult = LIB_SMS_IsValidHexStr(pPDUStr,uPDUStrLen); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdSendPDUMsg,FAIL! LIB_SMS_IsValidHexStr FAIL!"); + return RIL_AT_INVALID_PARAM; + } + + if((uPDUStrLen % 2) != 0) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdSendPDUMsg,FAIL! (uPDUStrLen % 2) != 0"); + return RIL_AT_INVALID_PARAM; + } + + CONV_STRING_TO_INTEGER(pPDUStr,2,uSCALen); + uTPDULen = ((uPDUStrLen / 2) - (uSCALen + 1)); + + //Set to PDU mode + SMS_SET_PDU_MODE(iResult,"RIL_SMS_ReadSMS_PDU"); + + (sInfo.pduString) = pPDUStr; + (sInfo.pduLen) = uPDUStrLen; + (sUserData.uHdlrType) = HDLR_TYPE_CMGS_PDU_CMD; + (sUserData.pUserData) = &sInfo; + + iLen = Ql_sprintf(aCmd, "AT+CMGS=%d", uTPDULen); + iResult = Ql_RIL_SendATCmd(aCmd, iLen, SMS_CMD_GeneralHandler,&sUserData, 0); + if(iResult != RIL_ATRSP_SUCCESS) + { + DBG_TRACE(sg_aDbgBuf,"Enter CmdSendPDUMsg,FAIL! CMD: %s execute FAIL!",aCmd); + return iResult; + } + + LIB_SMS_SET_POINTER_VAL(pMsgRef,(sInfo.mr)); + + DBG_TRACE(sg_aDbgBuf,"Enter CmdSendPDUMsg,SUCCESS. mr:%u",(sInfo.mr)); + + return RIL_ATRSP_SUCCESS; +} + +/****************************************************************************** +* Function: RIL_SMS_GetStorage +* +* Description: +* Get SMS storage info +* +* Parameters: +* : +* [In] The pointer of current SMS storage type,same as: 'Enum_RIL_SMS_SMSStorage' +* : +* [In] The pointer of used count in SMS storage +* +* [In] The pointer of total count in SMS storage +* +* Return: +* RIL_ATRSP_CONTINUE: Need to wait later AT response +* RIL_ATRSP_SUCCESS: AT command run SUCCESS. +* RIL_ATRSP_FAILED: AT command run FAIL! +* OTHER VALUES: This function works FAIL! +* NOTE: +* 1. If you DONOT want to get ,pTotal value,please set it to NULL. +******************************************************************************/ +s32 RIL_SMS_GetStorage(u8* pCurrMem, u32* pUsed,u32* pTotal) +{ + s32 iResult = 0; + + iResult = CmdGetStorageInfo((u8*)pCurrMem,pUsed,pTotal); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_GetStorage,SUCCESS. iResult:%d",iResult); + + return iResult; +} + +/****************************************************************************** +* Function: RIL_SMS_SetStorage +* +* Description: +* Set SMS storage +* +* Parameters: +* : +* [In] SMS storage,same as 'Enum_RIL_SMS_SMSStorage' +* +* Return: +* RIL_ATRSP_SUCCESS: This function works SUCCESS. +* RIL_ATRSP_CONTINUE: Need to wait later AT response +* RIL_ATRSP_SUCCESS: AT command run SUCCESS. +* RIL_ATRSP_FAILED: AT command run FAIL! +* OTHER VALUES: This function works FAIL! +* +* NOTE: +* 1. If you DONOT want to get ,pTotal value,please set it to NULL. +******************************************************************************/ +s32 RIL_SMS_SetStorage(Enum_RIL_SMS_StorageType eStorage,u32* pUsed,u32* pTotal) +{ + s32 iResult = 0; + + iResult = CmdSetStorageInfo(eStorage,pUsed,pTotal); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SetStorage,SUCCESS. iResult:%d",iResult); + + return iResult; +} + +/****************************************************************************** +* Function: RIL_SMS_ReadSMS_PDU +* +* Description: +* Read a PDU SMS +* +* Parameters: +* : +* [In] The SMS index in current SMS storage +* : +* [In] The pointer of 'ST_RIL_SMS_PDUInfo' data +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_SMS_ReadSMS_PDU(u32 uIndex, ST_RIL_SMS_PDUInfo* pPDUInfo) +{ + s32 iResult = 0; + bool bResult = FALSE; + + if(NULL == pPDUInfo) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_PDU,FAIL! Parameter is NULL."); + return RIL_AT_INVALID_PARAM; + } + + //Initialize + Ql_memset(pPDUInfo,0x00,sizeof(ST_RIL_SMS_PDUInfo)); + + iResult = CmdReadPDUMsg(uIndex,pPDUInfo); + if(iResult != RIL_ATRSP_SUCCESS) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_PDU,FAIL! CmdReadPDUMsg FAIL!"); + return iResult; + } + + //The message of position is NOT exist. + if(0 == (pPDUInfo->length)) + { + SMS_SET_INVALID_PDU_INFO(pPDUInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_PDU,SUCCESS. NOTE:(pPDUInfo->length) is 0."); + return RIL_ATRSP_SUCCESS; + } + + //Check the + if(FALSE == IS_VALID_PDU_INFO(pPDUInfo)) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_PDU,FAIL! IS_VALID_PDU_INFO FAIL!"); + return RIL_AT_FAILED; + } + + LIB_SMS_CHECK_PDU_STR((pPDUInfo->data),(pPDUInfo->length),bResult); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_PDU,WARNING! LIB_SMS_CHECK_PDU_STR FAIL!"); + } + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_PDU,SUCCESS. status:%u,length:%u",(pPDUInfo->status),(pPDUInfo->length)); + + return RIL_ATRSP_SUCCESS; +} + +/****************************************************************************** +* Function: RIL_SMS_ReadSMS_Text +* +* Description: +* Read a TEXT SMS +* +* Parameters: +* : +* [In] The SMS index in current SMS storage +* : +* [In] Character set enum value +* +* [In] The pointer of TEXT SMS info +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_SMS_ReadSMS_Text(u32 uIndex, LIB_SMS_CharSetEnum eCharset,ST_RIL_SMS_TextInfo* pTextInfo) +{ + ST_RIL_SMS_PDUInfo *pPDUInfo = NULL; + LIB_SMS_PDUParamStruct *pSMSParam = NULL; + s32 iResult = 0; + bool bResult = FALSE; + + if(NULL == pTextInfo) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_Text,FAIL! Parameter is NULL."); + return RIL_AT_INVALID_PARAM; + } + + //Initialize + Ql_memset(pTextInfo,0x00,sizeof(ST_RIL_SMS_TextInfo)); + + if(FALSE == LIB_SMS_IS_SUPPORT_CHARSET(eCharset)) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_Text,FAIL! LIB_SMS_IS_SUPPORT_CHARSET FAIL! eCharset:%d",eCharset); + return RIL_AT_INVALID_PARAM; + } + + pPDUInfo = (ST_RIL_SMS_PDUInfo*)Ql_MEM_Alloc(sizeof(ST_RIL_SMS_PDUInfo)); + if(NULL == pPDUInfo) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_Text,FAIL! Ql_MEM_Alloc FAIL! size:%u",sizeof(ST_RIL_SMS_PDUInfo)); + return RIL_AT_FAILED; + } + + pSMSParam = (LIB_SMS_PDUParamStruct*)Ql_MEM_Alloc(sizeof(LIB_SMS_PDUParamStruct)); + if(NULL == pSMSParam) + { + Ql_MEM_Free(pPDUInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_Text,FAIL! Ql_MEM_Alloc FAIL! size:%u",sizeof(LIB_SMS_PDUParamStruct)); + return RIL_AT_FAILED; + } + + //Initialize + Ql_memset(pPDUInfo,0x00,sizeof(ST_RIL_SMS_PDUInfo)); + Ql_memset(pSMSParam,0x00,sizeof(LIB_SMS_PDUParamStruct)); + + iResult = CmdReadPDUMsg(uIndex,pPDUInfo); + if(iResult != RIL_ATRSP_SUCCESS) + { + Ql_MEM_Free(pPDUInfo); + Ql_MEM_Free(pSMSParam); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_Text,FAIL! CmdReadPDUMsg FAIL!"); + return iResult; + } + + //The message of position is NOT exist. + if(0 == (pPDUInfo->length)) + { + SMS_SET_INVALID_TEXT_INFO(pTextInfo); + + Ql_MEM_Free(pPDUInfo); + Ql_MEM_Free(pSMSParam); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_PDU,SUCCESS. NOTE: (pPDUInfo->length) is 0."); + return RIL_ATRSP_SUCCESS; + } + + //Check the + if(FALSE == IS_VALID_PDU_INFO(pPDUInfo)) + { + Ql_MEM_Free(pPDUInfo); + Ql_MEM_Free(pSMSParam); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_Text,FAIL! IS_VALID_PDU_INFO FAIL!"); + return RIL_AT_FAILED; + } + + bResult = LIB_SMS_DecodePDUStr((pPDUInfo->data),(pPDUInfo->length),pSMSParam); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_Text,FAIL! LIB_SMS_DecodePDUStr FAIL! PDU length:%u",(pPDUInfo->length)); + + Ql_MEM_Free(pPDUInfo); + Ql_MEM_Free(pSMSParam); + + return RIL_AT_FAILED; + } + + (pTextInfo->status) = (pPDUInfo->status); + + bResult = ConvSMSParamToTextInfo(eCharset,pSMSParam,pTextInfo); + if(FALSE == bResult) + { + Ql_MEM_Free(pPDUInfo); + Ql_MEM_Free(pSMSParam); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_Text,FAIL! ConvSMSParamToTextInfo FAIL!"); + return RIL_AT_FAILED; + } + + Ql_MEM_Free(pPDUInfo); + Ql_MEM_Free(pSMSParam); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_ReadSMS_Text,SUCCESS. status:%u",(pTextInfo->status)); + + return RIL_AT_SUCCESS; +} + +/****************************************************************************** +* Function: RIL_SMS_SendSMS_PDU +* +* Description: +* This function is used to send PDU message +* +* Parameters: +* : +* [In] The pointer of PDU string +* : +* [In] The length of PDU string +* +* [Out] The pointer of message reference number +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +* Note: +* 1. If you DONOT want to get value,please set it to NULL. +******************************************************************************/ +s32 RIL_SMS_SendSMS_PDU(char* pPDUStr,u32 uPDUStrLen,u32 *pMsgRef) +{ + bool bResult = FALSE; + s32 iResult = 0; + + if((NULL == pPDUStr) || (0 == uPDUStrLen)) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_PDU,FAIL! Parameter is NULL."); + return RIL_AT_INVALID_PARAM; + } + + LIB_SMS_CHECK_SUBMIT_PDU_STR_FOR_SEND(pPDUStr,uPDUStrLen,bResult); + if(FALSE == bResult) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_PDU,FAIL! LIB_SMS_CHECK_SUBMIT_PDU_STR_FOR_SEND FAIL!"); + return RIL_AT_INVALID_PARAM; + } + + iResult = CmdSendPDUMsg(pPDUStr,uPDUStrLen,pMsgRef); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_PDU,SUCCESS. uPDUStrLen:%u,iResult:%d",uPDUStrLen,iResult); + + return iResult; +} + +/****************************************************************************** +* Function: RIL_SMS_SendSMS_Text +* +* Description: +* This function is used to send TEXT message +* +* Parameters: +* : +* [In] The pointer of phone number +* : +* [In] The length of phone number +* +* [In] CharSet,it's value is same as 'LIB_SMS_CharSetEnum' +* +* [In] The pointer of message content +* +* [In] The length of message content +* +* [Out] The pointer of message reference number +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +* Note: +* 1. If you DONOT want to get value,please set it to NULL. +******************************************************************************/ +s32 RIL_SMS_SendSMS_Text(char* pNumber, u8 uNumberLen, LIB_SMS_CharSetEnum eCharset, u8* pMsg, u32 uMsgLen,u32 *pMsgRef) +{ + LIB_SMS_PDUParamStruct *pParam = NULL; + LIB_SMS_SubmitPDUParamStruct *pSubmitParam = NULL; + LIB_SMS_PDUInfoStruct *pInfo = NULL; + bool bResult = FALSE; + char *pPDUStr = NULL; + u32 uPDUStrLen = 0; + s32 iResult = 0; + + if((NULL == pNumber) || (0 == uNumberLen) || (NULL == pMsg)) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! Parameter is NULL."); + return RIL_AT_INVALID_PARAM; + } + + if(FALSE == LIB_SMS_IS_SUPPORT_CHARSET(eCharset)) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! LIB_SMS_IS_SUPPORT_CHARSET FAIL! eCharset:%u",eCharset); + return RIL_AT_INVALID_PARAM; + } + + pParam = (LIB_SMS_PDUParamStruct*)Ql_MEM_Alloc(sizeof(LIB_SMS_PDUParamStruct)); + if(NULL == pParam) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! Ql_MEM_Alloc FAIL! size:%u",sizeof(LIB_SMS_PDUParamStruct)); + return RIL_AT_FAILED; + } + + pInfo = (LIB_SMS_PDUInfoStruct*)Ql_MEM_Alloc(sizeof(LIB_SMS_PDUInfoStruct)); + if(NULL == pInfo) + { + Ql_MEM_Free(pParam); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! Ql_MEM_Alloc FAIL! size:%u",sizeof(LIB_SMS_PDUInfoStruct)); + return RIL_AT_FAILED; + } + + //Initialize + Ql_memset(pParam,0x00,sizeof(LIB_SMS_PDUParamStruct)); + Ql_memset(pInfo,0x00,sizeof(LIB_SMS_PDUInfoStruct)); + pSubmitParam = &((pParam->sParam).sSubmitParam); + + //Set + (pParam->uFO) = LIB_SMS_DEFAULT_FO_IN_SUBMIT_PDU; + + //Set + bResult = ConvStringToPhoneNumber(pNumber,uNumberLen,&(pSubmitParam->sDA)); + if(FALSE == bResult) + { + Ql_MEM_Free(pParam); + Ql_MEM_Free(pInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! ConvStringToPhoneNumber FAIL!"); + return RIL_AT_FAILED; + } + + //Set + (pSubmitParam->uPID) = LIB_SMS_PDU_DEFAULT_PID; + //Set + LIB_SMS_SET_DEFAULT_DCS_IN_SUBMIT_PDU(eCharset,(pSubmitParam->uDCS)); + //Set + ((pSubmitParam->sVP).uRelative) = LIB_SMS_SUBMIT_PDU_DEFAULT_VP_RELATIVE; + + //Set + ((pSubmitParam->sUserData).uLen) = sizeof((pSubmitParam->sUserData).aUserData); + bResult = LIB_SMS_ConvCharSetToAlpha( + eCharset, + pMsg, + uMsgLen, + (pSubmitParam->uDCS), + ((pSubmitParam->sUserData).aUserData), + &((pSubmitParam->sUserData).uLen) + ); + + if(FALSE == bResult) + { + Ql_MEM_Free(pParam); + Ql_MEM_Free(pInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! LIB_SMS_ConvCharSetToAlpha FAIL!"); + return RIL_AT_FAILED; + } + + bResult = LIB_SMS_EncodeSubmitPDU(pParam,pInfo); + if(FALSE == bResult) + { + Ql_MEM_Free(pParam); + Ql_MEM_Free(pInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! LIB_SMS_EncodeSubmitPDU FAIL!"); + return RIL_AT_FAILED; + } + + Ql_MEM_Free(pParam); //Not need ,free it directly + pParam = NULL; + + pPDUStr = (char*)Ql_MEM_Alloc((pInfo->uLen) * 2); + if(NULL == pPDUStr) + { + Ql_MEM_Free(pInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! Ql_MEM_Alloc FAIL! size:%d",((pInfo->uLen) * 2)); + return RIL_AT_FAILED; + } + + uPDUStrLen = ((pInfo->uLen) * 2); + bResult = LIB_SMS_ConvHexOctToHexStr((pInfo->aPDUOct),(pInfo->uLen),pPDUStr,(u16*)&uPDUStrLen); + if(NULL == pPDUStr) + { + Ql_MEM_Free(pInfo); + Ql_MEM_Free(pPDUStr); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! Ql_MEM_Alloc FAIL! size:%d",((pInfo->uLen) * 2)); + return RIL_AT_FAILED; + } + + //Now send SUBMIT-PDU message + LIB_SMS_CHECK_SUBMIT_PDU_STR_FOR_SEND(pPDUStr,uPDUStrLen,bResult); + if(FALSE == bResult) + { + Ql_MEM_Free(pInfo); + Ql_MEM_Free(pPDUStr); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_PDU,FAIL! LIB_SMS_CHECK_SUBMIT_PDU_STR_FOR_SEND FAIL!"); + return RIL_AT_INVALID_PARAM; + } + + iResult = CmdSendPDUMsg(pPDUStr,uPDUStrLen,pMsgRef); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_PDU,SUCCESS. iResult:%d",iResult); + + Ql_MEM_Free(pInfo); + Ql_MEM_Free(pPDUStr); + + return iResult; +} + +/****************************************************************************** +* Function: RIL_SMS_SendSMS_Text_Ext +* +* Description: +* This function is used to send TEXT message witch external info +* +* Parameters: +* : +* [In] The pointer of phone number +* : +* [In] The length of phone number +* +* [In] CharSet,it's value is same as 'LIB_SMS_CharSetEnum' +* +* [In] The pointer of message content +* +* [In] The length of message content +* +* [Out] The pointer of message reference number +* +* [In] The pointer of 'ST_RIL_SMS_SendExt' data +* + conPres con-SMS present or not +* + con 'ST_RIL_SMS_Con' data +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +* Note: +* 1. If you DONOT want to get value,please set it to NULL. +* 2. If you want to send normal SMS, you can set to NULL. +******************************************************************************/ +s32 RIL_SMS_SendSMS_Text_Ext(char* pNumber, u8 uNumberLen, LIB_SMS_CharSetEnum eCharset, u8* pMsg, u32 uMsgLen,u32 *pMsgRef,ST_RIL_SMS_SendExt *pExt) +{ + LIB_SMS_PDUParamStruct *pParam = NULL; + LIB_SMS_SubmitPDUParamStruct *pSubmitParam = NULL; + LIB_SMS_PDUInfoStruct *pInfo = NULL; + bool bResult = FALSE; + char *pPDUStr = NULL; + u32 uPDUStrLen = 0; + s32 iResult = 0; + + if((NULL == pNumber) || (0 == uNumberLen) || (NULL == pMsg)) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text_Ext,FAIL! Parameter is NULL."); + return RIL_AT_INVALID_PARAM; + } + + if(FALSE == LIB_SMS_IS_SUPPORT_CHARSET(eCharset)) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text_Ext,FAIL! LIB_SMS_IS_SUPPORT_CHARSET FAIL! eCharset:%u",eCharset); + return RIL_AT_INVALID_PARAM; + } + + if((pExt != NULL) && (TRUE == pExt->conPres)) + { + if( ((pExt->con.msgType) != LIB_SMS_UD_TYPE_CON_6_BYTE) + && ((pExt->con.msgType) != LIB_SMS_UD_TYPE_CON_7_BYTE) + ) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text_Ext,WARNING! msgType:%d is INVALID,use default!",pExt->con.msgType); + (pExt->con.msgType) = LIB_SMS_UD_TYPE_CON_DEFAULT; + } + + if(FALSE == IsValidConParam(&(pExt->con))) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text_Ext,FAIL! IsValidConParam FAIL!"); + return RIL_AT_INVALID_PARAM; + } + } + + pParam = (LIB_SMS_PDUParamStruct*)Ql_MEM_Alloc(sizeof(LIB_SMS_PDUParamStruct)); + if(NULL == pParam) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text_Ext,FAIL! Ql_MEM_Alloc FAIL! size:%u",sizeof(LIB_SMS_PDUParamStruct)); + return RIL_AT_FAILED; + } + + pInfo = (LIB_SMS_PDUInfoStruct*)Ql_MEM_Alloc(sizeof(LIB_SMS_PDUInfoStruct)); + if(NULL == pInfo) + { + Ql_MEM_Free(pParam); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text_Ext,FAIL! Ql_MEM_Alloc FAIL! size:%u",sizeof(LIB_SMS_PDUInfoStruct)); + return RIL_AT_FAILED; + } + + //Initialize + Ql_memset(pParam,0x00,sizeof(LIB_SMS_PDUParamStruct)); + Ql_memset(pInfo,0x00,sizeof(LIB_SMS_PDUInfoStruct)); + pSubmitParam = &((pParam->sParam).sSubmitParam); + + //Set + (pParam->uFO) = LIB_SMS_DEFAULT_FO_IN_SUBMIT_PDU; + if((pExt != NULL) && (TRUE == pExt->conPres)) + { + (pParam->uFO) |= (LIB_SMS_PDU_FO_UDHI_BIT_HAS_UDH << 6); + pSubmitParam->sConSMSParam.uMsgType = pExt->con.msgType; + pSubmitParam->sConSMSParam.uMsgRef = pExt->con.msgRef; + pSubmitParam->sConSMSParam.uMsgSeg= pExt->con.msgSeg; + pSubmitParam->sConSMSParam.uMsgTot= pExt->con.msgTot; + } + + //Set + bResult = ConvStringToPhoneNumber(pNumber,uNumberLen,&(pSubmitParam->sDA)); + if(FALSE == bResult) + { + Ql_MEM_Free(pParam); + Ql_MEM_Free(pInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! ConvStringToPhoneNumber FAIL!"); + return RIL_AT_FAILED; + } + + //Set + (pSubmitParam->uPID) = LIB_SMS_PDU_DEFAULT_PID; + //Set + LIB_SMS_SET_DEFAULT_DCS_IN_SUBMIT_PDU(eCharset,(pSubmitParam->uDCS)); + //Set + ((pSubmitParam->sVP).uRelative) = LIB_SMS_SUBMIT_PDU_DEFAULT_VP_RELATIVE; + + //Set + ((pSubmitParam->sUserData).uLen) = sizeof((pSubmitParam->sUserData).aUserData); + bResult = LIB_SMS_ConvCharSetToAlpha( + eCharset, + pMsg, + uMsgLen, + (pSubmitParam->uDCS), + ((pSubmitParam->sUserData).aUserData), + &((pSubmitParam->sUserData).uLen) + ); + + if(FALSE == bResult) + { + Ql_MEM_Free(pParam); + Ql_MEM_Free(pInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! LIB_SMS_ConvCharSetToAlpha FAIL!"); + return RIL_AT_FAILED; + } + + bResult = LIB_SMS_EncodeSubmitPDU(pParam,pInfo); + if(FALSE == bResult) + { + Ql_MEM_Free(pParam); + Ql_MEM_Free(pInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! LIB_SMS_EncodeSubmitPDU FAIL!"); + return RIL_AT_FAILED; + } + + Ql_MEM_Free(pParam); //Not need ,free it directly + pParam = NULL; + + pPDUStr = (char*)Ql_MEM_Alloc((pInfo->uLen) * 2); + if(NULL == pPDUStr) + { + Ql_MEM_Free(pInfo); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! Ql_MEM_Alloc FAIL! size:%d",((pInfo->uLen) * 2)); + return RIL_AT_FAILED; + } + + uPDUStrLen = ((pInfo->uLen) * 2); + bResult = LIB_SMS_ConvHexOctToHexStr((pInfo->aPDUOct),(pInfo->uLen),pPDUStr,(u16*)&uPDUStrLen); + if(NULL == pPDUStr) + { + Ql_MEM_Free(pInfo); + Ql_MEM_Free(pPDUStr); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_Text,FAIL! Ql_MEM_Alloc FAIL! size:%d",((pInfo->uLen) * 2)); + return RIL_AT_FAILED; + } + + //Now send SUBMIT-PDU message + LIB_SMS_CHECK_SUBMIT_PDU_STR_FOR_SEND(pPDUStr,uPDUStrLen,bResult); + if(FALSE == bResult) + { + Ql_MEM_Free(pInfo); + Ql_MEM_Free(pPDUStr); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_PDU,FAIL! LIB_SMS_CHECK_SUBMIT_PDU_STR_FOR_SEND FAIL!"); + return RIL_AT_INVALID_PARAM; + } + + iResult = CmdSendPDUMsg(pPDUStr,uPDUStrLen,pMsgRef); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_SendSMS_PDU,SUCCESS. iResult:%d",iResult); + + Ql_MEM_Free(pInfo); + Ql_MEM_Free(pPDUStr); + + return iResult; +} + +/****************************************************************************** +* Function: RIL_SMS_DeleteSMS +* +* Description: +* This function deletes SMS messages in current SMS storage. +* +* Parameters: +* index: +* [In] The index number of SMS message. +* flag: +* [In] Delete flag , which is one value of 'Enum_RIL_SMS_DeleteFlag'. +* +* Return: +* RIL_AT_SUCCESS,send AT successfully. +* RIL_AT_FAILED, send AT failed. +* RIL_AT_TIMEOUT,send AT timeout. +* RIL_AT_BUSY, sending AT. +* RIL_AT_INVALID_PARAM, invalid input parameter. +* RIL_AT_UNINITIALIZED, RIL is not ready, need to wait for MSG_ID_RIL_READY +* and then call Ql_RIL_Initialize to initialize RIL. +******************************************************************************/ +s32 RIL_SMS_DeleteSMS(u32 uIndex,Enum_RIL_SMS_DeleteFlag eDelFlag) +{ + s32 iResult = 0; + u8 uStoType = 0; //Current memory type,same as: 'Enum_RIL_SMS_SMSStorage' + u32 uStoTot = 0; //The total count of current memory + u32 uCoreIdx = 0; + + s32 iLen = 0; + char aCmd[SMS_CMD_MAX_LEN] = {0,}; + + //Check parameter + if(eDelFlag > RIL_SMS_DEL_ALL_MSG) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_DeleteSMS,FAIL! eDelFlag is INVALID. eDelFlag:%d", eDelFlag); + return RIL_AT_INVALID_PARAM; + } + + //Get the total count of current memory type + iResult = CmdGetStorageInfo(&uStoType,NULL,&uStoTot); + if(iResult != RIL_ATRSP_SUCCESS) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_DeleteSMS,FAIL! CmdGetStorageInfo FAIL! AT+CPMS? execute FAL!"); + return RIL_AT_INVALID_PARAM; + } + + //Check parameter + if((RIL_SMS_DEL_INDEXED_MSG == eDelFlag) + && ((uIndex < 1) || (uIndex > uStoTot)) + ) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_DeleteSMS,FAIL! uIndex is INVALID. eDelFlag:%d,uIndex:%u,uCurrStoTot:%u", eDelFlag,uIndex,uStoTot); + return RIL_AT_INVALID_PARAM; + } + + //Covert RIL SMS index to core SMS index + if(RIL_SMS_DEL_INDEXED_MSG == eDelFlag) + { + uCoreIdx = ADP_SMS_ConvIdxToCoreIdx(uStoType,uIndex,uStoTot); + if(0 == uCoreIdx) + { + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_DeleteSMS,FAIL! ADP_SMS_ConvIdxToCoreIdx FAIL! uCurrStoType:%u,uIndex:%u,uCurrStoTot:%u", uStoType,uIndex,uStoTot); + return RIL_AT_INVALID_PARAM; + } + } + else + { + uCoreIdx = uIndex; + } + + //Set to PDU mode + SMS_SET_PDU_MODE(iResult,"RIL_SMS_DeleteSMS"); + + //Delete SMS use AT+CMGD=, + iLen = Ql_sprintf(aCmd, "AT+CMGD=%d,%d", uIndex,eDelFlag); + iResult = Ql_RIL_SendATCmd(aCmd, iLen, NULL, NULL, 0); + + DBG_TRACE(sg_aDbgBuf,"Enter RIL_SMS_DeleteSMS,SUCCESS. CMD: %s,uStoType:%u,uStoTot:%u,eDelFlag:%u,uIndex:%u", aCmd,uStoType,uStoTot,eDelFlag,uIndex); + + return iResult; +} + +#endif //#if (defined(__OCPU_RIL_SUPPORT__) && defined(__OCPU_RIL_SMS_SUPPORT__)) + diff --git a/cores/opencpu/ril/src/ril_system.c b/cores/opencpu/ril/src/ril_system.c new file mode 100644 index 0000000..4d81749 --- /dev/null +++ b/cores/opencpu/ril/src/ril_system.c @@ -0,0 +1,382 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_system.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module defines the information, and APIs related to RIL. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ril.h" +#include "ril_util.h" +#include "ril_system.h" +#include "ql_stdlib.h" +#include "ql_trace.h" +#include "ql_error.h" +#include "ql_system.h" + +#ifdef __OCPU_RIL_SUPPORT__ +static s32 SYS_ATResponse_Hanlder(char* line, u32 len, void* userdata) +{ + s32* pSysInitStatus = (s32* )userdata; + char *head = Ql_RIL_FindString(line, len, "+QINISTAT:"); //continue wait + if(head) + { + char strTmp[10]; + char* p1 = NULL; + char* p2 = NULL; + + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + p1 = Ql_strstr(head, ":"); + p2 = Ql_strstr(p1 + 1, "\r\n"); + if (p1 && p2) + { + Ql_memcpy(strTmp, p1 + 2, p2 - p1 - 2); + *pSysInitStatus = Ql_atoi(strTmp); + } + return RIL_ATRSP_CONTINUE; + } + + head = Ql_RIL_FindLine(line, len, "OK"); + if(head) + { + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR"); + if(head) + { + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + + +s32 RIL_QuerySysInitStatus( s32* SysInitStatus) +{ + return Ql_RIL_SendATCmd("AT+QINISTAT", 11, SYS_ATResponse_Hanlder, (void *)SysInitStatus, 0); +} + +static s32 Power_ATResponse_Hanlder(char* line, u32 len, void* userdata) +{ + ST_SysPower *PowerSupply; + + PowerSupply = (ST_SysPower *)userdata; + char *head = Ql_RIL_FindString(line, len, "+CBC:"); //continue wait + if(head) + { + char strTmp[10]; + char *p1,*p2; + p1 = Ql_strstr(head, ":"); + p2 = Ql_strstr(p1 + 1, ","); + if (p1 && p2) + { + p1 = p2; + p2 = Ql_strstr(p1 + 1, ","); + if (p1 && p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_memcpy(strTmp, p1 + 1, p2 - p1 - 1); + PowerSupply->capacity = Ql_atoi(strTmp); + p1 = p2; + p2 = Ql_strstr(p1 + 1, "\r\n"); + if (p1 && p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_memcpy(strTmp, p1 + 1, p2 - p1 - 1); + PowerSupply->voltage = Ql_atoi(strTmp); + } + } + } + // Ql_sscanf(head,"%*[^ ]%d,%d,%[^\r\n]",&PowerSupply->capacity,&PowerSupply->voltage); + return RIL_ATRSP_CONTINUE; + } + + head = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if(head) + { + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if(head) + { + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait + +} + + +/***************************************************************** +* Function: RIL_GetPowerSupply +* +* Description: +* This function queries the battery balance, and the battery voltage. +* +* Parameters: +* capacity: +* [out] battery balance, a percent, ranges from 1 to 100. +* +* voltage: +* [out] battery voltage, unit in mV +* Return: +* QL_RET_OK, indicates this function successes. +* -1, fail. +*****************************************************************/ +s32 RIL_GetPowerSupply(u32* capacity, u32* voltage) +{ + s32 ret; + ST_SysPower PowerSupply; + + ret = Ql_RIL_SendATCmd("AT+CBC", 6, Power_ATResponse_Hanlder, (void *)&PowerSupply, 0); + if (RIL_AT_SUCCESS == ret) + { + *capacity = PowerSupply.capacity; + *voltage = PowerSupply.voltage; + } + return ret; +} + +s32 Ql_SecureData_Store(u8 index , u8* pData, u32 len) +{ + s32 ret,i,AtHeadlen, hexstrlen; + char* pstrBuff = NULL; + char* ATstrhead = NULL; + + if(index <= 0 || index > 13 ) + { + return QL_RET_ERR_PARAM; + } + if(((index <= 8) && (len > 50)) || ((index > 8) && (index <= 12) && (len > 100)) ||((index > 12) && (len > 500))) + { + return QL_RET_ERR_PARAM; + } + + hexstrlen = 2*len; + ATstrhead = (char*)Ql_MEM_Alloc(hexstrlen+40); + if(NULL == ATstrhead) + return QL_RET_ERR_GET_MEM; + + Ql_memset(ATstrhead, 0x00, hexstrlen+40); + pstrBuff = ATstrhead; + Ql_sprintf(pstrBuff,"AT+QUSERDAT=1,%d,\"",index); + AtHeadlen =Ql_strlen(pstrBuff); + pstrBuff = ATstrhead+AtHeadlen; + for(i=0; i\r\n",ATstrhead); + ret = Ql_RIL_SendATCmd(ATstrhead, Ql_strlen(ATstrhead), NULL, NULL, 0); + Ql_MEM_Free(ATstrhead); + ATstrhead = NULL; + return ret; +} + + +static bool hexstring_to_value(u8 *str, u8*val) +{ + u16 i = 0, j = 0; + u8 temp = 0; + + if((str == NULL) && (val == NULL)) + return FALSE; + + Ql_StrToUpper((char*)str); + while (str[i] != END_OF_STR) + { + if (IS_NUMBER(str[i])) + { + temp = (temp << 4) + (str[i] - CHAR_0); + } + else if ((str[i] >= CHAR_A) && (str[i] <= CHAR_F)) + { + temp = (temp << 4) + ((str[i] - CHAR_A) + 10); + } + else + { + return FALSE; + } + if(i%2) + { + *(val+j)= temp; + j++; + temp = 0; + } + i++; + + } + + return TRUE; +} + +u32 SecureDataStringLen; +bool IsDataReadSuccess = FALSE; +typedef struct { + u8* pHexBuf; + u32 realLen; +}ST_CustomParam; +static s32 SecureData_Read_Callback(char* line, u32 len, void* userdata) +{ + char *head = Ql_RIL_FindString(line, len, "+QUSERDAT: 3,"); //continue wait + if(head) + { + u32 cplen; + char* p1 = NULL; + char* p2 = NULL; + p1 = Ql_strstr(line, "\""); + p2 = Ql_strstr(p1+1, "\""); + if ((p1 != NULL)&&(p2!= NULL)) + { + ST_CustomParam* pCus = (ST_CustomParam*)userdata; + cplen = (SecureDataStringLen < (p2-p1-1))? (SecureDataStringLen):(p2-p1-1) ; + pCus->realLen = cplen / 2; + Ql_memcpy(pCus->pHexBuf, p1+1,cplen); + // Ql_Debug_Trace("Read backup hex:%s",userdata); + IsDataReadSuccess = TRUE; + } + else + { + IsDataReadSuccess = FALSE; + } + } + + head = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if(head) + { + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if(head) + { + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait + +} +s32 Ql_SecureData_Read(u8 index, u8* pBuffer, u32 len) +{ + s32 ret; + char ATstr[20]; + ST_CustomParam ptrCus; + + if(index <= 0 || index > 13 ) + { + return QL_RET_ERR_PARAM; + } + if(((index <= 8) && (len > 50)) || ((index > 8) && (index <= 12) && (len > 100)) ||((index > 12) && (len > 500))) + { + return QL_RET_ERR_PARAM; + } + + SecureDataStringLen = 2*len; + Ql_memset(&ptrCus, 0x0, sizeof(ST_CustomParam)); + ptrCus.pHexBuf = Ql_MEM_Alloc(SecureDataStringLen+1); // 2*len the buffer stroe the data read form + if(NULL == ptrCus.pHexBuf) + return QL_RET_ERR_GET_MEM; + + Ql_memset(ATstr, 0x00, sizeof(ATstr)); + Ql_sprintf(ATstr,"AT+QUSERDAT=3,%d",index); // read index + Ql_memset(ptrCus.pHexBuf, 0x00, SecureDataStringLen+1); + ret = Ql_RIL_SendATCmd(ATstr, Ql_strlen(ATstr), SecureData_Read_Callback, &ptrCus, 0); + if(ret <0) + return ret; + if(!IsDataReadSuccess) + { + Ql_MEM_Free(ptrCus.pHexBuf); + ptrCus.pHexBuf = NULL; + return Ql_RET_ERR_UNKOWN; + } + hexstring_to_value(ptrCus.pHexBuf,pBuffer); + Ql_MEM_Free(ptrCus.pHexBuf); + ptrCus.pHexBuf = NULL; + + return ptrCus.realLen; +} + +static s32 ATRsp_IMEI_Handler(char* line, u32 len, void* param) +{ + char* pHead = NULL; + pHead = Ql_RIL_FindLine(line, len, "OK"); // find OK, OK£¬OK + if (pHead) + { + return RIL_ATRSP_SUCCESS; + } + + pHead = Ql_RIL_FindLine(line, len, "ERROR");// find ERROR, ERROR£¬ERROR + if (pHead) + { + return RIL_ATRSP_FAILED; + } + + pHead = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if (pHead) + { + return RIL_ATRSP_FAILED; + } + //uh1:solve imei caused bonding issue + Ql_memcpy((char*)param, line+2, len - 4); // \r\n + return RIL_ATRSP_CONTINUE; //continue wait +} + +s32 RIL_GetIMEI(char* imei) +{ + char strAT[] = "AT+GSN\0"; + if (NULL == imei) + { + return RIL_AT_INVALID_PARAM; + } + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), ATRsp_IMEI_Handler,(void*)imei, 0); +} + +#endif //__OCPU_RIL_SUPPORT__ + diff --git a/cores/opencpu/ril/src/ril_telephony.c b/cores/opencpu/ril/src/ril_telephony.c new file mode 100644 index 0000000..f87dd07 --- /dev/null +++ b/cores/opencpu/ril/src/ril_telephony.c @@ -0,0 +1,147 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_sms.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements telephony related APIs. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ril.h" +#include "ril_util.h" +#include "ril_telephony.h " +#include "ql_stdlib.h" + +#if defined(__OCPU_RIL_SUPPORT__) + +ST_ComingCallInfo g_comingCall; + +#if defined(__OCPU_RIL_CALL_SUPPORT__) +static s32 Telephony_Dial_AT_handler(char* line, u32 len, void* userdata) +{ + char *head = Ql_RIL_FindLine(line, len, "NO DIALTONE"); + if(head) + { + (*(s32* )userdata) = CALL_STATE_NO_DIALTONE; + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "BUSY"); + if(head) + { + (*(s32* )userdata) = CALL_STATE_BUSY; + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "NO CARRIER"); + if(head) + { + (*(s32* )userdata) = CALL_STATE_NO_CARRIER; + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "OK"); + if(head) + { + (*(s32* )userdata) = CALL_STATE_OK; + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR"); + if(head) + { + (*(s32* )userdata) = CALL_STATE_ERROR; + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + (*(s32* )userdata) = CALL_STATE_ERROR; + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +s32 RIL_Telephony_Dial(u8 type, char* phoneNumber, s32 *result) +{ + char strAT[40]; + if (NULL == phoneNumber) + { + return -1; + } + Ql_memset(strAT, 0x0, sizeof(strAT)); + Ql_sprintf(strAT, "ATD%s;", phoneNumber); + return Ql_RIL_SendATCmd(strAT, Ql_strlen(strAT), Telephony_Dial_AT_handler, (void* )result, 0); +} + +static s32 Telephony_Answer_AT_handler(char* line, u32 len, void* userdata) +{ + char *head; + head = Ql_RIL_FindLine(line, len, "OK"); + if(head) + { + (*(s32* )userdata) = CALL_STATE_OK; + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "NO CARRIER"); + if(head) + { + (*(s32* )userdata) = CALL_STATE_NO_CARRIER; + return RIL_ATRSP_SUCCESS; + } + + head = Ql_RIL_FindLine(line, len, "ERROR"); + if(head) + { + (*(s32* )userdata) = CALL_STATE_ERROR; + return RIL_ATRSP_FAILED; + } + + head = Ql_RIL_FindString(line, len, "+CME ERROR:");//fail + if(head) + { + (*(s32* )userdata) = CALL_STATE_ERROR; + return RIL_ATRSP_FAILED; + } + + return RIL_ATRSP_CONTINUE; //continue wait +} + +s32 RIL_Telephony_Answer(s32 *result) +{ + return Ql_RIL_SendATCmd("ATA", 3, Telephony_Answer_AT_handler, result, 0); +} + +s32 RIL_Telephony_Hangup(void) +{ + return Ql_RIL_SendATCmd("ATH", 3, NULL, NULL, 0); +} +#endif +#endif diff --git a/cores/opencpu/ril/src/ril_urc.c b/cores/opencpu/ril/src/ril_urc.c new file mode 100644 index 0000000..5fde450 --- /dev/null +++ b/cores/opencpu/ril/src/ril_urc.c @@ -0,0 +1,607 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_urc.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module handles URC in RIL. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "custom_feature_def.h" +#include "ql_stdlib.h" +#include "ril.h " +#include "ril_util.h" +#include "ril_sms.h" +#include "ril_telephony.h " +#include "ql_power.h" +#include "ql_system.h" +#include "ril_audio.h" +#include "ril_ftp.h" +#include "ril_http.h" + +#ifdef __OCPU_RIL_SUPPORT__ + +/************************************************************************/ +/* Definition for URC receive task id. */ +/************************************************************************/ +#define URC_RCV_TASK_ID main_task_id + +/************************************************************************/ +/* Declarations for URC handler. */ +/************************************************************************/ +static void OnURCHandler_Call(const char* strURC, void* reserved); +static void OnURCHandler_SMS(const char* strURC, void* reserved); +static void OnURCHandler_Network(const char* strURC, void* reserved); +static void OnURCHandler_SIM(const char* strURC, void* reserved); +static void OnURCHandler_CFUN(const char* strURC, void* reserved); +static void OnURCHandler_Voltage(const char* strURC, void* reserved); +static void OnURCHandler_InitStat(const char* strURC, void* reserved); +static void OnURCHandler_HTTP(const char* strURC, void* reserved); +static void OnURCHandler_FTP(const char* strURC, void* reserved); +static void OnURCHandler_AlarmRing(const char* strURC, void* reserved); +#ifdef __OCPU_RIL_BT_SUPPORT__ +extern void OnURCHandler_BTScan(const char* strURC, void* reserved); +extern void OnURCHandler_BTPair(const char* strURC, void* reserved); +extern void OnURCHandler_BTPairCnf(const char* strURC, void* reserved); +extern void OnURCHandler_BTConn(const char* strURC, void* reserved); +extern void OnURCHandler_BTConnCnf(const char* strURC, void* reserved); +extern void OnURCHandler_BTDisconn(const char* strURC, void* reserved); +extern void OnURCHandler_BTIndication(const char* strURC, void* reserved); +extern void OnURCHandler_BTVisible(const char* strURC, void* reserved); +#endif +static void OnURCHandler_AudPlayInd(const char* strURC, void* reserved); +extern void OnURCHandler_QCELLLocation(const char* strURC,void* reserved); +// DTMF URC callback +extern void OnURCHandler_QToneDet( const char* strURC, void* reserved ); +extern void OnURCHandler_QWDTMF( const char* strURC, void* reserved ); +// NTP URC callback +extern void OnURCHandler_NTPCMD(const char* strURC, void* reserved); +/************************************************************************/ +/* Customer ATC URC callback */ +/************************************************************************/ +CallBack_Ftp_Upload FtpPut_IND_CB = NULL; +CallBack_Ftp_Download FtpGet_IND_CB = NULL; + +/****************************************************************************** +* Definitions for URCs and the handler. +* ------------------------------------- +* ------------------------------------- +* In OpenCPU RIL, URC contains two types: system URC and AT URC. +* - System URCs indicate the various status of module. +* - AT URC serves some specific AT command. +* For example, some AT command responses as below: +* AT+QABC (send at command) +* +* OK (response1) +* +QABC:xxx (response2) --> this is the final result which is reported by URC. +* When calling Ql_RIL_SendATCmd() to send such AT command, the return value of +* Ql_RIL_SendATCmd indicates the response1, and the response2 may be reported +* via the callback function. Especially for some AT commands that the time span +* between response1 and response2 is very long, such as AT+QHTTPDL, AT+QFTPGET. +******************************************************************************/ +/****************************************************/ +/* Definitions for system URCs and the handler */ +/****************************************************/ +const static ST_URC_HDLENTRY m_SysURCHdlEntry[] = { + + //Telephony unsolicited response + {"\r\n+CRING: VOICE\r\n", OnURCHandler_Call}, + {"\r\nRING\r\n", OnURCHandler_Call}, + {"\r\nBUSY\r\n", OnURCHandler_Call}, + {"\r\nNO ANSWER\r\n", OnURCHandler_Call}, + {"\r\nNO CARRIER\r\n", OnURCHandler_Call}, + {"\r\nNO DIALTONE\r\n", OnURCHandler_Call}, +// {"\r\n+CCWA:", OnURCHandler_Call},//AT+CCWA=1,1 + {"\r\n+CLIP:", OnURCHandler_Call}, + + //SMS unsolicited response + {"\r\n+CMTI:", OnURCHandler_SMS}, +// {"\r\n+CMT:", OnURCHandler_SMS},//AT+CNMI=2,2 +// {"\r\n+CDS:", OnURCHandler_SMS},//AT+CNMI=2,2 +// {"\r\n+CBM:", OnURCHandler_SMS},//AT+CNMI=2,2 + + //Network status unsolicited response + {"\r\n+CREG:", OnURCHandler_Network}, + {"\r\n+CGREG:", OnURCHandler_Network}, + + //SIM card unsolicited response + {"\r\n+CPIN:", OnURCHandler_SIM}, + + //CFUN unsolicited response + {"\r\n+CFUN:", OnURCHandler_CFUN}, + + //Voltage indication + {"\r\nUNDER_VOLTAGE WARNING \r\n", OnURCHandler_Voltage}, + {"\r\nUNDER_VOLTAGE POWER DOWN \r\n", OnURCHandler_Voltage}, + {"\r\nOVER_VOLTAGE WARNING \r\n", OnURCHandler_Voltage}, + {"\r\nOVER_VOLTAGE POWER DOWN \r\n", OnURCHandler_Voltage}, + + //Init status unsolicited response + {"\r\nCall Ready\r\n", OnURCHandler_InitStat}, + {"\r\nSMS Ready\r\n", OnURCHandler_InitStat}, + + // Clock alarm ring indication + {"\r\nALARM RING\r\n", OnURCHandler_AlarmRing}, + {"\r\nALARM MODE\r\n", OnURCHandler_AlarmRing}, + + // Location indication + {"\r\n+QCELLLOC:", OnURCHandler_QCELLLocation}, +}; + +/****************************************************/ +/* Definitions for AT URCs and the handler */ +/****************************************************/ +const static ST_URC_HDLENTRY m_AtURCHdlEntry[] = { + //HTTP unsolicited response + {"\r\n+QHTTPDL:", OnURCHandler_HTTP}, + + //FTP unsolicited response + {"\r\n+QFTPGET:", OnURCHandler_FTP}, + {"\r\n+QFTPPUT:", OnURCHandler_FTP}, + + //Audio (file or resource) playing indication + {"\r\n+QAUDPIND:", OnURCHandler_AudPlayInd}, + {"\r\n+QPLAYRES:", OnURCHandler_AudPlayInd}, + {"\r\n+QPRESBG:", OnURCHandler_AudPlayInd}, + + // BT unsolicited response +#ifdef __OCPU_RIL_BT_SUPPORT__ + {"\r\n+QBTSCAN:", OnURCHandler_BTScan}, + {"\r\n+QBTPAIR:", OnURCHandler_BTPair}, + {"\r\n+QBTPAIRCNF:", OnURCHandler_BTPairCnf}, + {"\r\n+QBTCONN:", OnURCHandler_BTConn}, + {"\r\n+QBTACPT:", OnURCHandler_BTConnCnf}, + {"\r\n+QBTDISC:", OnURCHandler_BTConnCnf}, + {"\r\n+QBTDISCONN:", OnURCHandler_BTDisconn}, + {"\r\n+QBTIND:", OnURCHandler_BTIndication}, + {"\r\n+QBTVISB:", OnURCHandler_BTVisible}, +#endif + + // DTMF unsolicited response + {"\r\n+QTONEDET:", OnURCHandler_QToneDet}, + {"\r\n+QWDTMF:", OnURCHandler_QWDTMF}, + //NTP unsolicited response + {"\r\n+QNTP:", OnURCHandler_NTPCMD}, +}; + +static void OnURCHandler_SIM(const char* strURC, void* reserved) +{ + char* p1 = NULL; + char* p2 = NULL; + char strTmp[20]; + s32 len; + extern s32 RIL_SIM_GetSimStateByName(char* simStat, u32 len); + + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + len = Ql_sprintf(strTmp, "\r\n+CPIN: "); + if (Ql_StrPrefixMatch(strURC, strTmp)) + { + p1 = Ql_strstr(strURC, "\r\n+CPIN: "); + p1 += len; + p2 = Ql_strstr(p1, "\r\n"); + if (p1 && p2) + { + u32 cpinStat; + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_memcpy(strTmp, p1, p2 - p1); + cpinStat = (u32)RIL_SIM_GetSimStateByName(strTmp, p2 - p1); + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_SIM_CARD_STATE_IND, cpinStat); + } + } +} +static void OnURCHandler_Network(const char* strURC, void* reserved) +{ + char* p1 = NULL; + char* p2 = NULL; + char strTmp[10]; + + if (Ql_StrPrefixMatch(strURC, "\r\n+CREG: ")) + { + u32 nwStat; + p1 = Ql_strstr(strURC, "\r\n+CREG: "); + p1 += Ql_strlen("\r\n+CREG: "); + if(*(p1+1) == 0x2C) //Active query network status without reporting URCS + { + return; + } + p2 = Ql_strstr(p1, "\r\n"); + if (p1 && p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_memcpy(strTmp, p1, p2 - p1); + nwStat = Ql_atoi(strTmp); + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_GSM_NW_STATE_IND, nwStat); + } + } + else if (Ql_StrPrefixMatch(strURC, "\r\n+CGREG: ")) + { + u32 nwStat; + p1 = Ql_strstr(strURC, "\r\n+CGREG: "); + p1 += Ql_strlen("\r\n+CGREG: "); + if(*(p1+1) == 0x2C) //Active query network status without reporting URCS + { + return; + } + p2 = Ql_strstr(p1, "\r\n"); + if (p1 && p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_memcpy(strTmp, p1, p2 - p1); + nwStat = Ql_atoi(strTmp); + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_GPRS_NW_STATE_IND, nwStat); + } + } +} +static void OnURCHandler_Call(const char* strURC, void* reserved) +{ + char* p1 = NULL; + char* p2 = NULL; + char strTmp[10]; + if (Ql_StrPrefixMatch(strURC, "\r\nRING\r\n") || + Ql_StrPrefixMatch(strURC, "\r\n+CLIP:") || + Ql_StrPrefixMatch(strURC, "\r\n+CRING: VOICE\r\n")) + {// Coming call + extern ST_ComingCallInfo g_comingCall; + u16 len; + + p1 = Ql_strstr(strURC, "\r\n+CLIP:"); + if (!p1) + { + return; + } + + g_comingCall.ringCnt++; + if ((g_comingCall.ringCnt / 6) > 0) + { + g_comingCall.ringCnt %= 6; + } + + // Retrieve phone number + p1 += Ql_strlen("\r\n+CLIP:"); + p2 = Ql_strstr(p1 + 1, ","); + len = p2 - (p1 + 2) - 1; + Ql_memcpy(g_comingCall.comingCall[g_comingCall.ringCnt].phoneNumber, p1 + 2, len); + g_comingCall.comingCall[g_comingCall.ringCnt].phoneNumber[len] = '\0'; + + // Retrieve number type + p1 = p2; + p2 = Ql_strstr(p1 + 1, ","); + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_memcpy(strTmp, p1 + 1, p2 - p1 -1); + g_comingCall.comingCall[g_comingCall.ringCnt].type = Ql_atoi(strTmp); + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_COMING_CALL_IND, (u32)(&(g_comingCall.comingCall[g_comingCall.ringCnt]))); + } + else if (Ql_StrPrefixMatch(strURC, "\r\nBUSY\r\n") || + Ql_StrPrefixMatch(strURC, "\r\nNO ANSWER\r\n") || + Ql_StrPrefixMatch(strURC, "\r\nNO CARRIER\r\n") || + Ql_StrPrefixMatch(strURC, "\r\nNO DIALTONE\r\n")) + { + u32 callStat; + + if (Ql_StrPrefixMatch(strURC, "\r\nBUSY\r\n")) + { + callStat = CALL_STATE_BUSY; + } + else if (Ql_StrPrefixMatch(strURC, "\r\nNO ANSWER\r\n")) + { + callStat = CALL_STATE_NO_ANSWER; + } + else if (Ql_StrPrefixMatch(strURC, "\r\nNO CARRIER\r\n")) + { + callStat = CALL_STATE_NO_CARRIER; + } + else if (Ql_StrPrefixMatch(strURC, "\r\nNO DIALTONE\r\n")) + { + callStat = CALL_STATE_NO_DIALTONE; + }else{ + return; + } + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_CALL_STATE_IND, callStat); + } +} + +static void OnURCHandler_SMS(const char* strURC, void* reserved) +{ + char* p1 = NULL; + char* p2 = NULL; + + //TODO: Something wrong with long SMS + if (Ql_StrPrefixMatch(strURC, "\r\n+CMTI:")) + { + u32 smsIndex; + char mem[SMS_MEM_CHAR_LEN]; + + // Get 'mem' + p1 = Ql_strstr(strURC, ":"); + p1 += 3; + p2 = Ql_strstr(p1, ","); + if (p1 && p2) + { + Ql_memset(mem, 0x0, sizeof(mem)); + Ql_strncpy(mem, p1, (p2 - p1 - 1)); + } + + // Get index + p1 = p2; + p2 = Ql_strstr(p1, "\r\n"); + if (p1 && p2) + { + char strIndex[10]; + Ql_memset(strIndex, 0x0, sizeof(strIndex)); + Ql_strncpy(strIndex, p1 + 1, p2 - p1 - 1); + smsIndex = Ql_atoi(strIndex); + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_NEW_SMS_IND, smsIndex); + } + } + else if (Ql_StrPrefixMatch(strURC, "\r\n+CMT:")) + { + } +} + +static void OnURCHandler_Voltage(const char* strURC, void* reserved) +{ + u32 volState = VBATT_UNDER_WRN; + + if (Ql_StrPrefixMatch(strURC, "\r\nUNDER_VOLTAGE WARNING \r\n")) + { + volState = VBATT_UNDER_WRN; + } + else if (Ql_StrPrefixMatch(strURC, "\r\nUNDER_VOLTAGE POWER DOWN \r\n")) + { + volState = VBATT_UNDER_PDN; + } + else if (Ql_StrPrefixMatch(strURC, "\r\nOVER_VOLTAGE WARNING \r\n")) + { + volState = VBATT_OVER_WRN; + } + else if (Ql_StrPrefixMatch(strURC, "\r\nOVER_VOLTAGE POWER DOWN \r\n")) + { + volState = VBATT_OVER_PDN; + }else{ + return; + } + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_MODULE_VOLTAGE_IND, volState); +} + +static void OnURCHandler_InitStat(const char* strURC, void* reserved) +{ + u32 sysInitStat = SYS_STATE_START; + + if (Ql_strstr(strURC, "\r\nCall Ready\r\n") != NULL) + { + sysInitStat = SYS_STATE_PHBOK; + } + else if(Ql_strstr(strURC, "\r\nSMS Ready\r\n") != NULL) + { + sysInitStat = SYS_STATE_SMSOK; + } + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_SYS_INIT_STATE_IND, sysInitStat); +} + +static void OnURCHandler_CFUN(const char* strURC, void* reserved) +{ + char* p1 = NULL; + char* p2 = NULL; + char strTmp[10]; + s32 len; + u32 cfun; + + len = Ql_strlen("\r\n+CFUN: "); + p1 = Ql_strstr(strURC, "\r\n+CFUN: "); + p1 += len; + p2 = Ql_strstr(p1, "\r\n"); + if (p1 && p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_memcpy(strTmp, p1, 1); + cfun = Ql_atoi(strTmp); + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_CFUN_STATE_IND, cfun); + } +} + +static void OnURCHandler_HTTP(const char* strURC, void* reserved) +{ + u32 dwnLoadedSize = 0; + u32 contentLen = 0; + s32 errCode = 0; + extern CB_HTTP_DwnldFile callback_http_dwnld; + + //+QHTTPDL: 23772,23772,0 + Ql_sscanf(strURC, "%*[^: ]: %d,%d,%d[^\r\n]", &dwnLoadedSize, &contentLen, &errCode); + if (callback_http_dwnld) + { + callback_http_dwnld(dwnLoadedSize, contentLen, errCode); + callback_http_dwnld = NULL; + } +} + +static void OnURCHandler_FTP(const char* strURC, void* reserved) +{ + char* p1 = NULL; + char* p2 = NULL; + s32 nFtpDlLen = 0; + char strTmp[10]; + + p1 = Ql_strstr(strURC, "\r\n+QFTPGET:"); + p1 += Ql_strlen("\r\n+QFTPGET:"); + p2 = Ql_strstr(p1, "\r\n"); + if (p1 && p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_memcpy(strTmp, p1, p2 - p1); + nFtpDlLen = Ql_atoi(strTmp); + //TODO: + if(NULL != FtpGet_IND_CB) + { + if(nFtpDlLen < 0) + { + FtpGet_IND_CB(0,nFtpDlLen); + } + else + { + FtpGet_IND_CB(1,nFtpDlLen); + } + FtpGet_IND_CB = NULL; + return; + } + } + + p1 = NULL; + p2 = NULL; + p1 = Ql_strstr(strURC, "\r\n+QFTPPUT:"); + p1 += Ql_strlen("\r\n+QFTPPUT:"); + p2 = Ql_strstr(p1, "\r\n"); + if (p1 && p2) + { + Ql_memset(strTmp, 0x0, sizeof(strTmp)); + Ql_memcpy(strTmp, p1, p2 - p1); + nFtpDlLen = Ql_atoi(strTmp); + //TODO: + if(NULL != FtpPut_IND_CB) + { + if(nFtpDlLen < 0) + { + FtpPut_IND_CB(0,nFtpDlLen); + } + else + { + FtpPut_IND_CB(1,nFtpDlLen); + } + FtpPut_IND_CB = NULL; + return; + } + } +} + +static void OnURCHandler_AlarmRing(const char* strURC, void* reserved) +{ + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_ALARM_RING_IND, 0); +} + +static void OnURCHandler_Undefined(const char* strURC, void* reserved) +{ + Ql_OS_SendMessage(URC_RCV_TASK_ID, MSG_ID_URC_INDICATION, URC_END, 0); +} + +static void OnURCHandler_AudPlayInd(const char* strURC, void* reserved) +{ + s32 errCode1 = 0; + s32 errCode2 = 0; + extern RIL_AUD_PLAY_IND cb_aud_play; + + //"+QAUDPIND: 0," + //"+QPLAYRES: 0,%d" + //"+QPRESBG: 0,%d" + Ql_sscanf(strURC, "%*[^: ]: %d,%d[^\r\n]", &errCode1, &errCode2); + if (cb_aud_play) + { + cb_aud_play(errCode2); + } +} + +/***************************************************************** +* Function: OnURCHandler +* +* Description: +* This function is the entrance for Unsolicited Result Code (URC) Handler. +* +* Parameters: +* strURC: +* [IN] a URC string terminated by '\0'. +* +* reserved: +* reserved, can be NULL. +* Return: +* The function returns "ptrUrc". +*****************************************************************/ +void OnURCHandler(const char* strURC, void* reserved) +{ + s32 i; + + if (NULL == strURC) + { + return; + } + + // For system URCs + for (i = 0; i < NUM_ELEMS(m_SysURCHdlEntry); i++) + { + if (Ql_strstr(strURC, m_SysURCHdlEntry[i].keyword)) + { + m_SysURCHdlEntry[i].handler(strURC, reserved); + return; + } + } + + // For AT URCs + for (i = 0; i < NUM_ELEMS(m_AtURCHdlEntry); i++) + { + if (Ql_strstr(strURC, m_AtURCHdlEntry[i].keyword)) + { + m_AtURCHdlEntry[i].handler(strURC, reserved); + return; + } + } + + // For undefined URCs + OnURCHandler_Undefined(strURC, reserved); +} + +/****************************************************************************** +* Function: Ql_RIL_IsURCStr +* +* Description: +* This function is used to check whether a string is URC information +* you defined. +. +* Parameters: +* strRsp: +* [in]a string for the response of the AT command. +* Return: +* 0 : not URC information +* 1 : URC information +******************************************************************************/ +s32 Ql_RIL_IsURCStr(const char* strRsp) +{ + s32 i; + for (i = 0; i < NUM_ELEMS(m_SysURCHdlEntry); i++) + { + if (Ql_strstr(strRsp, m_SysURCHdlEntry[i].keyword)) + { + return 1; + } + } + for (i = 0; i < NUM_ELEMS(m_AtURCHdlEntry); i++) + { + if (Ql_strstr(strRsp, m_AtURCHdlEntry[i].keyword)) + { + return 1; + } + } + return 0; +} + +#endif // __OCPU_RIL_SUPPORT__ diff --git a/cores/opencpu/ril/src/ril_util.c b/cores/opencpu/ril/src/ril_util.c new file mode 100644 index 0000000..90ddaed --- /dev/null +++ b/cores/opencpu/ril/src/ril_util.c @@ -0,0 +1,254 @@ +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of Quectel Co., Ltd. 2013 +* +*****************************************************************************/ +/***************************************************************************** + * + * Filename: + * --------- + * ril_util.c + * + * Project: + * -------- + * OpenCPU + * + * Description: + * ------------ + * The module implements some common API functions. + * + * Author: + * ------- + * ------- + * + *============================================================================ + * HISTORY + *---------------------------------------------------------------------------- + * + ****************************************************************************/ +#include "ril_util.h " +#include "ql_memory.h" +#include "ql_stdlib.h" + +s32 Ql_StrPrefixMatch(const char* str, const char *prefix) +{ + for ( ; *str != '\0' && *prefix != '\0' ; str++, prefix++) { + if (*str != *prefix) { + return 0; + } + } + return *prefix == '\0'; +} + +char* Ql_StrToUpper(char* str) +{ + char* pCh = str; + if (!str) + { + return NULL; + } + for ( ; *pCh != '\0'; pCh++) + { + if (((*pCh) >= 'a') && ((*pCh) <= 'z')) + { + *pCh = Ql_toupper(*pCh); + } + } + return str; +} + +bool Ql_HexStrToInt(u8* str, u32* val) +{ + u16 i = 0; + u32 temp = 0; + + //ASSERT((str != NULL) && (val != NULL)); + if (NULL == str || NULL == val) + { + return FALSE; + } + Ql_StrToUpper((char*)str); + + while (str[i] != '\0') + { + if (IS_NUMBER(str[i])) + { + temp = (temp << 4) + (str[i] - CHAR_0); + } + else if ((str[i] >= CHAR_A) && (str[i] <= CHAR_F)) + { + temp = (temp << 4) + ((str[i] - CHAR_A) + 10); + }else{ + return FALSE; + } + i++; + } + *val = temp; + return TRUE; +} + +/****************************************************************************** +* Function: Ql_RIL_FindString +* +* Description: +* This function is used to match string within a specified length. +* This function is very much like strstr. +* +* Parameters: +* line: +* [in]The address of the string. +* len: +* [in]The length of the string. +* str: +* [in]The specified item which you want to look for in the string. +* +* Return: + The function returns a pointer to the located string, + or a null pointer if the specified string is not found. +******************************************************************************/ +char* Ql_RIL_FindString(char *line, u32 len,char *str) +{ + s32 i; + s32 strlen; + char *p; + + if ((NULL == line) || (NULL == str)) + return NULL; + + strlen = Ql_strlen(str); + if(strlen > len) + { + return NULL; + } + + p = line; + for (i = 0;i < len - strlen + 1; i++) + { + if (0 == Ql_strncmp (p, str, strlen)) + { + return p; + }else{ + p++; + } + } + return NULL; +} + +/****************************************************************************** +* Function: Ql_RIL_FindLine +* +* Description: +* This function is used to find the specified character line by line. +* for example,if you want to find "OK", In fact, we think that you are +* looking for OK,OK,OK or OK. +* +* +* Parameters: +* line: +* [in]The address of the string. +* len: +* [in]The length of the string. +* str: +* [in]The specified item which you want to look for in the string. +* +* Return: + The function returns a pointer to the located string, + or a null pointer if the specified string is not found. +******************************************************************************/ +char* Ql_RIL_FindLine(char *line, u32 len,char *str) +{ + s32 i = 0; + s32 strlen = 0; + char *p = NULL; + char *pStr = NULL; + char *pStr2 = NULL; + char *pStr3 = NULL; + + if ((NULL == line) || (NULL == str)) + return NULL; + + strlen = Ql_strlen (str); + + pStr = Ql_MEM_Alloc(strlen + 4 + 1); + if (NULL == pStr) + return NULL; + + if (len >= strlen + 4)//two \r\n + { + p = line; + Ql_memset(pStr, 0, strlen + 5); + Ql_sprintf(pStr,"\r\n%s\r\n",str); + for (i = 0;i < len - (strlen + 4) + 1; i++) + { + if (0 == Ql_strncmp(p, pStr, strlen + 4)) + { + Ql_MEM_Free(pStr); + return p; + }else{ + p++; + } + } + } + + if (len >= strlen + 2)//two \r or two\n + { + p = line; + + // xx + Ql_memset(pStr, 0, strlen + 5); + Ql_sprintf(pStr,"\r%s\r",str); + + // xx + pStr2 = (char*)Ql_MEM_Alloc(strlen + 5); + Ql_memset(pStr2, 0, strlen + 5); + Ql_sprintf(pStr2,"\n%s\n",str); + + // xx + pStr3 = (char*)Ql_MEM_Alloc(strlen + 5); + Ql_memset(pStr3, 0, strlen + 5); + Ql_sprintf(pStr3,"%s\r\n",str); + + for (i = 0;i < len - (strlen + 2) + 1; i++) + { + if ((0 == Ql_strncmp (p, pStr, strlen + 2)) || + (0 == Ql_strncmp (p, pStr2, strlen + 2)) || + (0 == Ql_strncmp (p, pStr3, strlen + 2))) + { + Ql_MEM_Free(pStr); + Ql_MEM_Free(pStr2); + Ql_MEM_Free(pStr3); + pStr = NULL; + pStr2 = NULL; + pStr3 = NULL; + return p; + }else{ + p++; + } + } + Ql_MEM_Free(pStr2); + Ql_MEM_Free(pStr3); + pStr2 = NULL; + pStr3 = NULL; + } + Ql_MEM_Free(pStr); + pStr = NULL; + + return NULL; +} + +u32 Ql_GenHash(char* strSrc, u32 len) +{ + u32 h, v; + u32 i; + for (h = 0, i = 0; i < len; i++) + { + h = (u32)(5527 * h + 7 * strSrc[i]); + v = h & 0x0000ffff; + h ^= v * v; + } + return h; +} diff --git a/cores/opencpu/wiring.c b/cores/opencpu/wiring.c new file mode 100644 index 0000000..d8d90f7 --- /dev/null +++ b/cores/opencpu/wiring.c @@ -0,0 +1,120 @@ +/* + wiring.c + + Copyright (c) 2019 Georgi Angelov + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +#include + +inline void yield(void) +{ + Ql_Sleep(1); +} + +inline unsigned int millis() +{ + return Ql_GetMsSincePwrOn(); +} + +inline unsigned int seconds(void) +{ + return millis() / 1000; +} + +inline unsigned int micros() +{ + return api_getMicro(); +} + +inline void delayMicroseconds(unsigned int us) +{ + api_delayMicro(us); +} + +inline void delay(unsigned int ms) +{ + Ql_Sleep(ms); +} + +/////////////////////////////////////////////////////////// + +#define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0])) + +PinDescription *getArduinoPin(uint8_t arduinoPin) +{ + for (int i = 0; i < ARRAYLEN(pinsMap); i++) + if (pinsMap[i].arduino == arduinoPin) + return &pinsMap[i]; + return NULL; +} + +PinDescription *getDevicePin(uint8_t devicePin) +{ + for (int i = 0; i < ARRAYLEN(pinsMap); i++) + if (pinsMap[i].device == devicePin) + return &pinsMap[i]; + return NULL; +} + +static void eint_callback(Enum_PinName eintPinName, Enum_PinLevel pinLevel, void *user) +{ + Enum_PinName pin = (Enum_PinName)user; + PinDescription *n = getDevicePin(pin); + if (n && n->eint) + { + Ql_EINT_Mask(pin); + eint_callback_t cb = (eint_callback_t)n->eint; + cb(Ql_EINT_GetLevel(n->device)); + Ql_EINT_Unmask(pin); + } +} + +void eintMode(uint8_t pin, Enum_EintType type, eint_callback_t cb, uint32_t hwDebounce, uint32_t swDebounce, bool automask) +{ + PinDescription *n = getArduinoPin(pin); + if (n) + { + if (type == EINT_CLOSE) + { + Ql_EINT_Uninit(n->device); + n->eint = NULL; + } + else if (cb) + { + n->eint = cb; + Ql_EINT_RegisterFast(n->device, eint_callback, (void *)((int)n->device)); + Ql_EINT_Init(n->device, type, hwDebounce, swDebounce, automask); + } + } +} + +/////////////////////////////////////////////////////////// + +static int _irq_; +int api_SaveAndSetIRQMask(void) __attribute__((weak)); +void api_RestoreIRQMask(int) __attribute__((weak)); + +void interrupts(void) +{ + api_RestoreIRQMask(_irq_); +} + +void noInterrupts(void) +{ + _irq_ = api_SaveAndSetIRQMask(); +} \ No newline at end of file diff --git a/cores/opencpu/wiring_analog.c b/cores/opencpu/wiring_analog.c new file mode 100644 index 0000000..e6652c7 --- /dev/null +++ b/cores/opencpu/wiring_analog.c @@ -0,0 +1,72 @@ +/* + * Created on: 01.15.2019 + * Author: Georgi Angelov + */ + +#include + +#define PWM_MAX 8193 + +static u32 adc_value = 0; + +void analogReference(uint8_t mode) {} + +void analogWrite(uint8_t pin, int val) +{ + if (PWM0 == pin) + Ql_PWM_Output((Enum_PinName)pin, val); +} + +void analogClose(uint8_t pin) +{ + switch (pin) + { + case ADC0: + Ql_ADC_Sampling((Enum_ADCPin)(pin - PINNAME_END), false); + adc_value = 0; + break; + case PWM0: + Ql_PWM_Uninit((Enum_PinName)pin); + } +} + +int analogRead(uint8_t pin) +{ + return adc_value; // 0 ~ 2800mV +} + +static void onADC(Enum_ADCPin adcPin, u32 adcValue, void *customParam) +{ + adc_value = adcValue; +} + +void analogOpen(uint8_t pin, /* val, src, div */...) +{ + switch (pin) + { + case ADC0: + { + Enum_ADCPin aPin = (Enum_ADCPin)(pin - PINNAME_END); + Ql_ADC_Register(aPin, onADC, NULL); + Ql_ADC_Init(aPin, 5, 200); + Ql_ADC_Sampling(aPin, true); + } + break; + + case PWM0: + { + va_list list; + va_start(list, pin); + uint32_t val = va_arg(list, uint32_t); + uint32_t pwmSrcClk = va_arg(list, uint32_t); + uint32_t pwmDiv = va_arg(list, uint32_t); + Ql_GPIO_Uninit((Enum_PinName)pin); + uint32_t PWM_lowPulseNum = PWM_MAX / 2; + uint32_t PWM_highPulseNum = PWM_MAX / 2; + Ql_PWM_Init((Enum_PinName)pin, (Enum_PwmSource)pwmSrcClk, (Enum_PwmSourceDiv)pwmDiv, PWM_lowPulseNum, PWM_highPulseNum); + Ql_PWM_Output((Enum_PinName)pin, val); + } + break; + + } //switch +} diff --git a/cores/opencpu/wiring_digital.c b/cores/opencpu/wiring_digital.c new file mode 100644 index 0000000..bd09d4f --- /dev/null +++ b/cores/opencpu/wiring_digital.c @@ -0,0 +1,69 @@ +/* + wiring_digital.c - digital input and output functions + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + Modified 28 September 2018 by Georgi Angelov +*/ + +#include +#include + +void pinMode(uint8_t pin, uint8_t mode) +{ + PinDescription *n = getArduinoPin(pin); + if (n) + { + if (mode == CLOSE) + { + Ql_GPIO_Uninit(n->device); + n->device = PINNAME_END; + } + else + { + Enum_PinPullSel pull = PINPULLSEL_DISABLE; + Enum_PinDirection dir = PINDIRECTION_IN; + Enum_PinLevel level = PINLEVEL_LOW; + if (mode & INPUT_PULLUP) + pull = PINPULLSEL_PULLUP; + if (mode & INPUT_PULLDOWN) + pull = PINPULLSEL_PULLDOWN; + if ((mode & OUTPUT) || (mode & OUTPUT_LO) || (mode & OUTPUT_HI)) + dir = PINDIRECTION_OUT; + if (mode & OUTPUT_HI) + level = PINLEVEL_HIGH; + Ql_GPIO_Init(n->device, dir, level, pull); + } + } +} + +void digitalWrite(uint8_t pin, uint8_t val) +{ + PinDescription *n = getArduinoPin(pin); + if (n) + Ql_GPIO_SetLevel(n->device, (Enum_PinLevel)val & 1); +} + +int digitalRead(uint8_t pin) +{ + PinDescription *n = getArduinoPin(pin); + if (n) + return Ql_GPIO_GetLevel(n->device); + return -1; +} diff --git a/cores/opencpu/wiring_pulse.c b/cores/opencpu/wiring_pulse.c new file mode 100644 index 0000000..b14db0d --- /dev/null +++ b/cores/opencpu/wiring_pulse.c @@ -0,0 +1,65 @@ +/* + wiring_pulse.c - pulseIn() function + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +#include + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) +{ + uint32_t init_time = micros(); + uint32_t curr_time = init_time; + uint32_t max_time = init_time + timeout; + int pin_state = 0; + + /* read GPIO info */ + pin_state = digitalRead(pin); + + // wait for any previous pulse to end + while ((pin_state == state) && (curr_time < max_time)) + { + curr_time = micros(); + pin_state = digitalRead(pin); + } + + // wait for the pulse to start + while ((pin_state != state) && (curr_time < max_time)) + { + curr_time = micros(); + init_time = curr_time; + pin_state = digitalRead(pin); + } + + // wait for the pulse to stop + while ((pin_state == state) && (curr_time < max_time)) + { + curr_time = micros(); + pin_state = digitalRead(pin); + } + + if (curr_time < max_time) + { + return (curr_time - init_time); + } + else + { + return 0; + } +} \ No newline at end of file diff --git a/cores/opencpu/wiring_shift.c b/cores/opencpu/wiring_shift.c new file mode 100644 index 0000000..fddbfba --- /dev/null +++ b/cores/opencpu/wiring_shift.c @@ -0,0 +1,54 @@ +/* + wiring_shift.c - shiftOut() function + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +#include + +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) +{ + uint8_t value = 0; + uint8_t i; + for (i = 0; i < 8; ++i) + { + digitalWrite(clockPin, HIGH); + if (bitOrder == LSBFIRST) + value |= digitalRead(dataPin) << i; + else + value |= digitalRead(dataPin) << (7 - i); + digitalWrite(clockPin, LOW); + } + return value; +} + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) +{ + uint8_t i; + for (i = 0; i < 8; i++) + { + if (bitOrder == LSBFIRST) + digitalWrite(dataPin, !!(val & (1 << i))); + else + digitalWrite(dataPin, !!(val & (1 << (7 - i)))); + + digitalWrite(clockPin, HIGH); + digitalWrite(clockPin, LOW); + } +} diff --git a/package_wizio.m66_index.json b/package_wizio.m66_index.json new file mode 100644 index 0000000..3a22edf --- /dev/null +++ b/package_wizio.m66_index.json @@ -0,0 +1,66 @@ +{ + "packages": [ + { + "name": "WizIO", + "maintainer": "WizIO", + "websiteURL": "https://github.com/Wiz-IO", + "email": "the_wizarda@gmail.com", + "platforms": [ + { + "name": "Quectel M66", + "architecture": "m66", + "version": "2.0.0", + "category": "Contributed", + "url": "http://m66_core.2.0.0.zip", + "archiveFileName": "m66_core.2.0.0.zip", + "checksum": "", + "size": "0", + "help": { "online": "https://github.com/Wiz-IO/Arduino-Quectel-M66" }, + "boards": [ + { "name": "M66" } + ], + "toolsDependencies": [ + { + "packager": "WizIO", + "name": "m66_gcc", + "version": "1.70201.0" + }, + { + "packager": "WizIO", + "name": "m66_tools", + "version": "1.0" + } + ] + } + ], + "tools": [ + { + "name": "m66_gcc", + "version": "1.70201.0", + "systems": [ + { + "host": "i686-mingw32", + "url": "http://gcc.1.70201.0.zip", + "archiveFileName": "gcc.1.70201.0.zip", + "size": "106761211", + "checksum": "" + } + ] + }, + { + "name": "m66_tools", + "version": "1.0", + "systems": [ + { + "host": "i686-mingw32", + "url": "http://m66_tools.1.0.zip", + "archiveFileName": "m66_tools.1.0.zip", + "size": "0", + "checksum": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/platform.txt b/platform.txt new file mode 100644 index 0000000..6550808 --- /dev/null +++ b/platform.txt @@ -0,0 +1,76 @@ +# WizIO 2018 Georgi Angelov +# https://github.com/Wiz-IO/Arduino-Quectel-BC66/blob/master/README.md +# the.wizarda@gmail.com +# +# Arduino Core and platform. +# For more info: +# https:\\github.com\arduino\Arduino\wiki\Arduino-IDE-1.5---3rd-party-Hardware-specification + +name=WizIO +version=2.0.0 + +compiler.path={build.compiler_path} +compiler.c.cmd=arm-none-eabi-gcc +compiler.cpp.cmd=arm-none-eabi-g++ +compiler.c.elf.cmd=arm-none-eabi-g++ +compiler.ar.cmd=arm-none-eabi-ar +compiler.objcopy.cmd=arm-none-eabi-objcopy +compiler.size.cmd=arm-none-eabi-size + +compiler.include="-I{build.core.path}\" "-I{build.core.path}\include\" "-I{build.core.path}\ril\inc\" "-I{build.core.path}\fota\inc\" "-I{build.core.path}\api\" + +compiler.S.flags=-x assembler-with-cpp + +compiler.gcc.c.flags=-Os -Wall -g -fno-strict-aliasing -ffunction-sections -fdata-sections -Wno-pointer-sign -Wstrict-prototypes -Wp,-w "-DARDUINO=200" + +compiler.c.flags=-std=c11 + +compiler.cpp.flags=-std=c++11 -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics + +compiler.c.elf.flags=-nostartfiles -fno-use-cxa-atexit -Xlinker --gc-sections -Wl,--gc-sections + +compiler.ar.flags=rcs + +compiler.objcopy.remove.flags=--strip-debug + +compiler.objcopy.bin.flags=-O binary + +###### Compile S files +recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {build.mcu} {compiler.S.flags} {compiler.c.flags} {compiler.include} {includes} "{source_file}" -o "{object_file}" + +###### C Compile files +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {build.mcu} {compiler.c.flags} {build.extra_flags} {compiler.gcc.c.flags} {compiler.include} {includes} "{source_file}" -c -o "{object_file}" + +###### CPP Compile files +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {build.mcu} {compiler.cpp.flags} {build.extra_flags} {compiler.gcc.c.flags} {compiler.include} {includes} "{source_file}" -c -o "{object_file}" + +###### AR Create archives +recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{archive_file_path}" "{object_file}" + +###### ELF Combine gc-sections, archives, and objects +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {build.mcu} {compiler.c.elf.flags} "-T{build.core.path}/cpp_m66.ld" -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -Wl,--start-group "{build.path}/{archive_file}" {object_files} "{build.core.path}/lib_app_start_m66.a" "{build.core.path}/lib_{build.firmware}.a" -Wl,--end-group -v + +###### Create BIN +recipe.objcopy.bin.1.pattern="{compiler.path}{compiler.objcopy.cmd}" -g -R .comment "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.dat" +recipe.objcopy.bin.2.pattern="{compiler.path}{compiler.objcopy.cmd}" -O binary "{build.path}/{build.project_name}.dat" "{build.path}/ARDUINO.bin" + +###### Add header to BIN +recipe.objcopy.hex.cmd.windows=gfh.bat +recipe.objcopy.hex.1.pattern="C:\Users\georgi.angelov\AppData\Local\Arduino15\packages\WizIO\tools\m66_tools\GFH_Generator" "{build.path}/ARDUINO.bin" +recipe.objcopy.hex.2.pattern=cmd /C copy /y "C:\Users\georgi.angelov\AppData\Local\Arduino15\packages\WizIO\tools\m66_tools\app_image_bin.cfg" "{build.path}\" + +###### Compute size +recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" +recipe.size.regex=^(?:\.iram0\.text|\.iram0\.vectors|\.dram0\.data|\.flash\.text|\.flash\.rodata|)\s+([0-9]+).* +recipe.size.regex.data=^(?:\.dram0\.data|\.dram0\.bss|\.noinit)\s+([0-9]+).* + + +########################################## + + +tools.m66.cmd= +tools.m66.cmd.windows= +tools.m66.path= +tools.m66.upload.params.verbose=-vvvvvv +tools.m66.upload.params.quiet=-q +tools.m66.upload.pattern=cmd /C echo [ UPLOAD ] USE QFlash Tool diff --git a/programmers.txt b/programmers.txt new file mode 100644 index 0000000..3610869 --- /dev/null +++ b/programmers.txt @@ -0,0 +1,4 @@ +# WizIO 2018 Georgi Angelov +# https://github.com/Wiz-IO/Arduino-MT2625-BC66/blob/master/README.md +# the.wizarda@gmail.com + diff --git a/tools/M66FAR01A12BT.zip b/tools/M66FAR01A12BT.zip new file mode 100644 index 0000000..ff3a9db Binary files /dev/null and b/tools/M66FAR01A12BT.zip differ diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..40986fa --- /dev/null +++ b/tools/README.md @@ -0,0 +1 @@ +# Tools diff --git a/variants/m66/variant.cpp b/variants/m66/variant.cpp new file mode 100644 index 0000000..b75336c --- /dev/null +++ b/variants/m66/variant.cpp @@ -0,0 +1,13 @@ +/* + * Created on: 01.15.2019 + * Author: Georgi Angelov + */ + +#include + +HardwareSerial Serial(UART_PORT1); +HardwareSerial Serial1(UART_PORT2); +HardwareSerial Serial2(UART_PORT3); + +HardwareSerial Virtual(VIRTUAL_PORT1); +HardwareSerial Virtual1(VIRTUAL_PORT2); \ No newline at end of file diff --git a/variants/m66/variant.h b/variants/m66/variant.h new file mode 100644 index 0000000..419aad3 --- /dev/null +++ b/variants/m66/variant.h @@ -0,0 +1,56 @@ +/* + * Created on: 01.15.2019 + * Author: Georgi Angelov + */ + +#ifndef __VARIANT_H__ +#define __VARIANT_H__ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define LED 0 /* PINNAME_NETLIGHT */ +#define LED_BUILTIN 0 /* PINNAME_NETLIGHT */ +#define PWM0 PINNAME_NETLIGHT /* ONLY ONE PIN */ +#define ADC0 PINNAME_END /* ONLY ONE PIN */ + + typedef struct + { + uint8_t arduino; + uint8_t device; + void *eint; + } PinDescription; + extern PinDescription pinsMap[13]; + + PinDescription *getArduinoPin(uint8_t arduinoPin); + PinDescription *getDevicePin(uint8_t devicePin); + + typedef void (*eint_callback_t)(uint32_t level); + void eintMode(uint8_t pin, Enum_EintType type, eint_callback_t cb, uint32_t hwDebounce, uint32_t swDebounce, bool automask); + + void analogReference(uint8_t mode) __attribute__((weak)); + void analogOpen(uint8_t pin, /* val, src, div */...); + void analogClose(uint8_t pin); + int analogRead(uint8_t pin); + void analogWrite(uint8_t pin, int val); + +#ifdef __cplusplus +} + +#include +extern HardwareSerial Serial; +extern HardwareSerial Serial1; +extern HardwareSerial Serial2; +extern HardwareSerial Virtual; +extern HardwareSerial Virtual1; + +#include +extern DeviceClass Dev; + +#endif //__cplusplus + +#endif /* __VARIANT_H__ */ diff --git a/variants/m66/variant_pins.c b/variants/m66/variant_pins.c new file mode 100644 index 0000000..211382e --- /dev/null +++ b/variants/m66/variant_pins.c @@ -0,0 +1,22 @@ +/* + * Created on: 01.15.2019 + * Author: Georgi Angelov + */ + +#include "variant.h" + +PinDescription pinsMap[13] = { + {0, PINNAME_NETLIGHT, NULL}, + {1, PINNAME_DTR, NULL}, + {2, PINNAME_RI, NULL}, + {3, PINNAME_DCD, NULL}, + {4, PINNAME_CTS, NULL}, + {5, PINNAME_RTS, NULL}, + {6, PINNAME_RXD_AUX, NULL}, + {7, PINNAME_TXD_AUX, NULL}, + {8, PINNAME_PCM_CLK, NULL}, + {9, PINNAME_PCM_SYNC, NULL}, + {10, PINNAME_PCM_IN, NULL}, + {11, PINNAME_PCM_OUT, NULL}, + {12, PINNAME_RFTXMON, NULL}, +};