Commit 098a6b88 authored by Christopher Reis's avatar Christopher Reis

Pulled back all those libraries...too many

Lots of errors
parent c9563b6c
No preview for this file type
http://developer.mbed.org/users/harrypowers/code/BMP180/#01c74f1b5f4d
01c74f1b5f4d3fdd80206eaaf423c412307c0ef1 4
01c74f1b5f4d3fdd80206eaaf423c412307c0ef1 default
4 01c74f1b5f4d3fdd80206eaaf423c412307c0ef1
[paths]
default = http://developer.mbed.org/users/harrypowers/code/BMP180/
revlogv1
fncache
store
dotencode
data/BMP180.cpp.i
data/BMP180.h.i
default
\ No newline at end of file
0
pull
http://developer.mbed.org/users/harrypowers/code/BMP180/
syntax: regexp
\.hgignore$
\.git$
\.svn$
\.orig$
\.msub$
\.meta$
\.ctags
\.uvproj$
\.uvopt$
\.project$
\.cproject$
\.launch$
\.project$
\.cproject$
\.launch$
Makefile$
\.ewp$
\.eww$
\ No newline at end of file
#include "BMP180.h"
BMP180::BMP180(PinName sda, PinName scl) : bmp180i2c(sda,scl)
{
bmp180i2c.frequency(BMP180FREQ);
oversampling_setting = OVERSAMPLING_HIGH_RESOLUTION;
rReg[0] = 0;
rReg[1] = 0;
rReg[2] = 0;
wReg[0] = 0;
wReg[1] = 0;
w[0] = 0xF4;
w[1] = 0xF4;
cmd = CMD_READ_CALIBRATION; // EEPROM calibration command
for (int i = 0; i < EEprom; i++) { // read the 22 registers of the EEPROM
bmp180i2c.write(BMP180ADDR, &cmd, 1);
bmp180i2c.read(BMP180ADDR, rReg, 1);
data[i] = rReg[0];
cmd += 1;
wait_ms(10);
}
// parameters AC1-AC6
//The calibration is partioned in 11 words of 16 bits, each of them representing a coefficient
ac1 = (data[0] <<8) | data[1]; // AC1(0xAA, 0xAB)... and so on
ac2 = (data[2] <<8) | data[3];
ac3 = (data[4] <<8) | data[5];
ac4 = (data[6] <<8) | data[7];
ac5 = (data[8] <<8) | data[9];
ac6 = (data[10] <<8) | data[11];
// parameters B1,B2
b1 = (data[12] <<8) | data[13];
b2 = (data[14] <<8) | data[15];
// parameters MB,MC,MD
mb = (data[16] <<8) | data[17];
mc = (data[18] <<8) | data[19];
md = (data[20] <<8) | data[21];
}
BMP180::~BMP180()
{
}
int BMP180::startTemperature() // Start temperature measurement
{
int errors = 0;
errors += bmp180i2c.write(BMP180ADDR, w, 2);
wReg[0] = 0xF4;
wReg[1] = 0x2E;
errors += bmp180i2c.write(BMP180ADDR, wReg, 2); // write 0x2E in reg 0XF4
return(errors);
}
int BMP180::readTemperature(long *t) // Get the temperature reading that was taken in startTemperature() but ensure 4.5 ms time has elapsed
{
int errors = 0;
rReg[0] = 0;
rReg[1] = 0;
rReg[2] = 0;
cmd = CMD_READ_VALUE; // 0xF6
errors += bmp180i2c.write(BMP180ADDR, &cmd, 1); // set pointer on 0xF6 before reading it?
errors += bmp180i2c.read(BMP180ADDR, rReg, 2); // read 0xF6 (MSB) and 0xF7 (LSB)// rReg is 3 long though
*t = (rReg[0] << 8) | rReg[1]; // UT = MSB << 8 + LSB
x1 = (((long) *t - (long) ac6) * (long) ac5) >> 15; // aka (ut-ac6) * ac5/pow(2,15)
x2 = ((long) mc << 11) / (x1 + md); // aka mc * pow(2, 11) / (x1 + md)
b5 = x1 + x2;
*t = ((b5 + 8) >> 4); // (b5+8)/pow(2, 4)
return(errors);
}
int BMP180::startPressure(int oversample) // Start pressure measurement! Note oversample will vary the time to complete this measurement. See defines above for oversampling constants to use!
{
int errors = 0;
oversampling_setting = BMP180::oversampleCheck(oversample);
int uncomp_pressure_cmd = 0x34 + (oversampling_setting<<6);
errors = bmp180i2c.write(BMP180ADDR, w, 2);
wReg[0] = 0xF4;
wReg[1] = uncomp_pressure_cmd;
errors += bmp180i2c.write(BMP180ADDR, wReg, 2);
return(errors);
}
int BMP180::readPressure(long *p) // Get the pressure reading that was taken in startPressure() but ensure time for the measurement to complete
{
int errors = 0;
rReg[0] = 0;
rReg[1] = 0;
rReg[2] = 0;
cmd = CMD_READ_VALUE; // 0xF6
errors += bmp180i2c.write(BMP180ADDR, &cmd, 1);
errors += bmp180i2c.read(BMP180ADDR, rReg, 3); // read 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB)
*p = ((rReg[0] << 16) | (rReg[1] << 8) | rReg[2]) >> (8 - oversampling_setting);
b6 = b5 - 4000; // realize b5 is set in readTemperature() function so that needs to be done first before this function!
x1 = (b6*b6) >> 12; // full formula(b2*(b6*b6)/pow(2,12))/pow(2,11)
x1 *= b2;
x1 >>= 11;
x2 = (ac2*b6);
x2 >>= 11;
x3 = x1 + x2;
b3 = (((((long)ac1 )*4 + x3) <<oversampling_setting) + 2) >> 2;
x1 = (ac3* b6) >> 13;
x2 = (b1 * ((b6*b6) >> 12) ) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
b7 = ((unsigned long) *p - b3) * (50000>>oversampling_setting);
if (b7 < 0x80000000) {
*p = (b7 << 1) / b4;
} else {
*p = (b7 / b4) << 1;
}
x1 = *p >> 8;
x1 *= x1; // pressure/pow(2,8) * pressure/pow(2, 8)
x1 = (x1 * 3038) >> 16;
x2 = ( *p * -7357) >> 16;
*p += (x1 + x2 + 3791) >> 4; // pressure in Pa
return(errors);
}
int BMP180::readTP(long *t, long *p, int oversample) // get both temperature and pressure calculations that are compensated
{
int errors = 0;
errors += BMP180::startTemperature();
wait_ms(4.5);
errors += BMP180::readTemperature(t);
errors += BMP180::startPressure(oversample);
switch (oversample) {
case OVERSAMPLING_ULTRA_LOW_POWER:
wait_ms(4.5);
break;
case OVERSAMPLING_STANDARD:
wait_ms(7.5);
break;
case OVERSAMPLING_HIGH_RESOLUTION:
wait_ms(13.5);
break;
case OVERSAMPLING_ULTRA_HIGH_RESOLUTION:
wait_ms(25.5);
break;
}
errors += BMP180::readPressure(p);
return(errors);
}
int BMP180::oversampleCheck(int oversample)
{
switch(oversample) {
case OVERSAMPLING_ULTRA_LOW_POWER:
break;
case OVERSAMPLING_STANDARD:
break;
case OVERSAMPLING_HIGH_RESOLUTION:
break;
case OVERSAMPLING_ULTRA_HIGH_RESOLUTION:
break;
default:
oversample = OVERSAMPLING_ULTRA_HIGH_RESOLUTION;
break;
}
return(oversample);
}
\ No newline at end of file
#ifndef BMP180_H
#define BMP180_H
/* BMP180 Digital Pressure Sensor Class for use with Mbed LPC1768 and other platforms
* BMP180 from Bosch Sensortec
* Copyright (c) 2013 Philip King Smith
*
* 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.
*
* Bosch data sheet at: http://ae-bst.resource.bosch.com/media/products/dokumente/bmp180/BST-BMP180-DS000-09.pdf
* Some parts of the calculations used are infact from Rom Clement published Mbed code here: https://mbed.org/users/Rom/code/Barometer_bmp085/
* I only used snippets of the Rom's code because i was making this into a class and so this is structured totaly different then his code example is.
* I also used the Bosch data sheet showing the calculations and adjusted everything accordingly!
*/
#include "mbed.h"
#define EEprom 22 // The EEPROM has 176bits of calibration data (176/8 = 22 Bytes)
#define BMP180ADDR 0xEF // I2C address of BMP180 device
#define BMP180FREQ 1000000 // Data sheet says 3.4 MHz is max but not sure what mbed can do here!
#define CMD_READ_VALUE 0xF6
#define CMD_READ_CALIBRATION 0xAA
#define OVERSAMPLING_ULTRA_LOW_POWER 0 // these are the constants used in the oversample variable in the below code!
#define OVERSAMPLING_STANDARD 1
#define OVERSAMPLING_HIGH_RESOLUTION 2
#define OVERSAMPLING_ULTRA_HIGH_RESOLUTION 3
/** BMP180 Digital Pressure Sensor class using mbed's i2c class
*
* Example:
* @code
* // show how the BMP180 class works
* #include "mbed.h"
* #include "BMP180.h"
*
* int main()
* {
*
* long temp ;
* long pressure;
* int error ;
* BMP180 mybmp180(p9,p10);
* while(1) {
* error = mybmp180.readTP(&temp,&pressure,OVERSAMPLING_ULTRA_HIGH_RESOLUTION);
* printf("Temp is %ld\r\n",temp);
* printf("Pressure is %ld\r\n",pressure);
* printf("Error is %d\r\n\r\n",error);
* wait(2);
* }
* }
* @endcode
*/
class BMP180
{
public:
/** Create object connected to BMP180 pins ( remember both pins need pull up resisters)
*
* Ensure the pull up resistors are used on these pins. Also note there is no checking on
* if you use these pins p9, p10, p27, p28 so ensure you only use these ones on the LPC1768 device
*
* @param sda pin that BMP180 connected to (p9 or p28 as defined on LPC1768)
* @param slc pin that BMP180 connected to (p10 or p27 ad defined on LPC1768)
*/
BMP180(PinName sda, PinName slc); // Constructor
~BMP180(); // Destructor
/** Read Temperature and Pressure at the same time
*
* This function will only return when it has readings. This means that the time will vary depending on oversample setting!
* Note if your code can not wait for these readings to be taken and calculated you should use the functions below.
* These other functions are designed to allow your code to do other things then get the final readings.
* This function is only designed as a one shot give me the answer function.
*
* @param t the temperature fully compensated value is returned in this variable. Degrees celsius with one decimal so 253 is 25.3 C.
* @param p the barometric pressure fully compensated value is returned in this variable. Pressure is in Pa so 88007 is 88.007 kPa.
* @param oversample is the method method for reading sensor. OVERSAMPLING_ULTRA_HIGH_RESOLUTION is used if an incorrect value is passed to this function.
* @param returns 0 for no errors during i2c communication. Any other number is just a i2c communication failure of some kind!
*/
int readTP(long *t, long *p, int oversample); // get both temperature and pressure fully compensated values! Note this only returns when measurements are complete
/** Start the temperature reading process but return after the commands are issued to BMP180
*
* This function is ment to start the temperature reading process but will return to allow other code to run then a reading could be made at a later time.
* Note the maximum time needed for this measurment is 4.5 ms.
*
* @param returns 0 for no errors during i2c communication. Any other number is just a i2c communication failure of some kind!
*/
int startTemperature(); // Start temperature measurement
/** Reads the last temperature reading that was started with startTemperature() function
*
* This function will return the fully compensated value of the temperature in Degrees celsius with one decimal so 253 is 25.3 C.
* Note this function should normaly follow the startTemperature() function and should also preceed the startPressure() and readPressure() commands!
* Note this function should follow startTemperature() after 4.5 ms minimum has elapsed or reading will be incorrect.
*
* @param t the temperature fully compensated value is returned in this variable.
* @param returns 0 for no errors during i2c communication. Any other number is just a i2c communication failure of some kind!
*/
int readTemperature(long *t); // Get the temperature reading that was taken in startTemperature() but ensure 4.5 ms time has elapsed
/** Start the pressure reading process but return after the commands are issued to BMP180
*
* This function is ment to start the pressure reading process but will return to allow other code to run then a reading could be made at a later time.
* Note the time needed for this reading pressure process will depend on oversample setting. The maximum time is 25.5 ms and minimum time is 4.5 ms.
*
* @param oversample is the method for reading sensor. OVERSAMPLING_ULTRA_HIGH_RESOLUTION is used if an incorrect value is passed to this function.
* @param returns 0 for no errors during i2c communication. Any other number is just a i2c communication failure of some kind!
*/
int startPressure(int oversample); // Start pressure measurement! Note oversample will vary the time to complete this measurement. See defines above for oversampling constants to use!
/** Reads the last barometric pressure reading that was started with startPressure() function
*
* This function will return the fully compensated value of the barometric pressure in Pa.
* Note this function should follow startPressure() after the time needed to read the pressure. This time will vary but maximum time is 25.5 ms and minimum time is 4.5 ms.
* Note that this reading is dependent on temperature so the startTemperature() and readTemperature() functions should proceed this function or the pressure value will be incorrect!
*
* @param p the barometric pressure fully compensated value is returned in this variable. Pressure is in Pa so 88007 is 88.007 kPa.
* @param returns 0 for no errors during i2c communication. Any other number is just a i2c communication failure of some kind!
*/
int readPressure(long *p); // Get the pressure reading that was taken in startPressure() but ensure time for the measurement to complete
protected:
long x1;
long x2;
long x3;
short ac1;
short ac2;
short ac3;
unsigned short ac4;
unsigned short ac5;
unsigned short ac6;
short b1;
short b2;
long b3;
unsigned long b4;
long b5;
long b6;
unsigned long b7;
short mb;
short mc;
short md;
int oversampling_setting;
char rReg[3];
char wReg[2];
char cmd;
char data[EEprom];
char w[2];
I2C bmp180i2c; // the I2C class for this bmp180 communication.
int oversampleCheck(int oversample);
};
#endif
\ No newline at end of file
http://developer.mbed.org/users/clemente/code/MPL3115A2/#82ac06669316
82ac06669316f85ebacbb6f76809094a3a856708 10
82ac06669316f85ebacbb6f76809094a3a856708 default
10 82ac06669316f85ebacbb6f76809094a3a856708
[paths]
default = http://developer.mbed.org/users/clemente/code/MPL3115A2/
revlogv1
fncache
store
dotencode
data/MPL3115A2.h.i
data/MPL3115A2.cpp.i
default
\ No newline at end of file
0
pull
http://developer.mbed.org/users/clemente/code/MPL3115A2/
syntax: regexp
\.hgignore$
\.git$
\.svn$
\.orig$
\.msub$
\.meta$
\.ctags
\.uvproj$
\.uvopt$
\.project$
\.cproject$
\.launch$
\.project$
\.cproject$
\.launch$
Makefile$
\.ewp$
\.eww$
\ No newline at end of file
#include "MPL3115A2.h"
#define REG_WHO_AM_I 0x0C // return 0xC4 by default
#define REG_STATUS 0x00
#define REG_CTRL_REG_1 0x26
#define REG_CTRL_REG_3 0x28
#define REG_CTRL_REG_4 0x29
#define REG_CTRL_REG_5 0x2A
#define REG_PRESSURE_MSB 0x01 // 3 byte pressure data
#define REG_ALTIMETER_MSB 0x01 // 3 byte altimeter data
#define REG_TEMP_MSB 0x04 // 2 byte temperature data
#define REG_PT_DATA_CFG 0x13
#define REG_P_TGT_MSB 0x16
#define REG_P_WND_MSB 0x19
#define REG_OFF_P 0x2b
#define REG_OFF_T 0x2c
#define REG_OFF_H 0x2d
#define REG_PRES_MIN_MSB 0x1c
#define REG_ALTI_MIN_MSB 0x1c
#define REG_TEMP_MIN_MSB 0x1f
#define REG_PRES_MAX_MSB 0x21
#define REG_ALTI_MAX_MSB 0x21
#define REG_TEMP_MAX_MSB 0x24
#define REG_PRES_DELTA_MSB 0x07
#define REG_ALTI_DELTA_MSB 0x07
#define REG_TEMP_DELTA_MSB 0x0a
#define UINT14_MAX 16383
// Status flag for data ready.
#define PTDR_STATUS 0x03 // Pressure Altitude and Temperature ready
#define PDR_STATUS 0x02 // Pressure and Altitude data ready
#define TDR_STATUS 0x01 // Temperature data ready
/** Interrupt schema
*
* :: The Altitude Trigger use the IRQ1.
*
* Altitude Trigger -- MPL3115A2_Int1.fall --- AltitudeTrg_IRQ --- MPL3115A2_usr1_fptr
*
*
* :: The Data ready use the IRQ2.
*
* Data Ready -- MPL3115A2_Int2.fall --- DataReady_IRQ --- MPL3115A2_usr2_fptr
*
*/
void (*MPL3115A2_usr2_fptr)(void); // Pointers to user function called after
void (*MPL3115A2_usr1_fptr)(void); // IRQ assertion.
//
InterruptIn MPL3115A2_Int1( PTD4); // INT1
InterruptIn MPL3115A2_Int2( PTA12); // INT2
MPL3115A2::MPL3115A2(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
unsigned char data[6];
MPL3115A2_mode = BAROMETRIC_MODE;
MPL3115A2_oversampling = OVERSAMPLE_RATIO_1;
//
MPL3115A2_usr1_fptr = NULL;
MPL3115A2_usr2_fptr = NULL;
MPL3115A2_Int1.fall( NULL);
MPL3115A2_Int2.fall( NULL);
Reset();
data[0]=REG_PRES_MIN_MSB;
data[1]=0;data[2]=0;data[3]=0;data[4]=0;data[5]=0;
writeRegs( &data[0], 6);
}
void MPL3115A2::Reset( void)
{
unsigned char t;
// soft reset...
readRegs( REG_CTRL_REG_1, &t, 1);
unsigned char data[2] = { REG_CTRL_REG_1, t|0x04};
writeRegs(data, 2);
wait( 0.1);
}
void MPL3115A2::DataReady( void(*fptr)(void), unsigned char OS)
{
unsigned char dt[5];
unsigned char data[2];
// Soft Reset
Reset();
Standby();
// Clear all interrupts by reading the output registers.
readRegs( REG_ALTIMETER_MSB, &dt[0], 5);
getStatus();
// Configure INT active low and pullup
data[0] = REG_CTRL_REG_3;
data[1] = 0x00;
writeRegs(data, 2);
// Enable Interrupt fot data ready
data[0] = REG_CTRL_REG_4;
data[1] = 0x80;
writeRegs(data, 2);
// Configure Interrupt to route to INT2
data[0] = REG_CTRL_REG_5;
data[1] = 0x00;
writeRegs(data, 2);
data[0] = REG_PT_DATA_CFG;
data[1] = 0x07;
writeRegs(data, 2);
// Configure the OverSampling rate, Altimeter/Barometer mode and set the sensor Active
data[0] = REG_CTRL_REG_1;
data[1] = (OS<<3);
//
if (MPL3115A2_mode == BAROMETRIC_MODE)
data[1] &= 0x7F;
else
data[1] |= 0x80;
//
data[1] |= 0x01;
writeRegs(data, 2);
MPL3115A2_usr2_fptr = fptr;
MPL3115A2_Int2.fall( this, &MPL3115A2::DataReady_IRQ);
}
void MPL3115A2::DataReady_IRQ( void)
{
// Clear the IRQ flag
getStatus();
// Run the user supplied function
MPL3115A2_usr2_fptr();
}
void MPL3115A2::AltitudeTrigger( void(*fptr)(void), unsigned short level)
{
unsigned char dt[5];
unsigned char data[2];
// Soft Reset
Reset();
// The device is on standby
Standby();
// Clear all interrupts by reading the output registers.
readRegs( REG_ALTIMETER_MSB, &dt[0], 5);
getStatus();
// Write Target and Window Values
dt[0] = REG_P_TGT_MSB;
dt[1] = (level>>8);
dt[2] = (level&0xFF);
writeRegs( dt, 3);
// Window values are zero
dt[0] = REG_P_WND_MSB;
dt[1] = 0;
dt[2] = 0;
writeRegs( dt, 3);
// Enable Pressure Threshold interrupt
data[0] = REG_CTRL_REG_4;
data[1] = 0x08;
writeRegs( data, 2);
// Interrupt is routed to INT1
data[0] = REG_CTRL_REG_5;
data[1] = 0x08;
writeRegs( data, 2);
data[0] = REG_PT_DATA_CFG;
data[1] = 0x07;
writeRegs(data, 2);
// Configure the OverSampling rate, Altimeter mode and set the sensor Active
data[0] = REG_CTRL_REG_1;
data[1] = 0x81 | (MPL3115A2_oversampling<<3);
writeRegs(data, 2);
MPL3115A2_usr1_fptr = fptr;
MPL3115A2_Int1.fall( this, &MPL3115A2::AltitudeTrg_IRQ);
}
void MPL3115A2::AltitudeTrg_IRQ( void)
{
// Clear the IRQ flag
getStatus();
// Run the user supplied function
MPL3115A2_usr1_fptr();
}
void MPL3115A2::Barometric_Mode( void)
{
unsigned char t;
unsigned char data[2];
Standby();
// soft reset...
Reset();
Standby();
readRegs( REG_CTRL_REG_1, &t, 1);
// Set the Barometric mode
data[0] = REG_CTRL_REG_1;
data[1] = t&0x7F;
writeRegs(data, 2);
data[0] = REG_PT_DATA_CFG;
data[1] = 0x07;
writeRegs(data, 2);
Oversample_Ratio( MPL3115A2_oversampling);
Active();
MPL3115A2_mode = BAROMETRIC_MODE;
}
void MPL3115A2::Altimeter_Mode( void)
{
unsigned char t;
unsigned char data[2];
Standby();
// soft reset...
Reset();
Standby();
readRegs( REG_CTRL_REG_1, &t, 1);
data[0] = REG_CTRL_REG_1;
data[1] = t|0x80;
writeRegs(data, 2);
data[0] = REG_PT_DATA_CFG;
data[1] = 0x07;
writeRegs(data, 2);
Oversample_Ratio( MPL3115A2_oversampling);
Active();
MPL3115A2_mode = ALTIMETER_MODE;
}
void MPL3115A2::Oversample_Ratio( unsigned int ratio)
{
unsigned char t;
Standby();
readRegs( REG_CTRL_REG_1, &t, 1);
t = t & 0xE7;
t = t | ( ratio<<3);
unsigned char data[2] = { REG_CTRL_REG_1, t};
writeRegs(data, 2);
Active();
MPL3115A2_oversampling = ratio;
}
void MPL3115A2::Active( void)
{
unsigned char t;
// Activate the peripheral
readRegs(REG_CTRL_REG_1, &t, 1);
unsigned char data[2] = {REG_CTRL_REG_1, t|0x01};
writeRegs(data, 2);
}
void MPL3115A2::Standby( void)
{
unsigned char t;
// Standby
readRegs(REG_CTRL_REG_1, &t, 1);
unsigned char data[2] = {REG_CTRL_REG_1, t&0xFE};
writeRegs(data, 2);
}
unsigned char MPL3115A2::getDeviceID() {
unsigned char device_id = 0;
readRegs(REG_WHO_AM_I, &device_id, 1);
return device_id;
}
unsigned int MPL3115A2::isDataAvailable( void)
{
unsigned char status;
readRegs( REG_STATUS, &status, 1);
return ((status>>1));
}
unsigned char MPL3115A2::getStatus( void)
{
unsigned char status;
readRegs( REG_STATUS, &status, 1);
return status;
}
unsigned int MPL3115A2::getAllData( float *f)
{
if ( isDataAvailable() & PTDR_STATUS) {
if ( MPL3115A2_mode == ALTIMETER_MODE) {
f[0] = getAltimeter( REG_ALTIMETER_MSB);
} else {
f[0] = getPressure( REG_PRESSURE_MSB);
}
f[1] = getTemperature( REG_TEMP_MSB);
//
return 1;
} else
return 0;
}
unsigned int MPL3115A2::getAllData( float *f, float *d)
{
if ( isDataAvailable() & PTDR_STATUS) {
if ( MPL3115A2_mode == ALTIMETER_MODE) {
f[0] = getAltimeter();
d[0] = getAltimeter( REG_ALTI_DELTA_MSB);
} else {
f[0] = getPressure();
d[0] = getPressure( REG_PRES_DELTA_MSB);
}
f[1] = getTemperature();
d[1] = getTemperature( REG_TEMP_DELTA_MSB);
//
return 1;
} else
return 0;
}
void MPL3115A2::getAllMaximumData( float *f)
{
if ( MPL3115A2_mode == ALTIMETER_MODE) {
f[0] = getAltimeter( REG_ALTI_MAX_MSB);
} else {
f[0] = getPressure( REG_PRES_MAX_MSB);
}
f[1] = getTemperature( REG_TEMP_MAX_MSB);
}
void MPL3115A2::getAllMinimumData( float *f)
{
if ( MPL3115A2_mode == ALTIMETER_MODE) {
f[0] = getAltimeter( REG_ALTI_MIN_MSB);
} else {
f[0] = getPressure( REG_PRES_MIN_MSB);
}
f[1] = getTemperature( REG_TEMP_MIN_MSB);
}
float MPL3115A2::getAltimeter( void)
{
float a;
a = getAltimeter( REG_ALTIMETER_MSB);
return a;
}
float MPL3115A2::getAltimeter( unsigned char reg)
{
unsigned char dt[3];
unsigned short altm;
short tmp;
float faltm;
/*
* dt[0] = Bits 12-19 of 20-bit real-time Altitude sample. (b7-b0)
* dt[1] = Bits 4-11 of 20-bit real-time Altitude sample. (b7-b0)
* dt[2] = Bits 0-3 of 20-bit real-time Altitude sample (b7-b4)
*/
readRegs( reg, &dt[0], 3);
altm = (dt[0]<<8) | dt[1];
//
if ( dt[0] > 0x7F) {
// negative number
tmp = ~altm + 1;
faltm = (float)tmp * -1.0f;
} else {
faltm = (float)altm * 1.0f;
}
//
faltm = faltm+((float)(dt[2]>>4) * 0.0625f);
return faltm;
}
float MPL3115A2::getPressure( void)
{
float a;
a = getPressure( REG_PRESSURE_MSB);
return a;
}
float MPL3115A2::getPressure( unsigned char reg)
{
unsigned char dt[3];
unsigned int prs;
int tmp;
float fprs;
/*
* dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0)
* dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0)
* dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4)
*/
readRegs( reg, &dt[0], 3);
prs = ((dt[0]<<10) | (dt[1]<<2) | (dt[2]>>6));
//
if ( dt[0] > 0x7f) {
// negative number
if ( dt[0] & 0x80)
prs |= 0xFFFC0000; // set at 1 the bits to complete the word len
else
prs |= 0xFFFE0000;
tmp = ~prs + 1; // make the complemets. At this point all the bits are inverted.
fprs = (float)tmp * -1.0f; // set the signe..
} else {
fprs = (float)prs * 1.0f;
}
if ( dt[2] & 0x10) // I did some experiment to set the fractional parte.
fprs += 0.25f; // ** Warning: the DS is wrong! **
if ( dt[2] & 0x20)
fprs += 0.5f;
return fprs;
}
float MPL3115A2::getTemperature( void)
{
float a;
a = getTemperature( REG_TEMP_MSB);
return a;
}
float MPL3115A2::getTemperature( unsigned char reg)
{
unsigned char dt[2];
unsigned short temp;
float ftemp;
/*
* dt[0] = Bits 4-11 of 16-bit real-time temperature sample. (b7-b0)
* dt[1] = Bits 0-3 of 16-bit real-time temperature sample. (b7-b4)
*/
readRegs( reg, &dt[0], 2);
temp = dt[0];
//
if ( dt[0] > 0x7F) {
temp = ~temp + 1;
ftemp = (float)temp * -1.0f;
} else {
ftemp = (float)temp * 1.0f;
}
//
ftemp = ftemp+((float)(dt[1]>>4) * 0.0625f);
return ftemp;
}
unsigned int MPL3115A2::getAllDataRaw( unsigned char *dt)
{
// Check for Press/Alti and Temp value ready
if ( isDataAvailable() & PTDR_STATUS) {
if ( MPL3115A2_mode == ALTIMETER_MODE) {
getAltimeterRaw( &dt[0]); // 3 bytes
} else {
getPressureRaw( &dt[0]); // 3 bytes
}
getTemperatureRaw( &dt[3]); // 2 bytes
return 1;
} else {
return 0;
}
}
unsigned int MPL3115A2::getAltimeterRaw( unsigned char *dt)
{
/*
* dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0)
* dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0)
* dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4)
*/
// Check for Press/Alti value ready
if ( isDataAvailable() & PDR_STATUS) {
readRegs( REG_ALTIMETER_MSB, &dt[0], 3);
return 1;
} else
return 0;
}
unsigned int MPL3115A2::getPressureRaw( unsigned char *dt)
{
/*
* dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0)
* dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0)
* dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4)
*/
// Check for Press/Alti value ready
if ( isDataAvailable() & PDR_STATUS) {
readRegs( REG_PRESSURE_MSB, &dt[0], 3);
return 1;
} else
return 0;
}
unsigned int MPL3115A2::getTemperatureRaw( unsigned char *dt)
{
/*
* dt[0] = Bits 4-11 of 16-bit real-time temperature sample. (b7-b0)
* dt[1] = Bits 0-3 of 16-bit real-time temperature sample. (b7-b4)
*/
// Check for Temp value ready
if ( isDataAvailable() & TDR_STATUS) {
readRegs( REG_TEMP_MSB, &dt[0], 2);
return 1;
} else
return 0;
}
void MPL3115A2::SetPressureOffset( char offset)
{
unsigned char data [2] = {REG_OFF_P, offset};
Standby();
writeRegs(data,2);
Active();
}
void MPL3115A2::SetTemperatureOffset( char offset)
{
unsigned char data [2] = {REG_OFF_T, offset};
Standby();
writeRegs(data,2);
Active();
}
void MPL3115A2::SetAltitudeOffset( char offset)
{
unsigned char data [2] = {REG_OFF_H, offset};
Standby();
writeRegs(data,2);
Active();
}
void MPL3115A2::readRegs(int addr, uint8_t * data, int len) {
char t[1] = {addr};
m_i2c.write(m_addr, t, 1, true);
m_i2c.read(m_addr, (char *)data, len);
}
void MPL3115A2::writeRegs(uint8_t * data, int len) {
m_i2c.write(m_addr, (char *)data, len);
}
#ifndef MPL3115A2_H
#define MPL3115A2_H
#include "mbed.h"
// Oversampling value and minimum time between sample
#define OVERSAMPLE_RATIO_1 0 // 6 ms
#define OVERSAMPLE_RATIO_2 1 // 10 ms
#define OVERSAMPLE_RATIO_4 2 // 18 ms
#define OVERSAMPLE_RATIO_8 3 // 34 ms
#define OVERSAMPLE_RATIO_16 4 // 66 ms
#define OVERSAMPLE_RATIO_32 5 // 130 ms
#define OVERSAMPLE_RATIO_64 6 // 258 ms
#define OVERSAMPLE_RATIO_128 7 // 512 ms
/* Mode */
#define ALTIMETER_MODE 1
#define BAROMETRIC_MODE 2
/**
* MPL3115A2 Altimeter example
*
* @code
* #include "mbed.h"
* #include "MPL3115A2.h"
*
* #define MPL3115A2_I2C_ADDRESS (0x60<<1)
* MPL3115A2 wigo_sensor1(PTE0, PTE1, MPL3115A2_I2C_ADDRESS);
* Serial pc(USBTX, USBRX);
*
* // pos [0] = altitude or pressure value
* // pos [1] = temperature value
* float sensor_data[2];
*
* int main(void) {
*
* pc.baud( 230400);
* pc.printf("MPL3115A2 Altimeter mode. [%d]\r\n", wigo_sensor1.getDeviceID());
*
* wigo_sensor1.Oversample_Ratio( OVERSAMPLE_RATIO_32);
*
* while(1) {
* //
* if ( wigo_sensor1.isDataAvailable()) {
* wigo_sensor1.getAllData( &sensor_data[0]);
* pc.printf("\tAltitude: %f\tTemperature: %f\r\n", sensor_data[0], sensor_data[1]);
* }
* //
* wait( 0.001);
* }
*
* }
* @endcode
*/
class MPL3115A2
{
public:
/**
* MPL3115A2 constructor
*
* @param sda SDA pin
* @param sdl SCL pin
* @param addr addr of the I2C peripheral
*/
MPL3115A2(PinName sda, PinName scl, int addr);
/**
* Get the value of the WHO_AM_I register
*
* @returns DEVICE_ID value == 0xC4
*/
uint8_t getDeviceID();
/**
* Return the STATUS register value
*
* @returns STATUS register value
*/
unsigned char getStatus( void);
/**
* Get the altimeter value
*
* @returns altimeter value as float
*/
float getAltimeter( void);
/**
* Get the altimeter value in raw mode
*
* @param dt pointer to unsigned char array
* @returns 1 if data are available, 0 if not.
*/
unsigned int getAltimeterRaw( unsigned char *dt);
/**
* Get the pressure value
*
* @returns pressure value as float
*/
float getPressure( void);
/**
* Get the pressure value in raw mode
*
* @param dt pointer to unsigned char array
* @returns 1 if data are available, 0 if not.
*/
unsigned int getPressureRaw( unsigned char *dt);
/**
* Get the temperature value
*
* @returns temperature value as float
*/
float getTemperature( void);
/**
* Get the temperature value in raw mode
*
* @param dt pointer to unsigned char array
* @returns 1 if data are available, 0 if not.
*/
unsigned int getTemperatureRaw( unsigned char *dt);
/**
* Set the Altimeter Mode
*
* @returns none
*/
void Altimeter_Mode( void);
/**
* Set the Barometric Mode
*
* @returns none
*/
void Barometric_Mode( void);
/**
* Get the altimeter or pressure and temperature values
*
* @param array of float f[2]
* @returns 0 no data available, 1 for data available
*/
unsigned int getAllData( float *f);
/**
* Get the altimeter or pressure and temperature values and the delta values
*
* @param array of float f[2], array of float d[2]
* @returns 0 no data available, 1 for data available
*/
unsigned int getAllData( float *f, float *d);
/**
* Get the altimeter or pressure and temperature captured maximum value
*
* @param array of float f[2]
* @returns 0 no data available, 1 for data available
*/
void getAllMaximumData( float *f);
/**
* Get the altimeter or pressure and temperature captured minimum value
*
* @param array of float f[2]
* @returns 0 no data available, 1 for data available
*/
void getAllMinimumData( float *f);
/**
* Get the altimeter or pressure, and temperature values in raw mode
*
* @param array of unsigned char[5]
* @returns 1 if data are available, 0 if not.
*/
unsigned int getAllDataRaw( unsigned char *dt);
/**
* Return if there are date available
*
* @return 0 for no data available, bit0 set for Temp data available, bit1 set for Press/Alti data available
* bit2 set for both Temp and Press/Alti data available
*/
unsigned int isDataAvailable( void);
/**
* Set the oversampling rate value
*
* @param oversampling values. See MPL3115A2.h
* @return none
*/
void Oversample_Ratio( unsigned int ratio);
/**
* Configure the sensor to streaming data using Interrupt
*
* @param user functin callback, oversampling values. See MPL3115A2.h
* @return none
*/
void DataReady( void(*fptr)(void), unsigned char OS);
/**
* Configure the sensor to generate an Interrupt crossing the center threshold
*
* @param user functin callback, level in meter
* @return none
*/
void AltitudeTrigger( void(*fptr)(void), unsigned short level);
/**
* Soft Reset
*
* @param none
* @return none
*/
void Reset( void);
/**
* Configure the Pressure offset.
* Pressure user accessible offset trim value expressed as an 8-bit 2's complement number.
* The user offset registers may be adjusted to enhance accuracy and optimize the system performance.
* Range is from -512 to +508 Pa, 4 Pa per LSB.
* In RAW output mode no scaling or offsets will be applied in the digital domain
*
* @param offset
* @return none
*/
void SetPressureOffset( char offset);
/**
* Configure the Temperature offset.
* Temperature user accessible offset trim value expressed as an 8-bit 2's complement number.
* The user offset registers may be adjusted to enhance accuracy and optimize the system performance.
* Range is from -8 to +7.9375°C 0.0625°C per LSB.
* In RAW output mode no scaling or offsets will be applied in the digital domain
*
* @param offset
* @return none
*/
void SetTemperatureOffset( char offset);
/**
* Configure the Altitude offset.
* Altitude Data User Offset Register (OFF_H) is expressed as a 2’s complement number in meters.
* The user offset register provides user adjustment to the vertical height of the Altitude output.
* The range of values are from -128 to +127 meters.
* In RAW output mode no scaling or offsets will be applied in the digital domain
*
* @param offset
* @return none
*/
void SetAltitudeOffset( char offset);
private:
I2C m_i2c;
int m_addr;
unsigned char MPL3115A2_mode;
unsigned char MPL3115A2_oversampling;
void DataReady_IRQ( void);
void AltitudeTrg_IRQ( void);
/** Set the device in active mode
*/
void Active( void);
/** Set the device in standby mode
*/
void Standby( void);
/** Get the altimiter value from the sensor.
*
* @param reg the register from which read the data.
* Can be: REG_ALTIMETER_MSB for altimeter value
* REG_ALTI_MIN_MSB for the minimum value captured
* REG_ALTI_MAX_MSB for the maximum value captured
*/
float getAltimeter( unsigned char reg);
/** Get the pressure value from the sensor.
*
* @param reg the register from which read the data.
* Can be: REG_PRESSURE_MSB for altimeter value
* REG_PRES_MIN_MSB for the minimum value captured
* REG_PRES_MAX_MSB for the maximum value captured
*/
float getPressure( unsigned char reg);
/** Get the altimiter value from the sensor.
*
* @param reg the register from which read the data.
* Can be: REG_TEMP_MSB for altimeter value
* REG_TEMP_MIN_MSB for the minimum value captured
* REG_TEMP_MAX_MSB for the maximum value captured
*/
float getTemperature( unsigned char reg);
void readRegs(int addr, uint8_t * data, int len);
void writeRegs(uint8_t * data, int len);
};
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
:020000040800F2
:1000000000800120C1130008151400081514000811
:10001000151400081514000815140008000000004D
:10002000000000000000000000000000A11B00080C
:100030001514000800000000351C0008951C00087D
:1000400015140008151400081514000815140008EC
:1000500015140008151400081514000815140008DC
:1000600015140008151400081514000815140008CC
:1000700015140008151400081514000815140008BC
:1000800015140008151400081514000800000000DD
:10009000000000000000000000000000151400082F
:1000A000151400081514000815140008151400088C
:1000B000151400081514000815140008151400087C
:1000C000151400081514000815140008151400086C
:1000D000151400081514000815140008000000008D
:1000E000151400081514000815140008000000007D
:1000F00000000000000000000000000015140008CF
:10010000000000001514000815140008151400085C
:1001100000000000000000000000000000000000DF
:10012000151400081514000815140008151400080B
:10013000151400080000000000000000000000008E
:10014000000000000000000000000000151400087E
:1001500015140008151400081514000815140008DB
:10016000151400081514000800000000000000002D
:10017000000000000000000000000000000000007F
:10018000000000001514000800000000000000003E
:100190001514000810B5054C237833B9044B13B17E
:1001A0000448AFF300800123237010BDA00200209B
:1001B0000000000068410008084B10B51BB108485A
:1001C0000849AFF300800848036803B910BD074B26
:1001D000002BFBD0BDE81040184700BF0000000016
:1001E00068410008A40200209C02002000000000DA
:1001F000154B002B08BF134B9D46A3F5803A0021F9
:100200008B460F461348144A121A02F045FF0F4B53
:10021000002B00D098470E4B002B00D098470020B1
:10022000002104000D000D48002802D00C4802F007
:10023000C6FC02F093FE2000290001F091F802F0C4
:10024000CBFC00BF0000080000800120000000007F
:1002500055140008A0020020E0100020BF2B000869
:10026000D52E0008F8B50368DE07044635D5984A50
:10027000916801F00C01042900F0F980916801F007
:100280000C01082900F0EF80924B914D00221A706A
:1002900000F050FB064606E000F04CFB801BB0F57A
:1002A000FA7F00F2C0802B689903F5D4894B22793C
:1002B0001A706368012B00F05F8100F03BFB844DF6
:1002C000064606E000F036FB801BB0F5FA7F00F230
:1002D000AA802B689B03F5D423689F072FD57C4AFF
:1002E000916811F00C0F00F0A480916801F00C01EE
:1002F000082900F09A80E368002B00F0D380764B49
:10030000734D01221A6000F015FB064605E000F06F
:1003100011FB801B642800F286802B686C4A9807CA
:10032000F5D51168F82090FAA0F0B0FA80F02369B2
:10033000C0B221F0F80183400B43136023681A0711
:1003400020D4590734D4A369D3B1614DAA6802F00F
:100350000C02082A00F09480022B604B4FF0000240
:100360001A6000F0B08000F0E5FA2C46054604E083
:1003700000F0E0FA401B642855D823689B01F7D4AD
:100380000020F8BD6369002B7CD0554B504D0122F5
:100390001A6000F0CFFA064604E000F0CBFA801BAA
:1003A000642840D86B6F9F07F7D523685907CAD5D3
:1003B000474B4C4D1A6C42F080521A642B6843F440
:1003C00080732B6000F0B6FA064604E000F0B2FA43
:1003D000801B642827D82B68DA05F7D5424B3C4DA3
:1003E00000221A7000F0A6FA064605E000F0A2FA14
:1003F000801BB0F5167F16D82B6F9B07F6D43A4BAF
:10040000227A1A70A368012B00F0C68000F092FADD
:100410002F4D06462B6F980795D500F08BFA801B61
:10042000B0F5167FF6D90320F8BD526856023FF5A5
:1004300062AF274A1268950702D5E268012A1FD1E8
:10044000234AF825106895FAA5F5B5FA85F52269CD
:100450001F49EDB220F0F800AA4002430A601A07D3
:100460007FF56FAF8EE7526855027FF50DAF184AE2
:10047000126890037FF531AF6268012A3FF42DAF17
:100480000120F8BD164A124D136000F053FA0646DB
:1004900004E000F04FFA801B6428C4D86B6F980703
:1004A000F7D482E70C4A0A4D136000F043FA06467F
:1004B00004E000F03FFA801B6428B4D82B68990749
:1004C000F7D423683BE700F035FA064613E000BF97
:1004D00000380240023802400000474260004742B4
:1004E000800E4742007000407038024000F022FA4F
:1004F000801B642897D82B689901F7D447F6C075FC
:1005000095FAA5F5B5FA85F54FF4403191FAA1F1C8
:10051000B1FA81F14FF0706292FAA2F2B2FA82F26D
:10052000D4F820C0E769A66AD4F824E0E06A224B38
:10053000224C4CEA0707EDB276080EFA05F5C9B26F
:1005400047F00057013E3D43D2B206FA01F100FAEE
:1005500002F229431143012261601A6000F0EAF9B6
:10056000054605E000F0E6F9401B64283FF65BAF66
:1005700023689A01F6D503E700F0DCF90F4D064633
:1005800006E000F0D7F9801BB0F5FA7F3FF64BAFDD
:100590002B689A03F5D59FE600F0CCF9074D064687
:1005A0002B6F9F073FF5CFAE00F0C4F9801BB0F56D
:1005B000167FF5D937E700BF600047420038024098
:1005C000694B1A6802F00F028A422DE9F0410C468D
:1005D000054609D2CAB21A701B6803F00F038B429A
:1005E00055D00120BDE8F08103689A0706D55F4A1F
:1005F0008168906820F0F00001439160DF0724D506
:100600006B685A4A012B126800F08780022B00F0B9
:100610008B809107E5D5554FBA6822F0030213434A
:10062000BB6000F087F96B68012B064641F2883801
:1006300062D0022B05D16AE000F07CF9801B4045B6
:100640006FD8BB6813F00C0FF6D1474BE2B21A70AB
:100650001B6803F00F03A342C3D12B685A0706D5CA
:10066000424AE968906820F4E050014391601B071A
:1006700007D53E4B29699A6822F4604242EAC102DA
:100680009A600F2000F084F90020BDE8F081036833
:100690009F0706D5354A8168906820F0F000014335
:1006A0009160DE07DAD56B68304A012B126858D0AA
:1006B000022B53D0910794D52C4EB26822F003023E
:1006C0001343B36000F036F96B68012B044641F226
:1006D000883732D0022B05D13AE000F02BF9001B0D
:1006E000B8421ED8B36813F00C0FF6D1B5E700F08E
:1006F00021F9801B404514D8BB6803F00C03042B80
:10070000F5D1A2E700F016F9801B404509D8BB6877
:1007100003F00C03082BF5D197E796033FF57BAF69
:100720005FE70320BDE8F08190013FF574AF58E723
:1007300000F000F9001BB842F3D8B36803F00C03D3
:10074000042BF5D189E700F0F5F8001BB842E8D892
:10075000B36803F00C03082BF5D17EE79001ABD40E
:100760003FE79403A8D43CE7003C02400038024035
:10077000234B9A6802F00C02042A10B43CD0082AD9
:1007800003D020485DF8044B704758685A6800F061
:100790003F014FF4800393FAA3F3B3FA83F302F417
:1007A0008002DBB232FA03F3154B47F6C0725C6885
:1007B00092FAA2F2B2FA82F247F6C07314BF12485C
:1007C0001048D2B22340D3400D4AB0FBF1F000FBF9
:1007D00003F052684FF4403393FAA3F3B3FA83F370
:1007E00002F44032DBB222FA03F301335B00B0FBC8
:1007F000F3F05DF8044B704703485DF8044B704715
:10080000003802400024F40000127A0008B5FFF717
:10081000AFFF094BF0229B6892FAA2F2B2FA82F281
:1008200003F0F003D2B223FA02F20449044B8A5CCB
:10083000D040186008BD00BF00380240BC3C000832
:100840009401002008B5FFF7E1FF084A4FF4E05398
:10085000926893FAA3F3B3FA83F302F4E052DBB2A3
:1008600022FA03F3024AD35CD84008BD00380240A4
:10087000BC3C000808B5FFF7C9FF084A4FF46043C5
:10088000926893FAA3F3B3FA83F302F46042DBB203
:1008900022FA03F3024AD35CD84008BD0038024074
:1008A000BC3C00080F4A30B493689468B4F1006F00
:1008B0001A4604D0103030BC42F8201070470A4A63
:1008C00003F5CA7553F8044B42F8044FAB42F9D113
:1008D0004FF00052034B10309A6030BC42F82010A9
:1008E000704700BF00ED00E0FCFFFF1F704700BF36
:1008F00008B50B4B1A6842F400721A601A6842F489
:1009000080621A601A6842F480721A60032000F054
:10091000E5FB0F2000F03CF8FFF7E8FF002008BDE2
:10092000003C0240024B1A6801321A60704700BF57
:10093000BC020020014B1868704700BFBC020020B9
:1009400070B5114C2368DA68910715D4DA6852073C
:1009500009D56FF004020D4E1A615D6A3368EB1A17
:10096000B3F57A7F00D270BDFFF7DCFF23683560F6
:1009700005F57A759D6370BD6FF002021A6101F092
:1009800091FF2368E2E700BF48100020C00200206A
:1009900038B5204B204C1A6C42F008021A641A6ACF
:1009A00042F008021A621A6A22F008021A6200F083
:1009B00087F91A4A1A4B12681A492160A3FB0212DE
:1009C000920C0025013A4FF0FF3320466260E3604D
:1009D0002561A560656100F005FC32201249FFF732
:1009E00061FF124B4FF480225A602946204600F0E6
:1009F00089FB2046042100F085FB23680C495A6AD4
:100A00000A6002F57A729A63DA6842F004022846B4
:100A1000DA6038BD00380240481000209401002000
:100A200083DE1B43000C00404109000800E100E0A8
:100A3000C00200202DE9F00F82B00F68DFF85CC221
:100A40008F4E0197002303E00133102B00F0BC8090
:100A50000122019D9A4002EA05049442F4D14A68B9
:100A600022F01009B9F1020F6CD05D004FF00308BD
:100A7000D0F800B008FA05F86FEA080802F0030A97
:100A800008EA0B0B0AFA05FA09F1FF394BEA0A0AE0
:100A9000B9F1010FC0F800A07ED9D0F80C908F6892
:100AA00008EA090807FA05F548EA0505C560D50012
:100AB000CAD5DCF84480734F23F0030505F1804567
:100AC00048F4804805F59C35CCF8448003F00308D1
:100AD000D5F808A04FEA88084FF00F0909FA08F97D
:100AE000B8422AEA090973D007F58067B84200F0D6
:100AF0009E80654FB84200F09F80644FB84200F07E
:100B0000A080634FB84200F0A180624FB84200F06D
:100B1000A780614FB84200F0A880DFF884A150455B
:100B200000F09980DFF87CA1504500F0A380DFF849
:100B300078A150450CBF4FF0090A4FF00A0A0AFA93
:100B400008F847E04FEAD30800EB880803F00709EC
:100B5000D8F820704FEA89094FF00F0A0AFA09FA0B
:100B600027EA0A0A0F6907FA09F94AEA0905C8F8E3
:100B700020505D004FF00308D0F800A008FA05F8F7
:100B80006FEA080802F0030908EA0A0A09FA05F9F7
:100B90004AEA0909C0F80090D0F80890CF6808EA3E
:100BA000090907FA05FA49EA0A09C0F80890D0F8D5
:100BB00004A0C2F300192AEA040A09FA03F94AEA6E
:100BC0000909C0F8049068E702B0BDE8F00F70476B
:100BD0004FF0000848EA0908C5F80880D6F80080F8
:100BE000E543D7034CBF44EA080805EA0808C6F8FD
:100BF0000080D6F8048097034CBF44EA080805EA51
:100C00000808C6F80480D6F80880D7024CBF44EA2A
:100C1000080805EA0808C6F80880D6F80C80920291
:100C200054BF05EA080444EA0804F4600CE74FF0F6
:100C3000010A0AFA08F8CDE74FF0020A0AFA08F8A2
:100C4000C8E74FF0030A0AFA08F8C3E74FF0040AAE
:100C50000AFA08F8BEE74FF0070A0AFA08F8B9E7F7
:100C60004FF0050A0AFA08F8B4E74FF0060A0AFA44
:100C700008F8AFE74FF0080A0AFA08F8AAE700BF39
:100C8000003C01400000024000080240000C02400D
:100C900000100240001402400018024000380240D8
:100CA000001C0240002002400024024008B572B639
:100CB000962001F027FE962001F024FEF8E700BF01
:100CC000164B9A6802F00C02042A24D0082A0AD093
:100CD000134A124B13489968134BC1F30311415C3B
:100CE000CA401A607047586859685B6842024CBF36
:100CF0000E4A0B4A01F03F01C3F38813B2FBF1F235
:100D000002FB03F2054B5B68C3F3014301335B0055
:100D1000B2FBF3F2DDE7054ADBE700BF0038024033
:100D20000024F400CC3C00089401002000127A005A
:100D30001E4A1F4B116C70B541F080511164196847
:100D400092B021F4404141F4004101221960069221
:100D5000B0B9079207234FF4A871042202244FF47C
:100D60008006082506A811930C940D960E950F91F8
:100D70001092FFF777FA034628B1002012B070BD39
:100D800005230793E6E74FF4805221460F2501A87B
:100D900002940393059301950492FFF711FCD0F19F
:100DA000010038BF002012B070BD00BF0038024003
:100DB000007000401E4A1F4B116CF0B541F080518D
:100DC00011641A6822F4404293B042F400421A605F
:100DD0004FF0030E102300240421072201270225CF
:100DE0004FF4A87606A80A930E93CDF818E0099759
:100DF00007940D940C950F9610911192FFF732FA0B
:100E0000034610B1204613B0F0BD4FF4805229467E
:100E10000F2401A802950393059301940492FFF710
:100E2000CFFBD0F1010038BF002013B0F0BD00BFF0
:100E3000003802400070004008B50120FFF778FF3D
:100E400000B108BDFFF774FF0028FAD1FFF7B2FF29
:100E50000028F6D1FEE700BF174B1848D3F88820CA
:100E600070B542F47002164CC3F888202268154E03
:100E7000154D002142F001022260A160226822F09B
:100E8000847222F480322260666026684FF000622D
:100E900026F480262660E1609A600560FFF728FD51
:100EA000FFF7CAFF236A43F008032362236A23F093
:100EB0000803236270BD00BF00ED00E09401002034
:100EC00000380240103000240024F4002DE9F041E5
:100ED0000568C1682B69C269D0F810E08768466967
:100EE00023F440531943044680692961EB684EEAB4
:100EF000070123F41643314323F00C0311430B4342
:100F0000EB606B6923F440730343B2F5004F6B61F0
:100F1000594B3CD09D4200F08C8003F580639D428C
:100F200000F08780FFF78EFC6368544E00EB800072
:100F30009B0000EB8000B0FBF3F7FFF783FC6368D6
:100F400000EB80009B0000EB8000B0FBF3F8FFF7A4
:100F500079FC636800EB800000EB80009B00B0FB35
:100F6000F3F3A6FB0727A6FB03237F095B09642095
:100F70003F0100FB13884FEA081808F13208A6FB6E
:100F80000836C6F343163743AF60BDE8F0819D4293
:100F90002DD003F580639D4229D0FFF753FC636891
:100FA000364E00EB80005B0000EB8000B0FBF3F7F7
:100FB000FFF748FC636800EB80005B0000EB8000FB
:100FC000B0FBF3F8FFF73EFCA6FB072763687F0939
:100FD00000EB80003F0100EB80005B00B0FBF3F30F
:100FE000A6FB03235B09642202FB1388C3E7FFF718
:100FF00041FC6368214E00EB80005B0000EB800049
:10100000B0FBF3F7FFF736FC636800EB80005B0092
:1010100000EB8000B0FBF3F8FFF72CFCA6FB0727E2
:1010200063687F0900EB80003F0100EB80005B00FC
:10103000D4E7FFF71FFC6368104E00EB80009B00B5
:1010400000EB8000B0FBF3F7FFF714FC636800EBE4
:1010500080009B0000EB8000B0FBF3F8FFF70AFC78
:10106000A6FB072763687F0900EB80003F0100EBC8
:1010700080009B00B2E700BF001001401F85EB51CC
:10108000704700BF10B5044628B390F83930FBB163
:101090002368022284F83920DA6822F40052DA60E8
:1010A0002046FFF713FF23681A6922F490421A6161
:1010B0005A6922F02A025A61D868002240F400508E
:1010C0000121D86084F83A20104684F8391010BD08
:1010D000FFF7D6FFDCE7012010BD00BF074AD1684B
:1010E0004FF6FF030B4043F0BF6300F0070043F4EB
:1010F000003343EA0023D360704700BF00ED00E0F7
:10110000704700BF03680E4A186A10B4012404FA3D
:1011100001F120EA01001862186A934241EA0001D5
:10112000196207D01A685DF8044B42F001020020F2
:101130001A6070475A6C42F400425A64F2E700BFEA
:1011400000000140264A0368904230B434D0B0F128
:10115000804F20D0A2F57C4290421CD002F58062E4
:10116000904218D002F58062904214D002F59A3273
:10117000904214D002F58062904210D002F5806255
:1011800090420CD08C680A6803600123C4628262BA
:1011900030BC436170474A6823F070031343CD6845
:1011A0008C680A6823F440732B4303600123C462F4
:1011B000826230BC436170474C68CA6823F0700398
:1011C0001C4324F44074224302608B68C3620B68A2
:1011D00083620B6903630123436130BC704700BF26
:1011E0000000014010B5044690B190F8393063B169
:1011F0002146022351F8040B84F83930FFF7A2FF8F
:10120000012384F83930002010BDFFF779FFEFE7A4
:10121000012010BD02480221032201F011BA00BFD3
:10122000C0100020022808B50BDDC21E074B53F882
:101230002200002143F8221028B103685B68984718
:1012400008BD002008BD4FF0FF3008BDC4020020DB
:10125000022870B50C4616460FDC0E4B1B680BB906
:10126000FFF7D8FFA51936B114F8011B0A4801F0A1
:1012700073FAAC42F8D1304670BD0338074B53F8CF
:10128000200018B103681B68984770BD4FF0FF300D
:1012900070BD00BF600F0020C0100020C4020020FD
:1012A000022810B50C4609DC0D4B1B688BB10D48AC
:1012B00001F046FA01232070184610BD03380A4B8E
:1012C00053F8200040B103689B68984703461846CE
:1012D00010BDFFF79FFFEAE74FF0FF33ECE700BFD9
:1012E000600F0020C0100020C4020020022808B5B2
:1012F00008DD0338064B53F8200028B10368DB688B
:10130000984708BD012008BD4FF0FF3008BD00BF61
:10131000C4020020022808B508DD0338064B53F844
:10132000200028B103681B69984708BD002008BD4C
:101330004FF0FF3008BD00BFC4020020022808B5EE
:1013400004D84FF400534B60002008BD01F03EFC70
:10135000092303604FF0FF3008BD00BF704700BF96
:1013600008B500F059F8FFF7F9FFBDE8084000F0B4
:101370001FBB00BF074A13681844EFF30881884277
:1013800002D2106018467047034B0C221A604FF0CF
:10139000FF30704798010020DC100020074C08B592
:1013A00023680546986801F0D9FC2368D86801F0E5
:1013B000D5FC05B9FEE7FFF779FCFBE78C020020BE
:1013C000DFF838D0002100F004B80D4B5B584350D3
:1013D00004310C480C4B42189A42FFF4F6AF0B4A0A
:1013E00000F003B8002342F8043B094B9A42FFF493
:1013F000F9AFFFF731FDFEF7FBFE704700800120DB
:101400007441000894010020A0020020A0020020E6
:10141000E0100020FFF7FEBF08B5FFF751FCBDE864
:101420000840FFF765BA00BFFEE7FFF73FBC08B111
:10143000FFF73CBC704700000449054AC1F1005366
:1014400003F5BE339360D160704700BFE010002009
:101450009C0100200020002104460D46094801F0AF
:10146000AEFB01F07BFD2046294600F0E9FEFFF7C8
:10147000E3FF0548002100F07FFF00F0F5FE01F0DA
:10148000ABFB0000D52E00089C010020034B00227E
:101490001A60034A1268DA80704700BFAC0E002061
:1014A000EC3C000808B5104B10485A68104B1968FE
:1014B00091421FBF1A60DA8802F1FF3102681CBF37
:1014C00052189A809A8803889A420BD1084B064892
:1014D00000221A6000F00EFCBDE8084001460248F8
:1014E00000F0F0BB08BD00BF3C0F0020200F002023
:1014F000AC0E0020054B1B7823B9054B4FF08052F2
:101500001A607047034B01221A707047B90E002011
:1015100004ED00E0B80E002038B5194B194D1A68DB
:1015200001215170186800F0F7FB6C78AA78154B10
:10153000EAB103EBC403586802781AB9198900F0BC
:1015400071FA07E0012A03D1996800F049FD01E032
:1015500000F0DAFAEB7801349C4208BF0024EFF384
:10156000108372B6AB78013BAB7062B6DEE75C709D
:10157000054800F0BFFBBDE8384000F08DB800BF63
:10158000BC0E0020C40B00203C0F0020084B1A6842
:10159000084B1A6000225A60072243F8042C064ABE
:1015A000136843F07F4313604FF0FF30704700BF74
:1015B000E83C000814E000E020ED00E07047000087
:1015C00008B50C4B1A6801215170186800F0A4FB93
:1015D000FFF768FF084A13680133136000F0CCFB83
:1015E00000F018FF054800F085FBBDE8084000F05A
:1015F00053B800BFBC0E0020200F00203C0F00207D
:10160000084B1B68DA78012A0AD0DA6A9B6A9A4288
:1016100003D81268044B9A4202D00120FFF705BF9D
:10162000704700BFBC0E0020A52E5AE208B5044842
:1016300000F060FB034B58600223437008BD00BFFD
:101640003C0F0020BC0E0020064B1A88064B0120E0
:10165000904204D853F8041F11B10130F8E700207C
:10166000704700BFDC3C0008440C002030B500246B
:10167000012504704570817044608460C460046119
:101680008482C4820483448380F820401146BDE8EC
:10169000304000F013BD0000024B5860022343703D
:1016A000704700BFBC0E002070B5044618B9BDE8F5
:1016B0007040FFF7BBBF0B4DA278286883789A4231
:1016C0004FF0010607D900F027FB2B685E7002235C
:1016D0006C60637070BD667021460348BDE8704061
:1016E00000F0F0BABC0E00203C0F002038B50D46CB
:1016F000014678B14FF6FF739842074C02D020683C
:1017000000F014FB236805485D7000F0F3FA022333
:101710006060437038BD00BFBC0E00203C0F00204D
:10172000024B186800B1C078704700BFBC0E0020A3
:1017300010B588B9174B1B689970174843689B7898
:101740008B4222D9134C216800F0BCFA2368012295
:101750005A70FFF76BFF18E0104B1B88984216D8A1
:1017600001380F4B53F820408CB10A4BA1701B6815
:101770009C42E2D0204600F051FB6378012B04D15B
:10178000054800F0B7FAFFF78FFF002010BDFF20DB
:1017900010BD00BFBC0E00203C0F0020DC3C000848
:1017A000480C002070B5184D18B12B68DB789842B2
:1017B00014D12B6800245C702E6800F0C6F9B0626A
:1017C000FFF71EFF2A681149D3782C60013B41F8CE
:1017D0002340D462FFF72AFF204670BD0C4B1B88C4
:1017E00098420FD8441E094E56F8245055B1284649
:1017F00000F0FEFA284600F02BFB002046F82400FB
:10180000E86270BDFF2070BDBC0E0020480C0020B7
:10181000DC3C000810B5284B1A880023934205D2FF
:101820002649002041F823000133F7E7244C254ADC
:10183000FF23E370244B1B8863622046234BE36243
:101840000021FFF713FF224A002304211170536087
:10185000204A1170D360136193821F4A14600222E0
:1018600062701E4A137053701D4B1B78D370FFF7C4
:101870000DFE1C4B1A6842F47F021A601B681B02A3
:1018800003F07F43DB43B3FA83F3174A1748126828
:10189000DBB2C3F10803C2F302229A42A8BF531C71
:1018A0006FF08071026801FA03F303F07F4122F0C8
:1018B0007F430B43036010BDDC3C0008480C002054
:1018C000C40E002029140008E43C0008A40C0020E9
:1018D0003C0F0020240F0020BC0E0020C40B002071
:1018E000E63C000820ED00E00CED00E01CED00E01F
:1018F00008B5FFF74BFE0C4B0028186012DB00F117
:10190000604000F56440FF2202701A6853119B008A
:1019100003F1604303F5614302F01F02012101FA64
:1019200002F21A6008BD00BFB40E002010B590F995
:1019300000300133044604D1064807493F2200F035
:1019400017FFA3681A6863681A4214BF01200020B9
:1019500010BD00BFF03C0008083D000838B590F904
:101960000030013304460D4604D1064806493522AD
:1019700000F0FEFE63680DB1E26800E022699BB2F0
:10198000138038BDF03C0008083D000808B5074842
:10199000FFF7CCFFB0FA80F104484909FFF7DEFFFA
:1019A0004FF47A7000F0ADF8F1E700BF0C0F0020A3
:1019B00000B597B04FF4006300220093019202A893
:1019C0000849134600F058F80748FFF7AFFFB0FA90
:1019D00080F105484909FFF7C1FF4FF4FA7000F0A4
:1019E00090F8F1E78D190008F80E002038B50B4C7F
:1019F00014252A462046002101F04EFB2046084CC3
:101A0000002100F0DDFE204600212A4601F044FBC3
:101A100020460121BDE8384000F0D2BEF80E00207B
:101A20000C0F002010B5038B42781943062A044698
:101A30000183438B04D101EA03029A4219D105E0E4
:101A4000052A16D111EA030213D0428321EA0301C9
:101A50002183204600F0FCF9012320466370082111
:101A6000628B00F05CFB21460248BDE8104000F0AC
:101A700029B910BD3C0F002070B5059D04461646DF
:101A800004980F4A2260A160A381206115B16561AD
:101A900000230AE08008B0F1FE5F94BF80004FF0A1
:101AA000FF3001F083F80123606184F84C3004F1C9
:101AB0000800314600F060FC6060204670BD00BF49
:101AC000783D0008406800F075BC000010B5074B79
:101AD00003600446FFF7F6FF94F84C301BB16069D1
:101AE00008B101F061F8204610BD00BF783D000844
:101AF00010B50446FFF7EAFF204601F04AF82046F9
:101B000010BD00F06DBC000010B542687AB100F065
:101B1000F1F8044600F09CF901216170204600F0C4
:101B2000F5FA21460448BDE8104000F0CBB84288E1
:101B30000132428010BD00BF3C0F00200321FFF79F
:101B4000D5BD000080F309887047EFF30980704726
:101B5000684680F3098855480078C00714BF022002
:101B6000032080F314887047DFF844C1EFF3058346
:101B70001B0618BF6047EFF31483DB0708BF6047FD
:101B800000DF7047DFF82CC1EFF305831B0618BF99
:101B90006047EFF31483DB0708BF604700DF70473F
:101BA000EFF30980816911F8021C99BB90E80F10CE
:101BB00010B5E047BDE81040EFF3098C8CE8070052
:101BC0003D4B93E80600914208BF704781B11EF07B
:101BD000100F06BF2CED108A0120002081F8200094
:101BE0002CE9F00FC1F828C00CB4FFF709FD0CBCBC
:101BF0001A60D2F828C0BCE8F00F92F82000002844
:101C00001ABFBCEC108A6FF0120E6FF0020E8CF34C
:101C10000988704710B5294A1268914209D8284CA2
:101C200054F8214090E80F10A047EFF3098C8CE89E
:101C30000F0010BD10B5FFF76FFCBDE810401E4B44
:101C400093E80600914208BF7047EFF3098C1EF03D
:101C5000100F06BF2CED108A0120002081F8200013
:101C60002CE9F00FC1F828C00CB4FFF7C9FC0CBC7C
:101C70001A60D2F828C0BCE8F00F92F820000028C3
:101C80001ABFBCEC108A6FF0120E6FF0020E8CF3CC
:101C90000988704710B5FFF793FCFFF7CEBF10B56A
:101CA000FFF78CFCFFF78CFCFFF7C7BFDE3C00089A
:101CB000352100084F210008BC0E00200000000064
:101CC000FCFFFFFF30B502788C784368013AD2B24E
:101CD0002BB19D78A54202D318465B68F8E7022A2B
:101CE0004B60416003D803B19960886030BD002328
:101CF0008B6030BD43685A6842600278013A022A1C
:101D00004FF0000205D8596809B188605A609A609E
:101D100000E05A6018467047034B5A684260002240
:101D200082605860704700BF3C0F002010B5114B17
:101D3000DA680AB19A8A0CE000248A1AC460D86072
:101D400003619A82848210BD002CF5D0A38A1A44C4
:101D500023468A42DC68F7D3C460D860C468036154
:101D600004B12061521A92B28282998A8A1A9A82A6
:101D700010BD00BF240F002038B51A4DEB68002BB2
:101D80002ED0AB8A013BAB82AB8A002B28D1154AFF
:101D9000D4682CB3A26842B161685160626812B124
:101DA000A168916063600023A3600F482146FFF79C
:101DB00089FFA38AAB826378042B01BF0B4B1A689F
:101DC000E38A9B1808BFA38201236370E368EB607A
:101DD000E268002312B103491161E3602361D3E794
:101DE00038BD00BF240F00203C0F0020200F002032
:101DF000836853B9084B5A68824202D142685A60DC
:101E000070471346002AF6D1704742685A6043680B
:101E10000BB182689A6070473C0F002038B5846827
:101E2000054624B94378012B0ED1084C03E02378F2
:101E30000BB9A468FBE72846FFF7DAFF20462946DE
:101E4000BDE83840FFF73EBF38BD00BF3C0F002063
:101E500003697BB1C268DA60C26842B19A8A818A3A
:101E60000A449A82C26813610023C36000E09A8228
:101E7000002303617047000030B50E4BDD78EFF3AF
:101E8000108272B69A78AA4207D201329A701A78F2
:101E9000541CAC4208BF00241C7062B6AA4204D293
:101EA00003EBC2035860996030BD0220BDE83040AA
:101EB000FFF7BBBAC40B0020012310390370890857
:101EC0000023437083704360038143818381C18118
:101ED0007047000038B5838904461546002B36D07C
:101EE0004389043350F823300B604389C28901339E
:101EF0009BB29A42438104BF002343814368EBB104
:101F00004378022B1AD1FFF7F5FE0021054600F0B9
:101F1000FDF82389E9691A1D013344F82210E2898A
:101F20009BB29A42238108BF0023284608BF238121
:101F3000FFF78EFF2846FFF7B7FB06E0EFF31083AD
:101F400072B6A389013BA38162B6002038BD82B17D
:101F50004268094B1AB11968FFF7B4FE05E01B6827
:101F600043605A6098600123437028460821FFF7B8
:101F7000BDFB012038BD00BFBC0E0020C289808996
:101F8000101A704708B5FFF777FFBDE80840FFF764
:101F9000B1BA10B583890446EBB14389043350F8D4
:101FA00023300B604378022B04D10021FFF764FF3C
:101FB000FFF7A0FAEFF3108372B6A389013BA38168
:101FC00062B66389E28901339BB29A42638104D18C
:101FD0000023638101E0184610BD042010BD0000FD
:101FE00070B5426804460E46002A4AD04578022D54
:101FF0001CD0032D0AD0012D5DD1FFF77BFE0446D6
:102000001021324600F08BF8657034E0084600F08D
:1020100091F8054600284ED02046FFF76BFE294672
:10202000044600F073F80123637024E0FFF762FEBA
:102030000021054600F06AF82389E9691A1D44F871
:102040002210EFF3108272B6A2890132A28162B629
:10205000E28901339BB29A42238104BF002323818A
:10206000012328466B70FFF7F3FE13482946BDE8AD
:102070007040FFF727BE2046FFF7EAFE0E482146D4
:10208000F5E78189C089814210D223891D1D44F85A
:102090002560EFF3108572B60131A18162B601337C
:1020A0009BB2834214BF2381228170BD0320BDE80F
:1020B0007040FFF7BAB970BD3C0F0020436AC26A96
:1020C00023F0030313445A0748BF043B4FF08072C8
:1020D00070B503E90600A3F14004A3F14402A3F1A3
:1020E0000C05002642F8046FAA42FAD1C26943F8EF
:1020F000202CC3788462012B1CBFC36A024A01638F
:1021000018BF1A6070BD00BFA52E5AE290F82020BB
:10211000836A0AB1603300E020331960704710B55C
:1021200090F82040836A0CB1603300E0203383E8EC
:10213000060010BDEFF3108372B6026803F00103CE
:102140000AB11168016003B962B610467047814256
:102150000DD3436899420AD2EFF3108372B6026836
:102160000A60016013F0010003D162B670470120DC
:1021700070470020704738B1830704D10378002BE3
:1021800018BF0020704700207047000000B5DFF83E
:102190000CC000DFDFF808C000DFFEE745230008C1
:1021A0005D23000830B50B4A1368002433B11D8944
:1021B000A94203D31C46491B1B68F7E789B2036099
:1021C000018113B11D89691A19810CB1206030BDDC
:1021D000106030BD580F0020431C11D00B4B9842AB
:1021E00011D80B4B1B684FF47A715A1E01FB00206B
:1021F000B0FBF3F04FF6FE73984228BF18467047C5
:102200004FF6FF7070474FF6FE70704700093D00B3
:10221000E03C000838B5084C257855B9FFF7FAFAC4
:10222000064B1B68FF229A702846FFF700F901232E
:102230002370002038BD00BF540F0020BC0E0020CA
:1022400010B5EFF305845CB9EFF31484E40703D40D
:10225000BDE81040FFF7DEBFDFF808C000DF10BDAB
:10226000822010BD1522000810B588B0EFF3058458
:1022700034BBEFF3148404F00304022C0CD0032CC1
:1022800016D0012C1ED008AC84F309880F4C24789A
:10229000E40705D5022404E00C4C2478E4070BD4B1
:1022A000032484F31488BFF34F8FBFF36F8F03E0D1
:1022B000064C2478E40705D4DFF814C000DF02E000
:1022C000822000E0FF2008B010BD00BFDE3C000807
:1022D000B12400082DE9F8438946044650B103684B
:1022E00043B18588EB1C9BB2062B03D883680BB1E6
:1022F000C2682AB98020FFF79AF80020BDE8F88369
:102300004363C26300F11006FFF79EF90B4F00F123
:10231000FF38291D47F82860C9B22268E074C4F864
:102320002C903046FFF7A2F93046FFF7BDF957F879
:102330002800034A836A5A63BDE8F883480C0020EA
:102340008D21000808B5FFF7EBF918B10138024BF1
:1023500053F8200008BD00BF480C002008B5FFF767
:102360000AFF38B1C078FFF71DFAFF280CBF8120A3
:10237000002008BD802008BD70B505460C46EFF36F
:10238000058686B9EFF31486F60706D4074E36782D
:102390001EB9BDE87040FFF79DBF28462146DFF813
:1023A00010C000DF70BD002070BD00BF5C0F0020BA
:1023B000D522000810B5EFF305841CB9DFF808C07A
:1023C00000DF10BD822010BD5D23000808B530B1CC
:1023D000FFF702FF80B2FFF7B1FB402008BD08BD48
:1023E00010B5EFF305841CB9DFF808C000DF10BD9D
:1023F000822010BDCD230008830704D128B10369D2
:10240000C1681B6803E0002300E003461946184634
:1024100070470000F8B5134B1C681F460CB32389A6
:10242000013B23812389E3B90F4B26681D683E6079
:1024300055B12B78012B07D12846FFF79FFD18B126
:1024400028462146FFF79EFD6379012B04D12046E3
:102450006189FFF7A7FE01E0012323710EB1344625
:10246000E0E7F8BD580F0020A80E002010B5044684
:102470000846DFF80CC000DF84E80300204610BDEA
:10248000F923000810B5044618B1016809B1406885
:1024900020B98020FEF7CBFF002010BD0378002B71
:1024A000F7D10431890089B2FFF706FD606810BDDD
:1024B00038B5104D2C78D4B921460F48FFF7E2FF0C
:1024C0000E4B214618600E48FFF704FF0D4B2146C6
:1024D00018602046FFF72CF90B4A13689B6A2033DB
:1024E00083F309881460FFF703FA01232B7000209F
:1024F00038BD00BF5C0F0020E0010020A80E0020C6
:10250000E8010020A40E0020BC0E00202DE9F04FB1
:102510000C4685B08046E8B10378012B1FD10846F0
:10252000FFF75AFE02A982B24046FFF7D3FC01280A
:1025300006D10020002C0246034618BF402003E0CD
:102540000020024603461020029904460D46164616
:102550001F4608E0802405460646074603E000259E
:1025600080242E462F462046294632463B4605B05B
:10257000BDE8F08F7FB5044616460846EFF30581A7
:10258000A9B101AD00B10AB180230AE00378012BA3
:10259000FAD102A9FFF7FDFC042801D0019601E061
:1025A0001023019395E8070084E8070005E0114631
:1025B000DFF80CC000DF84E80700204604B070BDDF
:1025C0000D2500087FB50A4B03A819684FF0FF32AC
:1025D000FFF7D0FF039B102BF5D101A80499FFF75B
:1025E00045FF019B002BEED002989847EBE700BF18
:1025F000A80E0020F0B4114B90F919700668856898
:10260000C468016942691E6001374FF000065D60D1
:102610009C60D9601A619E610AD090F91820074821
:1026200001320CBF04220C22F0BC5A61FEF72ABD15
:10263000082202485A61F0BCFEF724BD8410002035
:10264000F8B504460E4608463449154600F010F920
:1026500033490746284600F00BF90146384600F09A
:10266000F5F8411C206051D02E4B98423CD003F528
:102670008063984230D0A3F55043984224D030462E
:10268000264900F0C1F82846254900F0BDF8721C23
:1026900003D03046012100F007FA6B1C03D0284616
:1026A000012100F001FA00234FF41652A260E3600A
:1026B00023616361267665762046FFF79BFF1A4A01
:1026C0002368934218D0F8BD184B196C012241F4CD
:1026D000003119646260D2E7144B596C052241F055
:1026E000200159646260CAE7104B596C002241F026
:1026F000100159646260C2E70D4B0E482146012467
:102700001C601C22BDE8F84000F0BBBC0A480B4925
:10271000502200F02DF82068A6E700BF503F0008C7
:10272000083F00080010014000440040003802400B
:10273000600F0020C0100020803D00089C3D000874
:10274000026813689B06FCD5024B50681A60C0F300
:102750000800704784100020026813681B06FCD52F
:10276000024BC1F3080151601A60704784100020C9
:1027700010B5084B1B6882B0DC6800920B4602461D
:102780000549204600F0BAFB02B0BDE81040FEF754
:102790008DBA00BF8C020020043E00080FB400B5C3
:1027A000064B83B004AA1B6852F8041BD868019238
:1027B00000F044FE012000F00FFA00BF8C02002060
:1027C00038B50D46044600F0BBF8013510D094F939
:1027D000003001330DD02369A2881A8020460121E0
:1027E00000F0CAF820460021BDE8384000F0C0B82B
:1027F00038BD034803493522FFF7BAFFEBE700BFB6
:10280000383E0008503E0008431C10B5044619D05D
:1028100091F90030581C04D10FE011F90C3F5A1CFB
:102820000BD09C42F9D12046896800F00DF9204672
:102830000021BDE8104000F037B90348BDE8104062
:10284000FFF7ACBF10BD00BFC03E0008884208B50E
:102850000AD0431C07D0013106D00448FFF79EFF81
:102860004FF0FF3008BD084608BD00BFD43E000849
:1028700008B5431C0DD091F900305A1C04D109E071
:1028800011F90C3F5A1C05D09842F9D14868411CF7
:1028900000D008BD0248FFF781FF4FF0FF30F8E796
:1028A000E83E000870B500F05BF90E4C0E4E236850
:1028B00073B11D6800F032F9281A00280CDC216879
:1028C00032688B682360002AF2D048689047EEE7B0
:1028D000BDE8704000F03AB92368BDE87040186860
:1028E00000F02AB9640F0020680F002038B50546B3
:1028F00000F014F9044600F011F9001BA842FAD3C5
:1029000038BD00BF4FF47A7303FB00F0FFF7EEBF52
:10291000431C10B5044608D02046002100F094F86E
:1029200004F00F040120A04010BD034803492722F2
:10293000FFF71EFFF0E700BF983F0008AC3F00081C
:1029400070B504464B1C0D46217010D0C1F3031026
:1029500000F032F806462846FFF7DAFF06F11002CB
:1029600006F118031A366060A260E360266170BD4C
:1029700090F9000000F098B838B5054690F90000CD
:10298000431C0C460BD0012C04D00021BDE838407C
:1029900000F05AB82146BDE8384000F055B8044868
:1029A00004494722FFF7E4FE95F90000EBE700BF7A
:1029B000383E0008AC3F000808B507282FD8DFE8EC
:1029C00000F00B121920272E2E04174B17481A6BF4
:1029D00042F080021A6308BD134B15481A6B42F08F
:1029E00001021A6308BD104B12481A6B42F0020232
:1029F0001A6308BD0C4B10481A6B42F004021A63AC
:102A000008BD094B0D481A6B42F008021A6308BD55
:102A1000054B0B481A6B42F010021A6308BD0948B7
:102A2000FFF7BCFE002008BD00380240001C024039
:102A3000000002400004024000080240000C024076
:102A4000001002404840000830B5431C87B00546DE
:102A50000C461CD0C5F30310FFF7AEFF05F00F05C1
:102A600004F00F0201210D4B01FA05F553F8223055
:102A700001950322C4F3021501A9C4F3C314029300
:102A8000039505940492FDF7D5FF07B030BD0448C7
:102A900004497D22FFF76CFEDCE700BF144000080C
:102AA000983F00086C40000838B5431C04460D46AA
:102AB00018D0C4F30310FFF77FFF04F00F04C268BF
:102AC000022D4FEA44044FF0030198BFA54001FADC
:102AD00004F422EA0404C460C26888BF00251543D8
:102AE000C56038BD02480349A222FFF741FEE0E776
:102AF000983F00086C400008054B186800B170470B
:102B0000044A0549116001221A60FDF741BF00BF68
:102B1000A80F00206C0F0020000C004008B5044BEB
:102B20001B680BB9FFF7E8FF024B586A08BD00BFEE
:102B3000A80F0020000C0040034B1B685863DA68A4
:102B400042F00202DA6070476C0F0020034B1B68F2
:102B5000DA6822F00202DA60704700BF6C0F0020D2
:102B6000024B1B686FF002021A6170476C0F002065
:102B700010B5002814BF04460124204600F062FA74
:102B800030B900F009F808B900F012F88047F4E70E
:102B900010BD00F05FBA0000024B1868BFF35F8FF2
:102BA000704700BFAC0F0020FFF7F3BFFFF7E0BF97
:102BB00008B5062000F018FE0120FEF7EFFB0146E5
:102BC00000200246034600F041BF0000014B186898
:102BD000704700BF8C02002008B5074B044613B1B4
:102BE000002100F08FFF054B1868836A03B19847F6
:102BF0002046FEF7D3FB00BF053B0008304100082C
:102C00008A892DE9F041054610070C4657D44B68D8
:102C1000002B02DC0B6C002B18DDE66AB6B102F467
:102C20008052002392B22F682B600AB1626D10E0CF
:102C3000216A28460123B047411C024609D12B686E
:102C40003BB11D2B01D0162B47D12F600020BDE8D2
:102C5000F081A3895B0705D56368D21A636B0BB15A
:102C6000236CD21AE66A216A00232846B047461C24
:102C7000A38905D12A681AB11D2A01D0162A19D1B3
:102C800000226260D9042269226004D5421C01D16D
:102C90002B6803B96065616B2F600029D6D004F101
:102CA0004403994202D0284600F0FEF900206063F8
:102CB000BDE8F08143F04003A381BDE8F0810F69D6
:102CC000002FC3D093070E6808BF4B690F6018BF71
:102CD0000023C7EB06088B6012E0A38943F0400392
:102CE000A3814FF0FF30BDE8F0812846216AA66A33
:102CF0003A464346B0470028EFDD0744C0EB0808DA
:102D0000B8F1000FF1DCA1E738B50B6905460C46B8
:102D1000DBB118B183690BB900F072F80C4B9C421F
:102D200001D16C6808E00B4B9C4201D1AC6803E018
:102D3000094B9C4208BFEC68B4F90C302BB1284613
:102D40002146BDE83840FFF75BBF002038BD00BF1B
:102D5000D0400008F040000810410008014620B9AA
:102D6000044B0549186800F0DBB8044B1868FFF7FE
:102D7000CBBF00BF30410008092D00088C020020A5
:102D8000014900F0CDB800BF092D0008002310B59F
:102D9000044603604360836081814366C2810361AE
:102DA0004361836119465C30082200F075F9054BD8
:102DB0006362054BA362054BE362054B2462236308
:102DC00010BD00BF21380008433800087B380008D8
:102DD0009F38000870B568234D1E5D430E4605F10F
:102DE000740100F0A5F9044640B1002180E84200DA
:102DF0000C30A06005F1680200F04EF9204670BD6D
:102E0000836910B5044633BB8364C3640365124B06
:102E1000124A1B688262984204BF0123836100F05A
:102E20001FF86060204600F01BF8A060204600F00C
:102E300017F80421E06000226068FFF7A7FFA06890
:102E400009210122FFF7A2FFE06812210222FFF709
:102E50009DFF0123A36110BD30410008812D0008B2
:102E6000F8B51B4B1E68B369074613B93046FFF728
:102E7000C7FF4836B4687368013B04D4B4F90C50FA
:102E800075B16834F8E733682BB938460421FFF789
:102E9000A1FF306008B13668ECE70C233B60F8BD59
:102EA0004FF6FF73E3810123A38165662560A5606A
:102EB000656025616561A56104F15C002946082211
:102EC00000F0EAF86563A563A564E5642046F8BDF3
:102ED0003041000838B5074B074CE41AA4101D46D2
:102EE00024B1013C55F824309847F9E7BDE8384053
:102EF00000F0DEBE980200209C0200200EB403B554
:102F0000014603AB054853F8042B0068019300F019
:102F10008DF902B05DF804EB03B070478C0200201D
:102F20002DE9F8438046894600F14804002694B113
:102F3000A5686768013F0CD4AB89012B07D9B5F9A7
:102F40000E30013303D040462946C8470643683552
:102F5000F0E72468EBE73046BDE8F88370B50E4B28
:102F60000E4CE41AA41000251E46A54204D056F8C3
:102F7000253098470135F8E700F094FE084C094BDE
:102F8000E41AA41000251E46A54204D056F82530A8
:102F900098470135F8E770BD9002002090020020AC
:102FA0009802002090020020F0B58B899D0791B017
:102FB00006460C4626D4B1F90E10002909DAA38979
:102FC00013F0800F4FF0000514BF40274FF48067C7
:102FD0000DE001AA00F010FE0028F0DB029D05F4D0
:102FE0007045A5F500514D424D414FF48067304684
:102FF000394600F09DF860B9A3899A051DD443F0C5
:103000000203A38104F14703236023610123636169
:1030100013E00B4BB362A389206043F08003A381CC
:10302000206167614DB13046B4F90E1000F0F6FD35
:1030300018B1A38943F00103A38111B0F0BD00BF13
:10304000812D0008024B0146186800F071B800BFDE
:103050008C020020024B0146186800F025B800BF22
:103060008C02002010B5C9B202449042034606D03B
:103070001C788C4200F10100F7D1184610BD0020E9
:1030800010BD10B5431E0A44914204D011F8014B03
:1030900003F8014FF8E710BD02440346934202D003
:1030A00003F8011BFAE7704730B500293DD051F80D
:1030B000042C0B1F1D49002AB8BF9B180A680C4638
:1030C00012B95A600B6030BD93420DD2196858187E
:1030D000904201BF5A5852181A6042685A602360E1
:1030E00030BD994203D80A4651680029F9D11468C5
:1030F00015199D420AD11B682344D01888421360D9
:1031000013D10868034413604B680DE002D90C2307
:10311000036030BD1C681819884204BF08684968FC
:10312000596004BF00191860536030BDB40F00200F
:1031300070B5CC1C24F0030408340C2C38BF0C24CC
:10314000002C064603DA0C233360002070BD8C424D
:10315000F9D3204A136810461946A1B10A68121B18
:103160000ED40B2A03D90A608B188C501FE08B42B7
:103170000DBF5A684A685A60026018BF0B4616E0D5
:103180000B464968E9E7144D2B681BB9304600F03F
:10319000F3FA28603046214600F0EEFA421C03465E
:1031A000D1D0C51C25F0030585420AD11C6003F16E
:1031B0000B001A1D20F00700821A0AD051429950C4
:1031C00070BD3046E91A00F0D7FA0130BBD02B466B
:1031D000ECE770BDB40F0020B00F00209368013BF6
:1031E000002B10B5936009DA9469A34202DBCBB2DD
:1031F0000A2B03D1BDE8104000F056BB1368581CE1
:1032000010601970C8B210BDF8B506460F461446D6
:10321000D518AC4208D0304614F8011B3A46FFF7E7
:10322000DDFF431CF5D100E00020F8BD2DE9F0439F
:103230009DB00D4690460393064618B183690BB9BD
:10324000FFF7DEFD754B9D4201D1756808E0744BB8
:103250009D4201D1B56803E0724B9D4208BFF568FD
:10326000AB891C070AD52B6943B10023099320239E
:103270008DF8293030238DF82A3041E03046294638
:1032800000F078FB0028F0D04FF0FF30C2E0039A46
:10329000111D12680391002ABBBF524243F0020382
:1032A00007920792B8BF0493013423782E2B7BD06A
:1032B000DFF88081217840460322FFF7D3FE38B142
:1032C000049AC8EB00004023834013430493013465
:1032D000217855488DF82810062204F10108FFF7DF
:1032E000C1FE002800F08580504B002B78D1039B55
:1032F000073323F0070308330393099B3B440993E7
:1033000043461C4613F8012B1AB9B4EB08090ED03A
:1033100002E0252AF5D1F8E73046294642464B46D9
:10332000FFF772FF013070D0099B4B44099323785B
:10333000002B6AD000234FF0FF32049307930592CD
:1033400006938DF853301A9304F101084446DFF8D0
:10335000E890217848460522FFF784FE08F101082D
:10336000049B30B1C9EB0000012282401343049357
:10337000ECE7D80644BF20228DF85320190744BF3C
:103380002B228DF8532022782A2A80D007992346B1
:103390001C4601332278303A092A03D80A2000FB60
:1033A0000121F5E7079180E763782A2B0AD1039B77
:1033B0001A1D1B680392002BB8BF4FF0FF33023475
:1033C000059375E7611C00220C4601312378303BE0
:1033D000092B03D80A2000FB0232F5E7059267E7C4
:1033E00003AB0093304604A92A46114BAFF300808B
:1033F00007E003AB0093304604A92A460C4B00F0CB
:10340000A1F8421C07467FF478AFAB895B063FF515
:103410003BAF09981DB0BDE8F08300BFD040000865
:10342000F0400008104100083E4100080000000084
:10343000093200083A4100083441000830B513460B
:10344000044A05460C46106829462246BDE830402D
:10345000FFF7ECBE8C0200202DE9F84391461F4691
:103460008A680B69DDF820809342B8BF1346C9F81B
:10347000003091F8432006460C4612B10133C9F8DA
:1034800000302368990642BFD9F800300233C9F8EA
:103490000030256815F006051CD094F843302268EA
:1034A000003318BF012392061FD5E1185A1C3020A3
:1034B00081F84300224494F8451082F84310023307
:1034C00013E03046394604F119020123C0470130A8
:1034D00007D00135E368D9F800209B1A9D42F0DB44
:1034E000DBE74FF0FF30BDE8F8833046394604F1A2
:1034F0004302C0470130F4D02268D9F80050E36895
:1035000002F00602042A08BF5D1B2269A3680CBFF3
:1035100025EAE57500259342C4BF9B1AED184FF0CC
:103520000009A9450ADA3046394604F11A02012396
:10353000C0470130D5D009F10109F2E70020BDE80C
:10354000F88300002DE9FF410C461746227E6E2AC3
:10355000984606460A9B01F1430100F0A98012D863
:10356000632A23D00AD8002A00F0B680582A40F0F7
:10357000C58084F84520DFF8F8E151E0642A1ED0C8
:10358000692A1CD0BAE0732A00F0AA8009D86F2AF1
:103590002BD0702A40F0B280226842F020022260D4
:1035A00039E0752A21D0782A35D0A7E01A68111D94
:1035B0001960136884F8423004F14205A2E02068E3
:1035C0001A6810F0800F03D0101D1860136805E012
:1035D0004506F9D5101D1860B2F90030002B3BDA12
:1035E0002D225B4284F8432036E020681A6810F0F0
:1035F000800F03D0101D1860136804E04006F9D551
:10360000101D18601388227EDFF864E16F2A0CBF5A
:1036100008220A221CE07822DFF858E184F84520CD
:103620002268186812F0800F00F104051D6001D0B7
:10363000036802E05506FBD50388D00744BF42F07B
:10364000200222601BB9226822F020022260102290
:10365000002084F8430002E0DFF814E10A226568E4
:10366000A560002DA2BF206820F00400206003B9EF
:1036700065B10D46B3FBF2F002FB10331EF80330C8
:1036800005F8013D03460028F4D100E00D46082A64
:103690000BD12368DA0708D5236962689A42DEBF36
:1036A000302305F8013C05F1FF35491B21612EE06F
:1036B00025681A68606915F0800F03D0151D1D601C
:1036C000136808E015F0400F02F104051D6013684F
:1036D00001D0188000E01860002323610D4616E039
:1036E0001A68111D19601568626828460021FFF7E5
:1036F000B9FC08B1401B6060636804E004F1420556
:1037000084F8422001232361002384F84330CDF85C
:1037100000803046214603AA3B46FFF79DFE01305C
:1037200002D14FF0FF301FE0304639462A46236968
:10373000C0470130F5D023689B0705D4E068039BA0
:103740009842B8BF18460FE00025E368039A9B1A19
:103750009D42F3DA3046394604F119020123C0478D
:103760000130DED00135F0E704B0BDE8F08100BFE4
:10377000454100085641000838B5064C002305466F
:1037800008462360FDF7F6FD431C02D1236803B110
:103790002B6038BDDC1000201F2938B504460D46CB
:1037A00004D9162303604FF0FF3038BD426C12B1CC
:1037B00052F821304BB9204600F030F82A46014635
:1037C0002046BDE8384000F017B8012B0AD0591C3C
:1037D00003D116230360012038BD002442F82540A0
:1037E00028469847002038BD024B01461868FFF76D
:1037F000D3BF00BF8C02002038B5074C002305461C
:1038000008461146236000F045FA431C02D12368A4
:1038100003B12B6038BD00BFDC10002000F032BACD
:1038200010B50C46B1F90E1000F01AFA0028ABBF23
:10383000636DA3891B1823F48053ACBF6365A38118
:1038400010BD2DE9F0411D468B89DB0507460C466E
:10385000164605D5B1F90E100022022300F0EEF94C
:10386000A389B4F90E1023F48053A381384632465D
:103870002B46BDE8F04100F06BB810B50C46B1F92D
:103880000E1000F0DBF9431CA38915BF606523F41B
:10389000805343F48053A38118BFA38110BDB1F9B5
:1038A0000E1000F099B9000070B50D46144606469A
:1038B00018B183690BB9FFF7A3FA224B9C4201D1DF
:1038C000746808E0204B9C4201D1B46803E01F4BB0
:1038D0009C4208BFF468A369A360A3891A0709D5AD
:1038E00023693BB123682069181A63699842EDB2D5
:1038F0000FDB08E03046214600F03CF80028F1D00C
:103900004FF0FF3070BD30462146FFF7FDF900282B
:10391000F6D1A368013BA36023685A1C22601D7086
:1039200063690130984204D0A389DB0707D50A2DCB
:1039300005D130462146FFF7E7F90028E0D12846B7
:1039400070BD00BFD0400008F040000810410008E2
:1039500038B5074C054600202060084611461A4637
:10396000FDF776FC431C02D1236803B12B6038BD00
:10397000DC100020314B70B51D6806460C4625B1A1
:10398000AB6913B92846FFF73BFA2D4B9C4201D196
:103990006C6808E02B4B9C4201D1AC6803E02A4BD9
:1039A0009C4208BFEC68A3899AB211071DD4D506C2
:1039B00002D40922326038E0500712D5616B41B160
:1039C00004F14403994202D03046FFF76DFB002317
:1039D0006363A38923F02403A38100236360236925
:1039E0002360A38943F00803A38123694BB9A3890A
:1039F00003F42073B3F5007F03D030462146FFF770
:103A0000D3FAA38913F0010205D00022A2606269F3
:103A10005242A26103E0990758BF6269A26022691D
:103A20004AB903F0800080B230B143F04003A38173
:103A30004FF0FF3070BD002070BD00BF8C02002031
:103A4000D0400008F0400008104100082DE9F8437C
:103A5000294D2C6806460F46914698460CB9274CCE
:103A60002C6063681F2B14DD254B1BB94FF0FF3012
:103A7000BDE8F8838C20FFF7E5FA04460028F5D06E
:103A800000232A68026043602860C0F888303EB98D
:103A900028E03EB3D4F8880078B9194B002BE5D064
:103AA0004FF48470FFF7CEFA0028DFD00023C0F86F
:103AB0000031C0F80431C4F88800626840F82290F0
:103AC0000123934000EB8201D0F800211A43022E1B
:103AD000C0F80021C1F8808002BFD0F80421134350
:103AE000C0F8043163685A1C02336260002044F855
:103AF0002370BDE8F88300BF44100020B80F0020F9
:103B0000453000082DE9F74F80460F46304E3468A7
:103B1000002C59D06568D4F8889005F1FF3AAD00C3
:103B200009EB050B04352544BAF1000F38DB37B13A
:103B3000B9F1000F2ED0DBF87C20BA422AD161689F
:103B40002A6801398A4516BF0021C4F804A02960FB
:103B500002B363680193B9F1000F06D00121D9F8CF
:103B6000000101FA0AF1014201D190470BE0D9F8B6
:103B70000401014204D140465BF8041C904702E076
:103B80005BF8040C90476268019B9342BED1326897
:103B9000A242BBD10AF1FF3AABF1040B043DC3E7EB
:103BA0000C4B8BB1626823685AB953B13360B9F1D9
:103BB000000F02D04846FFF74DFA2046FFF74AFAB9
:103BC000A5E726461C46A3E703B0BDE8F08F00BF7B
:103BD000441000205530000838B5064C0023054637
:103BE00008462360FDF71EFB431C02D1236803B186
:103BF0002B6038BDDC10002038B5074C002305468B
:103C0000084611462360FDF799FB431C02D1236847
:103C100003B12B6038BD00BFDC10002038B5064C66
:103C20000023054608462360FDF760FB431C02D1D4
:103C3000236803B12B6038BDDC10002038B5074C79
:103C4000054600202060084611461A46FDF762FB33
:103C5000431C02D1236803B12B6038BDDC10002067
:103C600038B5074C054600202060084611461A4624
:103C7000FDF716FB431C02D1236803B12B6038BD4E
:103C8000DC100020024B58221A604FF0FF307047C2
:103C9000DC100020024B58221A604FF0FF307047B2
:103CA000DC100020F8B500BFF8BC08BC9E46704789
:103CB000F8B500BFF8BC08BC9E4670470000000085
:103CC00001020304010203040607080900000000C2
:103CD0000000000001020304060708090F000100AC
:103CE000E8030000800010001F48010005000100EB
:103CF0006F626A2D3E70696E20213D202850696EEA
:103D00004E616D65294E4300443A5C4D79446F63C2
:103D1000756D656E74735C4769744875625C536554
:103D20006E736F722D426F6172645C6D6265645C6C
:103D30005441524745545F4E55434C454F5F4634BE
:103D4000303152455C5441524745545F53544D5CA9
:103D50005441524745545F53544D333246342F67D4
:103D600070696F5F6F626A6563742E68000000009F
:103D70000000000000000000CD1A0008F11A000841
:103D80006F626A2D3E7561727420213D2028554175
:103D900052544E616D65294E43000000433A5C4326
:103DA0006F64655C6769745F7265706F5C67697486
:103DB0006875625C6D6265642D6F666669636961D2
:103DC0006C5C6C69627261726965735C6D6265647A
:103DD0005C746172676574735C68616C5C544152B9
:103DE0004745545F53544D5C5441524745545F53CB
:103DF000544D333246345C73657269616C5F617037
:103E0000692E63006D62656420617373657274610D
:103E100074696F6E206661696C65643A2025732C45
:103E20002066696C653A2025732C206C696E6520CC
:103E30002564200A000000006F626A2D3E70696EE2
:103E400020213D202850696E4E616D65294E43004A
:103E5000433A5C436F64655C6769745F7265706F59
:103E60005C6769746875625C6D6265642D6F666617
:103E7000696369616C5C6275696C645C6D626564E0
:103E80005C5441524745545F4E55434C454F5F4645
:103E900034303152455C5441524745545F53544D80
:103EA0005C5441524745545F53544D333246342F8E
:103EB0006770696F5F6F626A6563742E68000000E7
:103EC000636F756C64206E6F742070696E6F7574AB
:103ED0000000000070696E6D6170206D69732D6D5A
:103EE000617463680000000070696E6D6170206E1F
:103EF0006F7420666F756E6420666F7220706572D5
:103F00006970686572616C00030000000044004045
:103F1000930300000A00000000100140930300001A
:103F20000C00000000140140130400001700000002
:103F3000001001409303000027000000001401401E
:103F400013040000FF000000FFFFFFFF000000005F
:103F5000020000000044004093030000090000003C
:103F600000100140930300000B000000001401400A
:103F7000130400001600000000100140930300002D
:103F8000260000000014014013040000FF000000A0
:103F9000FFFFFFFF0000000070696E20213D202818
:103FA00050696E4E616D65294E430000433A5C4393
:103FB0006F64655C6769745F7265706F5C67697474
:103FC0006875625C6D6265642D6F666669636961C0
:103FD0006C5C6C69627261726965735C6D62656468
:103FE0005C746172676574735C68616C5C544152A7
:103FF0004745545F53544D5C5441524745545F53B9
:10400000544D333246345C6770696F5F6170692E5E
:10401000630000000000000001000000110000002B
:104020000200000012000000030000000000111058
:1040300000002110000031100000121000002210BA
:10404000000032100000001050696E6D6170206534
:1040500072726F723A2077726F6E6720706F72742F
:10406000206E756D6265722E00000000433A5C435D
:104070006F64655C6769745F7265706F5C676974B3
:104080006875625C6D6265642D6F666669636961FF
:104090006C5C6C69627261726965735C6D626564A7
:1040A0005C746172676574735C68616C5C544152E6
:1040B0004745545F53544D5C5441524745545F53F8
:1040C000544D333246345C70696E6D61702E6300FE
:1040D00000000000000000000000000000000000E0
:1040E00000000000000000000000000000000000D0
:1040F00000000000000000000000000000000000C0
:1041000000000000000000000000000000000000AF
:10411000000000000000000000000000000000009F
:10412000000000000000000000000000000000008F
:104130002C020020232D302B2000686C4C0065667B
:1041400067454647003031323334353637383941E8
:1041500042434445460030313233343536373839FE
:0C416000616263646566000000000000FE
:08416C0084C0FF7F0100000088
:1041740000BD0105E01000206113000800000000EC
:10418400000000000000000000000000000000002B
:10419400000000000000000000000000000000001B
:1041A400000000000000000000000000000000000B
:1041B40000000000000000000000000004000000F7
:1041C400840C0020C525000802000000000800003F
:1041D400C4030020000000000000000000000000F4
:1041E40000000000000000000000000000000000CB
:1041F40000000000000000000000000000000000BB
:10420400000000000000000000000000D040000892
:10421400F040000810410008000000000000000009
:104224000000000000000000063D0008000000003F
:10423400000000000000000000000000000000007A
:10424400000000000000000000000000000000006A
:10425400000000000000000000000000000000005A
:1042640000000000000000002C020020B90100083A
:0C427400ED190008950100080000000092
:04000005080013C11B
:00000001FF
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version='1.0' encoding='UTF-8'?>
<history>
<processor signature="4.9.3 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -Wall -g -Map=SensorBoard.map -Os --gc-sections -Wl,--wrap,main --specs=nano.specs -u _printf_float -u _scanf_float D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_cryp.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_tim_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_ll_fmc.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_rcc.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_smartcard.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_pwr_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_ll_fsmc.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_rng.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_eth.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/cmsis_nvic.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_dma_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_ll_sdmmc.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_hcd.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/hal_tick.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_pccard.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_dac_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_irda.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_sd.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_sai.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_i2s_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_sram.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_spi.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_adc_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_gpio.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_flash.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_pcd_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/board.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_hash.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_adc.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_iwdg.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_flash_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_rtc_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_nor.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_i2s.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/system_stm32f4xx.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_sdram.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_pcd.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_uart.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_i2c.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_cortex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_rtc.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_ltdc.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_tim.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_ll_usb.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_hash_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_rcc_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/retarget.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/startup_stm32f401xe.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/mbed_overrides.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_dma.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_can.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_dma2d.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_dac.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_flash_ramfunc.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_crc.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_pwr.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_wwdg.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_i2c_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_cryp_ex.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_nand.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_usart.o D:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/stm32f4xx_hal_dcmi.o -LD:\MyDocuments\GitHub\Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM -LD:/MyDocuments/GitHub/Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM -TD:/MyDocuments/GitHub/Sensor-Board/mbed/TARGET_NUCLEO_F401RE/TOOLCHAIN_GCC_ARM/STM32F401XE.ld -g -L..\..\.. -lmbed -L..\..\.. -lstdc++ -L..\..\.. -lsupc++ -L..\..\.. -lm -L..\..\.. -lgcc -L..\..\.. -lc -L..\..\.. -lnosys">
<target file="SensorBoard.elf" lastModified="14bd21f0321">
<source file="..\obj\arm_mat_inverse_f32.o" lastModified="14bd21e3808"/>
<source file="..\obj\arm_bitreversal2.o" lastModified="14bd21e3833"/>
<source file="..\obj\rabbit.o" lastModified="14bd21e38e1"/>
<source file="..\obj\arm_cfft_radix2_q31.o" lastModified="14bd21e3994"/>
<source file="..\obj\arm_add_q7.o" lastModified="14bd21e39f6"/>
<source file="..\obj\arm_scale_q7.o" lastModified="14bd21e3a5d"/>
<source file="..\obj\arm_mat_add_f32.o" lastModified="14bd21e3ac2"/>
<source file="..\obj\arm_q31_to_float.o" lastModified="14bd21e3b26"/>
<source file="..\obj\arm_cfft_radix4_q15.o" lastModified="14bd21e3c07"/>
<source file="..\obj\arm_pid_init_q31.o" lastModified="14bd21e3c64"/>
<source file="..\obj\arm_float_to_q7.o" lastModified="14bd21e3cc9"/>
<source file="..\obj\arm_q31_to_q7.o" lastModified="14bd21e3d2d"/>
<source file="..\obj\RTX_Conf_CM.o" lastModified="14bd21e3d78"/>
<source file="..\obj\arm_conv_partial_opt_q15.o" lastModified="14bd21e3e1b"/>
<source file="..\obj\arm_biquad_cascade_df1_q15.o" lastModified="14bd21e3e9a"/>
<source file="..\obj\sha.o" lastModified="14bd21e3fd6"/>
<source file="..\obj\arm_cmplx_dot_prod_q15.o" lastModified="14bd21e4040"/>
<source file="..\obj\arm_fir_decimate_fast_q15.o" lastModified="14bd21e40cc"/>
<source file="..\obj\arm_cfft_radix4_f32.o" lastModified="14bd21e41a6"/>
<source file="..\obj\arm_sin_cos_q31.o" lastModified="14bd21e4210"/>
<source file="..\obj\arm_scale_q31.o" lastModified="14bd21e4288"/>
<source file="..\obj\rt_Robin.o" lastModified="14bd21e42c7"/>
<source file="..\obj\tls.o" lastModified="14bd21e43aa"/>
<source file="..\obj\arm_fir_sparse_init_q31.o" lastModified="14bd21e4405"/>
<source file="..\obj\arm_rfft_q15.o" lastModified="14bd21e4486"/>
<source file="..\obj\arm_correlate_q7.o" lastModified="14bd21e4553"/>
<source file="..\obj\Mutex.o" lastModified="14bd21e49a4"/>
<source file="..\obj\arm_biquad_cascade_df1_f32.o" lastModified="14bd21e4a0f"/>
<source file="..\obj\arm_cmplx_dot_prod_f32.o" lastModified="14bd21e4a82"/>
<source file="..\obj\arm_conv_partial_opt_q7.o" lastModified="14bd21e4b1f"/>
<source file="..\obj\pwdbased.o" lastModified="14bd21e4b7d"/>
<source file="..\obj\arm_cmplx_mult_real_q31.o" lastModified="14bd21e4bed"/>
<source file="..\obj\keys.o" lastModified="14bd21e4cb7"/>
<source file="..\obj\arm_q15_to_q31.o" lastModified="14bd21e4d18"/>
<source file="..\obj\arm_abs_q7.o" lastModified="14bd21e4d81"/>
<source file="..\obj\arm_common_tables.o" lastModified="14bd21e502d"/>
<source file="..\obj\arm_fill_q31.o" lastModified="14bd21e508d"/>
<source file="..\obj\arm_rfft_f32.o" lastModified="14bd21e510d"/>
<source file="..\obj\arm_q7_to_q15.o" lastModified="14bd21e5172"/>
<source file="..\obj\arm_conv_q7.o" lastModified="14bd21e523d"/>
<source file="..\obj\arm_sin_q31.o" lastModified="14bd21e52a5"/>
<source file="..\obj\arm_fir_sparse_q15.o" lastModified="14bd21e5363"/>
<source file="..\obj\arm_dot_prod_q15.o" lastModified="14bd21e53ca"/>
<source file="..\obj\arm_q15_to_float.o" lastModified="14bd21e542d"/>
<source file="..\obj\arm_correlate_fast_q15.o" lastModified="14bd21e54f0"/>
<source file="..\obj\Display.o" lastModified="14bd21e572a"/>
<source file="..\obj\cyassl_int.o" lastModified="14bd21e5a4f"/>
<source file="..\obj\arm_biquad_cascade_df2T_init_f32.o" lastModified="14bd21e5aac"/>
<source file="..\obj\arm_lms_init_q15.o" lastModified="14bd21e5b0b"/>
<source file="..\obj\arm_correlate_q31.o" lastModified="14bd21e5bbc"/>
<source file="..\obj\arm_fir_sparse_f32.o" lastModified="14bd21e5c42"/>
<source file="..\obj\arm_max_q31.o" lastModified="14bd21e5ca8"/>
<source file="..\obj\arm_conv_partial_q15.o" lastModified="14bd21e5db1"/>
<source file="..\obj\arm_biquad_cascade_df1_32x64_q31.o" lastModified="14bd21e5e61"/>
<source file="..\obj\arm_dot_prod_f32.o" lastModified="14bd21e5ec4"/>
<source file="..\obj\arm_conv_fast_opt_q15.o" lastModified="14bd21e5f54"/>
<source file="..\obj\arm_dct4_init_q15.o" lastModified="14bd21e60b9"/>
<source file="..\obj\arm_cfft_radix4_init_q31.o" lastModified="14bd21e611b"/>
<source file="..\obj\arm_cfft_f32.o" lastModified="14bd21e61df"/>
<source file="..\obj\arm_lms_init_f32.o" lastModified="14bd21e623a"/>
<source file="..\obj\arm_rms_q15.o" lastModified="14bd21e64c0"/>
<source file="..\obj\coding.o" lastModified="14bd21e6539"/>
<source file="..\obj\arm_conv_partial_f32.o" lastModified="14bd21e65db"/>
<source file="..\obj\arm_dct4_init_f32.o" lastModified="14bd21e6860"/>
<source file="..\obj\arm_mat_mult_q31.o" lastModified="14bd21e68d6"/>
<source file="..\obj\arm_fir_interpolate_init_q31.o" lastModified="14bd21e6935"/>
<source file="..\obj\arm_fill_q7.o" lastModified="14bd21e6995"/>
<source file="..\obj\arm_iir_lattice_init_q15.o" lastModified="14bd21e69f0"/>
<source file="..\obj\arm_shift_q31.o" lastModified="14bd21e6a60"/>
<source file="..\obj\arm_mult_q31.o" lastModified="14bd21e6acb"/>
<source file="..\obj\arm_fir_lattice_q15.o" lastModified="14bd21e6b79"/>
<source file="..\obj\arm_rms_f32.o" lastModified="14bd21e6bdc"/>
<source file="..\obj\arm_biquad_cascade_df1_init_q15.o" lastModified="14bd21e6c42"/>
<source file="..\obj\arm_std_q15.o" lastModified="14bd21e6cb1"/>
<source file="..\obj\rt_System.o" lastModified="14bd21e6d1f"/>
<source file="..\obj\arm_iir_lattice_init_f32.o" lastModified="14bd21e6d7c"/>
<source file="..\obj\arm_mat_add_q31.o" lastModified="14bd21e6de3"/>
<source file="..\obj\asn.o" lastModified="14bd21e6f6f"/>
<source file="..\obj\arm_abs_q15.o" lastModified="14bd21e6fd6"/>
<source file="..\obj\arm_fir_sparse_q7.o" lastModified="14bd21e706d"/>
<source file="..\obj\arm_fir_lattice_f32.o" lastModified="14bd21e70ec"/>
<source file="..\obj\arm_negate_q7.o" lastModified="14bd21e7154"/>
<source file="..\obj\arm_sub_q15.o" lastModified="14bd21e71b8"/>
<source file="..\obj\arm_biquad_cascade_df1_init_f32.o" lastModified="14bd21e7219"/>
<source file="..\obj\arm_std_f32.o" lastModified="14bd21e7281"/>
<source file="..\obj\integer.o" lastModified="14bd21e75cf"/>
<source file="..\obj\arm_mat_init_q15.o" lastModified="14bd21e762a"/>
<source file="..\obj\arm_abs_f32.o" lastModified="14bd21e768c"/>
<source file="..\obj\arm_conv_q15.o" lastModified="14bd21e7789"/>
<source file="..\obj\arm_fir_lattice_init_q15.o" lastModified="14bd21e77e4"/>
<source file="..\obj\arm_sub_f32.o" lastModified="14bd21e784a"/>
<source file="..\obj\arm_cfft_radix4_q31.o" lastModified="14bd21e795d"/>
<source file="..\obj\rt_Task.o" lastModified="14bd21e79d5"/>
<source file="..\obj\arm_q15_to_q7.o" lastModified="14bd21e7a3b"/>
<source file="..\obj\arm_mat_init_f32.o" lastModified="14bd21e7a97"/>
<source file="..\obj\arm_conv_f32.o" lastModified="14bd21e7b33"/>
<source file="..\obj\arm_fir_lattice_init_f32.o" lastModified="14bd21e7b8f"/>
<source file="..\obj\arm_biquad_cascade_df1_q31.o" lastModified="14bd21e7c0f"/>
<source file="..\obj\arm_cmplx_dot_prod_q31.o" lastModified="14bd21e7c85"/>
<source file="..\obj\arm_fir_decimate_fast_q31.o" lastModified="14bd21e7d20"/>
<source file="..\obj\arm_rfft_init_q15.o" lastModified="14bd21e7e01"/>
<source file="..\obj\arm_conv_partial_fast_q15.o" lastModified="14bd21e7edd"/>
<source file="..\obj\arm_min_q15.o" lastModified="14bd21e7f46"/>
<source file="..\obj\arm_q7_to_float.o" lastModified="14bd21e7fa8"/>
<source file="..\obj\arm_correlate_fast_opt_q15.o" lastModified="14bd21e8035"/>
<source file="..\obj\main.o" lastModified="14bd21e811a"/>
<source file="..\obj\arm_conv_opt_q15.o" lastModified="14bd21e81ba"/>
<source file="..\obj\rt_Event.o" lastModified="14bd21e8210"/>
<source file="..\obj\arm_rfft_q31.o" lastModified="14bd21e82a3"/>
<source file="..\obj\arm_fir_q7.o" lastModified="14bd21e8332"/>
<source file="..\obj\arm_cfft_radix2_init_q15.o" lastModified="14bd21e8397"/>
<source file="..\obj\arm_rfft_init_f32.o" lastModified="14bd21e8501"/>
<source file="..\obj\arm_min_f32.o" lastModified="14bd21e8588"/>
<source file="..\obj\arm_fir_sparse_init_q7.o" lastModified="14bd21e8605"/>
<source file="..\obj\sha256.o" lastModified="14bd21e86bc"/>
<source file="..\obj\arm_q7_to_q31.o" lastModified="14bd21e871f"/>
<source file="..\obj\arm_cfft_radix2_init_f32.o" lastModified="14bd21e8786"/>
<source file="..\obj\W5200.o" lastModified="14bd21e8852"/>
<source file="..\obj\arm_dct4_q15.o" lastModified="14bd21e88d2"/>
<source file="..\obj\arm_fir_sparse_q31.o" lastModified="14bd21e8b44"/>
<source file="..\obj\arm_fir_init_q15.o" lastModified="14bd21e8ba2"/>
<source file="..\obj\arm_dot_prod_q31.o" lastModified="14bd21e8c10"/>
<source file="..\obj\Thread.o" lastModified="14bd21e8c6f"/>
<source file="..\obj\des3.o" lastModified="14bd21e8d41"/>
<source file="..\obj\arm_correlate_fast_q31.o" lastModified="14bd21e8e20"/>
<source file="..\obj\arm_cmplx_conj_q15.o" lastModified="14bd21e8e87"/>
<source file="..\obj\arm_dct4_f32.o" lastModified="14bd21e8f06"/>
<source file="..\obj\arm_lms_init_q31.o" lastModified="14bd21e8f63"/>
<source file="..\obj\arm_iir_lattice_q15.o" lastModified="14bd21e8ff6"/>
<source file="..\obj\arm_fir_init_f32.o" lastModified="14bd21e9056"/>
<source file="..\obj\arm_conv_partial_q31.o" lastModified="14bd21e910b"/>
<source file="..\obj\arm_dct4_init_q31.o" lastModified="14bd21e9288"/>
<source file="..\obj\arm_rfft_fast_f32.o" lastModified="14bd21e9304"/>
<source file="..\obj\arm_cmplx_conj_f32.o" lastModified="14bd21e9368"/>
<source file="..\obj\rt_Mutex.o" lastModified="14bd21e93c0"/>
<source file="..\obj\arm_power_q15.o" lastModified="14bd21e9423"/>
<source file="..\obj\rt_Semaphore.o" lastModified="14bd21e9475"/>
<source file="..\obj\arm_rms_q31.o" lastModified="14bd21e94d9"/>
<source file="..\obj\arm_iir_lattice_f32.o" lastModified="14bd21e9550"/>
<source file="..\obj\WIZnetInterface.o" lastModified="14bd21e991f"/>
<source file="..\obj\arm_shift_q7.o" lastModified="14bd21e9990"/>
<source file="..\obj\arm_iir_lattice_init_q31.o" lastModified="14bd21e99ec"/>
<source file="..\obj\arm_fir_fast_q15.o" lastModified="14bd21e9a7a"/>
<source file="..\obj\arm_fir_lattice_q31.o" lastModified="14bd21e9af0"/>
<source file="..\obj\arm_power_f32.o" lastModified="14bd21e9b50"/>
<source file="..\obj\arm_lms_norm_q15.o" lastModified="14bd21e9bf1"/>
<source file="..\obj\arm_cmplx_mag_q15.o" lastModified="14bd21e9c58"/>
<source file="..\obj\arm_biquad_cascade_df1_init_q31.o" lastModified="14bd21e9cb3"/>
<source file="..\obj\arm_std_q31.o" lastModified="14bd21e9d1e"/>
<source file="..\obj\arm_fir_decimate_q15.o" lastModified="14bd21e9db7"/>
<source file="..\obj\arm_abs_q31.o" lastModified="14bd21e9e1e"/>
<source file="..\obj\aes.o" lastModified="14bd21e9f52"/>
<source file="..\obj\arm_copy_q15.o" lastModified="14bd21e9fb6"/>
<source file="..\obj\arm_pid_reset_q15.o" lastModified="14bd21ea010"/>
<source file="..\obj\arm_sub_q31.o" lastModified="14bd21ea079"/>
<source file="..\obj\arm_lms_norm_f32.o" lastModified="14bd21ea0f7"/>
<source file="..\obj\arm_cmplx_mag_f32.o" lastModified="14bd21ea161"/>
<source file="..\obj\RtosTimer.o" lastModified="14bd21ea1bb"/>
<source file="..\obj\arm_fir_decimate_f32.o" lastModified="14bd21ea24b"/>
<source file="..\obj\arm_mat_init_q31.o" lastModified="14bd21ea2a6"/>
<source file="..\obj\arm_cmplx_mag_squared_q15.o" lastModified="14bd21ea30e"/>
<source file="..\obj\arm_conv_q31.o" lastModified="14bd21ea3bb"/>
<source file="..\obj\arm_copy_f32.o" lastModified="14bd21ea42a"/>
<source file="..\obj\arm_pid_reset_f32.o" lastModified="14bd21ea483"/>
<source file="..\obj\arm_fir_lattice_init_q31.o" lastModified="14bd21ea4de"/>
<source file="..\obj\arm_conv_partial_fast_opt_q15.o" lastModified="14bd21ea570"/>
<source file="..\obj\arm_fir_q15.o" lastModified="14bd21ea609"/>
<source file="..\obj\arm_rfft_fast_init_f32.o" lastModified="14bd21ea66e"/>
<source file="..\obj\arm_add_q15.o" lastModified="14bd21ea6d4"/>
<source file="..\obj\arm_fir_interpolate_q15.o" lastModified="14bd21ea772"/>
<source file="..\obj\arm_cmplx_mag_squared_f32.o" lastModified="14bd21ea7d5"/>
<source file="..\obj\arm_fir_f32.o" lastModified="14bd21ea86a"/>
<source file="..\obj\arm_add_f32.o" lastModified="14bd21ea8ce"/>
<source file="..\obj\arm_rfft_init_q31.o" lastModified="14bd21ea9b5"/>
<source file="..\obj\arm_conv_partial_fast_q31.o" lastModified="14bd21eaa85"/>
<source file="..\obj\arm_min_q31.o" lastModified="14bd21eaaea"/>
<source file="..\obj\md4.o" lastModified="14bd21eab87"/>
<source file="..\obj\arm_conv_partial_q7.o" lastModified="14bd21eae23"/>
<source file="..\obj\arm_fir_interpolate_f32.o" lastModified="14bd21eaeb6"/>
<source file="..\obj\arm_fir_init_q7.o" lastModified="14bd21eaf11"/>
<source file="..\obj\cyassl_io.o" lastModified="14bd21eaf6f"/>
<source file="..\obj\arm_lms_norm_init_q15.o" lastModified="14bd21eafd4"/>
<source file="..\obj\arm_mean_q15.o" lastModified="14bd21eb037"/>
<source file="..\obj\arm_cfft_radix2_init_q31.o" lastModified="14bd21eb09d"/>
<source file="..\obj\arm_biquad_cascade_df1_32x64_init_q31.o" lastModified="14bd21eb0f9"/>
<source file="..\obj\md5.o" lastModified="14bd21eb1ae"/>
<source file="..\obj\arm_fir_decimate_init_q15.o" lastModified="14bd21eb212"/>
<source file="..\obj\arm_cfft_radix8_f32.o" lastModified="14bd21eb2db"/>
<source file="..\obj\rt_Time.o" lastModified="14bd21eb31a"/>
<source file="..\obj\TCPSocketConnection.o" lastModified="14bd21eb3f8"/>
<source file="..\obj\arm_float_to_q15.o" lastModified="14bd21eb45d"/>
<source file="..\obj\arm_lms_norm_init_f32.o" lastModified="14bd21eb4ba"/>
<source file="..\obj\arm_mean_f32.o" lastModified="14bd21eb51a"/>
<source file="..\obj\arm_dct4_q31.o" lastModified="14bd21eb5a0"/>
<source file="..\obj\arm_cos_q15.o" lastModified="14bd21eb60c"/>
<source file="..\obj\arm_lms_q15.o" lastModified="14bd21eb6a6"/>
<source file="..\obj\arm_fir_init_q31.o" lastModified="14bd21eb702"/>
<source file="..\obj\arm_negate_q15.o" lastModified="14bd21eb765"/>
<source file="..\obj\arm_biquad_cascade_df1_fast_q15.o" lastModified="14bd21eb7dd"/>
<source file="..\obj\arm_sqrt_q15.o" lastModified="14bd21eb84b"/>
<source file="..\obj\TCPSocketServer.o" lastModified="14bd21ebaf7"/>
<source file="..\obj\arm_fir_decimate_init_f32.o" lastModified="14bd21ebb63"/>
<source file="..\obj\Semaphore.o" lastModified="14bd21ebbc1"/>
<source file="..\obj\arm_var_q15.o" lastModified="14bd21ebc2d"/>
<source file="..\obj\arm_cmplx_conj_q31.o" lastModified="14bd21ebc9a"/>
<source file="..\obj\HAL_CM4.o" lastModified="14bd21ebcb8"/>
<source file="..\obj\arm_mat_sub_q15.o" lastModified="14bd21ebd1f"/>
<source file="..\obj\arm_offset_q15.o" lastModified="14bd21ebd84"/>
<source file="..\obj\arm_mat_trans_q15.o" lastModified="14bd21ebdf5"/>
<source file="..\obj\rt_List.o" lastModified="14bd21ebe77"/>
<source file="..\obj\arm_cos_f32.o" lastModified="14bd21ebeee"/>
<source file="..\obj\arm_iir_lattice_q31.o" lastModified="14bd21ebf7b"/>
<source file="..\obj\arm_lms_f32.o" lastModified="14bd21ebff7"/>
<source file="..\obj\arm_negate_f32.o" lastModified="14bd21ec057"/>
<source file="..\obj\DNSClient.o" lastModified="14bd21ec1e5"/>
<source file="..\obj\arm_cmplx_mult_cmplx_q15.o" lastModified="14bd21ec25b"/>
<source file="..\obj\rt_Mailbox.o" lastModified="14bd21ec2cb"/>
<source file="..\obj\arm_mat_mult_fast_q15.o" lastModified="14bd21ec349"/>
<source file="..\obj\arm_conv_fast_q15.o" lastModified="14bd21ec40d"/>
<source file="..\obj\arm_var_f32.o" lastModified="14bd21ec470"/>
<source file="..\obj\arm_mat_scale_q15.o" lastModified="14bd21ec4e0"/>
<source file="..\obj\arm_mat_trans_f32.o" lastModified="14bd21ec547"/>
<source file="..\obj\arm_offset_f32.o" lastModified="14bd21ec5a9"/>
<source file="..\obj\arm_mat_sub_f32.o" lastModified="14bd21ec60f"/>
<source file="..\obj\arm_power_q31.o" lastModified="14bd21ec67e"/>
<source file="..\obj\arm_power_q7.o" lastModified="14bd21ec6e2"/>
<source file="..\obj\arm_cmplx_mult_cmplx_f32.o" lastModified="14bd21ec74d"/>
<source file="..\obj\arm_fir_fast_q31.o" lastModified="14bd21ec7d4"/>
<source file="..\obj\hmac.o" lastModified="14bd21ec842"/>
<source file="..\obj\arm_cfft_radix2_q15.o" lastModified="14bd21ec8fb"/>
<source file="..\obj\arm_mat_scale_f32.o" lastModified="14bd21ec95e"/>
<source file="..\obj\arm_lms_norm_q31.o" lastModified="14bd21ec9ff"/>
<source file="..\obj\arm_cmplx_mag_q31.o" lastModified="14bd21eca71"/>
<source file="..\obj\arm_offset_q7.o" lastModified="14bd21ecad7"/>
<source file="..\obj\arm_fir_decimate_q31.o" lastModified="14bd21ecb4c"/>
<source file="..\obj\arm_pid_init_q15.o" lastModified="14bd21ecd76"/>
<source file="..\obj\arm_pid_reset_q31.o" lastModified="14bd21ecdcf"/>
<source file="..\obj\arm_copy_q31.o" lastModified="14bd21ece30"/>
<source file="..\obj\arm_cfft_radix2_f32.o" lastModified="14bd21eced9"/>
<source file="..\obj\arm_correlate_opt_q15.o" lastModified="14bd21ecf71"/>
<source file="..\obj\random.o" lastModified="14bd21ecfd1"/>
<source file="..\obj\arc4.o" lastModified="14bd21ed032"/>
<source file="..\obj\ssl.o" lastModified="14bd21ed1a2"/>
<source file="..\obj\arm_conv_opt_q7.o" lastModified="14bd21ed258"/>
<source file="..\obj\arm_pid_init_f32.o" lastModified="14bd21ed2bb"/>
<source file="..\obj\UDPSocket.o" lastModified="14bd21ed42f"/>
<source file="..\obj\Sine_f32.o" lastModified="14bd21ed4be"/>
<source file="..\obj\arm_cmplx_mag_squared_q31.o" lastModified="14bd21ed52b"/>
<source file="..\obj\arm_scale_q15.o" lastModified="14bd21ed596"/>
<source file="..\obj\arm_fir_q31.o" lastModified="14bd21ed624"/>
<source file="..\obj\arm_mult_q7.o" lastModified="14bd21ed692"/>
<source file="..\obj\arm_add_q31.o" lastModified="14bd21ed702"/>
<source file="..\obj\arm_fir_sparse_init_q15.o" lastModified="14bd21ed777"/>
<source file="..\obj\W5500.o" lastModified="14bd21edbba"/>
<source file="..\obj\HAL_CM.o" lastModified="14bd21edc41"/>
<source file="..\obj\arm_fir_interpolate_q31.o" lastModified="14bd21edd03"/>
<source file="..\obj\math_helper.o" lastModified="14bd21eddb9"/>
<source file="..\obj\misc.o" lastModified="14bd21ede06"/>
<source file="..\obj\arm_sin_cos_f32.o" lastModified="14bd21ede73"/>
<source file="..\obj\arm_cmplx_mult_real_q15.o" lastModified="14bd21edee6"/>
<source file="..\obj\arm_scale_f32.o" lastModified="14bd21edf47"/>
<source file="..\obj\arm_max_q7.o" lastModified="14bd21edfaf"/>
<source file="..\obj\arm_min_q7.o" lastModified="14bd21ee017"/>
<source file="..\obj\arm_fill_q15.o" lastModified="14bd21ee078"/>
<source file="..\obj\arm_fir_sparse_init_f32.o" lastModified="14bd21ee0d3"/>
<source file="..\obj\arm_sin_q15.o" lastModified="14bd21ee13c"/>
<source file="..\obj\arm_cmplx_mult_real_f32.o" lastModified="14bd21ee1a5"/>
<source file="..\obj\Socket.o" lastModified="14bd21ee271"/>
<source file="..\obj\SVC_Table.o" lastModified="14bd21ee28c"/>
<source file="..\obj\arm_lms_norm_init_q31.o" lastModified="14bd21ee2ea"/>
<source file="..\obj\arm_biquad_cascade_df2T_f32.o" lastModified="14bd21ee357"/>
<source file="..\obj\rsa.o" lastModified="14bd21ee40d"/>
<source file="..\obj\arm_mean_q31.o" lastModified="14bd21ee46f"/>
<source file="..\obj\arm_fill_f32.o" lastModified="14bd21ee4ce"/>
<source file="..\obj\arm_q31_to_q15.o" lastModified="14bd21ee531"/>
<source file="..\obj\DHCPClient.o" lastModified="14bd21ee69a"/>
<source file="..\obj\arm_fir_decimate_init_q31.o" lastModified="14bd21ee6f7"/>
<source file="..\obj\arm_sin_f32.o" lastModified="14bd21ee760"/>
<source file="..\obj\arm_correlate_q15.o" lastModified="14bd21ee857"/>
<source file="..\obj\arm_float_to_q31.o" lastModified="14bd21ee8bf"/>
<source file="..\obj\arm_max_q15.o" lastModified="14bd21ee92b"/>
<source file="..\obj\arm_mean_q7.o" lastModified="14bd21ee98e"/>
<source file="..\obj\W5100.o" lastModified="14bd21eea52"/>
<source file="..\obj\arm_cos_q31.o" lastModified="14bd21eeaba"/>
<source file="..\obj\rt_MemBox.o" lastModified="14bd21eeb06"/>
<source file="..\obj\arm_cfft_radix4_init_q15.o" lastModified="14bd21eeb6a"/>
<source file="..\obj\arm_lms_q31.o" lastModified="14bd21eebf7"/>
<source file="..\obj\arm_negate_q31.o" lastModified="14bd21eec5a"/>
<source file="..\obj\arm_biquad_cascade_df1_fast_q31.o" lastModified="14bd21eecdd"/>
<source file="..\obj\arm_sqrt_q31.o" lastModified="14bd21eed4c"/>
<source file="..\obj\arm_bitreversal.o" lastModified="14bd21eedda"/>
<source file="..\obj\arm_dot_prod_q7.o" lastModified="14bd21eee42"/>
<source file="..\obj\arm_correlate_f32.o" lastModified="14bd21eeee7"/>
<source file="..\obj\arm_max_f32.o" lastModified="14bd21eef4f"/>
<source file="..\obj\arm_var_q31.o" lastModified="14bd21eefc2"/>
<source file="..\obj\arm_mat_mult_q15.o" lastModified="14bd21ef212"/>
<source file="..\obj\arm_fir_interpolate_init_q15.o" lastModified="14bd21ef271"/>
<source file="..\obj\arm_mat_sub_q31.o" lastModified="14bd21ef2d9"/>
<source file="..\obj\arm_mat_trans_q31.o" lastModified="14bd21ef343"/>
<source file="..\obj\arm_offset_q31.o" lastModified="14bd21ef3a7"/>
<source file="..\obj\arm_shift_q15.o" lastModified="14bd21ef417"/>
<source file="..\obj\Endpoint.o" lastModified="14bd21ef540"/>
<source file="..\obj\arm_cfft_radix4_init_f32.o" lastModified="14bd21ef5aa"/>
<source file="..\obj\arm_copy_q7.o" lastModified="14bd21ef60b"/>
<source file="..\obj\arm_mult_q15.o" lastModified="14bd21ef674"/>
<source file="..\obj\arm_sub_q7.o" lastModified="14bd21ef6de"/>
<source file="..\obj\rt_CMSIS.o" lastModified="14bd21ef8a7"/>
<source file="..\obj\arm_correlate_opt_q7.o" lastModified="14bd21ef945"/>
<source file="..\obj\arm_cmplx_mult_cmplx_q31.o" lastModified="14bd21ef9c6"/>
<source file="..\obj\arm_mat_mult_fast_q31.o" lastModified="14bd21efa40"/>
<source file="..\obj\arm_conv_fast_q31.o" lastModified="14bd21efb11"/>
<source file="..\obj\arm_mat_scale_q31.o" lastModified="14bd21efb7f"/>
<source file="..\obj\arm_mat_mult_f32.o" lastModified="14bd21efbee"/>
<source file="..\obj\arm_fir_interpolate_init_f32.o" lastModified="14bd21efc83"/>
<source file="..\obj\arm_mat_add_q15.o" lastModified="14bd21efcec"/>
<source file="..\obj\arm_mult_f32.o" lastModified="14bd21efd51"/>
</target>
</processor>
</history>
<?xml version='1.0' encoding='UTF-8'?>
<history>
<processor signature="arm-none-eabi-gcc noversion nomachine -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -Wall -ffunction-sections -g -Os -fno-common -fmessage-length=0 -Wall -fno-strict-aliasing -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -std=gnu++98 -c -DTARGET_NUCLEO_F401RE -DTARGET_M4 -DTARGET_CORTEX_M -DTARGET_STM -DTARGET_STM32F4 -DTARGET_STM32F401RE -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -D__CORTEX_M4 -DARM_MATH_CM4 -D__FPU_PRESENT=1 -DMBED_BUILD_TIMESTAMP=1425112289.35 -D__MBED__=1 -DTARGET_FF_ARDUINO -DTARGET_FF_MORPHO -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\Display -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-rtos\rtos -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-rtos\rtx\TARGET_CORTEX_M\TARGET_M4\TOOLCHAIN_GCC -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\WIZnet_Library\WIZnetInterface\Socket -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-rtos\rtx -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-rtos\rtx\TARGET_CORTEX_M -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed -I..\..\..\..\..\MyDocuments\GitHub -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed\TARGET_NUCLEO_F401RE -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\TransformFunctions -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed\TARGET_NUCLEO_F401RE\TARGET_STM\TARGET_STM32F4 -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed\TARGET_NUCLEO_F401RE\TARGET_STM -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed\TARGET_NUCLEO_F401RE\TARGET_STM\TARGET_STM32F4\TARGET_NUCLEO_F401RE -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\ControllerFunctions -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\ComplexMathFunctions -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\WIZnet_Library\WIZnetInterface\DNSClient -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\WIZnet_Library\WIZnetInterface -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed\TARGET_NUCLEO_F401RE\TARGET_STM\TARGET_NUCLEO_F401RE -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\WIZnet_Library\WIZnetInterface\WIZnet -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\FastMathFunctions -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\CommonTables -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\MatrixFunctions -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\WIZnet_Library -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\WIZnet_Library\WIZnetInterface\DHCPClient -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\SupportFunctions -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\BasicMathFunctions -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed\TARGET_NUCLEO_F401RE\TOOLCHAIN_GCC_ARM -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\dsp -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-rtos\rtx\TARGET_CORTEX_M\TARGET_M4 -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\FilteringFunctions -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-dsp\cmsis_dsp\StatisticsFunctions -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\CyaSSL -I..\..\..\..\..\MyDocuments\GitHub\Sensor-Board\mbed-rtos">
<target file="arm_shift_q31.o" lastModified="14bd21e6a60">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_shift_q31.c" lastModified="14bcf515ece"/>
</target>
<target file="arm_fir_decimate_init_f32.o" lastModified="14bd21ebb63">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_decimate_init_f32.c" lastModified="14bcf515225"/>
</target>
<target file="rt_Task.o" lastModified="14bd21e79d5">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_Task.c" lastModified="14bcf5166cc"/>
</target>
<target file="arm_min_q15.o" lastModified="14bd21e7f46">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_min_q15.c" lastModified="14bcf5165b5"/>
</target>
<target file="arm_bitreversal.o" lastModified="14bd21eedda">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_bitreversal.c" lastModified="14bcf514bd0"/>
</target>
<target file="arm_add_q31.o" lastModified="14bd21ed702">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_add_q31.c" lastModified="14bcf516223"/>
</target>
<target file="arm_conv_q7.o" lastModified="14bd21e523d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_q7.c" lastModified="14bcf515367"/>
</target>
<target file="rt_Time.o" lastModified="14bd21eb31a">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_Time.c" lastModified="14bcf516837"/>
</target>
<target file="arm_mat_init_f32.o" lastModified="14bd21e7a97">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_init_f32.c" lastModified="14bcf51577c"/>
</target>
<target file="ssl.o" lastModified="14bd21ed1a2">
<source file="..\..\..\CyaSSL\ssl.c" lastModified="14bcf511013"/>
</target>
<target file="arm_mat_add_q31.o" lastModified="14bd21e6de3">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_add_q31.c" lastModified="14bcf515876"/>
</target>
<target file="arm_iir_lattice_init_q31.o" lastModified="14bd21e99ec">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_iir_lattice_init_q31.c" lastModified="14bcf515332"/>
</target>
<target file="arm_fill_q15.o" lastModified="14bd21ee078">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_fill_q15.c" lastModified="14bcf514e6a"/>
</target>
<target file="arm_mat_scale_q15.o" lastModified="14bd21ec4e0">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_scale_q15.c" lastModified="14bcf515800"/>
</target>
<target file="arm_biquad_cascade_df2T_init_f32.o" lastModified="14bd21e5aac">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df2T_init_f32.c" lastModified="14bcf515342"/>
</target>
<target file="arm_conv_q15.o" lastModified="14bd21e7789">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_q15.c" lastModified="14bcf515407"/>
</target>
<target file="arm_conv_partial_fast_opt_q15.o" lastModified="14bd21ea570">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_partial_fast_opt_q15.c" lastModified="14bcf5150c6"/>
</target>
<target file="sha.o" lastModified="14bd21e3fd6">
<source file="..\..\..\CyaSSL\sha.c" lastModified="14bcf510e95"/>
</target>
<target file="arm_iir_lattice_f32.o" lastModified="14bd21e9550">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_iir_lattice_f32.c" lastModified="14bcf515218"/>
</target>
<target file="arm_std_q15.o" lastModified="14bd21e6cb1">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_std_q15.c" lastModified="14bcf516677"/>
</target>
<target file="arm_biquad_cascade_df1_fast_q31.o" lastModified="14bd21eecdd">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_fast_q31.c" lastModified="14bcf51541b"/>
</target>
<target file="arm_dot_prod_q7.o" lastModified="14bd21eee42">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_dot_prod_q7.c" lastModified="14bcf516248"/>
</target>
<target file="arm_rfft_q15.o" lastModified="14bd21e4486">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_rfft_q15.c" lastModified="14bcf514a0d"/>
</target>
<target file="arm_fir_q31.o" lastModified="14bd21ed624">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_q31.c" lastModified="14bcf515558"/>
</target>
<target file="arm_conv_fast_opt_q15.o" lastModified="14bd21e5f54">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_fast_opt_q15.c" lastModified="14bcf515321"/>
</target>
<target file="tls.o" lastModified="14bd21e43aa">
<source file="..\..\..\CyaSSL\tls.c" lastModified="14bcf510f84"/>
</target>
<target file="arm_correlate_fast_opt_q15.o" lastModified="14bd21e8035">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_correlate_fast_opt_q15.c" lastModified="14bcf5151e0"/>
</target>
<target file="arm_min_q7.o" lastModified="14bd21ee017">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_min_q7.c" lastModified="14bcf516546"/>
</target>
<target file="arm_rfft_init_q15.o" lastModified="14bd21e7e01">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_rfft_init_q15.c" lastModified="14bcf514bf5"/>
</target>
<target file="arm_fir_interpolate_init_q15.o" lastModified="14bd21ef271">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_interpolate_init_q15.c" lastModified="14bcf51516a"/>
</target>
<target file="arm_cmplx_dot_prod_f32.o" lastModified="14bd21e4a82">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_dot_prod_f32.c" lastModified="14bcf516392"/>
</target>
<target file="arm_copy_q7.o" lastModified="14bd21ef60b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_copy_q7.c" lastModified="14bcf514ddd"/>
</target>
<target file="arm_correlate_opt_q15.o" lastModified="14bd21ecf71">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_correlate_opt_q15.c" lastModified="14bcf515116"/>
</target>
<target file="arm_biquad_cascade_df1_f32.o" lastModified="14bd21e4a0f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_f32.c" lastModified="14bcf515145"/>
</target>
<target file="arm_dot_prod_f32.o" lastModified="14bd21e5ec4">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_dot_prod_f32.c" lastModified="14bcf5161cf"/>
</target>
<target file="arm_correlate_q15.o" lastModified="14bd21ee857">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_correlate_q15.c" lastModified="14bcf51545c"/>
</target>
<target file="arm_power_f32.o" lastModified="14bd21e9b50">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_power_f32.c" lastModified="14bcf5165e9"/>
</target>
<target file="arm_fir_sparse_init_q15.o" lastModified="14bd21ed777">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_sparse_init_q15.c" lastModified="14bcf5154a9"/>
</target>
<target file="arm_fir_sparse_q15.o" lastModified="14bd21e5363">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_sparse_q15.c" lastModified="14bcf51542f"/>
</target>
<target file="W5200.o" lastModified="14bd21e8852">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\WIZnet\W5200.cpp" lastModified="14bcf518517"/>
</target>
<target file="arm_var_q31.o" lastModified="14bd21eefc2">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_var_q31.c" lastModified="14bcf516557"/>
</target>
<target file="arm_cfft_radix2_init_q31.o" lastModified="14bd21eb09d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix2_init_q31.c" lastModified="14bcf514cca"/>
</target>
<target file="arm_dct4_init_q31.o" lastModified="14bd21e9288">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_dct4_init_q31.c" lastModified="14bcf514cf2"/>
</target>
<target file="arm_mean_q15.o" lastModified="14bd21eb037">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_mean_q15.c" lastModified="14bcf516695"/>
</target>
<target file="arm_float_to_q15.o" lastModified="14bd21eb45d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_float_to_q15.c" lastModified="14bcf514ef3"/>
</target>
<target file="arm_scale_f32.o" lastModified="14bd21edf47">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_scale_f32.c" lastModified="14bcf5162d7"/>
</target>
<target file="arm_q7_to_q31.o" lastModified="14bd21e871f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_q7_to_q31.c" lastModified="14bcf514eb2"/>
</target>
<target file="rt_CMSIS.o" lastModified="14bd21ef8a7">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_CMSIS.c" lastModified="14bcf5167ce"/>
</target>
<target file="arm_cfft_radix4_q31.o" lastModified="14bd21e795d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix4_q31.c" lastModified="14bcf514d33"/>
</target>
<target file="arm_cmplx_mag_q31.o" lastModified="14bd21eca71">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mag_q31.c" lastModified="14bcf5163b6"/>
</target>
<target file="arm_mult_f32.o" lastModified="14bd21efd51">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_mult_f32.c" lastModified="14bcf515fdb"/>
</target>
<target file="arm_biquad_cascade_df2T_f32.o" lastModified="14bd21ee357">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df2T_f32.c" lastModified="14bcf5155c9"/>
</target>
<target file="arm_sin_q31.o" lastModified="14bd21e52a5">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FastMathFunctions\arm_sin_q31.c" lastModified="14bcf5164c9"/>
</target>
<target file="arm_cfft_radix2_f32.o" lastModified="14bd21eced9">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix2_f32.c" lastModified="14bcf514bdf"/>
</target>
<target file="arm_fir_decimate_init_q15.o" lastModified="14bd21eb212">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_decimate_init_q15.c" lastModified="14bcf515654"/>
</target>
<target file="arm_add_q7.o" lastModified="14bd21e39f6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_add_q7.c" lastModified="14bcf51619b"/>
</target>
<target file="arm_mat_init_q15.o" lastModified="14bd21e762a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_init_q15.c" lastModified="14bcf51584a"/>
</target>
<target file="arm_copy_q31.o" lastModified="14bd21ece30">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_copy_q31.c" lastModified="14bcf514e04"/>
</target>
<target file="cyassl_io.o" lastModified="14bd21eaf6f">
<source file="..\..\..\CyaSSL\cyassl_io.c" lastModified="14bcf510f74"/>
</target>
<target file="arm_q31_to_q7.o" lastModified="14bd21e3d2d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_q31_to_q7.c" lastModified="14bcf514df4"/>
</target>
<target file="W5100.o" lastModified="14bd21eea52">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\WIZnet\W5100.cpp" lastModified="14bcf51854f"/>
</target>
<target file="arm_cmplx_mag_squared_f32.o" lastModified="14bd21ea7d5">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mag_squared_f32.c" lastModified="14bcf516372"/>
</target>
<target file="arm_conv_opt_q15.o" lastModified="14bd21e81ba">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_opt_q15.c" lastModified="14bcf5152c9"/>
</target>
<target file="arm_max_q31.o" lastModified="14bd21e5ca8">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_max_q31.c" lastModified="14bcf516586"/>
</target>
<target file="arm_correlate_q7.o" lastModified="14bd21e4553">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_correlate_q7.c" lastModified="14bcf5155d8"/>
</target>
<target file="arm_offset_q31.o" lastModified="14bd21ef3a7">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_offset_q31.c" lastModified="14bcf516234"/>
</target>
<target file="arm_fir_lattice_q31.o" lastModified="14bd21e9af0">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_lattice_q31.c" lastModified="14bcf5151fc"/>
</target>
<target file="md4.o" lastModified="14bd21eab87">
<source file="..\..\..\CyaSSL\md4.c" lastModified="14bcf5110c3"/>
</target>
<target file="arm_iir_lattice_q15.o" lastModified="14bd21e8ff6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_iir_lattice_q15.c" lastModified="14bcf51548a"/>
</target>
<target file="arm_conv_partial_opt_q15.o" lastModified="14bd21e3e1b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_partial_opt_q15.c" lastModified="14bcf515300"/>
</target>
<target file="arc4.o" lastModified="14bd21ed032">
<source file="..\..\..\CyaSSL\arc4.c" lastModified="14bcf510ffd"/>
</target>
<target file="arm_cmplx_dot_prod_q15.o" lastModified="14bd21e4040">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_dot_prod_q15.c" lastModified="14bcf516322"/>
</target>
<target file="arm_biquad_cascade_df1_q15.o" lastModified="14bd21e3e9a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_q15.c" lastModified="14bcf5153bf"/>
</target>
<target file="arm_dot_prod_q15.o" lastModified="14bd21e53ca">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_dot_prod_q15.c" lastModified="14bcf51618a"/>
</target>
<target file="arm_pid_init_q31.o" lastModified="14bd21e3c64">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ControllerFunctions\arm_pid_init_q31.c" lastModified="14bcf515721"/>
</target>
<target file="arm_dct4_f32.o" lastModified="14bd21e8f06">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_dct4_f32.c" lastModified="14bcf514cab"/>
</target>
<target file="arm_conv_fast_q31.o" lastModified="14bd21efb11">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_fast_q31.c" lastModified="14bcf51543d"/>
</target>
<target file="arm_fir_init_f32.o" lastModified="14bd21e9056">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_init_f32.c" lastModified="14bcf51537a"/>
</target>
<target file="arm_sub_q31.o" lastModified="14bd21ea079">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_sub_q31.c" lastModified="14bcf5160fb"/>
</target>
<target file="arm_fir_interpolate_f32.o" lastModified="14bd21eaeb6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_interpolate_f32.c" lastModified="14bcf51538c"/>
</target>
<target file="arm_power_q15.o" lastModified="14bd21e9423">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_power_q15.c" lastModified="14bcf516566"/>
</target>
<target file="rt_MemBox.o" lastModified="14bd21eeb06">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_MemBox.c" lastModified="14bcf516752"/>
</target>
<target file="aes.o" lastModified="14bd21e9f52">
<source file="..\..\..\CyaSSL\aes.c" lastModified="14bcf5110a3"/>
</target>
<target file="keys.o" lastModified="14bd21e4cb7">
<source file="..\..\..\CyaSSL\keys.c" lastModified="14bcf511258"/>
</target>
<target file="arm_cos_q31.o" lastModified="14bd21eeaba">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FastMathFunctions\arm_cos_q31.c" lastModified="14bcf5164db"/>
</target>
<target file="arm_mat_sub_q31.o" lastModified="14bd21ef2d9">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_sub_q31.c" lastModified="14bcf5157d6"/>
</target>
<target file="arm_rms_f32.o" lastModified="14bd21e6bdc">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_rms_f32.c" lastModified="14bcf5164ee"/>
</target>
<target file="RTX_Conf_CM.o" lastModified="14bd21e3d78">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\RTX_Conf_CM.c" lastModified="14bcf516825"/>
</target>
<target file="arm_lms_norm_init_f32.o" lastModified="14bd21eb4ba">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_norm_init_f32.c" lastModified="14bcf5153ad"/>
</target>
<target file="math_helper.o" lastModified="14bd21eddb9">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\math_helper.c" lastModified="14bcf514e16"/>
</target>
<target file="arm_fir_fast_q31.o" lastModified="14bd21ec7d4">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_fast_q31.c" lastModified="14bcf515299"/>
</target>
<target file="arm_cmplx_mult_real_q31.o" lastModified="14bd21e4bed">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mult_real_q31.c" lastModified="14bcf5163a5"/>
</target>
<target file="arm_cmplx_mult_cmplx_f32.o" lastModified="14bd21ec74d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mult_cmplx_f32.c" lastModified="14bcf5163ea"/>
</target>
<target file="arm_sub_q7.o" lastModified="14bd21ef6de">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_sub_q7.c" lastModified="14bcf516123"/>
</target>
<target file="arm_scale_q15.o" lastModified="14bd21ed596">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_scale_q15.c" lastModified="14bcf5160d8"/>
</target>
<target file="arm_mat_trans_f32.o" lastModified="14bd21ec547">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_trans_f32.c" lastModified="14bcf515810"/>
</target>
<target file="UDPSocket.o" lastModified="14bd21ed42f">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\Socket\UDPSocket.cpp" lastModified="14bcf518444"/>
</target>
<target file="arm_sqrt_q15.o" lastModified="14bd21eb84b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FastMathFunctions\arm_sqrt_q15.c" lastModified="14bcf5164b8"/>
</target>
<target file="arm_negate_q7.o" lastModified="14bd21e7154">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_negate_q7.c" lastModified="14bcf515ff7"/>
</target>
<target file="rt_List.o" lastModified="14bd21ebe77">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_List.c" lastModified="14bcf516866"/>
</target>
<target file="coding.o" lastModified="14bd21e6539">
<source file="..\..\..\CyaSSL\coding.c" lastModified="14bcf51113a"/>
</target>
<target file="arm_mat_mult_f32.o" lastModified="14bd21efbee">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_mult_f32.c" lastModified="14bcf5157c7"/>
</target>
<target file="arm_abs_q31.o" lastModified="14bd21e9e1e">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_abs_q31.c" lastModified="14bcf5162f7"/>
</target>
<target file="arm_mult_q15.o" lastModified="14bd21ef674">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_mult_q15.c" lastModified="14bcf516288"/>
</target>
<target file="arm_cfft_radix2_q15.o" lastModified="14bd21ec8fb">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix2_q15.c" lastModified="14bcf514c9c"/>
</target>
<target file="arm_biquad_cascade_df1_init_f32.o" lastModified="14bd21e7219">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_init_f32.c" lastModified="14bcf5150f7"/>
</target>
<target file="rt_System.o" lastModified="14bd21e6d1f">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_System.c" lastModified="14bcf5167af"/>
</target>
<target file="arm_min_q31.o" lastModified="14bd21eaaea">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_min_q31.c" lastModified="14bcf516649"/>
</target>
<target file="DHCPClient.o" lastModified="14bd21ee69a">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\DHCPClient\DHCPClient.cpp" lastModified="14bcf51859c"/>
</target>
<target file="arm_cmplx_mag_squared_q15.o" lastModified="14bd21ea30e">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mag_squared_q15.c" lastModified="14bcf51643b"/>
</target>
<target file="arm_shift_q7.o" lastModified="14bd21e9990">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_shift_q7.c" lastModified="14bcf51613d"/>
</target>
<target file="arm_lms_init_f32.o" lastModified="14bd21e623a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_init_f32.c" lastModified="14bcf515608"/>
</target>
<target file="arm_mat_scale_q31.o" lastModified="14bd21efb7f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_scale_q31.c" lastModified="14bcf51576d"/>
</target>
<target file="arm_fill_q31.o" lastModified="14bd21e508d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_fill_q31.c" lastModified="14bcf51508c"/>
</target>
<target file="arm_conv_q31.o" lastModified="14bd21ea3bb">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_q31.c" lastModified="14bcf51550e"/>
</target>
<target file="arm_fir_sparse_init_q7.o" lastModified="14bd21e8605">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_sparse_init_q7.c" lastModified="14bcf515194"/>
</target>
<target file="hmac.o" lastModified="14bd21ec842">
<source file="..\..\..\CyaSSL\hmac.c" lastModified="14bcf511186"/>
</target>
<target file="WIZnetInterface.o" lastModified="14bd21e991f">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\WIZnetInterface.cpp" lastModified="14bcf5183eb"/>
</target>
<target file="arm_q7_to_float.o" lastModified="14bd21e7fa8">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_q7_to_float.c" lastModified="14bcf514e79"/>
</target>
<target file="arm_std_q31.o" lastModified="14bd21e9d1e">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_std_q31.c" lastModified="14bcf516576"/>
</target>
<target file="rabbit.o" lastModified="14bd21e38e1">
<source file="..\..\..\CyaSSL\rabbit.c" lastModified="14bcf51119b"/>
</target>
<target file="arm_rfft_q31.o" lastModified="14bd21e82a3">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_rfft_q31.c" lastModified="14bcf514c03"/>
</target>
<target file="HAL_CM4.o" lastModified="14bd21ebcb8">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\TARGET_M4\TOOLCHAIN_GCC\HAL_CM4.s" lastModified="14bcf5168ab"/>
</target>
<target file="arm_mean_q7.o" lastModified="14bd21ee98e">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_mean_q7.c" lastModified="14bcf5165a6"/>
</target>
<target file="arm_fir_decimate_fast_q15.o" lastModified="14bd21e40cc">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_decimate_fast_q15.c" lastModified="14bcf515245"/>
</target>
<target file="arm_rfft_init_q31.o" lastModified="14bd21ea9b5">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_rfft_init_q31.c" lastModified="14bcf514d08"/>
</target>
<target file="arm_fir_interpolate_init_q31.o" lastModified="14bd21e6935">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_interpolate_init_q31.c" lastModified="14bcf5156b0"/>
</target>
<target file="rt_Event.o" lastModified="14bd21e8210">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_Event.c" lastModified="14bcf5167db"/>
</target>
<target file="arm_conv_partial_fast_q15.o" lastModified="14bd21e7edd">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_partial_fast_q15.c" lastModified="14bcf5155a4"/>
</target>
<target file="rt_Mailbox.o" lastModified="14bd21ec2cb">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_Mailbox.c" lastModified="14bcf516774"/>
</target>
<target file="arm_dct4_q15.o" lastModified="14bd21e88d2">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_dct4_q15.c" lastModified="14bcf514d64"/>
</target>
<target file="integer.o" lastModified="14bd21e75cf">
<source file="..\..\..\CyaSSL\integer.c" lastModified="14bcf5111c9"/>
</target>
<target file="arm_correlate_q31.o" lastModified="14bd21e5bbc">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_correlate_q31.c" lastModified="14bcf515499"/>
</target>
<target file="arm_fir_init_q15.o" lastModified="14bd21e8ba2">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_init_q15.c" lastModified="14bcf5155f8"/>
</target>
<target file="arm_fir_interpolate_q15.o" lastModified="14bd21ea772">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_interpolate_q15.c" lastModified="14bcf515310"/>
</target>
<target file="arm_cmplx_conj_f32.o" lastModified="14bd21e9368">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_conj_f32.c" lastModified="14bcf516419"/>
</target>
<target file="arm_fir_sparse_init_q31.o" lastModified="14bd21e4405">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_sparse_init_q31.c" lastModified="14bcf5152dd"/>
</target>
<target file="Semaphore.o" lastModified="14bd21ebbc1">
<source file="..\..\..\mbed-rtos\rtos\Semaphore.cpp" lastModified="14bcf518090"/>
</target>
<target file="arm_sin_cos_q31.o" lastModified="14bd21e4210">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ControllerFunctions\arm_sin_cos_q31.c" lastModified="14bcf51575b"/>
</target>
<target file="arm_fir_sparse_q31.o" lastModified="14bd21e8b44">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_sparse_q31.c" lastModified="14bcf51546c"/>
</target>
<target file="arm_rms_q15.o" lastModified="14bd21e64c0">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_rms_q15.c" lastModified="14bcf516527"/>
</target>
<target file="arm_cfft_radix4_init_f32.o" lastModified="14bd21ef5aa">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix4_init_f32.c" lastModified="14bcf514d25"/>
</target>
<target file="arm_lms_norm_init_q15.o" lastModified="14bd21eafd4">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_norm_init_q15.c" lastModified="14bcf5153f4"/>
</target>
<target file="arm_fir_decimate_f32.o" lastModified="14bd21ea24b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_decimate_f32.c" lastModified="14bcf5154b8"/>
</target>
<target file="arm_lms_f32.o" lastModified="14bd21ebff7">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_f32.c" lastModified="14bcf515355"/>
</target>
<target file="arm_biquad_cascade_df1_32x64_q31.o" lastModified="14bd21e5e61">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_32x64_q31.c" lastModified="14bcf5150aa"/>
</target>
<target file="arm_rfft_fast_f32.o" lastModified="14bd21e9304">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_rfft_fast_f32.c" lastModified="14bcf514c12"/>
</target>
<target file="arm_mean_q31.o" lastModified="14bd21ee46f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_mean_q31.c" lastModified="14bcf5165fa"/>
</target>
<target file="arm_fir_lattice_init_f32.o" lastModified="14bd21e7b8f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_lattice_init_f32.c" lastModified="14bcf5152ed"/>
</target>
<target file="arm_cmplx_mult_cmplx_q15.o" lastModified="14bd21ec25b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mult_cmplx_q15.c" lastModified="14bcf516382"/>
</target>
<target file="arm_float_to_q31.o" lastModified="14bd21ee8bf">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_float_to_q31.c" lastModified="14bcf514ee6"/>
</target>
<target file="arm_correlate_opt_q7.o" lastModified="14bd21ef945">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_correlate_opt_q7.c" lastModified="14bcf5150e8"/>
</target>
<target file="arm_pid_reset_f32.o" lastModified="14bd21ea483">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ControllerFunctions\arm_pid_reset_f32.c" lastModified="14bcf51573e"/>
</target>
<target file="arm_mat_trans_q15.o" lastModified="14bd21ebdf5">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_trans_q15.c" lastModified="14bcf51585b"/>
</target>
<target file="arm_conv_partial_f32.o" lastModified="14bd21e65db">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_partial_f32.c" lastModified="14bcf51544b"/>
</target>
<target file="arm_mat_mult_q15.o" lastModified="14bd21ef212">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_mult_q15.c" lastModified="14bcf5157a9"/>
</target>
<target file="RtosTimer.o" lastModified="14bd21ea1bb">
<source file="..\..\..\mbed-rtos\rtos\RtosTimer.cpp" lastModified="14bcf517fe4"/>
</target>
<target file="arm_biquad_cascade_df1_init_q15.o" lastModified="14bd21e6c42">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_init_q15.c" lastModified="14bcf5151c2"/>
</target>
<target file="arm_mult_q7.o" lastModified="14bd21ed692">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_mult_q7.c" lastModified="14bcf5162c2"/>
</target>
<target file="Sine_f32.o" lastModified="14bd21ed4be">
<source file="..\..\..\mbed-dsp\dsp\Sine_f32.cpp" lastModified="14bcf512b96"/>
</target>
<target file="arm_fir_decimate_init_q31.o" lastModified="14bd21ee6f7">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_decimate_init_q31.c" lastModified="14bcf515549"/>
</target>
<target file="des3.o" lastModified="14bd21e8d41">
<source file="..\..\..\CyaSSL\des3.c" lastModified="14bcf5110d1"/>
</target>
<target file="arm_negate_f32.o" lastModified="14bd21ec057">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_negate_f32.c" lastModified="14bcf51607a"/>
</target>
<target file="arm_lms_norm_f32.o" lastModified="14bd21ea0f7">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_norm_f32.c" lastModified="14bcf5156de"/>
</target>
<target file="Endpoint.o" lastModified="14bd21ef540">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\Socket\Endpoint.cpp" lastModified="14bcf518454"/>
</target>
<target file="arm_mat_init_q31.o" lastModified="14bd21ea2a6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_init_q31.c" lastModified="14bcf5157f1"/>
</target>
<target file="arm_add_f32.o" lastModified="14bd21ea8ce">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_add_f32.c" lastModified="14bcf5161aa"/>
</target>
<target file="arm_lms_init_q15.o" lastModified="14bd21e5b0b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_init_q15.c" lastModified="14bcf515267"/>
</target>
<target file="cyassl_int.o" lastModified="14bd21e5a4f">
<source file="..\..\..\CyaSSL\cyassl_int.c" lastModified="14bcf511023"/>
</target>
<target file="arm_mat_add_f32.o" lastModified="14bd21e3ac2">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_add_f32.c" lastModified="14bcf5158a7"/>
</target>
<target file="arm_iir_lattice_init_f32.o" lastModified="14bd21e6d7c">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_iir_lattice_init_f32.c" lastModified="14bcf515137"/>
</target>
<target file="arm_correlate_fast_q15.o" lastModified="14bd21e54f0">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_correlate_fast_q15.c" lastModified="14bcf51561c"/>
</target>
<target file="TCPSocketConnection.o" lastModified="14bd21eb3f8">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\Socket\TCPSocketConnection.cpp" lastModified="14bcf5184a4"/>
</target>
<target file="arm_iir_lattice_q31.o" lastModified="14bd21ebf7b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_iir_lattice_q31.c" lastModified="14bcf5153e3"/>
</target>
<target file="pwdbased.o" lastModified="14bd21e4b7d">
<source file="..\..\..\CyaSSL\pwdbased.c" lastModified="14bcf5110f1"/>
</target>
<target file="arm_cmplx_dot_prod_q31.o" lastModified="14bd21e7c85">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_dot_prod_q31.c" lastModified="14bcf51644c"/>
</target>
<target file="arm_fir_q7.o" lastModified="14bd21e8332">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_q7.c" lastModified="14bcf515679"/>
</target>
<target file="arm_biquad_cascade_df1_q31.o" lastModified="14bd21e7c0f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_q31.c" lastModified="14bcf515233"/>
</target>
<target file="arm_fir_f32.o" lastModified="14bd21ea86a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_f32.c" lastModified="14bcf515568"/>
</target>
<target file="random.o" lastModified="14bd21ecfd1">
<source file="..\..\..\CyaSSL\random.c" lastModified="14bcf510f00"/>
</target>
<target file="arm_dot_prod_q31.o" lastModified="14bd21e8c10">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_dot_prod_q31.c" lastModified="14bcf5161e0"/>
</target>
<target file="rt_Robin.o" lastModified="14bd21e42c7">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_Robin.c" lastModified="14bcf516765"/>
</target>
<target file="arm_offset_q7.o" lastModified="14bd21ecad7">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_offset_q7.c" lastModified="14bcf5161bb"/>
</target>
<target file="arm_cmplx_conj_q15.o" lastModified="14bd21e8e87">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_conj_q15.c" lastModified="14bcf5163fa"/>
</target>
<target file="arm_power_q31.o" lastModified="14bd21ec67e">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_power_q31.c" lastModified="14bcf516622"/>
</target>
<target file="Display.o" lastModified="14bd21e572a">
<source file="..\..\..\Display\Display.cpp" lastModified="14bcf5115fb"/>
</target>
<target file="arm_cfft_radix4_init_q15.o" lastModified="14bd21eeb6a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix4_init_q15.c" lastModified="14bcf514c23"/>
</target>
<target file="arm_fir_decimate_q15.o" lastModified="14bd21e9db7">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_decimate_q15.c" lastModified="14bcf515522"/>
</target>
<target file="arm_lms_q15.o" lastModified="14bd21eb6a6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_q15.c" lastModified="14bcf515209"/>
</target>
<target file="arm_mat_mult_fast_q15.o" lastModified="14bd21ec349">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_mult_fast_q15.c" lastModified="14bcf51578d"/>
</target>
<target file="arm_fir_lattice_init_q15.o" lastModified="14bd21e77e4">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_lattice_init_q15.c" lastModified="14bcf5151d2"/>
</target>
<target file="arm_var_f32.o" lastModified="14bd21ec470">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_var_f32.c" lastModified="14bcf516537"/>
</target>
<target file="arm_cfft_radix2_init_f32.o" lastModified="14bd21e8786">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix2_init_f32.c" lastModified="14bcf514c8a"/>
</target>
<target file="arm_dct4_init_f32.o" lastModified="14bd21e6860">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_dct4_init_f32.c" lastModified="14bcf514c64"/>
</target>
<target file="arm_conv_partial_opt_q7.o" lastModified="14bd21e4b1f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_partial_opt_q7.c" lastModified="14bcf51539d"/>
</target>
<target file="arm_scale_q31.o" lastModified="14bd21e4288">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_scale_q31.c" lastModified="14bcf516310"/>
</target>
<target file="arm_fir_init_q7.o" lastModified="14bd21eaf11">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_init_q7.c" lastModified="14bcf51527d"/>
</target>
<target file="arm_pid_reset_q15.o" lastModified="14bd21ea010">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ControllerFunctions\arm_pid_reset_q15.c" lastModified="14bcf515710"/>
</target>
<target file="arm_fill_q7.o" lastModified="14bd21e6995">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_fill_q7.c" lastModified="14bcf514e32"/>
</target>
<target file="arm_sqrt_q31.o" lastModified="14bd21eed4c">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FastMathFunctions\arm_sqrt_q31.c" lastModified="14bcf516470"/>
</target>
<target file="arm_cfft_radix8_f32.o" lastModified="14bd21eb2db">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix8_f32.c" lastModified="14bcf514d90"/>
</target>
<target file="arm_conv_partial_q15.o" lastModified="14bd21e5db1">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_partial_q15.c" lastModified="14bcf5153d2"/>
</target>
<target file="arm_mult_q31.o" lastModified="14bd21e6acb">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_mult_q31.c" lastModified="14bcf51615f"/>
</target>
<target file="arm_cfft_radix4_f32.o" lastModified="14bd21e41a6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix4_f32.c" lastModified="14bcf514d72"/>
</target>
<target file="arm_cfft_radix2_q31.o" lastModified="14bd21e3994">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix2_q31.c" lastModified="14bcf514d16"/>
</target>
<target file="SVC_Table.o" lastModified="14bd21ee28c">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\TARGET_M4\TOOLCHAIN_GCC\SVC_Table.s" lastModified="14bcf5168b9"/>
</target>
<target file="arm_cmplx_mag_f32.o" lastModified="14bd21ea161">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mag_f32.c" lastModified="14bcf51640b"/>
</target>
<target file="arm_negate_q15.o" lastModified="14bd21eb765">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_negate_q15.c" lastModified="14bcf5162e9"/>
</target>
<target file="arm_lms_norm_q15.o" lastModified="14bd21e9bf1">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_norm_q15.c" lastModified="14bcf515258"/>
</target>
<target file="arm_rfft_fast_init_f32.o" lastModified="14bd21ea66e">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_rfft_fast_init_f32.c" lastModified="14bcf5149ff"/>
</target>
<target file="arm_shift_q15.o" lastModified="14bd21ef417">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_shift_q15.c" lastModified="14bcf516097"/>
</target>
<target file="arm_sin_f32.o" lastModified="14bd21ee760">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FastMathFunctions\arm_sin_f32.c" lastModified="14bcf5164a6"/>
</target>
<target file="arm_conv_opt_q7.o" lastModified="14bd21ed258">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_opt_q7.c" lastModified="14bcf5152a8"/>
</target>
<target file="arm_cmplx_mag_squared_q31.o" lastModified="14bd21ed52b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mag_squared_q31.c" lastModified="14bcf51635f"/>
</target>
<target file="arm_add_q15.o" lastModified="14bd21ea6d4">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_add_q15.c" lastModified="14bcf51629c"/>
</target>
<target file="arm_copy_f32.o" lastModified="14bd21ea42a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_copy_f32.c" lastModified="14bcf514f01"/>
</target>
<target file="sha256.o" lastModified="14bd21e86bc">
<source file="..\..\..\CyaSSL\sha256.c" lastModified="14bcf51110f"/>
</target>
<target file="Thread.o" lastModified="14bd21e8c6f">
<source file="..\..\..\mbed-rtos\rtos\Thread.cpp" lastModified="14bcf518034"/>
</target>
<target file="arm_cfft_f32.o" lastModified="14bd21e61df">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_f32.c" lastModified="14bcf514cde"/>
</target>
<target file="arm_mat_add_q15.o" lastModified="14bd21efcec">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_add_q15.c" lastModified="14bcf51583b"/>
</target>
<target file="arm_iir_lattice_init_q15.o" lastModified="14bd21e69f0">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_iir_lattice_init_q15.c" lastModified="14bcf5154e8"/>
</target>
<target file="arm_max_f32.o" lastModified="14bd21eef4f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_max_f32.c" lastModified="14bcf516658"/>
</target>
<target file="arm_fir_sparse_q7.o" lastModified="14bd21e706d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_sparse_q7.c" lastModified="14bcf515125"/>
</target>
<target file="Socket.o" lastModified="14bd21ee271">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\Socket\Socket.cpp" lastModified="14bcf518433"/>
</target>
<target file="arm_offset_f32.o" lastModified="14bd21ec5a9">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_offset_f32.c" lastModified="14bcf5162b2"/>
</target>
<target file="arm_fir_lattice_f32.o" lastModified="14bd21e70ec">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_lattice_f32.c" lastModified="14bcf515668"/>
</target>
<target file="arm_q31_to_float.o" lastModified="14bd21e3b26">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_q31_to_float.c" lastModified="14bcf514ed6"/>
</target>
<target file="arm_q15_to_q7.o" lastModified="14bd21e7a3b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_q15_to_q7.c" lastModified="14bcf514ea1"/>
</target>
<target file="arm_biquad_cascade_df1_fast_q15.o" lastModified="14bd21eb7dd">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_fast_q15.c" lastModified="14bcf51547c"/>
</target>
<target file="arm_fir_decimate_fast_q31.o" lastModified="14bd21e7d20">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_decimate_fast_q31.c" lastModified="14bcf515634"/>
</target>
<target file="rt_Mutex.o" lastModified="14bd21e93c0">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_Mutex.c" lastModified="14bcf516847"/>
</target>
<target file="arm_fir_q15.o" lastModified="14bd21ea609">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_q15.c" lastModified="14bcf5156ce"/>
</target>
<target file="arm_conv_partial_fast_q31.o" lastModified="14bd21eaa85">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_partial_fast_q31.c" lastModified="14bcf51509d"/>
</target>
<target file="arm_dct4_q31.o" lastModified="14bd21eb5a0">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_dct4_q31.c" lastModified="14bcf5149d5"/>
</target>
<target file="arm_fir_init_q31.o" lastModified="14bd21eb702">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_init_q31.c" lastModified="14bcf5155ba"/>
</target>
<target file="arm_fir_interpolate_q31.o" lastModified="14bd21edd03">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_interpolate_q31.c" lastModified="14bcf515108"/>
</target>
<target file="arm_pid_init_f32.o" lastModified="14bd21ed2bb">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ControllerFunctions\arm_pid_init_f32.c" lastModified="14bcf51572f"/>
</target>
<target file="arm_power_q7.o" lastModified="14bd21ec6e2">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_power_q7.c" lastModified="14bcf516668"/>
</target>
<target file="asn.o" lastModified="14bd21e6f6f">
<source file="..\..\..\CyaSSL\asn.c" lastModified="14bcf51114a"/>
</target>
<target file="arm_sub_f32.o" lastModified="14bd21e784a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_sub_f32.c" lastModified="14bcf5160be"/>
</target>
<target file="arm_rms_q31.o" lastModified="14bd21e94d9">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_rms_q31.c" lastModified="14bcf5165c6"/>
</target>
<target file="arm_lms_norm_init_q31.o" lastModified="14bd21ee2ea">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_norm_init_q31.c" lastModified="14bcf5151a5"/>
</target>
<target file="arm_cos_f32.o" lastModified="14bd21ebeee">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FastMathFunctions\arm_cos_f32.c" lastModified="14bcf516497"/>
</target>
<target file="arm_mat_sub_f32.o" lastModified="14bd21ec60f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_sub_f32.c" lastModified="14bcf51582d"/>
</target>
<target file="arm_var_q15.o" lastModified="14bd21ebc2d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_var_q15.c" lastModified="14bcf516687"/>
</target>
<target file="HAL_CM.o" lastModified="14bd21edc41">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\HAL_CM.c" lastModified="14bcf516896"/>
</target>
<target file="arm_cfft_radix2_init_q15.o" lastModified="14bd21e8397">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix2_init_q15.c" lastModified="14bcf514c75"/>
</target>
<target file="arm_cmplx_mult_cmplx_q31.o" lastModified="14bd21ef9c6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mult_cmplx_q31.c" lastModified="14bcf5163c9"/>
</target>
<target file="arm_dct4_init_q15.o" lastModified="14bd21e60b9">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_dct4_init_q15.c" lastModified="14bcf514d49"/>
</target>
<target file="arm_mat_trans_q31.o" lastModified="14bd21ef343">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_trans_q31.c" lastModified="14bcf5157e3"/>
</target>
<target file="misc.o" lastModified="14bd21ede06">
<source file="..\..\..\CyaSSL\misc.c" lastModified="14bcf510ea8"/>
</target>
<target file="arm_cmplx_mult_real_f32.o" lastModified="14bd21ee1a5">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mult_real_f32.c" lastModified="14bcf516333"/>
</target>
<target file="rt_Semaphore.o" lastModified="14bd21e9475">
<source file="..\..\..\mbed-rtos\rtx\TARGET_CORTEX_M\rt_Semaphore.c" lastModified="14bcf516809"/>
</target>
<target file="arm_conv_partial_q7.o" lastModified="14bd21eae23">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_partial_q7.c" lastModified="14bcf515579"/>
</target>
<target file="arm_mat_mult_q31.o" lastModified="14bd21e68d6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_mult_q31.c" lastModified="14bcf5157b9"/>
</target>
<target file="arm_mat_inverse_f32.o" lastModified="14bd21e3808">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_inverse_f32.c" lastModified="14bcf515887"/>
</target>
<target file="arm_q7_to_q15.o" lastModified="14bd21e5172">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_q7_to_q15.c" lastModified="14bcf514e5c"/>
</target>
<target file="arm_cfft_radix4_q15.o" lastModified="14bd21e3c07">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix4_q15.c" lastModified="14bcf514c47"/>
</target>
<target file="arm_biquad_cascade_df1_init_q31.o" lastModified="14bd21e9cb3">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_init_q31.c" lastModified="14bcf5150b8"/>
</target>
<target file="Mutex.o" lastModified="14bd21e49a4">
<source file="..\..\..\mbed-rtos\rtos\Mutex.cpp" lastModified="14bcf51805a"/>
</target>
<target file="arm_cmplx_mag_q15.o" lastModified="14bd21e9c58">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mag_q15.c" lastModified="14bcf51634d"/>
</target>
<target file="arm_abs_f32.o" lastModified="14bd21e768c">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_abs_f32.c" lastModified="14bcf51625f"/>
</target>
<target file="arm_float_to_q7.o" lastModified="14bd21e3cc9">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_float_to_q7.c" lastModified="14bcf514ec5"/>
</target>
<target file="arm_sin_q15.o" lastModified="14bd21ee13c">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FastMathFunctions\arm_sin_q15.c" lastModified="14bcf516482"/>
</target>
<target file="arm_min_f32.o" lastModified="14bd21e8588">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_min_f32.c" lastModified="14bcf51660e"/>
</target>
<target file="arm_q15_to_float.o" lastModified="14bd21e542d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_q15_to_float.c" lastModified="14bcf514e8f"/>
</target>
<target file="arm_lms_init_q31.o" lastModified="14bd21e8f63">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_init_q31.c" lastModified="14bcf515645"/>
</target>
<target file="arm_copy_q15.o" lastModified="14bd21e9fb6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_copy_q15.c" lastModified="14bcf514e4e"/>
</target>
<target file="arm_abs_q7.o" lastModified="14bd21e4d81">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_abs_q7.c" lastModified="14bcf51614f"/>
</target>
<target file="TCPSocketServer.o" lastModified="14bd21ebaf7">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\Socket\TCPSocketServer.cpp" lastModified="14bcf5184b2"/>
</target>
<target file="arm_max_q15.o" lastModified="14bd21ee92b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_max_q15.c" lastModified="14bcf516513"/>
</target>
<target file="arm_fill_f32.o" lastModified="14bd21ee4ce">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_fill_f32.c" lastModified="14bcf514e40"/>
</target>
<target file="arm_mat_scale_f32.o" lastModified="14bd21ec95e">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_scale_f32.c" lastModified="14bcf515897"/>
</target>
<target file="arm_offset_q15.o" lastModified="14bd21ebd84">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_offset_q15.c" lastModified="14bcf516276"/>
</target>
<target file="arm_correlate_fast_q31.o" lastModified="14bd21e8e20">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_correlate_fast_q31.c" lastModified="14bcf5154c6"/>
</target>
<target file="rsa.o" lastModified="14bd21ee40d">
<source file="..\..\..\CyaSSL\rsa.c" lastModified="14bcf510f3b"/>
</target>
<target file="arm_conv_f32.o" lastModified="14bd21e7b33">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_f32.c" lastModified="14bcf5150d8"/>
</target>
<target file="arm_bitreversal2.o" lastModified="14bd21e3833">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_bitreversal2.S" lastModified="14bcf514d82"/>
</target>
<target file="arm_fir_lattice_q15.o" lastModified="14bd21e6b79">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_lattice_q15.c" lastModified="14bcf5151b4"/>
</target>
<target file="DNSClient.o" lastModified="14bd21ec1e5">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\DNSClient\DNSClient.cpp" lastModified="14bcf5184c4"/>
</target>
<target file="arm_std_f32.o" lastModified="14bd21e7281">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_std_f32.c" lastModified="14bcf516500"/>
</target>
<target file="arm_rfft_f32.o" lastModified="14bd21e510d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_rfft_f32.c" lastModified="14bcf514cba"/>
</target>
<target file="W5500.o" lastModified="14bd21edbba">
<source file="..\..\..\WIZnet_Library\WIZnetInterface\WIZnet\W5500.cpp" lastModified="14bcf518560"/>
</target>
<target file="arm_rfft_init_f32.o" lastModified="14bd21e8501">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_rfft_init_f32.c" lastModified="14bcf514c35"/>
</target>
<target file="arm_fir_interpolate_init_f32.o" lastModified="14bd21efc83">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_interpolate_init_f32.c" lastModified="14bcf51515b"/>
</target>
<target file="arm_q15_to_q31.o" lastModified="14bd21e4d18">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_q15_to_q31.c" lastModified="14bcf514e25"/>
</target>
<target file="arm_pid_init_q15.o" lastModified="14bd21ecd76">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ControllerFunctions\arm_pid_init_q15.c" lastModified="14bcf515700"/>
</target>
<target file="arm_cmplx_conj_q31.o" lastModified="14bd21ebc9a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_conj_q31.c" lastModified="14bcf51642a"/>
</target>
<target file="arm_conv_fast_q15.o" lastModified="14bd21ec40d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_fast_q15.c" lastModified="14bcf5156a1"/>
</target>
<target file="arm_correlate_f32.o" lastModified="14bd21eeee7">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_correlate_f32.c" lastModified="14bcf5154d7"/>
</target>
<target file="arm_sub_q15.o" lastModified="14bd21e71b8">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_sub_q15.c" lastModified="14bcf516112"/>
</target>
<target file="arm_cfft_radix4_init_q31.o" lastModified="14bd21e611b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\TransformFunctions\arm_cfft_radix4_init_q31.c" lastModified="14bcf5149e7"/>
</target>
<target file="arm_biquad_cascade_df1_32x64_init_q31.o" lastModified="14bd21eb0f9">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_biquad_cascade_df1_32x64_init_q31.c" lastModified="14bcf5155e8"/>
</target>
<target file="arm_common_tables.o" lastModified="14bd21e502d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\CommonTables\arm_common_tables.c" lastModified="14bcf514db4"/>
</target>
<target file="arm_fir_sparse_init_f32.o" lastModified="14bd21ee0d3">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_sparse_init_f32.c" lastModified="14bcf51558f"/>
</target>
<target file="arm_cos_q15.o" lastModified="14bd21eb60c">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FastMathFunctions\arm_cos_q15.c" lastModified="14bcf516460"/>
</target>
<target file="arm_fir_decimate_q31.o" lastModified="14bd21ecb4c">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_decimate_q31.c" lastModified="14bcf515185"/>
</target>
<target file="arm_lms_q31.o" lastModified="14bd21eebf7">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_q31.c" lastModified="14bcf515689"/>
</target>
<target file="arm_sin_cos_f32.o" lastModified="14bd21ede73">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ControllerFunctions\arm_sin_cos_f32.c" lastModified="14bcf51574c"/>
</target>
<target file="arm_mat_mult_fast_q31.o" lastModified="14bd21efa40">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_mult_fast_q31.c" lastModified="14bcf51579b"/>
</target>
<target file="arm_fir_sparse_f32.o" lastModified="14bd21e5c42">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_sparse_f32.c" lastModified="14bcf5156bf"/>
</target>
<target file="arm_mat_sub_q15.o" lastModified="14bd21ebd1f">
<source file="..\..\..\mbed-dsp\cmsis_dsp\MatrixFunctions\arm_mat_sub_q15.c" lastModified="14bcf51581e"/>
</target>
<target file="arm_fir_lattice_init_q31.o" lastModified="14bd21ea4de">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_lattice_init_q31.c" lastModified="14bcf5151ee"/>
</target>
<target file="arm_scale_q7.o" lastModified="14bd21e3a5d">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_scale_q7.c" lastModified="14bcf516207"/>
</target>
<target file="arm_mean_f32.o" lastModified="14bd21eb51a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_mean_f32.c" lastModified="14bcf5165d8"/>
</target>
<target file="md5.o" lastModified="14bd21eb1ae">
<source file="..\..\..\CyaSSL\md5.c" lastModified="14bcf511093"/>
</target>
<target file="arm_pid_reset_q31.o" lastModified="14bd21ecdcf">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ControllerFunctions\arm_pid_reset_q31.c" lastModified="14bcf5156ef"/>
</target>
<target file="arm_fir_fast_q15.o" lastModified="14bd21e9a7a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_fir_fast_q15.c" lastModified="14bcf515177"/>
</target>
<target file="arm_cmplx_mult_real_q15.o" lastModified="14bd21edee6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\ComplexMathFunctions\arm_cmplx_mult_real_q15.c" lastModified="14bcf5163d9"/>
</target>
<target file="arm_q31_to_q15.o" lastModified="14bd21ee531">
<source file="..\..\..\mbed-dsp\cmsis_dsp\SupportFunctions\arm_q31_to_q15.c" lastModified="14bcf514dcf"/>
</target>
<target file="arm_conv_partial_q31.o" lastModified="14bd21e910b">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_conv_partial_q31.c" lastModified="14bcf5154fb"/>
</target>
<target file="main.o" lastModified="14bd21e811a">
<source file="..\..\..\main.cpp" lastModified="14bd21dc9d2"/>
</target>
<target file="arm_max_q7.o" lastModified="14bd21edfaf">
<source file="..\..\..\mbed-dsp\cmsis_dsp\StatisticsFunctions\arm_max_q7.c" lastModified="14bcf516596"/>
</target>
<target file="arm_abs_q15.o" lastModified="14bd21e6fd6">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_abs_q15.c" lastModified="14bcf516172"/>
</target>
<target file="arm_negate_q31.o" lastModified="14bd21eec5a">
<source file="..\..\..\mbed-dsp\cmsis_dsp\BasicMathFunctions\arm_negate_q31.c" lastModified="14bcf5161f4"/>
</target>
<target file="arm_lms_norm_q31.o" lastModified="14bd21ec9ff">
<source file="..\..\..\mbed-dsp\cmsis_dsp\FilteringFunctions\arm_lms_norm_q31.c" lastModified="14bcf515535"/>
</target>
</processor>
</history>
This source diff could not be displayed because it is too large. You can view the blob instead.
http://developer.mbed.org/users/Kojto/code/cc3000_hostdriver_mbedsocket/#a63fe1a4f568
a63fe1a4f568af873f24ee03b69ee81c68201c71 47
a63fe1a4f568af873f24ee03b69ee81c68201c71 default
47 a63fe1a4f568af873f24ee03b69ee81c68201c71
[paths]
default = http://developer.mbed.org/users/Kojto/code/cc3000_hostdriver_mbedsocket/
data/cc3000_common.h.i
data/cc3000_spi.cpp.i
data/cc3000_security.cpp.i
data/Socket/TCPSocketServer.h.i
data/Socket/Socket.cpp.i
data/cc3000.cpp.i
data/cc3000_wlan.cpp.i
data/Helper/def.h.i
data/Socket/Endpoint.cpp.i
data/Socket/UDPSocket.h.i
data/Socket/TCPSocketServer.cpp.i
data/cc3000_socket.cpp.i
data/cc3000_spi.h.i
data/Socket/UDPSocket.cpp.i
data/cc3000_simplelink.cpp.i
data/cc3000_event.cpp.i
data/cc3000_simplelink.h.i
data/Socket/TCPSocketConnection.cpp.i
data/cc3000_socket.h.i
data/cc3000.h.i
data/cc3000_netapp.cpp.i
data/Socket/TCPSocketConnection.h.i
data/cc3000_client.cpp.i
data/cc3000_nvmem.h.i
data/Socket/Endpoint.h.i
data/Socket/Socket.h.i
data/cc3000_server.cpp.i
data/cc3000_hci.cpp.i
data/cc3000_event.h.i
data/cc3000_nvmem.cpp.i
data/cc3000_netapp.h.i
0
pull
http://developer.mbed.org/users/Kojto/code/cc3000_hostdriver_mbedsocket/
syntax: regexp
\.hgignore$
\.git$
\.svn$
\.orig$
\.msub$
\.meta$
\.ctags
\.uvproj$
\.uvopt$
\.project$
\.cproject$
\.launch$
\.project$
\.cproject$
\.launch$
Makefile$
\.ewp$
\.eww$
\ No newline at end of file
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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 DEF_H
#define DEF_H
#include "cmsis.h"
#endif
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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.
*/
#include "Socket/Socket.h"
#include "Socket/Endpoint.h"
#include "Helper/def.h"
#include <cstring>
#include "cc3000.h"
/* Copied from lwip */
static char *cc3000_inet_ntoa_r(const in_addr addr, char *buf, int buflen)
{
uint32_t s_addr;
char inv[3];
char *rp;
uint8_t *ap;
uint8_t rem;
uint8_t n;
uint8_t i;
int len = 0;
s_addr = addr.s_addr;
rp = buf;
ap = (uint8_t *)&s_addr;
for(n = 0; n < 4; n++) {
i = 0;
do {
rem = *ap % (uint8_t)10;
*ap /= (uint8_t)10;
inv[i++] = '0' + rem;
} while(*ap);
while(i--) {
if (len++ >= buflen) {
return NULL;
}
*rp++ = inv[i];
}
if (len++ >= buflen) {
return NULL;
}
*rp++ = '.';
ap++;
}
*--rp = 0;
return buf;
}
Endpoint::Endpoint() {
_cc3000_module = cc3000::get_instance();
if (_cc3000_module == NULL) {
error("Endpoint constructor error: no cc3000 instance available!\r\n");
}
reset_address();
}
Endpoint::~Endpoint() {}
void Endpoint::reset_address(void) {
_ipAddress[0] = '\0';
std::memset(&_remote_host, 0, sizeof(sockaddr_in));
}
int Endpoint::set_address(const char* host, const int port) {
reset_address();
char address[5];
char *p_address = address;
signed int add[5];
// Dot-decimal notation
int result = std::sscanf(host, "%3u.%3u.%3u.%3u", &add[0], &add[1], &add[2], &add[3]);
for (int i=0;i<4;i++) {
address[i] = add[i];
}
std::memset(_ipAddress,0,sizeof(_ipAddress));
if (result != 4) {
#ifndef CC3000_TINY_DRIVER
//Resolve DNS address or populate hard-coded IP address
uint32_t address_integer;
int resolveRetCode;
resolveRetCode = _cc3000_module->_socket.gethostbyname((uint8_t *)host, strlen(host) , &address_integer);
if ((resolveRetCode > -1) && (0 != address_integer)) {
_remote_host.sin_addr.s_addr = htonl(address_integer);
cc3000_inet_ntoa_r(_remote_host.sin_addr, _ipAddress, sizeof(_ipAddress));
} else {
// Failed to resolve the address
DBG_SOCKET("Failed to resolve the hostname : %s",host);
return (-1);
}
#else
return -1;
#endif
} else {
std::memcpy((char*)&_remote_host.sin_addr.s_addr, p_address, 4);
}
_remote_host.sin_family = AF_INET;
_remote_host.sin_port = htons(port);
DBG_SOCKET("remote host address (string): %s",get_address());
DBG_SOCKET("remote host address from s_addr : %d.%d.%d.%d",
int(_remote_host.sin_addr.s_addr & 0xFF),
int((_remote_host.sin_addr.s_addr & 0xFF00) >> 8),
int((_remote_host.sin_addr.s_addr & 0xFF0000) >> 16),
int((_remote_host.sin_addr.s_addr & 0xFF000000) >> 24));
DBG_SOCKET("port: %d", port);
return 0;
}
char* Endpoint::get_address() {
if ((_ipAddress[0] == '\0') && (_remote_host.sin_addr.s_addr != 0))
cc3000_inet_ntoa_r(_remote_host.sin_addr, _ipAddress, sizeof(_ipAddress));
return _ipAddress;
}
int Endpoint::get_port() {
return ntohs(_remote_host.sin_port);
}
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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 ENDPOINT_H
#define ENDPOINT_H
#include "cc3000.h"
using namespace mbed_cc3000;
class UDPSocket;
/**
IP Endpoint (address, port)
*/
class Endpoint {
friend class UDPSocket;
public:
/** IP Endpoint (address, port)
*/
Endpoint(void);
~Endpoint(void);
/** Reset the address of this endpoint
*/
void reset_address(void);
/** Set the address of this endpoint
\param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS).
\param port The endpoint port
\return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS).
*/
int set_address(const char* host, const int port);
/** Get the IP address of this endpoint
\return The IP address of this endpoint.
*/
char* get_address(void);
/** Get the port of this endpoint
\return The port of this endpoint
*/
int get_port(void);
protected:
char _ipAddress[17];
sockaddr_in _remote_host;
cc3000 *_cc3000_module;
};
#endif
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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.
*/
#include "Socket.h"
#include <cstring>
Socket::Socket() : _sock_fd(-1), _blocking(true), _timeout(1500) {
_cc3000_module = cc3000::get_instance();
if (_cc3000_module == NULL) {
error("Socket constructor error: no cc3000 instance available!\r\n");
}
}
int Socket::init_socket(int type, int protocol) {
if (_sock_fd != -1) {
DBG_SOCKET("Socket was initialized previously");
return -1;
}
int fd = _cc3000_module->_socket.socket(AF_INET, type, protocol);
if (fd < -1) {
DBG_SOCKET("Failed to create new socket (type: %d, protocol: %d)",type, protocol);
return -1;
}
DBG_SOCKET("Socket created (fd: %d type: %d, protocol: %d)",fd, type, protocol);
_sock_fd = fd;
return 0;
}
void Socket::set_blocking(bool blocking, unsigned int timeout) {
_blocking = blocking;
_timeout = timeout;
}
int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen) {
#ifndef CC3000_TINY_DRIVER
return _cc3000_module->_socket.setsockopt(_sock_fd, level, optname, optval, optlen);
#else
return -1;
#endif
}
int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) {
return _cc3000_module->_socket.getsockopt(_sock_fd, level, optname, optval, optlen);
}
int Socket::select(struct timeval *timeout, bool read, bool write) {
if (_sock_fd < 0) {
return -1;
}
fd_set fdSet;
FD_ZERO(&fdSet);
FD_SET(_sock_fd, &fdSet);
fd_set* readset = (read ) ? (&fdSet) : (NULL);
fd_set* writeset = (write) ? (&fdSet) : (NULL);
int ret = _cc3000_module->_socket.select(_sock_fd+1, readset, writeset, NULL, timeout);
DBG_SOCKET("Select on sock_fd: %d, returns %d. fdSet: %d", _sock_fd, ret, FD_ISSET(_sock_fd, &fdSet));
// TODO
//return (ret <= 0 || !FD_ISSET(_sock_fd, &fdSet)) ? (-1) : (0);
if (FD_ISSET(_sock_fd, &fdSet)) {
return 0;
} else {
return -1;
}
}
int Socket::wait_readable(TimeInterval& timeout) {
return select(&timeout._time, true, false);
}
int Socket::wait_writable(TimeInterval& timeout) {
return select(&timeout._time, false, true);
}
int Socket::close() {
if (_sock_fd < 0 ) {
return -1;
}
_cc3000_module->_socket.closesocket(_sock_fd);
_sock_fd = -1;
return 0;
}
Socket::~Socket() {
close();
}
TimeInterval::TimeInterval(unsigned int ms) {
_time.tv_sec = ms / 1000;
_time.tv_usec = (ms - (_time.tv_sec * 1000)) * 1000;
}
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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 SOCKET_H
#define SOCKET_H
#include "cc3000.h"
using namespace mbed_cc3000;
class TimeInterval;
/** Socket file descriptor and select wrapper
*/
class Socket {
public:
/** Socket
*/
Socket();
/** Set blocking or non-blocking mode of the socket and a timeout on
blocking socket operations
\param blocking true for blocking mode, false for non-blocking mode.
\param timeout timeout in ms [Default: (1500)ms].
*/
void set_blocking(bool blocking, unsigned int timeout=1500);
/** Set socket options
\param level stack level (see: lwip/sockets.h)
\param optname option ID
\param optval option value
\param socklen_t length of the option value
\return 0 on success, -1 on failure
*/
int set_option(int level, int optname, const void *optval, socklen_t optlen);
/** Get socket options
\param level stack level (see: lwip/sockets.h)
\param optname option ID
\param optval buffer pointer where to write the option value
\param socklen_t length of the option value
\return 0 on success, -1 on failure
*/
int get_option(int level, int optname, void *optval, socklen_t *optlen);
/** Close the socket file descriptor
*/
int close();
~Socket();
protected:
int _sock_fd;
int init_socket(int type, int protocol);
int wait_readable(TimeInterval& timeout);
int wait_writable(TimeInterval& timeout);
bool _blocking;
int _timeout;
cc3000 *_cc3000_module;
private:
int select(struct timeval *timeout, bool read, bool write);
};
/** Time interval class used to specify timeouts
*/
class TimeInterval {
friend class Socket;
public:
/** Time Interval
\param ms time interval expressed in milliseconds
*/
TimeInterval(unsigned int ms);
private:
struct timeval _time;
};
#endif /* SOCKET_H */
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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.
*/
#include "TCPSocketConnection.h"
#include <algorithm>
TCPSocketConnection::TCPSocketConnection() : _is_connected(false) {
_cc3000_module = cc3000::get_instance();
if (_cc3000_module == NULL) {
error("Endpoint constructor error: no cc3000 instance available!\r\n");
}
}
int TCPSocketConnection::connect(const char *host, const int port) {
if (init_socket(SOCK_STREAM, IPPROTO_TCP) < 0) {
DBG_SOCKET("Failed to create tcp socket");
return -1;
}
if (set_address(host, port) != 0) {
DBG_SOCKET("Failed to set address (tcp)");
return -1;
}
if (_cc3000_module->_socket.connect(_sock_fd, (const sockaddr *)&_remote_host, sizeof(_remote_host)) < 0) {
DBG_SOCKET("Failed to connect (tcp)");
close();
return -1;
}
_is_connected = true;
return 0;
}
bool TCPSocketConnection::is_connected(void) {
return _is_connected;
}
int TCPSocketConnection::send(char* data, int length) {
if ((_sock_fd < 0) || !_is_connected) {
return -1;
}
if (!_blocking) {
TimeInterval timeout(_timeout);
if (wait_writable(timeout) != 0) {
return -1;
}
}
int n = _cc3000_module->_socket.send(_sock_fd, data, length, 0);
_is_connected = (n != 0);
return n;
}
int TCPSocketConnection::send_all(char *data, int length) {
if ((_sock_fd < 0) || !_is_connected) {
return -1;
}
int writtenLen = 0;
TimeInterval timeout(_timeout);
while (writtenLen < length) {
if (!_blocking) {
// Wait for socket to be writeable
if (wait_writable(timeout) != 0) {
return writtenLen;
}
}
int ret = _cc3000_module->_socket.send(_sock_fd, data + writtenLen, length - writtenLen, 0);
if (ret > 0) {
writtenLen += ret;
continue;
} else if (ret == 0) {
_is_connected = false;
return writtenLen;
} else {
return -1; //Connnection error
}
}
return writtenLen;
}
int TCPSocketConnection::receive(char *data, int length) {
if ((_sock_fd < 0) || !_is_connected) {
return -1;
}
if (!_blocking) {
TimeInterval timeout(_timeout);
if (wait_readable(timeout) != 0)
return -1;
}
int n = _cc3000_module->_socket.recv(_sock_fd, data, length, 0);
if (n >= 0) {
_is_connected = 1;
} else {
_is_connected = 0;
}
return n;
}
int TCPSocketConnection::receive_all(char *data, int length) {
if ((_sock_fd < 0) || !_is_connected) {
return -1;
}
int readLen = 0;
TimeInterval timeout(_timeout);
while (readLen < length) {
if (!_blocking) {
//Wait for socket to be readable
if (wait_readable(timeout) != 0)
return readLen;
}
int ret = _cc3000_module->_socket.recv(_sock_fd, data + readLen, length - readLen, 0);
if (ret > 0) {
readLen += ret;
} else if (ret == 0) {
_is_connected = false;
return readLen;
} else {
return -1; //Connnection error
}
}
return readLen;
}
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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 TCPSOCKET_H
#define TCPSOCKET_H
#include "Socket.h"
#include "Endpoint.h"
/**
TCP socket connection
*/
class TCPSocketConnection: public Socket, public Endpoint {
friend class TCPSocketServer;
public:
/** TCP socket connection
*/
TCPSocketConnection();
/** Connects this TCP socket to the server
\param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
\param port The host's port to connect to.
\return 0 on success, -1 on failure.
*/
int connect(const char *host, const int port);
/** Check if the socket is connected
\return true if connected, false otherwise.
*/
bool is_connected(void);
/** Send data to the remote host.
\param data The buffer to send to the host.
\param length The length of the buffer to send.
\return the number of written bytes on success (>=0) or -1 on failure
*/
int send(char *data, int length);
/** Send all the data to the remote host.
\param data The buffer to send to the host.
\param length The length of the buffer to send.
\return the number of written bytes on success (>=0) or -1 on failure
*/
int send_all(char *data, int length);
/** Receive data from the remote host.
\param data The buffer in which to store the data received from the host.
\param length The maximum length of the buffer.
\return the number of received bytes on success (>=0) or -1 on failure
*/
int receive(char *data, int length);
/** Receive all the data from the remote host.
\param data The buffer in which to store the data received from the host.
\param length The maximum length of the buffer.
\return the number of received bytes on success (>=0) or -1 on failure
*/
int receive_all(char *data, int length);
private:
bool _is_connected;
cc3000 *_cc3000_module;
};
#endif
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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.
*/
#include "TCPSocketServer.h"
#include <string>
TCPSocketServer::TCPSocketServer() {
}
int TCPSocketServer::bind(int port) {
if (init_socket(SOCK_STREAM, IPPROTO_TCP) < 0) {
return -1;
}
sockaddr_in localHost;
memset(&localHost, 0, sizeof(localHost));
localHost.sin_family = AF_INET;
localHost.sin_port = htons(port);
localHost.sin_addr.s_addr = 0;
if (_cc3000_module->_socket.bind(_sock_fd, (const sockaddr *)&localHost, sizeof(localHost)) < 0) {
close();
return -1;
}
return 0;
}
int TCPSocketServer::listen(int max) {
if (_sock_fd < 0) {
return -1;
}
if (_cc3000_module->_socket.listen(_sock_fd, max) < 0) {
close();
return -1;
}
return 0;
}
int TCPSocketServer::accept(TCPSocketConnection& connection) {
if (_sock_fd < 0) {
return -1;
}
if (!_blocking) {
TimeInterval timeout(_timeout);
if (wait_readable(timeout) != 0) {
return -1;
}
}
connection.reset_address();
socklen_t newSockRemoteHostLen = sizeof(connection._remote_host);
int fd = _cc3000_module->_socket.accept(_sock_fd, (sockaddr *) &connection._remote_host, &newSockRemoteHostLen);
if (fd < 0) {
return -1;
}
/* s_addr is returned in the little endian */
connection._remote_host.sin_addr.s_addr = htonl(connection._remote_host.sin_addr.s_addr);
connection._sock_fd = fd;
connection._is_connected = true;
return 0;
}
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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 TCPSOCKETSERVER_H
#define TCPSOCKETSERVER_H
#include "Socket/Socket.h"
#include "TCPSocketConnection.h"
/** TCP Server.
*/
class TCPSocketServer : public Socket {
public:
/** Instantiate a TCP Server.
*/
TCPSocketServer();
/** Bind a socket to a specific port.
\param port The port to listen for incoming connections on.
\return 0 on success, -1 on failure.
*/
int bind(int port);
/** Start listening for incoming connections.
\param backlog number of pending connections that can be queued up at any
one time [Default: 1].
\return 0 on success, -1 on failure.
*/
int listen(int backlog=1);
/** Accept a new connection.
\param connection A TCPSocketConnection instance that will handle the incoming connection.
\return 0 on success, -1 on failure.
*/
int accept(TCPSocketConnection& connection);
};
#endif
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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.
*/
#include "UDPSocket.h"
#include <string>
#include <algorithm>
UDPSocket::UDPSocket() {
}
int UDPSocket::init(void) {
return init_socket(SOCK_DGRAM, IPPROTO_UDP);
}
int UDPSocket::bind(int port) {
if (init_socket(SOCK_DGRAM, IPPROTO_UDP) < 0) {
return -1;
}
sockaddr_in localHost;
std::memset(&localHost, 0, sizeof(sockaddr_in));
localHost.sin_family = AF_INET;
localHost.sin_port = htons(port);
localHost.sin_addr.s_addr = 0;
if (_cc3000_module->_socket.bind(_sock_fd, (sockaddr *)&localHost, sizeof(sockaddr_in)) != 0) {
DBG_SOCKET("Failed to bind a socket (udp). Closing socket");
_cc3000_module->_socket.closesocket(_sock_fd);
_sock_fd = -1;
return -1;
}
return 0;
}
int UDPSocket::sendTo(Endpoint &remote, char *packet, int length)
{
if (_sock_fd < 0) {
return -1;
}
// TODO - seems to be a bug, waiting for TI to respond
// if (!_blocking) {
// TimeInterval timeout(_timeout);
// if (wait_writable(timeout) != 0) {
// DBG_SOCKET("The socket is not writeable. _sock_fd: %d", _sock_fd);
// return 0;
// }
// }
return _cc3000_module->_socket.sendto(_sock_fd, packet, length, 0, (sockaddr *)&remote._remote_host, sizeof(sockaddr));
}
int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length)
{
if (_sock_fd < 0) {
return -1;
}
if (!_blocking) {
TimeInterval timeout(_timeout);
if (wait_readable(timeout) != 0) {
DBG_SOCKET("The socket is not readable. _sock_fd: %d", _sock_fd);
return 0;
}
}
remote.reset_address();
socklen_t remote_host_length = sizeof(remote._remote_host);
return _cc3000_module->_socket.recvfrom(_sock_fd, buffer, length, 0, (sockaddr *)&remote._remote_host, &remote_host_length);
}
/* Copyright (C) 2013 mbed.org, MIT License
*
* 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 UDPSOCKET_H
#define UDPSOCKET_H
#include "Endpoint.h"
#include "Socket.h"
#include <cstdint>
/**
UDP Socket
*/
class UDPSocket: public Socket {
public:
/** Instantiate an UDP Socket.
*/
UDPSocket();
/** Init the UDP Client Socket without binding it to any specific port
\return 0 on success, -1 on failure.
*/
int init(void);
/** Bind a UDP Server Socket to a specific port
\param port The port to listen for incoming connections on
\return 0 on success, -1 on failure.
*/
int bind(int port = -1);
/** Send a packet to a remote endpoint
\param remote The remote endpoint
\param packet The packet to be sent
\param length The length of the packet to be sent
\return the number of written bytes on success (>=0) or -1 on failure
*/
int sendTo(Endpoint &remote, char *packet, int length);
/** Receive a packet from a remote endpoint
\param remote The remote endpoint
\param buffer The buffer for storing the incoming packet data. If a packet
is too long to fit in the supplied buffer, excess bytes are discarded
\param length The length of the buffer
\return the number of received bytes on success (>=0) or -1 on failure
*/
int receiveFrom(Endpoint &remote, char *buffer, int length);
};
#include "def.h"
#endif
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
#include "cc3000_event.h"
namespace mbed_cc3000 {
/* TODO this prefix remove? verify */
static uint8_t cc3000_prefix[] = {'T', 'T', 'T'};
cc3000 *cc3000::_inst;
cc3000::cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi)
: _event(_simple_link, _hci, _spi, *this), _socket(_simple_link, _hci, _event),
_spi(cc3000_irq, cc3000_en, cc3000_cs, cc3000_spi, _event, _simple_link), _hci(_spi),
_nvmem(_hci, _event, _simple_link), _netapp(_simple_link, _nvmem, _hci, _event),
_wlan(_simple_link, _event, _spi, _hci) {
_simple_link.set_tx_complete_signal(1);
memset(&_status, 0, sizeof(_status));
_inst = this;
}
cc3000::~cc3000() {
}
#if (CC3000_ETH_COMPAT == 1)
cc3000::cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, const char *ssid,
const char *phrase, Security sec, bool smart_config)
: _event(_simple_link, _hci, _spi, *this), _socket(_simple_link, _hci, _event),
_spi(cc3000_irq, cc3000_en, cc3000_cs, cc3000_spi, _event, _simple_link), _hci(_spi),
_nvmem(_hci, _event, _simple_link), _netapp(_simple_link, _nvmem, _hci, _event),
_wlan(_simple_link, _event, _spi, _hci), _sec(sec), _smart_config(smart_config) {
_simple_link.set_tx_complete_signal(1);
memset(&_status, 0, sizeof(_status));
strcpy((char *)_ssid, ssid);
strcpy((char *)_phrase, phrase);
_inst = this;
}
// Ethernet library compatible, functions return strings
// Caches the ipconfig from the usync callback
static char mac_addr[19]= "\0";
static char ip_addr[17] = "\0";
static char gateway[17] = "\0";
static char networkmask[17] = "\0";
void cc3000::init() {
_wlan.start(0);
uint32_t subnet[4] = {0};
uint32_t ip[4] = {0};
uint32_t getway[4] = {0};
uint32_t dns[4] = {0};
_netapp.dhcp(ip, subnet, getway, dns);
_wlan.stop();
wait(1);
_wlan.start(0);
_status.enabled = 1;
_wlan.set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT | HCI_EVNT_WLAN_KEEPALIVE);
}
void cc3000::init(const char *ip, const char *mask, const char *gateway) {
_netapp.dhcp((uint32_t *)ip, (uint32_t *)mask, (uint32_t *)gateway, (uint32_t *)ip); //dns = ip
_wlan.stop();
wait(1);
_wlan.start(0);
_status.enabled = 1;
_wlan.set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT | HCI_EVNT_WLAN_KEEPALIVE);
}
int cc3000::connect(unsigned int timeout_ms) {
Timer t;
int ret = 0;
if (_smart_config == false) {
_wlan.ioctl_set_connection_policy(0, 0, 0);
} else {
tUserFS user_info;
get_user_file_info((uint8_t *)&user_info, sizeof(user_info));
if (user_info.FTC == 1) {
_wlan.ioctl_set_connection_policy(0, 1, 1);
} else {
DBG_CC("Smart config is not set. Please run the first time configuration.");
return -1;
}
}
t.start();
while (is_connected() == false) {
if (strlen((const char *)_phrase) < 8) {
if (connect_open(_ssid)) {
break;
}
} else {
#ifndef CC3000_TINY_DRIVER
if (connect_secure(_ssid,_phrase, _sec)) {
break;
}
#else
return -1; /* secure connection not supported with TINY_DRIVER */
#endif
}
if (t.read_ms() > timeout_ms) {
ret = -1;
DBG_CC("Connection to AP failed");
break;
}
}
while (is_dhcp_configured() == false)
{
if (t.read_ms() > timeout_ms) {
ret = -1;
DBG_CC("Connection to AP failed");
break;
}
}
return ret;
}
char* cc3000::getMACAddress() {
return mac_addr;
}
char* cc3000::getIPAddress() {
return ip_addr;
}
char* cc3000::getGateway() {
return gateway;
}
char* cc3000::getNetworkMask() {
return networkmask;
}
int cc3000::disconnect(void){
if (_wlan.disconnect()) {
return -1;
} else {
return 0;
}
}
#endif
void cc3000::usync_callback(int32_t event_type, uint8_t *data, uint8_t length) {
if (event_type == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE) {
DBG_CC("Callback : HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE");
_status.smart_config_complete = 1;
_status.stop_smart_config = 1;
}
if (event_type == HCI_EVNT_WLAN_UNSOL_CONNECT) {
DBG_CC("Callback : HCI_EVNT_WLAN_UNSOL_CONNECT");
_status.connected = 1;
// Connect message is always followed by a DHCP message, connection is not useable until then
_status.dhcp = 0;
}
if (event_type == HCI_EVNT_WLAN_UNSOL_DISCONNECT) {
DBG_CC("Callback : HCI_EVNT_WLAN_UNSOL_DISCONNECT");
_status.connected = 0;
_status.dhcp = 0;
_status.dhcp_configured = 0;
}
if (event_type == HCI_EVNT_WLAN_UNSOL_DHCP) {
#if (CC3000_ETH_COMPAT == 1)
_socket.inet_ntoa_r( htonl(*((uint32_t *)(&data[NETAPP_IPCONFIG_IP_OFFSET]))), ip_addr, 17);
_socket.inet_ntoa_r( htonl(*((uint32_t *)(&data[NETAPP_IPCONFIG_GW_OFFSET]))), gateway, 17);
_socket.inet_ntoa_r( htonl(*((uint32_t *)(&data[NETAPP_IPCONFIG_SUBNET_OFFSET]))), networkmask, 17);
_socket.inet_ntoa_r( htonl(*((uint32_t *)(&data[NETAPP_IPCONFIG_MAC_OFFSET]))), mac_addr, 19);
#endif
if (*(data + NETAPP_IPCONFIG_MAC_OFFSET) == 0) {
_status.dhcp = 1;
DBG_CC("Callback : HCI_EVNT_WLAN_UNSOL_DHCP %i.%i.%i.%i", data[3], data[2], data[1], data[0]);
} else {
DBG_CC("Callback : HCI_EVNT_WLAN_UNSOL_DHCP - Disconnecting");
_status.dhcp = 0;
}
}
if (event_type == HCI_EVENT_CC3000_CAN_SHUT_DOWN) {
// Note this means the modules is idle, so it could be shutdown..
//DBG_CC("Callback : HCI_EVENT_CC3000_CAN_SHUT_DOWN");
_status.ok_to_shut_down = 1;
}
if (event_type == HCI_EVNT_WLAN_ASYNC_PING_REPORT) {
DBG_CC("Callback : HCI_EVNT_WLAN_ASYNC_PING_REPORT");
memcpy(&_ping_report, data, length);
}
if (event_type == HCI_EVNT_BSD_TCP_CLOSE_WAIT) {
uint8_t socketnum = data[0];
DBG_CC("Callback : HCI_EVNT_BSD_TCP_CLOSE_WAIT - Socket : %d", socketnum);
if (socketnum < MAX_SOCKETS) {
_closed_sockets[socketnum] = true; /* clients socket is closed */
}
}
}
void cc3000::start_smart_config(const uint8_t *smart_config_key) {
_status.smart_config_complete = 0;
_wlan.ioctl_set_connection_policy(0, 0, 0);
if (_status.connected == 1) {
disconnect();
}
//Wait until CC3000 is disconected
while (_status.connected == 1) {
wait_us(5);
_event.hci_unsolicited_event_handler();
}
// Trigger the Smart Config process
_wlan.smart_config_set_prefix(cc3000_prefix);
// Start the Smart Config process with AES disabled
_wlan.smart_config_start(0);
DBG_CC("Waiting for smartconfig to be completed");
// Wait for Smart config finished
while (_status.smart_config_complete == 0) {
wait_ms(100);
}
DBG_CC("Smartconfig finished");
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
// create new entry for AES encryption key
_nvmem.create_entry(NVMEM_AES128_KEY_FILEID, 16);
// write AES key to NVMEM
_security.aes_write_key((uint8_t *)(&smart_config_key[0]));
// Decrypt configuration information and add profile
_wlan.smart_config_process();
#endif
// Configure to connect automatically to the AP retrieved in the
// Smart config process
_wlan.ioctl_set_connection_policy(0, 0, 1);
// reset the CC3000
_wlan.stop();
_status.enabled = 0;
wait(5);
_wlan.start(0);
_status.enabled = 1;
// Mask out all non-required events
_wlan.set_event_mask(HCI_EVNT_WLAN_KEEPALIVE | HCI_EVNT_WLAN_UNSOL_INIT);
}
bool cc3000::connect_secure(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) {
#ifdef CC3000_TINY_DRIVER
return false; /* not supported*/
#else
uint32_t ret;
//_wlan.disconnect();
wait_ms(3);
ret = _wlan.connect(security_mode, ssid, strlen((const char *)ssid), 0, (uint8_t *)key, strlen((const char *)key));
if (ret == 0) { /* TODO static internal cc3000 state 0 to TRUE */
ret = true;
} else {
ret = false;
}
return ret;
#endif
}
bool cc3000::connect_non_blocking(const uint8_t *ssid, const uint8_t *key, int32_t security_mode)
{
bool ret = false;
if (key == 0) {
if (connect_open(ssid)) {
ret = true;
}
} else {
#ifndef CC3000_TINY_DRIVER
if (connect_secure(ssid,key,security_mode)) {
ret = true;
}
#else
/* secure connection not supported with TINY_DRIVER */
#endif
}
return ret;
}
bool cc3000::connect_to_AP(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) {
Timer t;
bool ret = true;
t.start();
while (is_connected() == false) {
if (key == 0) {
if (connect_open(ssid)) {
break;
}
} else {
#ifndef CC3000_TINY_DRIVER
if (connect_secure(ssid,key,security_mode)) {
break;
}
#else
return false; /* secure connection not supported with TINY_DRIVER */
#endif
}
/* timeout 10 seconds */
if (t.read_ms() > 10000) {
ret = false;
DBG_CC("Connection to AP failed");
break;
}
}
return ret;
}
void cc3000::start(uint8_t patch) {
_wlan.start(patch);
_status.enabled = 1;
_wlan.set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT | HCI_EVNT_WLAN_KEEPALIVE);
}
void cc3000::stop(void) {
_wlan.stop();
_status.enabled = 0;
}
void cc3000::restart(uint8_t patch) {
_wlan.stop();
_status.enabled = 0;
wait_ms(500);
_wlan.start(patch);
_status.enabled = 1;
}
bool cc3000::connect_open(const uint8_t *ssid) {
_wlan.disconnect();
wait_ms(3);
uint32_t ret;
#ifndef CC3000_TINY_DRIVER
ret = _wlan.connect(0,ssid, strlen((const char *)ssid), 0, 0, 0);
#else
ret = _wlan.connect(ssid, strlen((const char *)ssid));
#endif
if (ret == 0) {
ret = true;
} else {
ret = false;
}
return ret;
}
bool cc3000::is_enabled()
{
return _status.enabled;
}
bool cc3000::is_connected() {
if (( _status.connected ) && ( _status.dhcp )) {
return 1;
} else {
return 0;
}
}
bool cc3000::is_dhcp_configured() {
return _status.dhcp;
}
bool cc3000::is_smart_confing_completed() {
return _status.smart_config_complete;
}
uint8_t cc3000::get_mac_address(uint8_t address[6]) {
return _nvmem.get_mac_address(address);
}
uint8_t cc3000::set_mac_address(uint8_t address[6]) {
return _nvmem.set_mac_address(address);
}
void cc3000::get_user_file_info(uint8_t *info_file, size_t size) {
_nvmem.read( NVMEM_USER_FILE_1_FILEID, size, 0, info_file);
}
uint8_t cc3000::read_sp_version(uint8_t firmware[2]){
return _nvmem.read_sp_version(firmware);
}
uint8_t cc3000::write_patch(uint32_t file_id, uint32_t length, const uint8_t *data){
if(file_id == NVMEM_WLAN_DRIVER_SP_FILEID || file_id == NVMEM_WLAN_FW_SP_FILEID){
return _nvmem.write_patch(file_id, length, data);
}
else return (1); // error
}
#ifndef CC3000_TINY_DRIVER
bool cc3000::get_ip_config(tNetappIpconfigRetArgs *ip_config) {
if ((_status.dhcp == false) || (_status.connected == false)) {
return false;
}
_netapp.ipconfig(ip_config);
return true;
}
#endif
void cc3000::delete_profiles(void) {
_wlan.ioctl_set_connection_policy(0, 0, 0);
_wlan.ioctl_del_profile(255);
tUserFS user_info;
get_user_file_info((uint8_t *)&user_info, sizeof(user_info));
user_info.FTC = 0;
set_user_file_info((uint8_t *)&user_info, sizeof(user_info));
}
void cc3000::set_user_file_info(uint8_t *info_file, size_t size) {
_nvmem.write( NVMEM_USER_FILE_1_FILEID, size, 0, info_file);
}
uint32_t cc3000::ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size) {
#ifndef CC3000_TINY_DRIVER
uint32_t reversed_ip = (ip >> 24) | ((ip >> 8) & 0xFF00) | ((ip << 8) & 0xFF0000) | (ip << 24);
_ping_report.packets_received = 0;
if (_netapp.ping_send(&reversed_ip, attempts, size, timeout) == -1) {
DBG_CC("Failed to send ping");
return 0;
}
wait_ms(timeout*attempts*2);
/* known issue of cc3000 - sent number is send + received */
// TODO : Remove the Sent/recv'd counts until ti fix the firmware issue?
DBG_CC("Sent: %d",_ping_report.packets_sent);
DBG_CC("Received: %d",_ping_report.packets_received);
DBG_CC("Min time: %d",_ping_report.min_round_time);
DBG_CC("Max time: %d",_ping_report.max_round_time);
DBG_CC("Avg time: %d",_ping_report.avg_round_time);
return _ping_report.packets_received;
#else
return 0;
#endif
}
/* Conversion between uint types and C strings */
uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32)
{
*(p)++ = (uint8_t)(u32);
*(p)++ = (uint8_t)((u32) >> 8);
*(p)++ = (uint8_t)((u32) >> 16);
*(p)++ = (uint8_t)((u32) >> 24);
return p;
}
uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16)
{
*(p)++ = (uint8_t)(u16);
*(p)++ = (uint8_t)((u16) >> 8);
return p;
}
uint16_t STREAM_TO_UINT16_f(uint8_t *p, uint16_t offset)
{
return (uint16_t)((uint16_t)((uint16_t)
(*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset)));
}
uint32_t STREAM_TO_UINT32_f(uint8_t *p, uint16_t offset)
{
return (uint32_t)((uint32_t)((uint32_t)
(*(p + offset + 3)) << 24) + (uint32_t)((uint32_t)
(*(p + offset + 2)) << 16) + (uint32_t)((uint32_t)
(*(p + offset + 1)) << 8) + (uint32_t)(*(p + offset)));
}
} // mbed_cc3000 namespace
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef CC3000_H
#define CC3000_H
#include "mbed.h"
#include "cc3000_common.h"
#include "cc3000_spi.h"
#include "cc3000_simplelink.h"
#include "cc3000_netapp.h"
#include "cc3000_nvmem.h"
#include "cc3000_socket.h"
#define MAX_SOCKETS 4
// cc3000 Ethernet Interface - enabled by default
#define CC3000_ETH_COMPAT 1
/** Enable debug messages - set 1 */
// Debug - Socket interface messages
#define CC3000_DEBUG_SOCKET 0
// Debug - HCI TX messages
#define CC3000_DEBUG_HCI_TX 0
// Debug - HCI Rx messages
#define CC3000_DEBUG_HCI_RX 0
// Debug - General Debug
#define CC3000_DEBUG 0
// Add colour to the debug messages, requires a VT100 terminal like putty, comment out to remove
#define VT100_COLOUR 0
#if (CC3000_DEBUG_SOCKET == 1)
#if (VT100_COLOUR == 1)
#define DBG_SOCKET(x, ...) std::printf("\x1b[2;32;40m[CC3000 : SOCKET] "x"\x1b[0;37;40m\r\n", ##__VA_ARGS__);
#else
#define DBG_SOCKET(x, ...) std::printf("[CC3000 : SOCKET] "x"\r\n", ##__VA_ARGS__);
#endif
#else
#define DBG_SOCKET(x, ...)
#endif
#if (CC3000_DEBUG_HCI_TX == 1)
#if (VT100_COLOUR == 1)
#define DBG_HCI(x, ...) std::printf("\x1b[2;35;40m[CC3000 : HCI RX] "x"\x1b[0;37;40m\r\n", ##__VA_ARGS__);
#else
#define DBG_HCI(x, ...) std::printf("[CC3000 : HCI RX] "x"\r\n", ##__VA_ARGS__);
#endif
#else
#define DBG_HCI(x, ...)
#endif
#if (CC3000_DEBUG_HCI_RX == 1)
#if (VT100_COLOUR == 1)
#define DBG_HCI_CMD(x, ...) std::printf("\x1b[2;36;40m[CC3000 : HCI TX] "x"\x1b[0;37;40m\r\n", ##__VA_ARGS__);
#else
#define DBG_HCI_CMD(x, ...) std::printf("[CC3000 : HCI TX] "x"\r\n", ##__VA_ARGS__);
#endif
#else
#define DBG_HCI_CMD(x, ...)
#endif
#if (CC3000_DEBUG == 1)
#if (VT100_COLOUR == 1)
#define DBG_CC(x, ...) std::printf("\x1b[2;32;40m[CC3000] "x"\x1b[0;37;40m\r\n", ##__VA_ARGS__);
#else
#define DBG_CC(x, ...) std::printf("[CC3000] "x"\r\n", ##__VA_ARGS__);
#endif
#else
#define DBG_CC(x, ...)
#endif
namespace mbed_cc3000 {
/** User info structure
*/
typedef struct {
uint8_t FTC; // First time config performed
uint8_t PP_version[2]; // Patch Programmer version
uint8_t SERV_PACK[2]; // Service Pack Version
uint8_t DRV_VER[3]; // Driver Version
uint8_t FW_VER[3]; // Firmware Version
uint8_t validCIK; // CIK[] is valid (Client Interface Key)
uint8_t CIK[40];
} tUserFS;
/** Function pointers which are not yet implemented
*/
enum FunctionNumber {
FW_PATCHES = 0,
DRIVER_PATCHES = 1,
BOOTLOADER_PATCHES = 2,
};
/** AP security
*/
enum Security {
NONE = 0,
WEP = 1,
WPA = 2,
WPA2 = 3
};
/** CC3000 Simple Link class which contains status of cc3000.
*/
class cc3000_simple_link {
public:
/**
* \brief ctor - sets magic number in the buffers (overflow mark).
* \param none
* \return none
*/
cc3000_simple_link();
/**
* \brief dtor
* \param none
* \return none
*/
~cc3000_simple_link();
/**
* \brief Returns data received flag.
* \return Data received flag.
*/
uint8_t get_data_received_flag();
/**
* \brief Set data received flag.
* \param value The value to be set.
*/
void set_data_received_flag(uint8_t value);
/** Returns if tx was completed.
* \return
* true if tx was completed,
* false otherwise.
*/
bool get_tx_complete_signal();
/**
* \brief Sets flag that tx was completed.
* \param value Value to be set
* \return none
*/
void set_tx_complete_signal(bool value);
/**
* \brief Get receive buffer.
* \param none
* \return Pointer to the receive buffer.
*/
uint8_t *get_received_buffer();
/**
* \brief Get transmit buffer.
* \param none
* \return Pointer to the transmit buffer.
*/
uint8_t *get_transmit_buffer();
/**
* \brief Get number of free buffers.
* \param none
* \return
* Number of free buffers.
*/
uint16_t get_number_free_buffers();
/**
* \brief Set number of free buffers.
* \param value Number of free buffers.
* \return none
*/
void set_number_free_buffers(uint16_t value);
/**
* \brief Retrieve buffer length.
* \param none
* \return Buffer length
*/
uint16_t get_buffer_length();
/**
* \brief Set buffer length
* \param value The length
* \return none
*/
void set_buffer_length(uint16_t value);
/**
* \brief Retrieve pending data flag.
* \param none
* \return Pending data flag
*/
uint16_t get_pending_data();
/**
* \brief Set pending data flag.
* \param value Pending data value.
* \return none
*/
void set_pending_data(uint16_t value);
/**
* \brief Retreive op code.
* \param none
* \return Op code
*/
uint16_t get_op_code();
/**
* \brief Set op code.
* \param code op code.
* \return none
*/
void set_op_code(uint16_t code);
/**
* \brief Get number of released packets.
* \param none
* \return Number of released packets.
*/
uint16_t get_released_packets();
/**
* \brief Set number of released packets.
* \param value Number of released packets.
* \return none
*/
void set_number_of_released_packets(uint16_t value);
/**
* \brief Get number of sent packats
* \param none
* \return Number of sent packets.
*/
uint16_t get_sent_packets();
/**
* \brief Set number of sent packets
* \param value Number of sent packets.
* \return none
*/
void set_sent_packets(uint16_t value);
/**
* \brief Retrieve transmit error
* \param none
* \return Transmit error
*/
int32_t get_transmit_error();
/**
* \brief Set transmit error.
* \param value Error to be set.
* \return none
*/
void set_transmit_error(int32_t value);
/**
* \brief Get buffer size.
* \param none
* \return Size of buffer.
*/
uint16_t get_buffer_size();
/**
* \brief Set buffer size.
* \param value Buffer size.
* \return none
*/
void set_buffer_size(uint16_t value);
/**
* \brief Not used currently.
* \param function Number of desired function.
* \return void pointer to the function (need to recast).
*/
void *get_func_pointer(FunctionNumber function);
/**
* \brief Retreive pointer to the received data.
* \param none
* \return Pointer to the received data buffer.
*/
uint8_t *get_received_data();
/**
* \brief Set received data pointer.
* \param pointer Pointer to the buffer.
* \return none
*/
void set_received_data(uint8_t *pointer);
private:
uint8_t _data_received_flag;
bool _tx_complete_signal;
uint16_t _rx_event_opcode;
uint16_t _free_buffers;
uint16_t _buffer_length;
uint16_t _buffer_size;
uint16_t _rx_data_pending;
uint16_t _sent_packets;
uint16_t _released_packets;
int32_t _transmit_data_error;
uint8_t *_received_data;
uint8_t _rx_buffer[CC3000_RX_BUFFER_SIZE];
uint8_t _tx_buffer[CC3000_TX_BUFFER_SIZE];
private:
/* Not used currently */
int8_t *(* _fFWPatches)(uint32_t *length);
int8_t *(* _fDriverPatches)(uint32_t *length);
int8_t *(* _fBootLoaderPatches)(uint32_t *length);
};
/** Forward declaration classes
*/
class cc3000_hci;
class cc3000_nvmem;
class cc3000_spi;
class cc3000;
/** Event layer
*/
class cc3000_event {
public:
/**
* \brief Ctor
* \param simplelink Reference to simple link object.
* \param hci Reference to hci object.
* \param spi Reference to spi object.
* \param cc3000 Reference to cc3000 object.
* \return none
*/
cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000);
/**
* \brief Dtor
* \param none
* \return none
*/
~cc3000_event();
/**
* \brief Handle unsolicited event from type patch request.
* \param event_hdr event header
* \return none
*/
void hci_unsol_handle_patch_request(uint8_t *event_hdr);
/**
* \brief Parse the incoming event packets and issue corresponding event handler from global array of handlers pointers.
* \param ret_param incoming data buffer
* \param from from information (in case of data received)
* \param fromlen from information length (in case of data received)
* \return none
*/
uint8_t* hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen);
/**
* \brief Handle unsolicited events.
* \param event_hdr Event header
* \return 1 if event supported and handled
* \return 0 if event is not supported
*/
int32_t hci_unsol_event_handler(uint8_t *event_hdr);
/**
* \brief Parse the incoming unsolicited event packets and start corresponding event handler.
* \param None
* \return ESUCCESS if successful, EFAIL if an error occurred.
*/
int32_t hci_unsolicited_event_handler(void);
/**
* \brief Get the socket status.
* \param Sd Socket IS
* \return Current status of the socket.
*/
int32_t get_socket_active_status(int32_t sd);
/**
* \brief Check if the socket ID and status are valid and set the global socket status accordingly.
* \param Sd Sock descr
* \param Status status to be set
* \return none
*/
void set_socket_active_status(int32_t sd, int32_t status);
/**
* \brief Keep track on the number of packets transmitted and update the number of free buffer in the SL device.
* \brief Called when unsolicited event = HCI_EVNT_DATA_UNSOL_FREE_BUFF has received.
* \param event pointer to the string contains parameters for IPERF.
* \return ESUCCESS if successful, EFAIL if an error occurred.
*/
int32_t hci_event_unsol_flowcontrol_handler(uint8_t *event);
/**
* \brief Update the socket status.
* \param resp_params Socket IS
* \return Current status of the socket.
*/
void update_socket_active_status(uint8_t *resp_params);
/**
* \brief Wait for event, pass it to the hci_event_handler and update the event opcode in a global variable.
* \param op_code Command operation code
* \param ret_param Command return parameters
* \return none
*/
void simplelink_wait_event(uint16_t op_code, void *ret_param);
/**
* \brief Wait for data, pass it to the hci_event_handler and set the data available flag.
* \param buffer Data buffer
* \param from From information
* \param fromlen From information length
* \return none
*/
void simplelink_wait_data(uint8_t *buffer, uint8_t *from, uint8_t *fromlen);
/**
* \brief Trigger Received event/data processing - called from the SPI library to receive the data
* \param buffer pointer to the received data buffer\n
* The function triggers Received event/data processing\n
* \return none
*/
void received_handler(uint8_t *buffer);
private:
uint32_t socket_active_status;
cc3000_simple_link &_simple_link;
cc3000_hci &_hci;
cc3000_spi &_spi;
cc3000 &_cc3000;
};
/** Netapp layer
*/
class cc3000_netapp {
public:
/**
* \brief Ctor
* \param simple_link Reference to the simple link object.
* \param nvmem Reference to the nvmem object.
* \param hci Reference to the hci object.
* \param event Reference to the event object.
* \return none
*/
cc3000_netapp(cc3000_simple_link &simple_link, cc3000_nvmem &nvmem, cc3000_hci &hci, cc3000_event &event);
/**
* \brief Dtor
* \param none
* \return none
*/
~cc3000_netapp();
/**
* \brief Configure device MAC address and store it in NVMEM.
* The value of the MAC address configured through the API will be\n
* stored in CC3000 non volatile memory, thus preserved over resets.\n
* \param mac device mac address, 6 bytes. Saved: yes
* \return return on success 0, otherwise error.
*/
int32_t config_mac_adrress(uint8_t *mac);
/**
* \brief Configure the network interface, static or dynamic (DHCP).
* In order to activate DHCP mode, ip, subnet_mask, default_gateway must be 0.\n
* The default mode of CC3000 is DHCP mode. The configuration is saved in non volatile memory\n
* and thus preserved over resets.\n
* \param ip device mac address, 6 bytes. Saved: yes
* \param subnet_mask device mac address, 6 bytes. Saved: yes
* \param default_gateway device mac address, 6 bytes. Saved: yes
* \param dns_server device mac address, 6 bytes. Saved: yes
* \return 0 on success, otherwise error.
* \note If the mode is altered, a reset of CC3000 device is required to apply the changes.\n
* Also note that an asynchronous event of type 'DHCP_EVENT' is generated only when\n
* a connection to the AP was established. This event is generated when an IP address\n
* is allocated either by the DHCP server or by static allocation.\n
*/
int32_t dhcp(uint32_t *ip, uint32_t *subnet_mask,uint32_t *default_gateway, uint32_t *dns_server);
#ifndef CC3000_TINY_DRIVER
/**
* \brief Get the CC3000 Network interface information.
* This information is only available after establishing a WLAN connection.\n
* Undefined values are returned when this function is called before association.\n
* \param ipconfig pointer to a tNetappIpconfigRetArgs structure for storing the network interface configuration.\n
* tNetappIpconfigRetArgs: aucIP - ip address,\n
* aucSubnetMask - mask
* aucDefaultGateway - default gateway address\n
* aucDHCPServer - dhcp server address\n
* aucDNSServer - dns server address\n
* uaMacAddr - mac address\n
* uaSSID - connected AP ssid\n
* \return none
* \note This function is useful for figuring out the IP Configuration of\n
* the device when DHCP is used and for figuring out the SSID of\n
* the Wireless network the device is associated with.\n
*/
void ipconfig(tNetappIpconfigRetArgs *ipconfig);
/**
* \brief Set new timeout values for DHCP lease timeout, ARP refresh timeout, keepalive event timeout and socket inactivity timeout
* \param dhcp DHCP lease time request, also impact\n
* the DHCP renew timeout.\n
* Range: [0-0xffffffff] seconds,\n
* 0 or 0xffffffff = infinite lease timeout.\n
* Resolution: 10 seconds.\n
* Influence: only after reconnecting to the AP. \n
* Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.\n
* The parameter is saved into the CC3000 NVMEM.\n
* The default value on CC3000 is 14400 seconds.\n
*
* \param arp ARP refresh timeout, if ARP entry is not updated by\n
* incoming packet, the ARP entry will be deleted by\n
* the end of the timeout. \n
* Range: [0-0xffffffff] seconds, 0 = infinite ARP timeout\n
* Resolution: 10 seconds.\n
* Influence: at runtime.\n
* Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds\n
* The parameter is saved into the CC3000 NVMEM.\n
* The default value on CC3000 is 3600 seconds.\n
*
* \param keep_alive Keepalive event sent by the end of keepalive timeout\n
* Range: [0-0xffffffff] seconds, 0 == infinite timeout\n
* Resolution: 10 seconds.\n
* Influence: at runtime.\n
* Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec\n
* The parameter is saved into the CC3000 NVMEM. \n
* The default value on CC3000 is 10 seconds.\n
*
* \param inactivity Socket inactivity timeout, socket timeout is\n
* refreshed by incoming or outgoing packet, by the\n
* end of the socket timeout the socket will be closed\n
* Range: [0-0xffffffff] sec, 0 == infinite timeout.\n
* Resolution: 10 seconds.\n
* Influence: at runtime.\n
* Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec\n
* The parameter is saved into the CC3000 NVMEM.\n
* The default value on CC3000 is 60 seconds.\n
*
* \return 0 on success,otherwise error.
*
* \note A parameter set to a non zero value less than 20s automatically changes to 20s.
*/
int32_t timeout_values(uint32_t *dhcp, uint32_t *arp,uint32_t *keep_alive, uint32_t *inactivity);
/**
* \brief send ICMP ECHO_REQUEST to network hosts
* \param ip destination IP address
* \param ping_attempts number of echo requests to send
* \param ping_size send buffer size which may be up to 1400 bytes
* \param ping_timeout Time to wait for a response,in milliseconds.
* \return 0 on success, otherwise error.
*
* \note A succesful operation will generate an asynchronous ping report event.\n
* The report structure is defined by structure netapp_pingreport_args_t.\n
* \warning Calling this function while a Ping Request is in progress will kill the ping request in progress.
*/
int32_t ping_send(uint32_t *ip, uint32_t ping_attempts, uint32_t ping_size, uint32_t ping_timeout);
/**
* \brief Ping status request.
* This API triggers the CC3000 to send asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT.\n
* This event will create the report structure in netapp_pingreport_args_t.\n
* This structure is filled with ping results until the API is triggered.\n
* netapp_pingreport_args_t: packets_sent - echo sent\n
* packets_received - echo reply\n
* min_round_time - minimum round time\n
* max_round_time - max round time\n
* avg_round_time - average round time\n
*
* \param none
* \return none
* \note When a ping operation is not active, the returned structure fields are 0.
*/
void ping_report();
/**
* \brief Stop any ping request.
* \param none
* \return 0 on success
* -1 on error
*/
int32_t ping_stop();
/**
* \brief Flush ARP table
* \param none
* \return none
*/
int32_t arp_flush();
#endif
private:
cc3000_simple_link &_simple_link;
cc3000_nvmem &_nvmem;
cc3000_hci &_hci;
cc3000_event &_event;
};
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
/** Security class used only if encrypted smart config is set
*/
class cc3000_security {
public:
/**
* \brief Expand a 16 bytes key for AES128 implementation.
* \param expanded_key expanded AES128 key
* \param key AES128 key - 16 bytes
* \return none
*/
void expandKey(uint8_t *expanded_key, uint8_t *key);
/**
* \brief multiply by 2 in the galois field.
* \param value Argument to multiply
* \return multiplied argument
*/
uint8_t galois_mul2(uint8_t value);
/**
* \brief internal implementation of AES128 encryption.
* straight forward aes encryption implementation\n
* first the group of operations
* - addRoundKey
* - subbytes
* - shiftrows
* - mixcolums\n
*
* is executed 9 times, after this addroundkey to finish the 9th\n
* round, after that the 10th round without mixcolums\n
* no further subfunctions to save cycles for function calls\n
* no structuring with "for (....)" to save cycles.\n
* \param[in] expanded_key expanded AES128 key
* \param[in/out] state 16 bytes of plain text and cipher text
* \return none
*/
void aes_encr(uint8_t *state, uint8_t *expanded_key);
/**
* \brief internal implementation of AES128 decryption.
* straightforward aes decryption implementation\n
* the order of substeps is the exact reverse of decryption\n
* inverse functions:
* - addRoundKey is its own inverse
* - rsbox is inverse of sbox
* - rightshift instead of leftshift
* - invMixColumns = barreto + mixColumns\n
*
* no further subfunctions to save cycles for function calls\n
* no structuring with "for (....)" to save cycles\n
* \param[in] expanded_key expanded AES128 key
* \param[in\out] state 16 bytes of cipher text and plain text
* \return none
*/
void aes_decr(uint8_t *state, uint8_t *expanded_key);
/**
* \brief AES128 encryption.
* Given AES128 key and 16 bytes plain text, cipher text of 16 bytes is computed.\n
* The AES implementation is in mode ECB (Electronic Code Book).\n
* \param[in] key AES128 key of size 16 bytes
* \param[in\out] state 16 bytes of plain text and cipher text
* \return none
*/
void aes_encrypt(uint8_t *state, uint8_t *key);
/**
* \brief AES128 decryption.
* Given AES128 key and 16 bytes cipher text, plain text of 16 bytes is computed.\n
* The AES implementation is in mode ECB (Electronic Code Book).\n
* \param[in] key AES128 key of size 16 bytes
* \param[in\out] state 16 bytes of cipher text and plain text
* \return none
*/
void aes_decrypt(uint8_t *state, uint8_t *key);
/**
* \brief Read the AES128 key from fileID #12 in EEPROM.
* \param[out] key AES128 key of size 16 bytes
* \return 0 on success, error otherwise.
*/
int32_t aes_read_key(uint8_t *key);
/**
* \brief Write the AES128 key to fileID #12 in EEPROM.
* \param[out] key AES128 key of size 16 bytes
* \return on success 0, error otherwise.
*/
int32_t aes_write_key(uint8_t *key);
private:
uint8_t _expanded_key[176];
};
#endif
/** Socket layer
*/
class cc3000_socket {
public:
/**
* \brief Ctor
* \param simplelink Reference to simple link object.
* \param hci Reference to hci object.
* \param event Reference to event object.
* \return none
*/
cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event);
/**
* \brief Dtor
* \param
* \return none
*/
~cc3000_socket();
/**
* \brief create an endpoint for communication.
* The socket function creates a socket that is bound to a specific transport service provider.\n
* This function is called by the application layer to obtain a socket handle.\n
*
* \param domain selects the protocol family which will be used for\n
* communication. On this version only AF_INET is supported\n
* \param type specifies the communication semantics. On this version\n
* only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported\n
* \param protocol specifies a particular protocol to be used with the\n
* socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are supported.\n
* \return On success, socket handle that is used for consequent socket operations\n
* On error, -1 is returned.\n
*/
int32_t socket(int32_t domain, int32_t type, int32_t protocol);
/**
* \brief accept a connection on a socket.
* This function is used with connection-based socket types\n
* (SOCK_STREAM). It extracts the first connection request on the\n
* queue of pending connections, creates a new connected socket, and\n
* returns a new file descriptor referring to that socket.\n
* The newly created socket is not in the listening state.\n
* The original socket sd is unaffected by this call.\n
* The argument sd is a socket that has been created with socket(),\n
* bound to a local address with bind(), and is listening for \n
* connections after a listen(). The argument addr is a pointer \n
* to a sockaddr structure. This structure is filled in with the \n
* address of the peer socket, as known to the communications layer.\n
* The exact format of the address returned addr is determined by the \n
* socket's address family. The addrlen argument is a value-result\n
* argument: it should initially contain the size of the structure\n
* pointed to by addr, on return it will contain the actual\n
* length (in bytes) of the address returned.\n
*
* \param[in] sd socket descriptor (handle)\n
* \param[out] addr the argument addr is a pointer to a sockaddr structure\n
* This structure is filled in with the address of the \n
* peer socket, as known to the communications layer. \n
* determined. The exact format of the address returned \n
* addr is by the socket's address sockaddr. \n
* On this version only AF_INET is supported.\n
* This argument returns in network order.\n
* \param[out] addrlen the addrlen argument is a value-result argument: \n
* it should initially contain the size of the structure\n
* pointed to by addr.\n
* \return For socket in blocking mode:\n
* - On success, socket handle. on failure negative\n
* For socket in non-blocking mode:\n
* - On connection establishment, socket handle\n
* - On connection pending, SOC_IN_PROGRESS (-2)\n
* - On failure, SOC_ERROR (-1)\n
* \sa socket ; bind ; listen
*/
int32_t accept(int32_t sd, sockaddr *addr, socklen_t *addrlen);
/**
* \brief assign a name to a socket.
* This function gives the socket the local address addr.\n
* addr is addrlen bytes long. Traditionally, this is called when a \n
* socket is created with socket, it exists in a name space (address \n
* family) but has no name assigned.\n
* It is necessary to assign a local address before a SOCK_STREAM\n
* socket may receive connections.\n
*
* \param[in] sd socket descriptor (handle)
* \param[out] addr specifies the destination address. On this version\n
* only AF_INET is supported.\n
* \param[out] addrlen contains the size of the structure pointed to by addr.\n
* \return On success, zero is returned.\n
* On error, -1 is returned.\n
* \sa socket ; accept ; listen
*/
int32_t bind(int32_t sd, const sockaddr *addr, int32_t addrlen);
/**
* \brief HostFlowControlConsumeBuff.
* if SEND_NON_BLOCKING is not defined - block until a free buffer is available,\n
* otherwise return the status of the available buffers.\n
*
* \param sd socket descriptor
* \return 0 in case there are buffers available, \n
* -1 in case of bad socket\n
* -2 if there are no free buffers present (only when SEND_NON_BLOCKING is enabled)\n
*/
int32_t HostFlowControlConsumeBuff(int32_t sd);
/**
* \brief The socket function closes a created socket.
* \param sd socket handle.
* \return On success, zero is returned. On error, -1 is returned.
*/
int32_t closesocket(int32_t sd);
/**
* \brief listen for connections on a socket.
* The willingness to accept incoming connections and a queue\n
* limit for incoming connections are specified with listen(),\n
* and then the connections are accepted with accept.\n
* The listen() call applies only to sockets of type SOCK_STREAM\n
* The backlog parameter defines the maximum length the queue of\n
* pending connections may grow to. \n
*
* \param[in] sd socket descriptor (handle)
* \param[in] backlog specifies the listen queue depth. On this version\n
* backlog is not supported.\n
* \return On success, zero is returned.\n
* On error, -1 is returned.\n
* \sa socket ; accept ; bind
* \note On this version, backlog is not supported
*/
int32_t listen(int32_t sd, int32_t backlog);
/**
* \brief initiate a connection on a socket.
* Function connects the socket referred to by the socket descriptor\n
* sd, to the address specified by addr. The addrlen argument \n
* specifies the size of addr. The format of the address in addr is \n
* determined by the address space of the socket. If it is of type \n
* SOCK_DGRAM, this call specifies the peer with which the socket is \n
* to be associated; this address is that to which datagrams are to be\n
* sent, and the only address from which datagrams are to be received. \n
* If the socket is of type SOCK_STREAM, this call attempts to make a \n
* connection to another socket. The other socket is specified by \n
* address, which is an address in the communications space of the\n
* socket. Note that the function implements only blocking behavior \n
* thus the caller will be waiting either for the connection \n
* establishment or for the connection establishment failure.\n
*
* \param[in] sd socket descriptor (handle)
* \param[in] addr specifies the destination addr. On this version\n
* only AF_INET is supported.\n
* \param[out] addrlen contains the size of the structure pointed to by addr
* \return On success, zero is returned.\n
On error, -1 is returned\n
* \sa socket
*/
int32_t connect(int32_t sd, const sockaddr *addr, int32_t addrlen);
/**
* \brief Monitor socket activity.
* Select allow a program to monitor multiple file descriptors,\n
* waiting until one or more of the file descriptors become \n
* "ready" for some class of I/O operation \n
*
* \param[in] nfds the highest-numbered file descriptor in any of the\n
* three sets, plus 1. \n
* \param[out] readsds socket descriptors list for read monitoring\n
* \param[out] writesds socket descriptors list for write monitoring\n
* \param[out] exceptsds socket descriptors list for exception monitoring\n
* \param[in] timeout is an upper bound on the amount of time elapsed\n
* before select() returns. Null means infinity \n
* timeout. The minimum timeout is 5 milliseconds,\n
* less than 5 milliseconds will be set\n
* automatically to 5 milliseconds.\n
* \return On success, select() returns the number of file descriptors\n
* contained in the three returned descriptor sets (that is, the\n
* total number of bits that are set in readfds, writefds,\n
* exceptfds) which may be zero if the timeout expires before\n
* anything interesting happens.\n
* On error, -1 is returned.\n
* *readsds - return the sockets on which Read request will\n
* return without delay with valid data.\n
* *writesds - return the sockets on which Write request \n
* will return without delay.\n
* *exceptsds - return the sockets which closed recently.\n
* \Note If the timeout value set to less than 5ms it will automatically\n
* change to 5ms to prevent overload of the system\n
* \sa socket
*/
int32_t select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout);
/**
* \brief get socket options.
* This function manipulate the options associated with a socket.\n
* Options may exist at multiple protocol levels; they are always\n
* present at the uppermost socket level.\n
* When manipulating socket options the level at which the option \n
* resides and the name of the option must be specified. \n
* To manipulate options at the socket level, level is specified as \n
* SOL_SOCKET. To manipulate options at any other level the protocol \n
* number of the appropriate protocol controlling the option is \n
* supplied. For example, to indicate that an option is to be \n
* interpreted by the TCP protocol, level should be set to the \n
* protocol number of TCP; \n
* The parameters optval and optlen are used to access optval -\n
* use for setsockopt(). For getsockopt() they identify a buffer\n
* in which the value for the requested option(s) are to \n
* be returned. For getsockopt(), optlen is a value-result \n
* parameter, initially containing the size of the buffer \n
* pointed to by option_value, and modified on return to \n
* indicate the actual size of the value returned. If no option \n
* value is to be supplied or returned, option_value may be NULL.\n
*
* \param[in] sd socket handle
* \param[in] level defines the protocol level for this option
* \param[in] optname defines the option name to Interrogate
* \param[out] optval specifies a value for the option
* \param[out] optlen specifies the length of the option value
* \return On success, zero is returned. On error, -1 is returned
*
* \Note On this version the following two socket options are enabled:\n
* The only protocol level supported in this version is SOL_SOCKET (level).\n
* 1. SOCKOPT_RECV_TIMEOUT (optname)\n
* SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout in milliseconds.\n
* In that case optval should be pointer to unsigned long.\n
* 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on or off.\n
* In that case optval should be SOCK_ON or SOCK_OFF (optval).\n
* \sa setsockopt
*/
int32_t getsockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen);
/**
* \brief Read data from socket (simple_link_recv).
* Return the length of the message on successful completion.\n
* If a message is too long to fit in the supplied buffer, excess bytes may\n
* be discarded depending on the type of socket the message is received from.\n
*
* \param sd socket handle
* \param buf read buffer
* \param len buffer length
* \param flags indicates blocking or non-blocking operation
* \param from pointer to an address structure indicating source address
* \param fromlen source address structure size
* \return Return the number of bytes received, or -1 if an error occurred
*/
int32_t simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode);
/**
* \brief Transmit a message to another socket (simple_link_send).
* \param sd socket handle
* \param buf write buffer
* \param len buffer length
* \param flags On this version, this parameter is not supported
* \param to pointer to an address structure indicating destination address
* \param tolen destination address structure size
* \return Return the number of bytes transmitted, or -1 if an error\n
* occurred, or -2 in case there are no free buffers available\n
* (only when SEND_NON_BLOCKING is enabled)\n
*/
int32_t simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode);
/**
* \brief Receive a message from a connection-mode socket.
* \param[in] sd socket handle
* \param[out] buf Points to the buffer where the message should be stored
* \param[in] len Specifies the length in bytes of the buffer pointed to \n
* by the buffer argument.\n
* \param[in] flags Specifies the type of message reception. \n
* On this version, this parameter is not supported.\n
* \return Return the number of bytes received, or -1 if an error occurred
* \sa recvfrom
* \Note On this version, only blocking mode is supported.
*/
int32_t recv(int32_t sd, void *buf, int32_t len, int32_t flags);
/**
* \brief read data from socket (recvfrom).
* Receives a message from a connection-mode or connectionless-mode socket.\n
* Note that raw sockets are not supported.\n
*
* \param[in] sd socket handle
* \param[out] buf Points to the buffer where the message should be stored
* \param[in] len Specifies the length in bytes of the buffer pointed to \n
* by the buffer argument.\n
* \param[in] flags Specifies the type of message reception.\n
* On this version, this parameter is not supported.\n
* \param[in] from pointer to an address structure indicating the source\n
* address: sockaddr. On this version only AF_INET is\n
* supported.\n
* \param[in] fromlen source address structure size
* \return Return the number of bytes received, or -1 if an error occurred
* \sa recv
* \Note On this version, only blocking mode is supported.
*/
int32_t recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen);
/**
* \brief Transmit a message to another socket (send).
* \param sd socket handle
* \param buf Points to a buffer containing the message to be sent
* \param len message size in bytes
* \param flags On this version, this parameter is not supported
* \return Return the number of bytes transmitted, or -1 if an\n
* error occurred\n
* \Note On this version, only blocking mode is supported.
* \sa sendto
*/
int32_t send(int32_t sd, const void *buf, int32_t len, int32_t flags);
/**
* \brief Transmit a message to another socket (sendto).
* \param sd socket handle
* \param buf Points to a buffer containing the message to be sent
* \param len message size in bytes
* \param flags On this version, this parameter is not supported
* \param to pointer to an address structure indicating the destination\n
* address: sockaddr. On this version only AF_INET is\n
* supported.\n
* \param tolen destination address structure size
* \return Return the number of bytes transmitted, or -1 if an error occurred
* \Note On this version, only blocking mode is supported.
* \sa send
*/
int32_t sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen);
/**
* \brief Set CC3000 in mDNS advertiser mode in order to advertise itself.
* \param[in] mdns_enabled flag to enable/disable the mDNS feature
* \param[in] device_service_name Service name as part of the published\n
* canonical domain name\n
* \param[in] device_service_name_length Length of the service name
* \return On success, zero is returned,\n
* return SOC_ERROR if socket was not opened successfully, or if an error occurred.\n
*/
int32_t mdns_advertiser(uint16_t mdns_enabled, uint8_t * device_service_name, uint16_t device_service_name_length);
/**
* \brief
* \param[in] s_addr in host format ( little endian )
* \param[in] *buf buffer to write too
* \param[in] buflen length of supplied buffer
* \return pointer to buf \n
*/
char * inet_ntoa_r(uint32_t s_addr, char *buf, int buflen);
#ifndef CC3000_TINY_DRIVER
/**
* \brief Get host IP by name.\n
* Obtain the IP Address of machine on network\n
*
* \param[in] hostname host name
* \param[in] name_length name length
* \param[out] out_ip_addr This parameter is filled in with host IP address.\n
* In case that host name is not resolved, \n
* out_ip_addr is zero.\n
* \return On success, positive is returned.\n
* On error, negative is returned by its name.\n
* \note On this version, only blocking mode is supported. Also note that\n
* The function requires DNS server to be configured prior to its usage.\n
*/
int32_t gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr);
/**
* \brief set socket options.
* This function manipulate the options associated with a socket.\n
* Options may exist at multiple protocol levels; they are always\n
* present at the uppermost socket level.\n
* When manipulating socket options the level at which the option \n
* resides and the name of the option must be specified.\n
* To manipulate options at the socket level, level is specified as\n
* SOL_SOCKET. To manipulate options at any other level the protocol \n
* number of the appropriate protocol controlling the option is \n
* supplied. For example, to indicate that an option is to be \n
* interpreted by the TCP protocol, level should be set to the \n
* protocol number of TCP; \n
* The parameters optval and optlen are used to access optval - \n
* use for setsockopt(). For getsockopt() they identify a buffer\n
* in which the value for the requested option(s) are to \n
* be returned. For getsockopt(), optlen is a value-result \n
* parameter, initially containing the size of the buffer \n
* pointed to by option_value, and modified on return to \n
* indicate the actual size of the value returned. If no option \n
* value is to be supplied or returned, option_value may be NULL.\n
*
* \param[in] sd socket handle
* \param[in] level defines the protocol level for this option
* \param[in] optname defines the option name to Interrogate
* \param[in] optval specifies a value for the option
* \param[in] optlen specifies the length of the option value
* \return On success, zero is returned.\n
* On error, -1 is returned\n
*
* \Note On this version the following two socket options are enabled:\n
* The only protocol level supported in this version is SOL_SOCKET (level).\n
* 1. SOCKOPT_RECV_TIMEOUT (optname)\n
* SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout in milliseconds.\n
* In that case optval should be pointer to unsigned long.\n
* 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on or off.\n
* In that case optval should be SOCK_ON or SOCK_OFF (optval).\n
* \sa getsockopt
*/
int32_t setsockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen);
#endif
private:
cc3000_simple_link &_simple_link;
cc3000_hci &_hci;
cc3000_event &_event;
};
/** SPI communication layer
*/
class cc3000_spi {
public:
/**
* \brief Ctor
* \param irq IRQ pin
* \param cc3000_en Enable pin
* \param cc3000_cs Chip select pin
* \param cc3000_spi SPI object
* \param irq_port Port for IRQ pin (needed for enable/disable interrupts)
* \param event Reference to the event object.
* \param simple_link Reference to the simple link object.
* \return none
*/
cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, cc3000_event &event, cc3000_simple_link &simple_link);
/**
* \brief Dtor
* \param none
* \return none
*/
~cc3000_spi();
/**
* \brief Close SPI - disables IRQ and set received buffer to 0
* \param none
* \return none
*/
void close();
/**
* \brief Open the SPI interface
* \param none
* \return none
*/
void open();
/**
* \brief First SPI write after powerup (delay needed between SPI header and body)
* \param buffer pointer to write buffer
* \param length buffer length
* \return 0
*/
uint32_t first_write(uint8_t *buffer, uint16_t length);
/**
* \brief SPI Write function
* \param buffer pointer to write buffer
* \param length buffer length
* \return 0
*/
uint32_t write(uint8_t *buffer, uint16_t length);
/**
* \brief Low level SPI write
* \param data pointer to data buffer
* \param size number of bytes
* \return none
*/
void write_synchronous(uint8_t *data, uint16_t size);
/**
* \brief Low level SPI read
* \param data pointer to data buffer
* \param size number of bytes
* \return none
*/
void read_synchronous(uint8_t *data, uint16_t size);
/**
* \brief Process the received SPI Header and in accordance with it - continue reading the packet
* \param None
* \return 0
*/
uint32_t read_data_cont();
/**
* \brief Enable WLAN interrutp
* \param None
* \return None
*/
void wlan_irq_enable();
/**
* \brief Disable WLAN interrutp
* \param None
* \return None
*/
void wlan_irq_disable();
/**
* \brief Get WLAN interrupt status
* \param None
* \return 0 : No interrupt occured
* 1 : Interrupt occured
*/
uint32_t wlan_irq_read();
/**
* \brief SPI interrupt Handler.
* The external WLAN device asserts the IRQ line when data is ready.\n
* The host CPU needs to acknowledges the IRQ by asserting CS.\n
*
* \param none
* \return none
*/
void WLAN_IRQHandler();
/**
* \brief Enable/Disable the WLAN module
* \param value 1 : Enable
* 0 : Disable
* \return None
*/
void set_wlan_en(uint8_t value);
private:
tSpiInfo _spi_info;
InterruptIn _wlan_irq;
DigitalOut _wlan_en;
DigitalOut _wlan_cs;
SPI _wlan_spi;
cc3000_event &_event;
cc3000_simple_link &_simple_link;
bool _process_irq;
};
/** HCI layer
*/
class cc3000_hci {
public:
/**
* \brief Ctor
* \param spi Reference to the spi object.
* \return none
*/
cc3000_hci(cc3000_spi &spi);
/**
* \brief Dtor
* \param none
* \return none
*/
~cc3000_hci();
/**
* \brief Initiate an HCI command.
* \param op_code command operation code
* \param buffer pointer to the command's arguments buffer
* \param length length of the arguments
* \return 0
*/
uint16_t command_send(uint16_t op_code, uint8_t *buffer, uint8_t length);
/**
* \brief Initiate an HCI data write operation
* \param op_code command operation code
* \param args pointer to the command's arguments buffer
* \param arg_length length of the arguments
* \param data_length length od data
* \param tail pointer to the data buffer
* \param tail_length buffer length
* \return ESUCCESS
*/
uint32_t data_send(uint8_t op_code, uint8_t *args, uint16_t arg_length,
uint16_t data_length, const uint8_t *tail, uint16_t tail_length);
/**
* \brief Prepare HCI header and initiate an HCI data write operation.
* \param op_code command operation code
* \param buffer pointer to the data buffer
* \param arg_length arguments length
* \param data_length data length
* \return none
*/
void data_command_send(uint16_t op_code, uint8_t *buffer, uint8_t arg_length,
uint16_t data_length);
/**
* \brief Prepare HCI header and initiate an HCI patch write operation.
* \param op_code command operation code
* \param buffer pointer to the command's arguments buffer
* \param patch pointer to patch content buffer
* \param data_length data length
* \return none
*/
void patch_send(uint8_t op_code, uint8_t *buffer, uint8_t *patch, uint16_t data_length);
private:
cc3000_spi &_spi;
};
/** NVMEM layer
*/
class cc3000_nvmem {
public:
/**
* \brief Ctor
* \param hci Reference to the hci object.
* \param event Reference to the event object.
* \param simple_link Reference to the simple link object.
* \return none
*/
cc3000_nvmem(cc3000_hci &hci, cc3000_event &event, cc3000_simple_link &simple_link);
/**
* \brief Dtor
* \param none
* \return none
*/
~cc3000_nvmem();
/**
* \brief Reads data from the file referred by the file_id parameter.
* Reads data from file offset till length. Err if the file can't be used,
* is invalid, or if the read is out of bounds.
* \param file_id nvmem file id.
* \param length number of bytes to read.
* \param offset offset in file from where to read.
* \param buff output buffer pointer.
* \return
* Number of bytes read, otherwise error.
*/
int32_t read(uint32_t file_id, uint32_t length, uint32_t offset, uint8_t *buff);
/**
* \brief Write data to nvmem.
* \param file_id Nvmem file id
* \param length number of bytes to write
* \param entry_offset offset in file to start write operation from
* \param buff data to write
* \return
* On success 0, error otherwise.
*/
int32_t write(uint32_t file_id, uint32_t length, uint32_t entry_offset, uint8_t *buff);
/**
* \brief Write MAC address to EEPROM.
* \param mac Mac address to be set
* \return
* On success 0, error otherwise.
*/
uint8_t set_mac_address(uint8_t *mac);
/**
* \brief Read MAC address from EEPROM.
* \param mac Mac address
* \return
* On success 0, error otherwise.
*/
uint8_t get_mac_address(uint8_t *mac);
/**
* \brief Program a patch to a specific file ID. The SP data is assumed to be organized in 2-dimensional.
* Each line is SP_PORTION_SIZE bytes long.
* \param file_id nvmem file id/
* \param length number of bytes to write
* \param data SP data to write
* \return
* On success 0, error otherwise.
*/
uint8_t write_patch(uint32_t file_id, uint32_t length, const uint8_t *data);
/**
* \brief Create new file entry and allocate space on the NVMEM. Applies only to user files.
* \param file_id nvmem file Id
* \param new_len entry ulLength
* \return
*/
int32_t create_entry(uint32_t file_id, uint32_t new_len);
#ifndef CC3000_TINY_DRIVER
/**
* \brief Read patch version. read package version (WiFi FW patch, river-supplicant-NS patch,
* bootloader patch)
* \param patch_ver First number indicates package ID and the second number indicates
* package build number
* \return
* On success 0, error otherwise.
*/
uint8_t read_sp_version(uint8_t* patch_ver);
#endif
private:
cc3000_hci &_hci;
cc3000_event &_event;
cc3000_simple_link &_simple_link;
};
/** WLAN layer
*/
class cc3000_wlan {
public:
/**
* \brief Ctor
* \param simple_link Reference to the simple link object.
* \param event Reference to the event object.
* \param spi Reference to the spi object.
* \param hci Reference to the hci object.
* \return none
*/
cc3000_wlan(cc3000_simple_link &simple_link, cc3000_event &event, cc3000_spi &spi, cc3000_hci &hci);
/**
* \brief Dtor
* \param none
* \return none
*/
~cc3000_wlan();
/**
* \brief Send SIMPLE LINK START to cc3000.
* \param patches_available_host Flag to indicate if patches are available.
* \return none
*/
void simpleLink_init_start(uint16_t patches_available_host);
/**
* \brief Start wlan device. Blocking call until init is completed.
* \param patches_available_host Flag to indicate if patches are available.
* \return none
*/
void start(uint16_t patches_available_host);
/**
* \brief Stop wlan device
* \param none
* \return none
*/
void stop(void);
#ifndef CC3000_TINY_DRIVER
/**
* \brief Connect to AP.
* \param sec_type Security option.
* \param ssid up to 32 bytes, ASCII SSID
* \param ssid_length length of SSID
* \param b_ssid 6 bytes specified the AP bssid
* \param key up to 16 bytes specified the AP security key
* \param key_len key length
* \return
* On success, zero is returned. On error, negative is returned.
*/
int32_t connect(uint32_t sec_type, const uint8_t *ssid, int32_t ssid_length, uint8_t *b_ssid, uint8_t *key, int32_t key_len);
/**
* \brief Add profile. Up to 7 profiles are supported.
* \param sec_type Security option.
* \param ssid Up to 32 bytes, ASCII SSID
* \param ssid_length Length of SSID
* \param b_ssid 6 bytes specified the AP bssid
* \param priority Up to 16 bytes specified the AP security key
* \param pairwise_cipher_or_tx_key_len Key length
* \param group_cipher_tx_key_index Key length for WEP security
* \param key_mgmt KEY management
* \param pf_or_key Security key
* \param pass_phrase_length Security key length for WPA\WPA2
* \return
* On success, zero is returned. On error, negative is returned.
*/
int32_t add_profile(uint32_t sec_type, uint8_t* ssid, uint32_t ssid_length, uint8_t *b_ssid, uint32_t priority, uint32_t pairwise_cipher_or_tx_key_len, uint32_t group_cipher_tx_key_index,
uint32_t key_mgmt, uint8_t* pf_or_key, uint32_t pass_phrase_length);
/**
* \brief Gets entry from scan result table. The scan results are returned
* one by one, and each entry represents a single AP found in the area.
* \param scan_timeout Not supported yet
* \param results Scan result
* \return
* On success, zero is returned. On error, -1 is returned
*/
int32_t ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results);
/**
* \brief Start and stop scan procedure. Set scan parameters.
* \param enable Start/stop application scan
* \param min_dwell_time Minimum dwell time value to be used for each channel, in ms. (Default: 20)
* \param max_dwell_time Maximum dwell time value to be used for each channel, in ms. (Default: 30)
* \param num_probe_requests Max probe request between dwell time. (Default:2)
* \param channel_mask Bitwise, up to 13 channels (0x1fff).
* \param rssi_threshold RSSI threshold. Saved: yes (Default: -80)
* \param snr_threshold NSR threshold. Saved: yes (Default: 0)
* \param default_tx_power probe Tx power. Saved: yes (Default: 205)
* \param interval_list Pointer to array with 16 entries (16 channels)
* \return
* On success, zero is returned. On error, -1 is returned.
*/
int32_t ioctl_set_scan_params(uint32_t enable, uint32_t min_dwell_time, uint32_t max_dwell_time, uint32_t num_probe_requests,
uint32_t channel_mask, int32_t rssi_threshold, uint32_t snr_threshold, uint32_t default_tx_power, uint32_t *interval_list);
/**
* \brief Get wlan status: disconnected, scanning, connecting or connected
* \param none
* \return
* WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, STATUS_CONNECTING or WLAN_STATUS_CONNECTED
*/
int32_t ioctl_statusget(void);
#else
/**
* \brief Connect to AP
* \param ssid Up to 32 bytes and is ASCII SSID of the AP
* \param ssid_length Length of the SSID
* \return
* On success, zero is returned. On error, negative is returned.
*/
int32_t connect(const uint8_t *ssid, int32_t ssid_length);
/**
* \brief When auto start is enabled, the device connects to station from the profiles table.
* If several profiles configured the device choose the highest priority profile.
* \param sec_type WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2
* \param ssid SSID up to 32 bytes
* \param ssid_length SSID length
* \param b_ssid bssid 6 bytes
* \param priority Profile priority. Lowest priority:0.
* \param pairwise_cipher_or_tx_key_len Key length for WEP security
* \param group_cipher_tx_key_index Key index
* \param key_mgmt KEY management
* \param pf_or_key Security key
* \param pass_phrase_length Security key length for WPA\WPA2
* \return
* On success, zero is returned. On error, -1 is returned
*/
int32_t add_profile(uint32_t sec_type, uint8_t *ssid, uint32_t ssid_length, uint8_t *b_ssid, uint32_t priority,
uint32_t pairwise_cipher_or_tx_key_len, uint32_t group_cipher_tx_key_index, uint32_t key_mgmt,
uint8_t* pf_or_key, uint32_t pass_phrase_length);
#endif
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
/**
* \brief Process the acquired data and store it as a profile.
* \param none
* \return
* On success, zero is returned. On error, -1 is returned.
*/
int32_t smart_config_process(void);
#endif
/**
* \brief Disconnect connection from AP.
* \param none
* \return
* 0 if disconnected done, other CC3000 already disconnected.
*/
int32_t disconnect();
/**
* \brief When auto is enabled, the device tries to connect according the following policy:
* 1) If fast connect is enabled and last connection is valid, the device will try to
* connect to it without the scanning procedure (fast). The last connection will be
* marked as invalid, due to adding/removing profile.
* 2) If profile exists, the device will try to connect it (Up to seven profiles).
* 3) If fast and profiles are not found, and open mode is enabled, the device
* will try to connect to any AP.
* Note that the policy settings are stored in the CC3000 NVMEM.
* \param should_connect_to_open_ap Enable(1), disable(0) connect to any available AP.
* \param use_fast_connect Enable(1), disable(0). if enabled, tries to
* connect to the last connected AP.
* \param use_profiles Enable(1), disable(0) auto connect after reset.
* and periodically reconnect if needed.
* \return
* On success, zero is returned. On error, -1 is returned
*/
int32_t ioctl_set_connection_policy(uint32_t should_connect_to_open_ap, uint32_t use_fast_connect, uint32_t use_profiles);
/**
* \brief Delete WLAN profile
* \param index Number of profile to delete
* \return
* On success, zero is returned. On error, -1 is returned
*/
int32_t ioctl_del_profile(uint32_t index);
/**
* \brief Mask event according to bit mask. In case that event is
* masked (1), the device will not send the masked event to host.
* \param mask event mask
* \return
* On success, zero is returned. On error, -1 is returned
*/
int32_t set_event_mask(uint32_t mask);
/**
* \brief Start to acquire device profile. The device acquire its own
* profile, if profile message is found.
* \param encrypted_flag Indicates whether the information is encrypted
* \return
* On success, zero is returned. On error, -1 is returned.
*/
int32_t smart_config_start(uint32_t encrypted_flag);
/**
* \brief Stop the acquire profile procedure.
* \param none
* \return
* On success, zero is returned. On error, -1 is returned
*/
int32_t smart_config_stop(void);
/**
* \brief Configure station ssid prefix.
* \param new_prefix 3 bytes identify the SSID prefix for the Smart Config.
* \return
* On success, zero is returned. On error, -1 is returned.
*/
int32_t smart_config_set_prefix(uint8_t *new_prefix);
private:
cc3000_simple_link &_simple_link;
cc3000_event &_event;
cc3000_spi &_spi;
cc3000_hci &_hci;
};
/** The main object of cc3000 implementation
*/
class cc3000 {
public:
/** status structure */
typedef struct {
uint8_t socket;
bool dhcp;
bool connected;
bool smart_config_complete;
bool stop_smart_config;
bool dhcp_configured;
bool ok_to_shut_down;
bool enabled;
} tStatus;
/**
* \brief Ctor.
* \param cc3000_irq IRQ pin
* \param cc3000_en Enable pin
* \param cc3000_cs Chip select pin
* \param cc3000_spi SPI interface
*/
cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi);
/**
* \brief Dtor.
*/
~cc3000();
/**
* \brief Initiate cc3000. It starts the wlan communication.
* \param patch Patch
*/
void start(uint8_t patch);
/**
* \brief Stops the wlan communication.
*/
void stop();
/**
* \brief Restarts the wlan communication.
*/
void restart(uint8_t patch);
/**
* \brief Callback which is called from the event class. This updates status of cc3000.
* \param event_type Type of the event
* \param data Pointer to data
* \param length Length of data
* \return none
*/
void usync_callback(int32_t event_type, uint8_t *data, uint8_t length);
/**
* \brief Start connection to SSID (open/secured) non-blocking
* \param ssid SSID name
* \param key Security key (if key = 0, open connection)
* \param security_mode Security mode
* \return true if connection was established, false otherwise.
*/
bool connect_non_blocking(const uint8_t *ssid, const uint8_t *key, int32_t security_mode);
/**
* \brief Connect to SSID (open/secured) with timeout (10s).
* \param ssid SSID name
* \param key Security key (if key = 0, open connection)
* \param security_mode Security mode
* \return true if connection was established, false otherwise.
*/
bool connect_to_AP(const uint8_t *ssid, const uint8_t *key, int32_t security_mode);
/**
* \brief Connect to SSID which is secured
* \param ssid SSID name
* \param key Security key
* \param security_mode Security mode
* \return true if connection was established, false otherwise.
*/
bool connect_secure(const uint8_t *ssid, const uint8_t *key, int32_t security_mode);
/**
* \brief Connect to SSID which is open (no security)
* \param ssid SSID name
* \return true if connection was established, false otherwise.
*/
bool connect_open(const uint8_t *ssid);
/**
* \brief Status of the cc3000 module.
* \return true if it's enabled, false otherwise.
*/
bool is_enabled();
/**
* \brief Status of the cc3000 connection.
* \return true if it's connected, false otherwise.
*/
bool is_connected();
/**
* \brief Status of DHCP.
* \param none
* \return true if DCHP is configured, false otherwise.
*/
bool is_dhcp_configured();
/**
* \brief Status of smart confing completation.
* \param none
* \return smart config was set, false otherwise.
*/
bool is_smart_confing_completed();
/**
* \brief Return the cc3000's mac address.
* \param address Retreived mac address.
* \return
*/
uint8_t get_mac_address(uint8_t address[6]);
/**
* \brief Set the cc3000's mac address.
* \param address Mac address to be set.
* \return
*/
uint8_t set_mac_address(uint8_t address[6]);
/**
* \brief Get user file info.
* \param info_file Pointer where info will be stored.
* \param size Available size.
* \return none
*/
void get_user_file_info(uint8_t *info_file, size_t size);
/**
* \brief Set user filo info.
* \param info_file Pointer to user's info.
* \return none
*/
void set_user_file_info(uint8_t *info_file, size_t size);
/**
* \brief Start smart config.
* \param smart_config_key Pointer to smart config key.
* \return none
*/
void start_smart_config(const uint8_t *smart_config_key); /* TODO enable AES ? */
#ifndef CC3000_TINY_DRIVER
/**
* \brief Return ip configuration.
* \param ip_config Pointer to ipconfig data.
* \return true if it's connected and info was retrieved, false otherwise.
*/
bool get_ip_config(tNetappIpconfigRetArgs *ip_config);
#endif
/**
* \brief Delete all stored profiles.
* \param none
* \return none
*/
void delete_profiles(void);
/**
* \brief Ping an ip address.
* \param ip Destination IP address
* \param attempts Number of attempts
* \param timeout Time to wait for a response,in milliseconds.
* \param size Send buffer size which may be up to 1400 bytes
*/
uint32_t ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size);
/**
* \brief Returns cc3000 instance. Used in Socket interface.
* \param none
* \return Pointer to cc3000 object
*/
static cc3000* get_instance() {
return _inst;
}
#if (CC3000_ETH_COMPAT == 1)
/**
* \brief Ctor for EthernetInterface
* \param cc3000_irq IRQ pin
* \param cc3000_en Enable pin
* \param cc3000_cs Chip select pin
* \param cc3000_spi SPI interface
* \param ssid SSID
* \param phrase Password
* \param sec Security of the AP
* \param smart_config Smart config selection
*/
cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, const char *ssid, const char *phrase, Security sec, bool smart_config);
/**
* \brief Disconnect wlan device.
* \param none
* \return 0 if successful, -1 otherwise.
*/
int disconnect();
/**
* \brief Initialize the interface with DHCP.
* \param none
* \return none
*/
void init();
/**
* \brief Initialize the interface with a static IP address.
* \param ip the IP address to use.
* \param mask the IP address mask
* \param gateway the gateway to use
* \return none
*/
void init(const char *ip, const char *mask, const char *gateway);
/**
* \brief Connect Bring the interface up.
* \param timeout_ms timeout in ms
* \return 0 if successful, -1 otherwise.
*/
int connect(unsigned int timeout_ms = 20000);
/**
* \brief Get the MAC address of your Ethernet interface.
* \param none
* \return
* Pointer to a string containing the MAC address.
*/
char* getMACAddress();
/**
* \brief Get the IP address of your Ethernet interface.
* \param none
* \return
* Pointer to a string containing the IP address.
*/
char* getIPAddress();
/**
* \brief Return the CC3000's firmware version.
* \param firmware Retreived firmware version.
* \return 0 if successful, -1 otherwise.
*/
uint8_t read_sp_version(uint8_t firmware[2]);
/**
* \brief routine to update firmware of CC3000
* \param
* \return 0 if successful, -1 otherwise.
*/
uint8_t write_patch(uint32_t file_id, uint32_t length, const uint8_t *data);
/**
* \brief Get the Gateway address of your Ethernet interface
* \param none
* \return
* Pointer to a string containing the Gateway address
*/
char* getGateway();
/**
* \brief Get the Network mask of your Ethernet interface
* \param none
* \return
* Pointer to a string containing the Network mask
*/
char* getNetworkMask();
#endif
public:
cc3000_simple_link _simple_link;
cc3000_event _event;
cc3000_socket _socket;
cc3000_spi _spi;
cc3000_hci _hci;
cc3000_nvmem _nvmem;
cc3000_netapp _netapp;
cc3000_wlan _wlan;
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
cc3000_security _security;
#endif
protected:
static cc3000 *_inst;
private:
tStatus _status;
netapp_pingreport_args_t _ping_report;
bool _closed_sockets[MAX_SOCKETS];
#if (CC3000_ETH_COMPAT == 1)
uint8_t _phrase[30];
uint8_t _ssid[30];
Security _sec;
bool _smart_config;
#endif
};
/**
* Copy 32 bit to stream while converting to little endian format.
* @param p pointer to the new stream
* @param u32 pointer to the 32 bit
* @return pointer to the new stream
*/
uint8_t *UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32);
/**
* Copy 16 bit to stream while converting to little endian format.
* @param p pointer to the new stream
* @param u32 pointer to the 16 bit
* @return pointer to the new stream
*/
uint8_t *UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16);
/**
* Copy received stream to 16 bit in little endian format.
* @param p pointer to the stream
* @param offset offset in the stream
* @return pointer to the new 16 bit
*/
uint16_t STREAM_TO_UINT16_f(uint8_t* p, uint16_t offset);
/**
* Copy received stream to 32 bit in little endian format.
* @param p pointer to the stream
* @param offset offset in the stream
* @return pointer to the new 32 bit
*/
uint32_t STREAM_TO_UINT32_f(uint8_t* p, uint16_t offset);
} /* end of mbed_cc3000 namespace */
#endif
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef CC3000_COMMON_H
#define CC3000_COMMON_H
#include <errno.h>
//#define CC3000_TINY_DRIVER // Driver for small memory model CPUs
#define ESUCCESS 0
#define EFAIL -1
#define EERROR EFAIL
#define CC3000_UNENCRYPTED_SMART_CONFIG // No encryption
#define ERROR_SOCKET_INACTIVE -57
#define HCI_CC_PAYLOAD_LEN 5
#define WLAN_ENABLE (1)
#define WLAN_DISABLE (0)
#define MAC_ADDR_LEN (6)
/*Defines for minimal and maximal RX buffer size. This size includes the spi
header and hci header.
maximal buffer size: MTU + HCI header + SPI header + sendto() args size
minimum buffer size: HCI header + SPI header + max args size
This buffer is used for receiving events and data.
The packet can not be longer than MTU size and CC3000 does not support
fragmentation. Note that the same buffer is used for reception of the data
and events from CC3000. That is why the minimum is defined.
The calculation for the actual size of buffer for reception is:
Given the maximal data size MAX_DATA that is expected to be received by
application, the required buffer Using recv() or recvfrom():
max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen + ucArgsize + 1)
Using gethostbyname() with minimal buffer size will limit the host name returned to 99 bytes.
The 1 is used for the overrun detection
*/
#define CC3000_MINIMAL_RX_SIZE (118 + 1)
#define CC3000_MAXIMAL_RX_SIZE (511 + 1)
/*Defines for minimal and maximal TX buffer size.
This buffer is used for sending events and data.
The packet can not be longer than MTU size and CC3000 does not support
fragmentation. Note that the same buffer is used for transmission of the data
and commands. That is why the minimum is defined.
The calculation for the actual size of buffer for transmission is:
Given the maximal data size MAX_DATA, the required buffer is:
Using Sendto():
max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
+ SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
Using Send():
max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
+ HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
The 1 is used for the overrun detection */
#define CC3000_MINIMAL_TX_SIZE (118 + 1)
#define CC3000_MAXIMAL_TX_SIZE (1519 + 1)
//TX and RX buffer size - allow to receive and transmit maximum data at lengh 8.
#ifdef CC3000_TINY_DRIVER
#define TINY_CC3000_MAXIMAL_RX_SIZE 44
#define TINY_CC3000_MAXIMAL_TX_SIZE 59
#endif
/*In order to determine your preferred buffer size,
change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between
the minimal and maximal specified above.
Note that the buffers are allocated by SPI.
*/
#ifndef CC3000_TINY_DRIVER
#define CC3000_RX_BUFFER_SIZE (CC3000_MAXIMAL_RX_SIZE)
#define CC3000_TX_BUFFER_SIZE (CC3000_MAXIMAL_TX_SIZE)
#define SP_PORTION_SIZE 512
//TINY DRIVER: We use smaller rx and tx buffers in order to minimize RAM consumption
#else
#define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE)
#define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE)
#define SP_PORTION_SIZE 32
#endif
//Copy 8 bit to stream while converting to little endian format.
#define UINT8_TO_STREAM(_p, _val) {*(_p)++ = (_val);}
//Copy 16 bit to stream while converting to little endian format.
#define UINT16_TO_STREAM(_p, _u16) (UINT16_TO_STREAM_f(_p, _u16))
//Copy 32 bit to stream while converting to little endian format.
#define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32))
//Copy a specified value length bits (l) to stream while converting to little endian format.
#define ARRAY_TO_STREAM(p, a, l) {uint32_t _i; for (_i = 0; _i < l; _i++) *(p)++ = ((uint8_t *) a)[_i];}
//Copy received stream to 8 bit in little endian format.
#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (uint8_t)(*(_p + _offset));}
//Copy received stream to 16 bit in little endian format.
#define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);}
//Copy received stream to 32 bit in little endian format.
#define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);}
#define STREAM_TO_STREAM(p, a, l) {uint32_t _i; for (_i = 0; _i < l; _i++) *(a)++= ((uint8_t *) p)[_i];}
typedef struct _sockaddr_t
{
uint16_t family;
uint8_t data[14];
} sockaddr;
struct timeval
{
int32_t tv_sec; /* seconds */
int32_t tv_usec; /* microseconds */
};
#define SMART_CONFIG_PROFILE_SIZE 67 // 67 = 32 (max ssid) + 32 (max key) + 1 (SSID length) + 1 (security type) + 1 (key length)
/* patches type */
#define PATCHES_HOST_TYPE_WLAN_DRIVER 0x01
#define PATCHES_HOST_TYPE_WLAN_FW 0x02
#define PATCHES_HOST_TYPE_BOOTLOADER 0x03
#define SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE (16)
#define SL_SIMPLE_CONFIG_PREFIX_LENGTH (3)
#define ETH_ALEN (6)
#define MAXIMAL_SSID_LENGTH (32)
#define SL_PATCHES_REQUEST_DEFAULT (0)
#define SL_PATCHES_REQUEST_FORCE_HOST (1)
#define SL_PATCHES_REQUEST_FORCE_NONE (2)
#define WLAN_SEC_UNSEC (0)
#define WLAN_SEC_WEP (1)
#define WLAN_SEC_WPA (2)
#define WLAN_SEC_WPA2 (3)
#define WLAN_SL_INIT_START_PARAMS_LEN (1)
#define WLAN_PATCH_PARAMS_LENGTH (8)
#define WLAN_SET_CONNECTION_POLICY_PARAMS_LEN (12)
#define WLAN_DEL_PROFILE_PARAMS_LEN (4)
#define WLAN_SET_MASK_PARAMS_LEN (4)
#define WLAN_SET_SCAN_PARAMS_LEN (100)
#define WLAN_GET_SCAN_RESULTS_PARAMS_LEN (4)
#define WLAN_ADD_PROFILE_NOSEC_PARAM_LEN (24)
#define WLAN_ADD_PROFILE_WEP_PARAM_LEN (36)
#define WLAN_ADD_PROFILE_WPA_PARAM_LEN (44)
#define WLAN_CONNECT_PARAM_LEN (29)
#define WLAN_SMART_CONFIG_START_PARAMS_LEN (4)
#endif
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
#include "cc3000_event.h"
#include "cc3000_netapp.h"
namespace mbed_cc3000 {
#if (CC3000_DEBUG_HCI_RX == 1)
const char *HCI_EVENT_STR[] =
{
"Socket",
"Bind",
"Send",
"Recv",
"Accept",
"Listen",
"Connect",
"BSD Select",
"Set Socket Options",
"Get Socket Options",
"Close Socket",
"Unknown",
"Recv From",
"Write",
"Send To",
"Get Hostname",
"mDNS Advertise"
};
const char *HCI_NETAPP_STR[] =
{
"DHCP",
"Ping Sent",
"Ping Report",
"Ping Stop",
"IP Config",
"ARP Flush",
"Unknown",
"Set Debug level",
"Set Timers"
};
// from 0-7
const char *HCI_MISC_STR[] =
{
"BASE - Error?",
"Connecting",
"Disconnect",
"Scan Param",
"Connect Policy",
"Add Profile",
"Del Profile",
"Get Scan Res",
"Event Mask",
"Status Req",
"Config Start",
"Config Stop",
"Config Set Prefix",
"Config Patch",
};
#endif
cc3000_event::cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000)
: socket_active_status(SOCKET_STATUS_INIT_VAL), _simple_link(simplelink), _hci(hci), _spi(spi), _cc3000(cc3000) {
}
cc3000_event::~cc3000_event() {
}
/* TODO removed buffer, set it in init */
void cc3000_event::received_handler(uint8_t *buffer) {
_simple_link.set_data_received_flag(1);
_simple_link.set_received_data(buffer);
hci_unsolicited_event_handler();
}
void cc3000_event::hci_unsol_handle_patch_request(uint8_t *event_hdr) {
uint8_t *params = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
uint32_t length = 0;
uint8_t *patch;
switch (*params)
{
case HCI_EVENT_PATCHES_DRV_REQ:
{
tDriverPatches func_pointer = (tDriverPatches)_simple_link.get_func_pointer(DRIVER_PATCHES);
if (func_pointer)
{
patch = func_pointer(&length);
if (patch)
{
_hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), patch, length);
return;
}
}
// Send 0 length Patches response event
_hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), 0, 0);
break;
}
case HCI_EVENT_PATCHES_FW_REQ:
{
tFWPatches func_pointer = (tFWPatches)_simple_link.get_func_pointer(FW_PATCHES);
if (func_pointer)
{
patch = func_pointer(&length);
// Build and send a patch
if (patch)
{
_hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), patch, length);
return;
}
}
// Send 0 length Patches response event
_hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), 0, 0);
break;
}
case HCI_EVENT_PATCHES_BOOTLOAD_REQ:
{
tBootLoaderPatches func_pointer = (tBootLoaderPatches)_simple_link.get_func_pointer(BOOTLOADER_PATCHES);
if (func_pointer)
{
patch = func_pointer(&length);
if (patch)
{
_hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), patch, length);
return;
}
}
// Send 0 length Patches response event
_hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), 0, 0);
break;
}
}
}
static void hci_event_debug_print(uint16_t hciEventNo)
{
#if (CC3000_DEBUG_HCI_RX == 1)
if ((hciEventNo > HCI_CMND_SOCKET_BASE) && ( hciEventNo <= HCI_CMND_MDNS_ADVERTISE))
{
DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_EVENT_STR[hciEventNo-HCI_CMND_SOCKET]);
}
else if ((hciEventNo > HCI_CMND_NETAPP_BASE) && ( hciEventNo <= HCI_NETAPP_SET_TIMERS))
{
DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_NETAPP_STR[hciEventNo-HCI_NETAPP_DHCP]);
}
else if (hciEventNo < HCI_CMND_WLAN_CONFIGURE_PATCH+1)
{
DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_MISC_STR[hciEventNo]);
}
else
{
DBG_HCI("Event Received : 0x%04X", hciEventNo);
}
#endif
}
uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) {
uint8_t *received_data, argument_size;
uint16_t length;
uint8_t *pucReceivedParams;
uint16_t received_op_code = 0;
uint32_t return_value;
uint8_t * RecvParams;
uint8_t *RetParams;
while (1)
{
if (_simple_link.get_data_received_flag() != 0)
{
received_data = _simple_link.get_received_data();
if (*received_data == HCI_TYPE_EVNT)
{
// Event Received
STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code);
pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE;
RecvParams = pucReceivedParams;
RetParams = (uint8_t *)ret_param;
// unsolicited event received - finish handling
if (hci_unsol_event_handler((uint8_t *)received_data) == 0)
{
STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length);
hci_event_debug_print( received_op_code );
switch(received_op_code)
{
case HCI_CMND_READ_BUFFER_SIZE:
{
uint16_t temp = _simple_link.get_number_free_buffers();
STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp);
_simple_link.set_number_free_buffers(temp);
temp = _simple_link.get_buffer_length();
STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp);
_simple_link.set_buffer_length(temp);
}
break;
case HCI_CMND_WLAN_CONFIGURE_PATCH:
case HCI_NETAPP_DHCP:
case HCI_NETAPP_PING_SEND:
case HCI_NETAPP_PING_STOP:
case HCI_NETAPP_ARP_FLUSH:
case HCI_NETAPP_SET_DEBUG_LEVEL:
case HCI_NETAPP_SET_TIMERS:
case HCI_EVNT_NVMEM_READ:
case HCI_EVNT_NVMEM_CREATE_ENTRY:
case HCI_CMND_NVMEM_WRITE_PATCH:
case HCI_NETAPP_PING_REPORT:
case HCI_EVNT_MDNS_ADVERTISE:
STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
break;
case HCI_CMND_SETSOCKOPT:
case HCI_CMND_WLAN_CONNECT:
case HCI_CMND_WLAN_IOCTL_STATUSGET:
case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
case HCI_CMND_EVENT_MASK:
case HCI_EVNT_WLAN_DISCONNECT:
case HCI_EVNT_SOCKET:
case HCI_EVNT_BIND:
case HCI_CMND_LISTEN:
case HCI_EVNT_CLOSE_SOCKET:
case HCI_EVNT_CONNECT:
case HCI_EVNT_NVMEM_WRITE:
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param);
break;
case HCI_EVNT_READ_SP_VERSION:
STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 1;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value);
UINT32_TO_STREAM((uint8_t *)ret_param, return_value);
break;
case HCI_EVNT_BSD_GETHOSTBYNAME:
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param);
break;
case HCI_EVNT_ACCEPT:
{
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
//This argument returns in network order
memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
break;
}
case HCI_EVNT_RECV:
case HCI_EVNT_RECVFROM:
{
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param);
if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
{
set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
}
break;
}
case HCI_EVNT_SEND:
case HCI_EVNT_SENDTO:
{
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
break;
}
case HCI_EVNT_SELECT:
{
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param);
break;
}
case HCI_CMND_GETSOCKOPT:
STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus);
//This argument returns in network order
memcpy((uint8_t *)ret_param, pucReceivedParams, 4);
break;
case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 4;
STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 2;
STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param);
ret_param = ((uint8_t *)ret_param) + 2;
memcpy((uint8_t *)ret_param, (uint8_t *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);
break;
case HCI_CMND_SIMPLE_LINK_START:
break;
case HCI_NETAPP_IPCONFIG:
//Read IP address
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
RecvParams += 4;
//Read subnet
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
RecvParams += 4;
//Read default GW
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
RecvParams += 4;
//Read DHCP server
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
RecvParams += 4;
//Read DNS server
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
RecvParams += 4;
//Read Mac address
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
RecvParams += 6;
//Read SSID
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
break;
default :
DBG_HCI("UNKNOWN Event Received : 0x%04X ", received_op_code);
break;
}
}
if (received_op_code == _simple_link.get_op_code())
{
_simple_link.set_op_code(0);
}
}
else
{
pucReceivedParams = received_data;
STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size);
STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length);
// Data received: note that the only case where from and from length
// are not null is in recv from, so fill the args accordingly
if (from)
{
STREAM_TO_UINT32((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen);
memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
}
memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size);
_simple_link.set_pending_data(0);
}
_simple_link.set_data_received_flag(0);
_spi.wlan_irq_enable();
// Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts
if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ))
{
hci_unsol_handle_patch_request((uint8_t *)received_data);
}
if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0))
{
return NULL;
}
}
}
}
int32_t cc3000_event::hci_unsol_event_handler(uint8_t *event_hdr) {
uint8_t *data = NULL;
int32_t event_type;
uint32_t number_of_released_packets;
uint32_t number_of_sent_packets;
STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);
if (event_type & HCI_EVNT_UNSOL_BASE) {
switch(event_type) {
case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
{
hci_event_unsol_flowcontrol_handler(event_hdr);
number_of_released_packets = _simple_link.get_released_packets();
number_of_sent_packets = _simple_link.get_sent_packets();
if (number_of_released_packets == number_of_sent_packets)
{
if (_simple_link.get_tx_complete_signal())
{
//tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
_cc3000.usync_callback(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
}
}
return 1;
}
}
}
if (event_type & HCI_EVNT_WLAN_UNSOL_BASE) {
switch(event_type) {
case HCI_EVNT_WLAN_KEEPALIVE:
case HCI_EVNT_WLAN_UNSOL_CONNECT:
case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
case HCI_EVNT_WLAN_UNSOL_INIT:
case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:
_cc3000.usync_callback(event_type, 0, 0);
break;
case HCI_EVNT_WLAN_UNSOL_DHCP:
{
uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
uint8_t *recParams = params;
data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
//Read IP address
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
data += 4;
//Read subnet
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
data += 4;
//Read default GW
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
data += 4;
//Read DHCP server
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
data += 4;
//Read DNS server
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
// read the status
STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);
_cc3000.usync_callback(event_type, (uint8_t *)params, sizeof(params));
break;
}
case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
{
netapp_pingreport_args_t params;
data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);
_cc3000.usync_callback(event_type, (uint8_t *)&params, sizeof(params));
break;
}
case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
{
_cc3000.usync_callback(event_type, NULL, 0);
break;
}
//'default' case which means "event not supported"
default:
return (0);
}
return(1);
}
if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) || (event_type == HCI_EVNT_WRITE)) {
uint8_t *pArg;
int32_t status;
pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);
if (ERROR_SOCKET_INACTIVE == status) {
// The only synchronous event that can come from SL device in form of
// command complete is "Command Complete" on data sent, in case SL device
// was unable to transmit
int32_t transmit_error = _simple_link.get_transmit_error();
STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, transmit_error);
_simple_link.set_transmit_error(transmit_error);
update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
return (1);
}
else {
return (0);
}
}
return(0);
}
int32_t cc3000_event::hci_unsolicited_event_handler(void) {
uint32_t res = 0;
uint8_t *received_data;
if (_simple_link.get_data_received_flag() != 0) {
received_data = (_simple_link.get_received_data());
if (*received_data == HCI_TYPE_EVNT) {
// unsolicited event received - finish handling
if (hci_unsol_event_handler((uint8_t *)received_data) == 1) {
// An unsolicited event was received:
// release the buffer and clean the event received
_simple_link.set_data_received_flag(0);
res = 1;
_spi.wlan_irq_enable();
}
}
}
return res;
}
void cc3000_event::set_socket_active_status(int32_t sd, int32_t status) {
if (M_IS_VALID_SD(sd) && M_IS_VALID_STATUS(status)) {
socket_active_status &= ~(1 << sd); /* clean socket's mask */
socket_active_status |= (status << sd); /* set new socket's mask */
}
}
int32_t cc3000_event::hci_event_unsol_flowcontrol_handler(uint8_t *event) {
int32_t temp, value;
uint16_t i;
uint16_t pusNumberOfHandles=0;
uint8_t *pReadPayload;
STREAM_TO_UINT16((uint8_t *)event,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
pReadPayload = ((uint8_t *)event + HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles));
temp = 0;
for(i = 0; i < pusNumberOfHandles; i++) {
STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value);
temp += value;
pReadPayload += FLOW_CONTROL_EVENT_SIZE;
}
_simple_link.set_number_free_buffers(_simple_link.get_number_free_buffers() + temp);
_simple_link.set_number_of_released_packets(_simple_link.get_released_packets() + temp);
return(ESUCCESS);
}
int32_t cc3000_event::get_socket_active_status(int32_t sd) {
if (M_IS_VALID_SD(sd)) {
return (socket_active_status & (1 << sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
} else {
return SOCKET_STATUS_INACTIVE;
}
}
void cc3000_event::update_socket_active_status(uint8_t *resp_params) {
int32_t status, sd;
STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd);
STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status);
if (ERROR_SOCKET_INACTIVE == status) {
set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
}
}
void cc3000_event::simplelink_wait_event(uint16_t op_code, void *ret_param) {
// In the blocking implementation the control to caller will be returned only
// after the end of current transaction
_simple_link.set_op_code(op_code);
hci_event_handler(ret_param, 0, 0);
}
void cc3000_event::simplelink_wait_data(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) {
// In the blocking implementation the control to caller will be returned only
// after the end of current transaction, i.e. only after data will be received
_simple_link.set_pending_data(1);
hci_event_handler(pBuf, from, fromlen);
}
} // end of cc3000
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef CC3000_EVENT_H
#define CC3000_EVENT_H
typedef struct _bsd_read_return_t
{
int32_t iSocketDescriptor;
int32_t iNumberOfBytes;
uint32_t uiFlags;
} tBsdReadReturnParams;
typedef struct _bsd_getsockopt_return_t
{
uint8_t ucOptValue[4];
uint8_t iStatus;
} tBsdGetSockOptReturnParams;
typedef struct _bsd_accept_return_t
{
int32_t iSocketDescriptor;
int32_t iStatus;
sockaddr tSocketAddress;
} tBsdReturnParams;
typedef struct _bsd_select_return_t
{
int32_t iStatus;
uint32_t uiRdfd;
uint32_t uiWrfd;
uint32_t uiExfd;
} tBsdSelectRecvParams;
typedef struct _bsd_gethostbyname_return_t
{
int32_t retVal;
int32_t outputAddress;
} tBsdGethostbynameParams;
#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0)
#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1)
#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2)
#define FLOW_CONTROL_EVENT_SIZE (4)
#define BSD_RSP_PARAMS_SOCKET_OFFSET (0)
#define BSD_RSP_PARAMS_STATUS_OFFSET (4)
#define GET_HOST_BY_NAME_RETVAL_OFFSET (0)
#define GET_HOST_BY_NAME_ADDR_OFFSET (4)
#define ACCEPT_SD_OFFSET (0)
#define ACCEPT_RETURN_STATUS_OFFSET (4)
#define ACCEPT_ADDRESS__OFFSET (8)
#define SL_RECEIVE_SD_OFFSET (0)
#define SL_RECEIVE_NUM_BYTES_OFFSET (4)
#define SL_RECEIVE__FLAGS__OFFSET (8)
#define SELECT_STATUS_OFFSET (0)
#define SELECT_READFD_OFFSET (4)
#define SELECT_WRITEFD_OFFSET (8)
#define SELECT_EXFD_OFFSET (12)
#define NETAPP_IPCONFIG_IP_OFFSET (0)
#define NETAPP_IPCONFIG_SUBNET_OFFSET (4)
#define NETAPP_IPCONFIG_GW_OFFSET (8)
#define NETAPP_IPCONFIG_DHCP_OFFSET (12)
#define NETAPP_IPCONFIG_DNS_OFFSET (16)
#define NETAPP_IPCONFIG_MAC_OFFSET (20)
#define NETAPP_IPCONFIG_SSID_OFFSET (26)
#define NETAPP_IPCONFIG_IP_LENGTH (4)
#define NETAPP_IPCONFIG_MAC_LENGTH (6)
#define NETAPP_IPCONFIG_SSID_LENGTH (32)
#define NETAPP_PING_PACKETS_SENT_OFFSET (0)
#define NETAPP_PING_PACKETS_RCVD_OFFSET (4)
#define NETAPP_PING_MIN_RTT_OFFSET (8)
#define NETAPP_PING_MAX_RTT_OFFSET (12)
#define NETAPP_PING_AVG_RTT_OFFSET (16)
#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0)
#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4)
#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8)
#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10)
#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38)
#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((uint8_t *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE)
#define SOCKET_STATUS_ACTIVE 0
#define SOCKET_STATUS_INACTIVE 1
/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE.
Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */
#define SOCKET_STATUS_INIT_VAL 0xFFFF
#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7))
#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE))
#define BSD_RECV_FROM_FROMLEN_OFFSET (4)
#define BSD_RECV_FROM_FROM_OFFSET (16)
#endif
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
namespace mbed_cc3000 {
cc3000_hci::cc3000_hci(cc3000_spi &spi) : _spi(spi) {
}
cc3000_hci::~cc3000_hci() {
}
uint16_t cc3000_hci::command_send(uint16_t op_code, uint8_t *buffer, uint8_t length) {
uint8_t *stream;
DBG_HCI_CMD("Command Sent : 0x%04X", op_code);
stream = (buffer + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_CMND);
stream = UINT16_TO_STREAM(stream, op_code);
UINT8_TO_STREAM(stream, length);
//Update the opcode of the event we will be waiting for
_spi.write(buffer, length + SIMPLE_LINK_HCI_CMND_HEADER_SIZE);
return(0);
}
uint32_t cc3000_hci::data_send(uint8_t op_code, uint8_t *args, uint16_t arg_length,
uint16_t data_length, const uint8_t *tail, uint16_t tail_length) {
uint8_t *stream;
stream = ((args) + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
UINT8_TO_STREAM(stream, op_code);
UINT8_TO_STREAM(stream, arg_length);
stream = UINT16_TO_STREAM(stream, arg_length + data_length + tail_length);
// Send the packet
_spi.write(args, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + arg_length + data_length + tail_length);
return 0;
}
void cc3000_hci::data_command_send(uint16_t op_code, uint8_t *buffer, uint8_t arg_length, uint16_t data_length) {
uint8_t *stream = (buffer + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
UINT8_TO_STREAM(stream, op_code);
UINT8_TO_STREAM(stream, arg_length);
stream = UINT16_TO_STREAM(stream, arg_length + data_length);
// Send the command
_spi.write(buffer, arg_length + data_length + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE);
return;
}
void cc3000_hci::patch_send(uint8_t op_code, uint8_t *buffer, uint8_t *patch, uint16_t data_length) {
uint16_t usTransLength;
uint8_t *stream = (buffer + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_PATCH);
UINT8_TO_STREAM(stream, op_code);
stream = UINT16_TO_STREAM(stream, data_length + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
if (data_length <= SL_PATCH_PORTION_SIZE) {
UINT16_TO_STREAM(stream, data_length);
stream = UINT16_TO_STREAM(stream, data_length);
memcpy((buffer + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, data_length);
// Update the opcode of the event we will be waiting for
_spi.write(buffer, data_length + HCI_PATCH_HEADER_SIZE);
} else {
usTransLength = (data_length/SL_PATCH_PORTION_SIZE);
UINT16_TO_STREAM(stream, data_length + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE);
memcpy(buffer + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE);
data_length -= SL_PATCH_PORTION_SIZE;
patch += SL_PATCH_PORTION_SIZE;
// Update the opcode of the event we will be waiting for
_spi.write(buffer, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE);
stream = (buffer + SPI_HEADER_SIZE);
while (data_length) {
if (data_length <= SL_PATCH_PORTION_SIZE) {
usTransLength = data_length;
data_length = 0;
} else {
usTransLength = SL_PATCH_PORTION_SIZE;
data_length -= usTransLength;
}
*(uint16_t *)stream = usTransLength;
memcpy(stream + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength);
patch += usTransLength;
// Update the opcode of the event we will be waiting for
_spi.write((unsigned char *)stream, usTransLength + sizeof(usTransLength));
}
}
}
} // mbed_cc3000 namespace
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
#include "cc3000_netapp.h"
namespace mbed_cc3000 {
cc3000_netapp::cc3000_netapp(cc3000_simple_link &simple_link, cc3000_nvmem &nvmem, cc3000_hci &hci , cc3000_event &event) :
_simple_link(simple_link), _nvmem(nvmem), _hci(hci), _event(event) {
}
cc3000_netapp::~cc3000_netapp() {
}
int32_t cc3000_netapp::config_mac_adrress(uint8_t * mac) {
return _nvmem.set_mac_address(mac);
}
int32_t cc3000_netapp::dhcp(uint32_t *ip, uint32_t *subnet_mask,uint32_t *default_gateway, uint32_t *dns_server) {
int8_t scRet;
uint8_t *ptr;
uint8_t *args;
scRet = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
ARRAY_TO_STREAM(args,ip,4);
ARRAY_TO_STREAM(args,subnet_mask,4);
ARRAY_TO_STREAM(args,default_gateway,4);
args = UINT32_TO_STREAM(args, 0);
ARRAY_TO_STREAM(args,dns_server,4);
// Initiate a HCI command
_hci.command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN);
// Wait for command complete event
_event.simplelink_wait_event(HCI_NETAPP_DHCP, &scRet);
return scRet;
}
#ifndef CC3000_TINY_DRIVER
void cc3000_netapp::ipconfig( tNetappIpconfigRetArgs * ipconfig ) {
uint8_t *ptr;
ptr = _simple_link.get_transmit_buffer();
// Initiate a HCI command
_hci.command_send(HCI_NETAPP_IPCONFIG, ptr, 0);
// Wait for command complete event
_event.simplelink_wait_event(HCI_NETAPP_IPCONFIG, ipconfig );
}
int32_t cc3000_netapp::timeout_values(uint32_t *dhcp, uint32_t *arp,uint32_t *keep_alive, uint32_t *inactivity) {
int8_t scRet;
uint8_t *ptr;
uint8_t *args;
scRet = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Set minimal values of timers
MIN_TIMER_SET(*dhcp)
MIN_TIMER_SET(*arp)
MIN_TIMER_SET(*keep_alive)
MIN_TIMER_SET(*inactivity)
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, *dhcp);
args = UINT32_TO_STREAM(args, *arp);
args = UINT32_TO_STREAM(args, *keep_alive);
args = UINT32_TO_STREAM(args, *inactivity);
// Initiate a HCI command
_hci.command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN);
// Wait for command complete event
_event.simplelink_wait_event(HCI_NETAPP_SET_TIMERS, &scRet);
return scRet;
}
int32_t cc3000_netapp::ping_send(uint32_t *ip, uint32_t ping_attempts, uint32_t ping_size, uint32_t ping_timeout) {
int8_t scRet;
uint8_t *ptr, *args;
scRet = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, *ip);
args = UINT32_TO_STREAM(args, ping_attempts);
args = UINT32_TO_STREAM(args, ping_size);
args = UINT32_TO_STREAM(args, ping_timeout);
// Initiate a HCI command
_hci.command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN);
// Wait for command complete event
_event.simplelink_wait_event(HCI_NETAPP_PING_SEND, &scRet);
return scRet;
}
void cc3000_netapp::ping_report() {
uint8_t *ptr;
int8_t scRet;
ptr = _simple_link.get_transmit_buffer();
scRet = EFAIL;
// Initiate a HCI command
_hci.command_send(HCI_NETAPP_PING_REPORT, ptr, 0);
// Wait for command complete event
_event.simplelink_wait_event(HCI_NETAPP_PING_REPORT, &scRet);
}
int32_t cc3000_netapp::ping_stop() {
int8_t scRet;
uint8_t *ptr;
scRet = EFAIL;
ptr = _simple_link.get_transmit_buffer();
// Initiate a HCI command
_hci.command_send(HCI_NETAPP_PING_STOP, ptr, 0);
// Wait for command complete event
_event.simplelink_wait_event(HCI_NETAPP_PING_STOP, &scRet);
return scRet;
}
int32_t cc3000_netapp::arp_flush() {
int8_t scRet;
uint8_t *ptr;
scRet = EFAIL;
ptr = _simple_link.get_transmit_buffer();
// Initiate a HCI command
_hci.command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0);
// Wait for command complete event
_event.simplelink_wait_event(HCI_NETAPP_ARP_FLUSH, &scRet);
return scRet;
}
#endif
} // mbed_cc3000
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef CC3000_NETAPP_H
#define CC3000_NETAPP_H
#define MIN_TIMER_VAL_SECONDS 20
#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \
{ \
t = MIN_TIMER_VAL_SECONDS; \
}
#define NETAPP_DHCP_PARAMS_LEN (20)
#define NETAPP_SET_TIMER_PARAMS_LEN (20)
#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4)
#define NETAPP_PING_SEND_PARAMS_LEN (16)
typedef struct _netapp_dhcp_ret_args_t
{
uint8_t aucIP[4];
uint8_t aucSubnetMask[4];
uint8_t aucDefaultGateway[4];
uint8_t aucDHCPServer[4];
uint8_t aucDNSServer[4];
}tNetappDhcpParams;
typedef struct _netapp_ipconfig_ret_args_t
{
uint8_t aucIP[4];
uint8_t aucSubnetMask[4];
uint8_t aucDefaultGateway[4];
uint8_t aucDHCPServer[4];
uint8_t aucDNSServer[4];
uint8_t uaMacAddr[6];
uint8_t uaSSID[32];
}tNetappIpconfigRetArgs;
/*Ping send report parameters*/
typedef struct _netapp_pingreport_args
{
uint32_t packets_sent;
uint32_t packets_received;
uint32_t min_round_time;
uint32_t max_round_time;
uint32_t avg_round_time;
} netapp_pingreport_args_t;
#endif
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
#include "cc3000_nvmem.h"
#include "cc3000_common.h"
namespace mbed_cc3000 {
cc3000_nvmem::cc3000_nvmem(cc3000_hci &hci, cc3000_event &event, cc3000_simple_link &simple_link)
: _hci(hci), _event(event), _simple_link(simple_link) {
}
cc3000_nvmem::~cc3000_nvmem() {
}
int32_t cc3000_nvmem::read(uint32_t file_id, uint32_t length, uint32_t offset, uint8_t *buff) {
uint8_t ucStatus = 0xFF;
uint8_t *ptr;
uint8_t *args;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, file_id);
args = UINT32_TO_STREAM(args, length);
args = UINT32_TO_STREAM(args, offset);
// Initiate HCI command
_hci.command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN);
_event.simplelink_wait_event(HCI_CMND_NVMEM_READ, &ucStatus);
// If data is present, read it even when an error is returned.
// Note: It is the users responsibility to ignore the data when an error is returned.
// Wait for the data in a synchronous way.
// We assume the buffer is large enough to also store nvmem parameters.
_event.simplelink_wait_data(buff, 0, 0);
return(ucStatus);
}
int32_t cc3000_nvmem::write(uint32_t file_id, uint32_t length, uint32_t entry_offset, uint8_t *buff) {
int32_t iRes;
uint8_t *ptr;
uint8_t *args;
iRes = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, file_id);
args = UINT32_TO_STREAM(args, 12);
args = UINT32_TO_STREAM(args, length);
args = UINT32_TO_STREAM(args, entry_offset);
memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE +
NVMEM_WRITE_PARAMS_LEN),buff,length);
// Initiate a HCI command on the data channel
_hci.data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, length);
_event.simplelink_wait_event(HCI_EVNT_NVMEM_WRITE, &iRes);
return(iRes);
}
uint8_t cc3000_nvmem::set_mac_address(uint8_t *mac) {
return write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
}
uint8_t cc3000_nvmem::get_mac_address(uint8_t *mac) {
return read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
}
uint8_t cc3000_nvmem::write_patch(uint32_t file_id, uint32_t length, const uint8_t *data) {
uint8_t status = 0;
uint16_t offset = 0;
uint8_t* spDataPtr = (uint8_t*)data;
while ((status == 0) && (length >= SP_PORTION_SIZE)) {
status = write(file_id, SP_PORTION_SIZE, offset, spDataPtr);
offset += SP_PORTION_SIZE;
length -= SP_PORTION_SIZE;
spDataPtr += SP_PORTION_SIZE;
}
if (status !=0) {
// NVMEM error occurred
return status;
}
if (length != 0) {
// If length MOD 512 is nonzero, write the remaining bytes.
status = write(file_id, length, offset, spDataPtr);
}
return status;
}
int32_t cc3000_nvmem::create_entry(uint32_t file_id, uint32_t new_len) {
uint8_t *ptr;
uint8_t *args;
uint16_t retval;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, file_id);
args = UINT32_TO_STREAM(args, new_len);
// Initiate a HCI command
_hci.command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN);
_event.simplelink_wait_event(HCI_CMND_NVMEM_CREATE_ENTRY, &retval);
return(retval);
}
#ifndef CC3000_TINY_DRIVER
uint8_t cc3000_nvmem::read_sp_version(uint8_t* patch_ver) {
uint8_t *ptr;
// 1st byte is the status and the rest is the SP version
uint8_t retBuf[5];
ptr = _simple_link.get_transmit_buffer();
// Initiate a HCI command, no args are required
_hci.command_send(HCI_CMND_READ_SP_VERSION, ptr, 0);
_event.simplelink_wait_event(HCI_CMND_READ_SP_VERSION, retBuf);
// package ID
*patch_ver = retBuf[3];
// package build number
*(patch_ver+1) = retBuf[4];
return(retBuf[0]);
}
#endif
} // mbed_cc3000 namespace
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef CC3000_NVMEM_H
#define CC3000_NVMEM_H
#define NVMEM_READ_PARAMS_LEN (12)
#define NVMEM_CREATE_PARAMS_LEN (8)
#define NVMEM_WRITE_PARAMS_LEN (16)
/****************************************************************************
**
** Definitions for File IDs
**
****************************************************************************/
/* --------------------------------------------------------- EEPROM FAT table ---------------------------------------------------------
File ID Offset File Size Used Size Parameter
# ID address (bytes) (bytes)
--------------------------------------------------------------------------------------------------------------------------------------
0 NVMEM_NVS_FILEID 0x50 0x1A0 0x1A RF Calibration results table(generated automatically by TX Bip)
1 NVMEM_NVS_SHADOW_FILEID 0x1F0 0x1A0 0x1A NVS Shadow
2 NVMEM_WLAN_CONFIG_FILEID 0x390 0x1000 0x64 WLAN configuration
3 NVMEM_WLAN_CONFIG_SHADOW_FILEID 0x1390 0x1000 0x64 WLAN configuration shadow
4 NVMEM_WLAN_DRIVER_SP_FILEID 0x2390 0x2000 variable WLAN Driver ROM Patches
5 NVMEM_WLAN_FW_SP_FILEID 0x4390 0x2000 variable WLAN FW Patches
6 NVMEM_MAC_FILEID 0x6390 0x10 0x10 6 bytes of MAC address
7 NVMEM_FRONTEND_VARS_FILEID 0x63A0 0x10 0x10 Frontend Vars
8 NVMEM_IP_CONFIG_FILEID 0x63B0 0x40 0x40 IP configuration
9 NVMEM_IP_CONFIG_SHADOW_FILEID 0x63F0 0x40 0x40 IP configuration shadow
10 NVMEM_BOOTLOADER_SP_FILEID 0x6430 0x400 variable Bootloader Patches
11 NVMEM_RM_FILEID 0x6830 0x200 0x7F Radio parameters
12 NVMEM_AES128_KEY_FILEID 0x6A30 0x10 0x10 AES128 key file
13 NVMEM_SHARED_MEM_FILEID 0x6A40 0x50 0x44 Host-CC3000 shared memory file
14 NVMEM_USER_FILE_1_FILEID 0x6A90 variable variable 1st user file
15 NVMEM_USER_FILE_2_FILEID variable variable variable 2nd user file
*/
/* NVMEM file ID - system files*/
#define NVMEM_NVS_FILEID (0)
#define NVMEM_NVS_SHADOW_FILEID (1)
#define NVMEM_WLAN_CONFIG_FILEID (2)
#define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3)
#define NVMEM_WLAN_DRIVER_SP_FILEID (4)
#define NVMEM_WLAN_FW_SP_FILEID (5)
#define NVMEM_MAC_FILEID (6)
#define NVMEM_FRONTEND_VARS_FILEID (7)
#define NVMEM_IP_CONFIG_FILEID (8)
#define NVMEM_IP_CONFIG_SHADOW_FILEID (9)
#define NVMEM_BOOTLOADER_SP_FILEID (10)
#define NVMEM_RM_FILEID (11)
/* NVMEM file ID - user files*/
#define NVMEM_AES128_KEY_FILEID (12)
#define NVMEM_SHARED_MEM_FILEID (13)
#define NVMEM_USER_FILE_1_FILEID (14)
#define NVMEM_USER_FILE_2_FILEID (15)
/* max entry in order to invalid nvmem */
#define NVMEM_MAX_ENTRY (16)
#endif
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
namespace mbed_cc3000 {
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
// forward sbox
static const uint8_t sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
// inverse sbox
static const uint8_t rsbox[256] =
{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
// round constant
static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
void cc3000_security::expandKey(uint8_t *expanded_key, uint8_t *key) {
uint16_t ii, buf1;
for (ii=0;ii<16;ii++)
expanded_key[ii] = key[ii];
for (ii=1;ii<11;ii++)
{
buf1 = expanded_key[ii*16 - 4];
expanded_key[ii*16 + 0] = sbox[expanded_key[ii*16 - 3]]^expanded_key[(ii-1)*16 + 0]^Rcon[ii];
expanded_key[ii*16 + 1] = sbox[expanded_key[ii*16 - 2]]^expanded_key[(ii-1)*16 + 1];
expanded_key[ii*16 + 2] = sbox[expanded_key[ii*16 - 1]]^expanded_key[(ii-1)*16 + 2];
expanded_key[ii*16 + 3] = sbox[buf1 ]^expanded_key[(ii-1)*16 + 3];
expanded_key[ii*16 + 4] = expanded_key[(ii-1)*16 + 4]^expanded_key[ii*16 + 0];
expanded_key[ii*16 + 5] = expanded_key[(ii-1)*16 + 5]^expanded_key[ii*16 + 1];
expanded_key[ii*16 + 6] = expanded_key[(ii-1)*16 + 6]^expanded_key[ii*16 + 2];
expanded_key[ii*16 + 7] = expanded_key[(ii-1)*16 + 7]^expanded_key[ii*16 + 3];
expanded_key[ii*16 + 8] = expanded_key[(ii-1)*16 + 8]^expanded_key[ii*16 + 4];
expanded_key[ii*16 + 9] = expanded_key[(ii-1)*16 + 9]^expanded_key[ii*16 + 5];
expanded_key[ii*16 +10] = expanded_key[(ii-1)*16 +10]^expanded_key[ii*16 + 6];
expanded_key[ii*16 +11] = expanded_key[(ii-1)*16 +11]^expanded_key[ii*16 + 7];
expanded_key[ii*16 +12] = expanded_key[(ii-1)*16 +12]^expanded_key[ii*16 + 8];
expanded_key[ii*16 +13] = expanded_key[(ii-1)*16 +13]^expanded_key[ii*16 + 9];
expanded_key[ii*16 +14] = expanded_key[(ii-1)*16 +14]^expanded_key[ii*16 +10];
expanded_key[ii*16 +15] = expanded_key[(ii-1)*16 +15]^expanded_key[ii*16 +11];
}
}
uint8_t cc3000_security::galois_mul2(uint8_t value) {
if (value >> 7) {
value = value << 1;
return (value ^ 0x1b);
} else {
return (value << 1);
}
}
void cc3000_security::aes_encr(uint8_t *state, uint8_t *expanded_key) {
uint8_t buf1, buf2, buf3, round;
for (round = 0; round < 9; round ++)
{
// addroundkey, sbox and shiftrows
// row 0
state[ 0] = sbox[(state[ 0] ^ expanded_key[(round*16) ])];
state[ 4] = sbox[(state[ 4] ^ expanded_key[(round*16) + 4])];
state[ 8] = sbox[(state[ 8] ^ expanded_key[(round*16) + 8])];
state[12] = sbox[(state[12] ^ expanded_key[(round*16) + 12])];
// row 1
buf1 = state[1] ^ expanded_key[(round*16) + 1];
state[ 1] = sbox[(state[ 5] ^ expanded_key[(round*16) + 5])];
state[ 5] = sbox[(state[ 9] ^ expanded_key[(round*16) + 9])];
state[ 9] = sbox[(state[13] ^ expanded_key[(round*16) + 13])];
state[13] = sbox[buf1];
// row 2
buf1 = state[2] ^ expanded_key[(round*16) + 2];
buf2 = state[6] ^ expanded_key[(round*16) + 6];
state[ 2] = sbox[(state[10] ^ expanded_key[(round*16) + 10])];
state[ 6] = sbox[(state[14] ^ expanded_key[(round*16) + 14])];
state[10] = sbox[buf1];
state[14] = sbox[buf2];
// row 3
buf1 = state[15] ^ expanded_key[(round*16) + 15];
state[15] = sbox[(state[11] ^ expanded_key[(round*16) + 11])];
state[11] = sbox[(state[ 7] ^ expanded_key[(round*16) + 7])];
state[ 7] = sbox[(state[ 3] ^ expanded_key[(round*16) + 3])];
state[ 3] = sbox[buf1];
// mixcolums //////////
// col1
buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
buf2 = state[0];
buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
// col2
buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
buf2 = state[4];
buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
// col3
buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
buf2 = state[8];
buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
// col4
buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
buf2 = state[12];
buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
}
// 10th round without mixcols
state[ 0] = sbox[(state[ 0] ^ expanded_key[(round*16) ])];
state[ 4] = sbox[(state[ 4] ^ expanded_key[(round*16) + 4])];
state[ 8] = sbox[(state[ 8] ^ expanded_key[(round*16) + 8])];
state[12] = sbox[(state[12] ^ expanded_key[(round*16) + 12])];
// row 1
buf1 = state[1] ^ expanded_key[(round*16) + 1];
state[ 1] = sbox[(state[ 5] ^ expanded_key[(round*16) + 5])];
state[ 5] = sbox[(state[ 9] ^ expanded_key[(round*16) + 9])];
state[ 9] = sbox[(state[13] ^ expanded_key[(round*16) + 13])];
state[13] = sbox[buf1];
// row 2
buf1 = state[2] ^ expanded_key[(round*16) + 2];
buf2 = state[6] ^ expanded_key[(round*16) + 6];
state[ 2] = sbox[(state[10] ^ expanded_key[(round*16) + 10])];
state[ 6] = sbox[(state[14] ^ expanded_key[(round*16) + 14])];
state[10] = sbox[buf1];
state[14] = sbox[buf2];
// row 3
buf1 = state[15] ^ expanded_key[(round*16) + 15];
state[15] = sbox[(state[11] ^ expanded_key[(round*16) + 11])];
state[11] = sbox[(state[ 7] ^ expanded_key[(round*16) + 7])];
state[ 7] = sbox[(state[ 3] ^ expanded_key[(round*16) + 3])];
state[ 3] = sbox[buf1];
// last addroundkey
state[ 0]^=expanded_key[160];
state[ 1]^=expanded_key[161];
state[ 2]^=expanded_key[162];
state[ 3]^=expanded_key[163];
state[ 4]^=expanded_key[164];
state[ 5]^=expanded_key[165];
state[ 6]^=expanded_key[166];
state[ 7]^=expanded_key[167];
state[ 8]^=expanded_key[168];
state[ 9]^=expanded_key[169];
state[10]^=expanded_key[170];
state[11]^=expanded_key[171];
state[12]^=expanded_key[172];
state[13]^=expanded_key[173];
state[14]^=expanded_key[174];
state[15]^=expanded_key[175];
}
void cc3000_security::aes_decr(uint8_t *state, uint8_t *expanded_key) {
uint8_t buf1, buf2, buf3;
int8_t round;
round = 9;
// initial addroundkey
state[ 0]^=expanded_key[160];
state[ 1]^=expanded_key[161];
state[ 2]^=expanded_key[162];
state[ 3]^=expanded_key[163];
state[ 4]^=expanded_key[164];
state[ 5]^=expanded_key[165];
state[ 6]^=expanded_key[166];
state[ 7]^=expanded_key[167];
state[ 8]^=expanded_key[168];
state[ 9]^=expanded_key[169];
state[10]^=expanded_key[170];
state[11]^=expanded_key[171];
state[12]^=expanded_key[172];
state[13]^=expanded_key[173];
state[14]^=expanded_key[174];
state[15]^=expanded_key[175];
// 10th round without mixcols
state[ 0] = rsbox[state[ 0]] ^ expanded_key[(round*16) ];
state[ 4] = rsbox[state[ 4]] ^ expanded_key[(round*16) + 4];
state[ 8] = rsbox[state[ 8]] ^ expanded_key[(round*16) + 8];
state[12] = rsbox[state[12]] ^ expanded_key[(round*16) + 12];
// row 1
buf1 = rsbox[state[13]] ^ expanded_key[(round*16) + 1];
state[13] = rsbox[state[ 9]] ^ expanded_key[(round*16) + 13];
state[ 9] = rsbox[state[ 5]] ^ expanded_key[(round*16) + 9];
state[ 5] = rsbox[state[ 1]] ^ expanded_key[(round*16) + 5];
state[ 1] = buf1;
// row 2
buf1 = rsbox[state[ 2]] ^ expanded_key[(round*16) + 10];
buf2 = rsbox[state[ 6]] ^ expanded_key[(round*16) + 14];
state[ 2] = rsbox[state[10]] ^ expanded_key[(round*16) + 2];
state[ 6] = rsbox[state[14]] ^ expanded_key[(round*16) + 6];
state[10] = buf1;
state[14] = buf2;
// row 3
buf1 = rsbox[state[ 3]] ^ expanded_key[(round*16) + 15];
state[ 3] = rsbox[state[ 7]] ^ expanded_key[(round*16) + 3];
state[ 7] = rsbox[state[11]] ^ expanded_key[(round*16) + 7];
state[11] = rsbox[state[15]] ^ expanded_key[(round*16) + 11];
state[15] = buf1;
for (round = 8; round >= 0; round--)
{
// barreto
//col1
buf1 = galois_mul2(galois_mul2(state[0]^state[2]));
buf2 = galois_mul2(galois_mul2(state[1]^state[3]));
state[0] ^= buf1; state[1] ^= buf2; state[2] ^= buf1; state[3] ^= buf2;
//col2
buf1 = galois_mul2(galois_mul2(state[4]^state[6]));
buf2 = galois_mul2(galois_mul2(state[5]^state[7]));
state[4] ^= buf1; state[5] ^= buf2; state[6] ^= buf1; state[7] ^= buf2;
//col3
buf1 = galois_mul2(galois_mul2(state[8]^state[10]));
buf2 = galois_mul2(galois_mul2(state[9]^state[11]));
state[8] ^= buf1; state[9] ^= buf2; state[10] ^= buf1; state[11] ^= buf2;
//col4
buf1 = galois_mul2(galois_mul2(state[12]^state[14]));
buf2 = galois_mul2(galois_mul2(state[13]^state[15]));
state[12] ^= buf1; state[13] ^= buf2; state[14] ^= buf1; state[15] ^= buf2;
// mixcolums //////////
// col1
buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
buf2 = state[0];
buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
// col2
buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
buf2 = state[4];
buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
// col3
buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
buf2 = state[8];
buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
// col4
buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
buf2 = state[12];
buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
// addroundkey, rsbox and shiftrows
// row 0
state[ 0] = rsbox[state[ 0]] ^ expanded_key[(round*16) ];
state[ 4] = rsbox[state[ 4]] ^ expanded_key[(round*16) + 4];
state[ 8] = rsbox[state[ 8]] ^ expanded_key[(round*16) + 8];
state[12] = rsbox[state[12]] ^ expanded_key[(round*16) + 12];
// row 1
buf1 = rsbox[state[13]] ^ expanded_key[(round*16) + 1];
state[13] = rsbox[state[ 9]] ^ expanded_key[(round*16) + 13];
state[ 9] = rsbox[state[ 5]] ^ expanded_key[(round*16) + 9];
state[ 5] = rsbox[state[ 1]] ^ expanded_key[(round*16) + 5];
state[ 1] = buf1;
// row 2
buf1 = rsbox[state[ 2]] ^ expanded_key[(round*16) + 10];
buf2 = rsbox[state[ 6]] ^ expanded_key[(round*16) + 14];
state[ 2] = rsbox[state[10]] ^ expanded_key[(round*16) + 2];
state[ 6] = rsbox[state[14]] ^ expanded_key[(round*16) + 6];
state[10] = buf1;
state[14] = buf2;
// row 3
buf1 = rsbox[state[ 3]] ^ expanded_key[(round*16) + 15];
state[ 3] = rsbox[state[ 7]] ^ expanded_key[(round*16) + 3];
state[ 7] = rsbox[state[11]] ^ expanded_key[(round*16) + 7];
state[11] = rsbox[state[15]] ^ expanded_key[(round*16) + 11];
state[15] = buf1;
}
}
void cc3000_security::aes_encrypt(uint8_t *state, uint8_t *key) {
// expand the key into 176 bytes
expandKey(_expanded_key, key);
aes_encr(state, _expanded_key);
}
void cc3000_security::aes_decrypt(uint8_t *state, uint8_t *key) {
expandKey(_expanded_key, key); // expand the key into 176 bytes
aes_decr(state, _expanded_key);
}
int32_t cc3000_security::aes_read_key(uint8_t *key) {
int32_t returnValue;
returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
return returnValue;
}
int32_t cc3000_security::aes_write_key(uint8_t *key) {
int32_t returnValue;
returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
return returnValue;
}
#endif
} // mbed_cc3000 namespace
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
#include "cc3000_common.h"
namespace mbed_cc3000 {
cc3000_simple_link::cc3000_simple_link() {
_rx_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
}
cc3000_simple_link::~cc3000_simple_link() {
}
uint8_t cc3000_simple_link::get_data_received_flag() {
return _data_received_flag;
}
void *cc3000_simple_link::get_func_pointer(FunctionNumber function){
void *result;
/* casting to void *, will be casted back once used */
switch(function) {
case FW_PATCHES:
result = (void *)_fFWPatches;
break;
case DRIVER_PATCHES:
result = (void *)_fDriverPatches;
break;
case BOOTLOADER_PATCHES:
result = (void *)_fBootLoaderPatches;
break;
default:
result = 0;
}
return result;
}
uint8_t* cc3000_simple_link::get_transmit_buffer() {
return _tx_buffer;
}
uint8_t* cc3000_simple_link::get_received_buffer() {
return _rx_buffer;
}
void cc3000_simple_link::set_op_code(uint16_t code) {
_rx_event_opcode = code;
}
void cc3000_simple_link::set_pending_data(uint16_t value) {
_rx_data_pending = value;
}
uint16_t cc3000_simple_link::get_pending_data() {
return _rx_data_pending;
}
void cc3000_simple_link::set_number_free_buffers(uint16_t value) {
_free_buffers = value;
}
void cc3000_simple_link::set_number_of_released_packets(uint16_t value) {
_released_packets = value;
}
void cc3000_simple_link::set_tx_complete_signal(bool value) {
_tx_complete_signal = value;
}
bool cc3000_simple_link::get_tx_complete_signal() {
return _tx_complete_signal;
}
void cc3000_simple_link::set_data_received_flag(uint8_t value) {
_data_received_flag = value;
}
uint16_t cc3000_simple_link::get_number_free_buffers() {
return _free_buffers;
}
uint16_t cc3000_simple_link::get_buffer_length() {
return _buffer_length;
}
void cc3000_simple_link::set_buffer_length(uint16_t value) {
_buffer_length = value;
}
uint16_t cc3000_simple_link::get_op_code() {
return _rx_event_opcode;
}
uint16_t cc3000_simple_link::get_released_packets() {
return _released_packets;
}
uint16_t cc3000_simple_link::get_sent_packets() {
return _sent_packets;
}
void cc3000_simple_link::set_sent_packets(uint16_t value) {
_sent_packets = value;
}
void cc3000_simple_link::set_transmit_error(int32_t value){
_transmit_data_error = value;
}
int32_t cc3000_simple_link::get_transmit_error(){
return _transmit_data_error;
}
void cc3000_simple_link::set_buffer_size(uint16_t value) {
_buffer_size = value;
}
uint16_t cc3000_simple_link::get_buffer_size(void) {
return _buffer_size;
}
uint8_t *cc3000_simple_link::get_received_data(void) {
return _received_data;
}
void cc3000_simple_link::set_received_data(uint8_t *pointer) {
_received_data = pointer;
}
} // mbed_cc3000 namespace
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef CC3000_SIMPLELINK_H
#define CC3000_SIMPLELINK_H
typedef uint8_t *(*tFWPatches)(uint32_t *usLength);
typedef uint8_t *(*tDriverPatches)(uint32_t *usLength);
typedef uint8_t *(*tBootLoaderPatches)(uint32_t *usLength);
#endif
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
#include "cc3000_socket.h"
#include "cc3000_event.h" //TODO - remove this
#include "cc3000_common.h"
namespace mbed_cc3000 {
cc3000_socket::cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event)
: _simple_link(simplelink), _hci(hci), _event(event) {
}
cc3000_socket::~cc3000_socket() {
}
int32_t cc3000_socket::HostFlowControlConsumeBuff(int32_t sd) {
#ifndef SEND_NON_BLOCKING
/* wait in busy loop */
do {
// When the last transmission failed, return the last failure reason.
// Note that the buffer will not be allocated in this case
if (_simple_link.get_transmit_error() != 0) {
errno = _simple_link.get_transmit_error();
_simple_link.set_transmit_error(0);
return errno;
}
if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd))
return -1;
} while (0 == _simple_link.get_number_free_buffers());
uint16_t free_buffer = _simple_link.get_number_free_buffers();
free_buffer--;
_simple_link.set_number_free_buffers(free_buffer);
return 0;
#else
// When the last transmission failed, return the last failure reason.
// Note that the buffer will not be allocated in this case
if (_simple_link.get_transmit_error() != 0) {
errno = _simple_link.get_transmit_error();
_simple_link.set_transmit_error(0);
return errno;
}
if (SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd))
return -1;
// If there are no available buffers, return -2. It is recommended to use
// select or receive to see if there is any buffer occupied with received data
// If so, call receive() to release the buffer.
if (0 == _simple_link.get_number_free_buffers()) {
return -2;
} else {
uint16_t free_buffer = _simple_link.get_number_free_buffers();
free_buffer--;
_simple_link.set_number_free_buffers(free_buffer);
return 0;
}
#endif
}
int32_t cc3000_socket::socket(int32_t domain, int32_t type, int32_t protocol) {
int32_t ret;
uint8_t *ptr, *args;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, domain);
args = UINT32_TO_STREAM(args, type);
args = UINT32_TO_STREAM(args, protocol);
// Initiate a HCI command
_hci.command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_CMND_SOCKET, &ret);
// Process the event
errno = ret;
_event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
return ret;
}
int32_t cc3000_socket::closesocket(int32_t sd) {
int32_t ret;
uint8_t *ptr, *args;
while (_simple_link.get_number_free_buffers() != SOCKET_MAX_FREE_BUFFERS);
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, sd);
// Initiate a HCI command
_hci.command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_CMND_CLOSE_SOCKET, &ret);
errno = ret;
// since 'close' call may result in either OK (and then it closed) or error, mark this socket as invalid
_event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
return ret;
}
int32_t cc3000_socket::accept(int32_t sd, sockaddr *addr, socklen_t *addrlen) {
int32_t ret;
uint8_t *ptr, *args;
tBsdReturnParams tAcceptReturnArguments;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, sd);
// Initiate a HCI command
_hci.command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
// need specify return parameters!!!
memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
*addrlen = ASIC_ADDR_LEN;
errno = tAcceptReturnArguments.iStatus;
ret = errno;
// if succeeded, iStatus = new socket descriptor. otherwise - error number
if(M_IS_VALID_SD(ret)) {
_event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
} else {
_event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
}
return ret;
}
int32_t cc3000_socket::bind(int32_t sd, const sockaddr *addr, int32_t addrlen) {
int32_t ret;
uint8_t *ptr, *args;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
addrlen = ASIC_ADDR_LEN;
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, sd);
args = UINT32_TO_STREAM(args, 0x00000008);
args = UINT32_TO_STREAM(args, addrlen);
ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
// Initiate a HCI command
_hci.command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_CMND_BIND, &ret);
errno = ret;
return ret;
}
int32_t cc3000_socket::listen(int32_t sd, int32_t backlog) {
int32_t ret;
uint8_t *ptr, *args;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, sd);
args = UINT32_TO_STREAM(args, backlog);
// Initiate a HCI command
_hci.command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_CMND_LISTEN, &ret);
errno = ret;
return(ret);
}
int32_t cc3000_socket::connect(int32_t sd, const sockaddr *addr, int32_t addrlen) {
int32_t ret;
uint8_t *ptr, *args;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
addrlen = 8;
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, sd);
args = UINT32_TO_STREAM(args, 0x00000008);
args = UINT32_TO_STREAM(args, addrlen);
ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
// Initiate a HCI command
_hci.command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_CMND_CONNECT, &ret);
errno = ret;
return((int32_t)ret);
}
int32_t cc3000_socket::select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) {
uint8_t *ptr, *args;
tBsdSelectRecvParams tParams;
uint32_t is_blocking;
if (timeout == NULL) {
is_blocking = 1; /* blocking , infinity timeout */
} else {
is_blocking = 0; /* no blocking, timeout */
}
// Fill in HCI packet structure
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, nfds);
args = UINT32_TO_STREAM(args, 0x00000014);
args = UINT32_TO_STREAM(args, 0x00000014);
args = UINT32_TO_STREAM(args, 0x00000014);
args = UINT32_TO_STREAM(args, 0x00000014);
args = UINT32_TO_STREAM(args, is_blocking);
args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0));
args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0));
args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0));
if (timeout) {
if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) {
timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
}
args = UINT32_TO_STREAM(args, timeout->tv_sec);
args = UINT32_TO_STREAM(args, timeout->tv_usec);
}
// Initiate a HCI command
_hci.command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_EVNT_SELECT, &tParams);
// Update actually read FD
if (tParams.iStatus >= 0) {
if (readsds) {
memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
}
if (writesds) {
memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
}
if (exceptsds) {
memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
}
return(tParams.iStatus);
} else {
errno = tParams.iStatus;
return -1;
}
}
int32_t cc3000_socket::getsockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen) {
uint8_t *ptr, *args;
tBsdGetSockOptReturnParams tRetParams;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, sd);
args = UINT32_TO_STREAM(args, level);
args = UINT32_TO_STREAM(args, optname);
// Initiate a HCI command
_hci.command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_CMND_GETSOCKOPT, &tRetParams);
if (((int8_t)tRetParams.iStatus) >= 0) {
*optlen = 4;
memcpy(optval, tRetParams.ucOptValue, 4);
return (0);
} else {
errno = tRetParams.iStatus;
return errno;
}
}
int32_t cc3000_socket::simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode) {
uint8_t *ptr, *args;
tBsdReadReturnParams tSocketReadEvent;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, sd);
args = UINT32_TO_STREAM(args, len);
args = UINT32_TO_STREAM(args, flags);
// Generate the read command, and wait for the
_hci.command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(opcode, &tSocketReadEvent);
// In case the number of bytes is more then zero - read data
if (tSocketReadEvent.iNumberOfBytes > 0) {
// Wait for the data in a synchronous way. Here we assume that the bug is
// big enough to store also parameters of receive from too....
_event.simplelink_wait_data((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen);
}
errno = tSocketReadEvent.iNumberOfBytes;
return(tSocketReadEvent.iNumberOfBytes);
}
int32_t cc3000_socket::recv(int32_t sd, void *buf, int32_t len, int32_t flags) {
return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
}
int32_t cc3000_socket::recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen) {
return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM));
}
int32_t cc3000_socket::simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode) {
uint8_t uArgSize = 0x00, addrlen = 0x00;
uint8_t *ptr, *pDataPtr = NULL, *args;
uint32_t addr_offset = 0x00;
int32_t res;
tBsdReadReturnParams tSocketSendEvent;
// Check the bsd_arguments
if (0 != (res = HostFlowControlConsumeBuff(sd))) {
return res;
}
//Update the number of sent packets
uint16_t sent_packets = _simple_link.get_sent_packets();
sent_packets++;
_simple_link.set_sent_packets(sent_packets);
// Allocate a buffer and construct a packet and send it over spi
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_DATA);
// Update the offset of data and parameters according to the command
switch(opcode)
{
case HCI_CMND_SENDTO:
{
addr_offset = len + sizeof(len) + sizeof(len);
addrlen = 8;
uArgSize = SOCKET_SENDTO_PARAMS_LEN;
pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
break;
}
case HCI_CMND_SEND:
{
tolen = 0;
to = NULL;
uArgSize = HCI_CMND_SEND_ARG_LENGTH;
pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
break;
}
default:
{
break;
}
}
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, sd);
args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
args = UINT32_TO_STREAM(args, len);
args = UINT32_TO_STREAM(args, flags);
if (opcode == HCI_CMND_SENDTO) {
args = UINT32_TO_STREAM(args, addr_offset);
args = UINT32_TO_STREAM(args, addrlen);
}
// Copy the data received from user into the TX Buffer
ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len);
// In case we are using SendTo, copy the to parameters
if (opcode == HCI_CMND_SENDTO) {
ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen);
}
// Initiate a HCI command
_hci.data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen);
if (opcode == HCI_CMND_SENDTO)
_event.simplelink_wait_event(HCI_EVNT_SENDTO, &tSocketSendEvent);
else
_event.simplelink_wait_event(HCI_EVNT_SEND, &tSocketSendEvent);
return (len);
}
int32_t cc3000_socket::send(int32_t sd, const void *buf, int32_t len, int32_t flags) {
return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
}
int32_t cc3000_socket::sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen) {
return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
}
int32_t cc3000_socket::mdns_advertiser(uint16_t mdns_enabled, uint8_t *device_service_name, uint16_t device_service_name_length) {
int32_t ret;
uint8_t *pTxBuffer, *pArgs;
if (device_service_name_length > MDNS_DEVICE_SERVICE_MAX_LENGTH) {
return EFAIL;
}
pTxBuffer = _simple_link.get_transmit_buffer();
pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
// Fill in HCI packet structure
pArgs = UINT32_TO_STREAM(pArgs, mdns_enabled);
pArgs = UINT32_TO_STREAM(pArgs, 8);
pArgs = UINT32_TO_STREAM(pArgs, device_service_name_length);
ARRAY_TO_STREAM(pArgs, device_service_name, device_service_name_length);
// Initiate a HCI command
_hci.command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + device_service_name_length);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_EVNT_MDNS_ADVERTISE, &ret);
return ret;
}
#ifndef CC3000_TINY_DRIVER
int32_t cc3000_socket::gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr) {
tBsdGethostbynameParams ret;
uint8_t *ptr, *args;
errno = EFAIL;
if (name_length > HOSTNAME_MAX_LENGTH) {
return errno;
}
ptr = _simple_link.get_transmit_buffer();
args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, 8);
args = UINT32_TO_STREAM(args, name_length);
ARRAY_TO_STREAM(args, hostname, name_length);
// Initiate a HCI command
_hci.command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + name_length - 1);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
errno = ret.retVal;
(*((int32_t*)out_ip_addr)) = ret.outputAddress;
return (errno);
}
int32_t cc3000_socket::setsockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen) {
int32_t ret;
uint8_t *ptr, *args;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, sd);
args = UINT32_TO_STREAM(args, level);
args = UINT32_TO_STREAM(args, optname);
args = UINT32_TO_STREAM(args, 0x00000008);
args = UINT32_TO_STREAM(args, optlen);
ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen);
// Initiate a HCI command
_hci.command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen);
// Since we are in blocking state - wait for event complete
_event.simplelink_wait_event(HCI_CMND_SETSOCKOPT, &ret);
if (ret >= 0) {
return (0);
} else {
errno = ret;
return ret;
}
}
#endif
char* cc3000_socket::inet_ntoa_r(uint32_t s_addr, char *buf, int buflen)
{
char inv[3];
char *rp;
uint8_t *ap;
uint8_t rem;
uint8_t n;
uint8_t i;
int len = 0;
rp = buf;
ap = (uint8_t *)&s_addr;
for (n = 0; n < 4; n++) {
i = 0;
do {
rem = *ap % (uint8_t)10;
*ap /= (uint8_t)10;
inv[i++] = '0' + rem;
} while(*ap);
while(i--) {
if (len++ >= buflen) {
return NULL;
}
*rp++ = inv[i];
}
if (len++ >= buflen) {
return NULL;
}
*rp++ = '.';
ap++;
}
*--rp = 0;
return buf;
}
} // mbed_cc3000 namespace
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef CC3000_SOCKET_H
#define CC3000_SOCKET_H
#define SOCKET_MAX_FREE_BUFFERS 6
#define SOCKET_STATUS_ACTIVE 0
#define SOCKET_STATUS_INACTIVE 1
#define SOCKET_STATUS_INIT_VAL 0xFFFF
#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7))
#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE))
#ifdef _API_USE_BSD_CLOSE
#define close(sd) closesocket(sd)
#endif
//Enable this flag if and only if you must comply with BSD socket read() and
//write() functions
#ifdef _API_USE_BSD_READ_WRITE
#define read(sd, buf, len, flags) recv(sd, buf, len, flags)
#define write(sd, buf, len, flags) send(sd, buf, len, flags)
#endif
#define SOCKET_OPEN_PARAMS_LEN (12)
#define SOCKET_CLOSE_PARAMS_LEN (4)
#define SOCKET_ACCEPT_PARAMS_LEN (4)
#define SOCKET_BIND_PARAMS_LEN (20)
#define SOCKET_LISTEN_PARAMS_LEN (8)
#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9)
#define SOCKET_CONNECT_PARAMS_LEN (20)
#define SOCKET_SELECT_PARAMS_LEN (44)
#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20)
#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12)
#define SOCKET_RECV_FROM_PARAMS_LEN (12)
#define SOCKET_SENDTO_PARAMS_LEN (24)
#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12)
//#define NULL 0
// The legnth of arguments for the SEND command: sd + buff_offset + len + flags,
// while size of each parameter is 32 bit - so the total length is 16 bytes;
#define HCI_CMND_SEND_ARG_LENGTH (16)
#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000
#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5)
#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32)
#define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value
//--------- Address Families --------
#define AF_INET 2
#define AF_INET6 23
//------------ Socket Types ------------
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers
#define SOCK_RDM 4
#define SOCK_SEQPACKET 5
//----------- Socket Protocol ----------
#define IPPROTO_IP 0 // dummy for IP
#define IPPROTO_ICMP 1 // control message protocol
#define IPPROTO_IPV4 IPPROTO_IP // IP inside IP
#define IPPROTO_TCP 6 // tcp
#define IPPROTO_UDP 17 // user datagram protocol
#define IPPROTO_IPV6 41 // IPv6 in IPv6
#define IPPROTO_NONE 59 // No next header
#define IPPROTO_RAW 255 // raw IP packet
#define IPPROTO_MAX 256
//----------- Socket retunr codes -----------
#define SOC_ERROR (-1) // error
#define SOC_IN_PROGRESS (-2) // socket in progress
//----------- Socket Options -----------
#define SOL_SOCKET 0xffff // socket level
#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout
#define SOCKOPT_NONBLOCK 2 // accept non block mode set SOCK_ON or SOCK_OFF (default block mode )
#define SOCK_ON 0 // socket non-blocking mode is enabled
#define SOCK_OFF 1 // socket blocking mode is enabled
#define TCP_NODELAY 0x0001
#define TCP_BSDURGENT 0x7000
#define MAX_PACKET_SIZE 1500
#define MAX_LISTEN_QUEUE 4
#define IOCTL_SOCKET_EVENTMASK
#define __FD_SETSIZE 32
#define ASIC_ADDR_LEN 8
#define NO_QUERY_RECIVED -3
typedef struct _in_addr_t
{
uint32_t s_addr; // load with inet_aton()
} in_addr;
/*typedef struct _sockaddr_t
{
unsigned short int sa_family;
unsigned char sa_data[14];
} sockaddr;*/
typedef struct _sockaddr_in_t
{
int16_t sin_family; // e.g. AF_INET
uint16_t sin_port; // e.g. htons(3490)
in_addr sin_addr; // see struct in_addr, below
uint8_t sin_zero[8]; // zero this if you want to
} sockaddr_in;
typedef uint32_t socklen_t;
// The fd_set member is required to be an array of longs.
typedef int32_t __fd_mask;
// It's easier to assume 8-bit bytes than to get CHAR_BIT.
#define __NFDBITS (8 * sizeof (__fd_mask))
#define __FDELT(d) ((d) / __NFDBITS)
#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))
#ifndef FD_SET
//not used in the current code
#define ENOBUFS 55 // No buffer space available
// Access macros for 'fd_set'.
#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp)
#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp)
#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp)
#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp)
// fd_set for select and pselect.
typedef struct
{
__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
#define __FDS_BITS(set) ((set)->fds_bits)
} fd_set;
#endif /* FD_SET */
// We don't use `memset' because this would require a prototype and
// the array isn't too big.
#define __FD_ZERO(set) \
do { \
uint32_t __i; \
fd_set *__arr = (set); \
for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \
__FDS_BITS (__arr)[__i] = 0; \
} while (0)
#define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d))
#define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d))
#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d))
//Use in case of Big Endian only
#define htonl(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \
(((uint32_t)(A) & 0x00ff0000) >> 8) | \
(((uint32_t)(A) & 0x0000ff00) << 8) | \
(((uint32_t)(A) & 0x000000ff) << 24))
#define ntohl htonl
//Use in case of Big Endian only
#define htons(A) ((((uint32_t)(A) & 0xff00) >> 8) | \
(((uint32_t)(A) & 0x00ff) << 8))
#define ntohs htons
// mDNS port - 5353 mDNS multicast address - 224.0.0.251
#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \
sockaddr.sa_data[1] = 0xe9; \
sockaddr.sa_data[2] = 0xe0; \
sockaddr.sa_data[3] = 0x0; \
sockaddr.sa_data[4] = 0x0; \
sockaddr.sa_data[5] = 0xfb;
#endif
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
#include "cc3000_spi.h"
namespace mbed_cc3000 {
cc3000_spi::cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, cc3000_event &event, cc3000_simple_link &simple_link)
: _wlan_irq(cc3000_irq), _wlan_en(cc3000_en), _wlan_cs(cc3000_cs), _wlan_spi(cc3000_spi), _event(event), _simple_link(simple_link) {
_wlan_spi.format(8,1);
_wlan_spi.frequency(12000000);
_wlan_irq.fall(this, &cc3000_spi::WLAN_IRQHandler);
_wlan_en = 0;
_wlan_cs = 1;
wait_ms(50); /* mbed board delay */
}
cc3000_spi::~cc3000_spi() {
}
void cc3000_spi::wlan_irq_enable()
{
_process_irq = true;
//_wlan_irq.enable_irq();
if (wlan_irq_read() == 0) {
WLAN_IRQHandler();
}
}
void cc3000_spi::wlan_irq_disable() {
_process_irq = false;
//_wlan_irq.disable_irq();
}
uint32_t cc3000_spi::wlan_irq_read() {
return _wlan_irq.read();
}
void cc3000_spi::close() {
wlan_irq_disable();
}
void cc3000_spi::open() {
_spi_info.spi_state = eSPI_STATE_POWERUP;
_spi_info.tx_packet_length = 0;
_spi_info.rx_packet_length = 0;
wlan_irq_enable();
}
uint32_t cc3000_spi::first_write(uint8_t *buffer, uint16_t length) {
_wlan_cs = 0;
wait_us(50);
/* first 4 bytes of the data */
write_synchronous(buffer, 4);
wait_us(50);
write_synchronous(buffer + 4, length - 4);
_spi_info.spi_state = eSPI_STATE_IDLE;
_wlan_cs = 1;
return 0;
}
uint32_t cc3000_spi::write(uint8_t *buffer, uint16_t length) {
uint8_t pad = 0;
// check the total length of the packet in order to figure out if padding is necessary
if(!(length & 0x0001)) {
pad++;
}
buffer[0] = WRITE;
buffer[1] = HI(length + pad);
buffer[2] = LO(length + pad);
buffer[3] = 0;
buffer[4] = 0;
length += (SPI_HEADER_SIZE + pad);
// The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size)
// If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever!
uint8_t *transmit_buffer = _simple_link.get_transmit_buffer();
if (transmit_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) {
while (1);
}
if (_spi_info.spi_state == eSPI_STATE_POWERUP) {
while (_spi_info.spi_state != eSPI_STATE_INITIALIZED);
}
if (_spi_info.spi_state == eSPI_STATE_INITIALIZED) {
// TX/RX transaction over SPI after powerup: IRQ is low - send read buffer size command
first_write(buffer, length);
} else {
// Prevent occurence of a race condition when 2 back to back packets are sent to the
// device, so the state will move to IDLE and once again to not IDLE due to IRQ
wlan_irq_disable();
while (_spi_info.spi_state != eSPI_STATE_IDLE);
_spi_info.spi_state = eSPI_STATE_WRITE_IRQ;
//_spi_info.pTxPacket = buffer;
_spi_info.tx_packet_length = length;
// Assert the CS line and wait until the IRQ line is active, then initialize the write operation
_wlan_cs = 0;
wlan_irq_enable();
}
// Wait until the transaction ends
while (_spi_info.spi_state != eSPI_STATE_IDLE);
return 0;
}
void cc3000_spi::write_synchronous(uint8_t *data, uint16_t size) {
while(size) {
_wlan_spi.write(*data++);
size--;
}
}
void cc3000_spi::read_synchronous(uint8_t *data, uint16_t size) {
for (uint32_t i = 0; i < size; i++) {
data[i] = _wlan_spi.write(0x03);
}
}
uint32_t cc3000_spi::read_data_cont() {
int32_t data_to_recv;
uint8_t *evnt_buff, type;
//determine the packet type
evnt_buff = _simple_link.get_received_buffer();
data_to_recv = 0;
STREAM_TO_UINT8((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type);
switch(type) {
case HCI_TYPE_DATA:
// Read the remaining data..
STREAM_TO_UINT16((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv);
if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1)) {
data_to_recv++;
}
if (data_to_recv) {
read_synchronous(evnt_buff + 10, data_to_recv);
}
break;
case HCI_TYPE_EVNT:
// Calculate the rest length of the data
STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_EVENT_LENGTH_OFFSET, data_to_recv);
data_to_recv -= 1;
// Add padding byte if needed
if ((HEADERS_SIZE_EVNT + data_to_recv) & 1) {
data_to_recv++;
}
if (data_to_recv) {
read_synchronous(evnt_buff + 10, data_to_recv);
}
_spi_info.spi_state = eSPI_STATE_READ_EOT;
break;
}
return 0;
}
void cc3000_spi::set_wlan_en(uint8_t value) {
if (value) {
_wlan_en = 1;
} else {
_wlan_en = 0;
}
}
void cc3000_spi::WLAN_IRQHandler() {
if (_process_irq) {
if (_spi_info.spi_state == eSPI_STATE_POWERUP) {
// Inform HCI Layer that IRQ occured after powerup
_spi_info.spi_state = eSPI_STATE_INITIALIZED;
} else if (_spi_info.spi_state == eSPI_STATE_IDLE) {
_spi_info.spi_state = eSPI_STATE_READ_IRQ;
/* IRQ line goes low - acknowledge it */
_wlan_cs = 0;
read_synchronous(_simple_link.get_received_buffer(), 10);
_spi_info.spi_state = eSPI_STATE_READ_EOT;
// The header was read - continue with the payload read
if (!read_data_cont()) {
// All the data was read - finalize handling by switching to the task
// Trigger Rx processing
wlan_irq_disable();
_wlan_cs = 1;
// The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size)
// If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever!
uint8_t *received_buffer = _simple_link.get_received_buffer();
if (received_buffer[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) {
while (1);
}
_spi_info.spi_state = eSPI_STATE_IDLE;
_event.received_handler(received_buffer + SPI_HEADER_SIZE);
}
} else if (_spi_info.spi_state == eSPI_STATE_WRITE_IRQ) {
write_synchronous(_simple_link.get_transmit_buffer(), _spi_info.tx_packet_length);
_spi_info.spi_state = eSPI_STATE_IDLE;
_wlan_cs = 1;
}
}
}
} // namespace mbed_cc3000
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef CC3000_SPI_H
#define CC3000_SPI_H
typedef struct
{
uint16_t tx_packet_length;
uint16_t rx_packet_length;
uint32_t spi_state;
} tSpiInfo;
/* ===========================================================================================
SPI
=========================================================================================== */
#define READ 3
#define WRITE 1
#define HI(value) (((value) & 0xFF00) >> 8)
#define LO(value) ((value) & 0x00FF)
#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5)
#define SPI_HEADER_SIZE (5)
#define eSPI_STATE_POWERUP (0)
#define eSPI_STATE_INITIALIZED (1)
#define eSPI_STATE_IDLE (2)
#define eSPI_STATE_WRITE_IRQ (3)
#define eSPI_STATE_WRITE_FIRST_PORTION (4)
#define eSPI_STATE_WRITE_EOT (5)
#define eSPI_STATE_READ_IRQ (6)
#define eSPI_STATE_READ_FIRST_PORTION (7)
#define eSPI_STATE_READ_EOT (8)
// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
// for the purpose of detection of the overrun. The location of the memory where the magic number
// resides shall never be written. In case it is written - overrun occured and either recevie function
// or send function will be stuck forever.
#define CC3000_BUFFER_MAGIC_NUMBER (0xDE)
/* ===========================================================================================
HCI
=========================================================================================== */
#define SL_PATCH_PORTION_SIZE (1000)
#define SPI_HEADER_SIZE (5)
#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4)
#define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5)
#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5)
#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2)
// Values that can be used as HCI Commands and HCI Packet header defines
#define HCI_TYPE_CMND 0x1
#define HCI_TYPE_DATA 0x2
#define HCI_TYPE_PATCH 0x3
#define HCI_TYPE_EVNT 0x4
#define HCI_EVENT_PATCHES_DRV_REQ (1)
#define HCI_EVENT_PATCHES_FW_REQ (2)
#define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3)
#define HCI_CMND_WLAN_BASE (0x0000)
#define HCI_CMND_WLAN_CONNECT 0x0001
#define HCI_CMND_WLAN_DISCONNECT 0x0002
#define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003
#define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004
#define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005
#define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006
#define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007
#define HCI_CMND_EVENT_MASK 0x0008
#define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009
#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A
#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B
#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C
#define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D
#define HCI_CMND_SOCKET_BASE 0x1000
#define HCI_CMND_SOCKET 0x1001
#define HCI_CMND_BIND 0x1002
#define HCI_CMND_RECV 0x1004
#define HCI_CMND_ACCEPT 0x1005
#define HCI_CMND_LISTEN 0x1006
#define HCI_CMND_CONNECT 0x1007
#define HCI_CMND_BSD_SELECT 0x1008
#define HCI_CMND_SETSOCKOPT 0x1009
#define HCI_CMND_GETSOCKOPT 0x100A
#define HCI_CMND_CLOSE_SOCKET 0x100B
#define HCI_CMND_RECVFROM 0x100D
#define HCI_CMND_GETHOSTNAME 0x1010
#define HCI_CMND_MDNS_ADVERTISE 0x1011
#define HCI_DATA_BASE 0x80
#define HCI_CMND_SEND (0x01 + HCI_DATA_BASE)
#define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE)
#define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE)
#define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE)
#define HCI_CMND_NVMEM_CBASE (0x0200)
#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203)
#define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205)
#define HCI_CMND_NVMEM_READ (0x0201)
#define HCI_CMND_NVMEM_WRITE (0x0090)
#define HCI_CMND_NVMEM_WRITE_PATCH (0x0204)
#define HCI_CMND_READ_SP_VERSION (0x0207)
#define HCI_CMND_READ_BUFFER_SIZE 0x400B
#define HCI_CMND_SIMPLE_LINK_START 0x4000
#define HCI_CMND_NETAPP_BASE 0x2000
#define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE)
#define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE)
#define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE)
#define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE)
#define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE)
#define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE)
#define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE)
#define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE)
// Values that can be used as HCI Events defines
#define HCI_EVNT_WLAN_BASE 0x0000
#define HCI_EVNT_WLAN_CONNECT 0x0001
#define HCI_EVNT_WLAN_DISCONNECT \
0x0002
#define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \
0x0005
#define HCI_EVNT_SOCKET HCI_CMND_SOCKET
#define HCI_EVNT_BIND HCI_CMND_BIND
#define HCI_EVNT_RECV HCI_CMND_RECV
#define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT
#define HCI_EVNT_LISTEN HCI_CMND_LISTEN
#define HCI_EVNT_CONNECT HCI_CMND_CONNECT
#define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT
#define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET
#define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM
#define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT
#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT
#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME
#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE
#define HCI_EVNT_SEND 0x1003
#define HCI_EVNT_WRITE 0x100E
#define HCI_EVNT_SENDTO 0x100F
#define HCI_EVNT_PATCHES_REQ 0x1000
#define HCI_EVNT_UNSOL_BASE 0x4000
#define HCI_EVNT_WLAN_UNSOL_BASE (0x8000)
#define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE)
#define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE)
#define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE)
#define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE)
#define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE)
#define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE)
#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE)
#define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE)
#define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE)
#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \
0x4100
#define HCI_EVNT_NVMEM_CREATE_ENTRY \
HCI_CMND_NVMEM_CREATE_ENTRY
#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY
#define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ
#define HCI_EVNT_NVMEM_WRITE (0x0202)
#define HCI_EVNT_READ_SP_VERSION \
HCI_CMND_READ_SP_VERSION
#define HCI_EVNT_INPROGRESS 0xFFFF
#define HCI_DATA_RECVFROM 0x84
#define HCI_DATA_RECV 0x85
#define HCI_DATA_NVMEM 0x91
#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99
// Prototypes for the structures for HCI APIs.
#define HCI_DATA_HEADER_SIZE (5)
#define HCI_EVENT_HEADER_SIZE (5)
#define HCI_DATA_CMD_HEADER_SIZE (5)
#define HCI_PATCH_HEADER_SIZE (6)
#define HCI_PACKET_TYPE_OFFSET (0)
#define HCI_PACKET_ARGSIZE_OFFSET (2)
#define HCI_PACKET_LENGTH_OFFSET (3)
#define HCI_EVENT_OPCODE_OFFSET (1)
#define HCI_EVENT_LENGTH_OFFSET (3)
#define HCI_EVENT_STATUS_OFFSET (4)
#define HCI_DATA_LENGTH_OFFSET (3)
#endif
/*****************************************************************************
*
* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
* provided help.
*
* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
* read the following copyright:
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "cc3000.h"
namespace mbed_cc3000 {
cc3000_wlan::cc3000_wlan(cc3000_simple_link &simple_link, cc3000_event &event, cc3000_spi &spi, cc3000_hci &hci) :
_simple_link(simple_link), _event(event), _spi(spi), _hci(hci) {
}
cc3000_wlan::~cc3000_wlan() {
}
void cc3000_wlan::simpleLink_init_start(uint16_t patches_available_host) {
uint8_t *ptr;
uint8_t *args;
ptr = _simple_link.get_transmit_buffer();
args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
UINT8_TO_STREAM(args, ((patches_available_host) ? SL_PATCHES_REQUEST_FORCE_HOST : SL_PATCHES_REQUEST_DEFAULT));
// IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000
_hci.command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN);
_event.simplelink_wait_event(HCI_CMND_SIMPLE_LINK_START, 0);
}
void cc3000_wlan::start(uint16_t patches_available_host) {
uint32_t spi_irq_state;
_simple_link.set_sent_packets(0);
_simple_link.set_number_of_released_packets(0);
_simple_link.set_op_code(0);
_simple_link.set_number_free_buffers(0);
_simple_link.set_buffer_length(0);
_simple_link.set_buffer_size(0);
_simple_link.set_pending_data(0);
_simple_link.set_transmit_error(0);
_simple_link.set_data_received_flag(0);
_simple_link.set_buffer_size(0);
// init spi
_spi.open();
// Check the IRQ line
spi_irq_state = _spi.wlan_irq_read();
// ASIC 1273 chip enable: toggle WLAN EN line
_spi.set_wlan_en(WLAN_ENABLE);
if (spi_irq_state) {
// wait till the IRQ line goes low
while(_spi.wlan_irq_read() != 0);
} else {
// wait till the IRQ line goes high and then low
while(_spi.wlan_irq_read() == 0);
while(_spi.wlan_irq_read() != 0);
}
simpleLink_init_start(patches_available_host);
// Read Buffer's size and finish
_hci.command_send(HCI_CMND_READ_BUFFER_SIZE, _simple_link.get_transmit_buffer(), 0);
_event.simplelink_wait_event(HCI_CMND_READ_BUFFER_SIZE, 0);
}
void cc3000_wlan::stop() {
// ASIC 1273 chip disable
_spi.set_wlan_en(WLAN_DISABLE);
// Wait till IRQ line goes high
while(_spi.wlan_irq_read() == 0);
_spi.close();
}
int32_t cc3000_wlan::disconnect() {
int32_t ret;
uint8_t *ptr;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
_hci.command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_DISCONNECT, &ret);
errno = ret;
return ret;
}
int32_t cc3000_wlan::ioctl_set_connection_policy(uint32_t should_connect_to_open_ap,
uint32_t use_fast_connect,
uint32_t use_profiles) {
int32_t ret;
uint8_t *ptr;
uint8_t *args;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, should_connect_to_open_ap);
args = UINT32_TO_STREAM(args, use_fast_connect);
args = UINT32_TO_STREAM(args, use_profiles);
// Initiate a HCI command
_hci.command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret);
return ret;
}
int32_t cc3000_wlan::ioctl_del_profile(uint32_t index) {
int32_t ret;
uint8_t *ptr;
uint8_t *args;
ptr = _simple_link.get_transmit_buffer();
args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, index);
ret = EFAIL;
// Initiate a HCI command
_hci.command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, ptr, WLAN_DEL_PROFILE_PARAMS_LEN);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret);
return ret;
}
int32_t cc3000_wlan::set_event_mask(uint32_t mask) {
int32_t ret;
uint8_t *ptr;
uint8_t *args;
if ((mask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE) {
_simple_link.set_tx_complete_signal(0);
// Since an event is a virtual event - i.e. it is not coming from CC3000
// there is no need to send anything to the device if it was an only event
if (mask == HCI_EVNT_WLAN_TX_COMPLETE) {
return 0;
}
mask &= ~HCI_EVNT_WLAN_TX_COMPLETE;
mask |= HCI_EVNT_WLAN_UNSOL_BASE;
} else {
_simple_link.set_tx_complete_signal(1);
}
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, mask);
// Initiate a HCI command
_hci.command_send(HCI_CMND_EVENT_MASK, ptr, WLAN_SET_MASK_PARAMS_LEN);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_EVENT_MASK, &ret);
return ret;
}
int32_t cc3000_wlan::smart_config_start(uint32_t encrypted_flag) {
int32_t ret;
uint8_t *ptr;
uint8_t *args;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, encrypted_flag);
ret = EFAIL;
_hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, WLAN_SMART_CONFIG_START_PARAMS_LEN);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret);
return ret;
}
int32_t cc3000_wlan::smart_config_stop(void) {
int32_t ret;
uint8_t *ptr;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
_hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret);
return ret;
}
int32_t cc3000_wlan::smart_config_set_prefix(uint8_t *new_prefix) {
int32_t ret;
uint8_t *ptr;
uint8_t *args;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
if (new_prefix == NULL) {
return ret;
} else {
// with the new Smart Config, prefix must be TTT
*new_prefix = 'T';
*(new_prefix + 1) = 'T';
*(new_prefix + 2) = 'T';
}
ARRAY_TO_STREAM(args, new_prefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
_hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret);
return ret;
}
#ifndef CC3000_TINY_DRIVER
int32_t cc3000_wlan::connect(uint32_t sec_type, const uint8_t *ssid, int32_t ssid_len, uint8_t *bssid,
uint8_t *key, int32_t key_len) {
int32_t ret;
uint8_t *ptr;
uint8_t *args;
uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in command buffer
args = UINT32_TO_STREAM(args, 0x0000001c);
args = UINT32_TO_STREAM(args, ssid_len);
args = UINT32_TO_STREAM(args, sec_type);
args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
args = UINT32_TO_STREAM(args, key_len);
args = UINT16_TO_STREAM(args, 0);
// padding shall be zeroed
if (bssid) {
ARRAY_TO_STREAM(args, bssid, ETH_ALEN);
} else {
ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
}
ARRAY_TO_STREAM(args, ssid, ssid_len);
if (key_len && key) {
ARRAY_TO_STREAM(args, key, key_len);
}
// Initiate a HCI command
_hci.command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len + key_len - 1);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
errno = ret;
return ret;
}
int32_t cc3000_wlan::add_profile(uint32_t sec_type,
uint8_t* ssid,
uint32_t ssid_length,
uint8_t *b_ssid,
uint32_t priority,
uint32_t pairwise_cipher_or_tx_key_len,
uint32_t group_cipher_tx_key_index,
uint32_t key_mgmt,
uint8_t* pf_or_key,
uint32_t pass_phrase_len) {
uint16_t arg_len = 0x00;
int32_t ret;
uint8_t *ptr;
int32_t i = 0;
uint8_t *args;
uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
args = UINT32_TO_STREAM(args, sec_type);
// Setup arguments in accordance with the security type
switch (sec_type)
{
//OPEN
case WLAN_SEC_UNSEC:
{
args = UINT32_TO_STREAM(args, 0x00000014);
args = UINT32_TO_STREAM(args, ssid_length);
args = UINT16_TO_STREAM(args, 0);
if(b_ssid) {
ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
} else {
ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
}
args = UINT32_TO_STREAM(args, priority);
ARRAY_TO_STREAM(args, ssid, ssid_length);
arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ssid_length;
}
break;
//WEP
case WLAN_SEC_WEP:
{
args = UINT32_TO_STREAM(args, 0x00000020);
args = UINT32_TO_STREAM(args, ssid_length);
args = UINT16_TO_STREAM(args, 0);
if (b_ssid) {
ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
} else {
ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
}
args = UINT32_TO_STREAM(args, priority);
args = UINT32_TO_STREAM(args, 0x0000000C + ssid_length);
args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
ARRAY_TO_STREAM(args, ssid, ssid_length);
for(i = 0; i < 4; i++) {
uint8_t *p = &pf_or_key[i * pairwise_cipher_or_tx_key_len];
ARRAY_TO_STREAM(args, p, pairwise_cipher_or_tx_key_len);
}
arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ssid_length +
pairwise_cipher_or_tx_key_len * 4;
}
break;
//WPA
//WPA2
case WLAN_SEC_WPA:
case WLAN_SEC_WPA2:
{
args = UINT32_TO_STREAM(args, 0x00000028);
args = UINT32_TO_STREAM(args, ssid_length);
args = UINT16_TO_STREAM(args, 0);
if (b_ssid) {
ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
} else {
ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
}
args = UINT32_TO_STREAM(args, priority);
args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
args = UINT32_TO_STREAM(args, key_mgmt);
args = UINT32_TO_STREAM(args, 0x00000008 + ssid_length);
args = UINT32_TO_STREAM(args, pass_phrase_len);
ARRAY_TO_STREAM(args, ssid, ssid_length);
ARRAY_TO_STREAM(args, pf_or_key, pass_phrase_len);
arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ssid_length + pass_phrase_len;
}
break;
}
// Initiate a HCI command
_hci.command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);
return ret;
}
int32_t cc3000_wlan::ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results) {
uint8_t *ptr;
uint8_t *args;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, scan_timeout);
// Initiate a HCI command
_hci.command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, results);
return 0;
}
int32_t cc3000_wlan::ioctl_set_scan_params(uint32_t enable,
uint32_t min_dwell_time,
uint32_t max_dwell_time,
uint32_t num_probe_requests,
uint32_t channel_mask,
int32_t rssi_threshold,
uint32_t snr_threshold,
uint32_t default_tx_power,
uint32_t *interval_list) {
uint32_t uiRes;
uint8_t *ptr;
uint8_t *args;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, 36);
args = UINT32_TO_STREAM(args, enable);
args = UINT32_TO_STREAM(args, min_dwell_time);
args = UINT32_TO_STREAM(args, max_dwell_time);
args = UINT32_TO_STREAM(args, num_probe_requests);
args = UINT32_TO_STREAM(args, channel_mask);
args = UINT32_TO_STREAM(args, rssi_threshold);
args = UINT32_TO_STREAM(args, snr_threshold);
args = UINT32_TO_STREAM(args, default_tx_power);
ARRAY_TO_STREAM(args, interval_list, sizeof(uint32_t) * SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE);
// Initiate a HCI command
_hci.command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, ptr, WLAN_SET_SCAN_PARAMS_LEN);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes);
return(uiRes);
}
int32_t cc3000_wlan::ioctl_statusget(void) {
int32_t ret;
uint8_t *ptr;
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
_hci.command_send(HCI_CMND_WLAN_IOCTL_STATUSGET,ptr, 0);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret);
return ret;
}
#else
int32_t cc3000_wlan::add_profile(uint32_t sec_type,
uint8_t *ssid,
uint32_t ssid_length,
uint8_t *b_ssid,
uint32_t priority,
uint32_t pairwise_cipher_or_tx_key_len,
uint32_t group_cipher_tx_key_index,
uint32_t key_mgmt,
uint8_t* pf_or_key,
uint32_t pass_phrase_length)
{
return -1;
}
int32_t cc3000_wlan::connect(const uint8_t *ssid, int32_t ssid_len) {
int32_t ret;
uint8_t *ptr;
uint8_t *args;
uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
ret = EFAIL;
ptr = _simple_link.get_transmit_buffer();
args = (ptr + HEADERS_SIZE_CMD);
// Fill in command buffer
args = UINT32_TO_STREAM(args, 0x0000001c);
args = UINT32_TO_STREAM(args, ssid_len);
args = UINT32_TO_STREAM(args, 0);
args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
args = UINT32_TO_STREAM(args, 0);
args = UINT16_TO_STREAM(args, 0);
// padding shall be zeroed
ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
ARRAY_TO_STREAM(args, ssid, ssid_len);
// Initiate a HCI command
_hci.command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len - 1);
// Wait for command complete event
_event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
errno = ret;
return ret;
}
#endif
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
int32_t cc3000_wlan::smart_config_process(void) {
int32_t returnValue;
uint32_t ssidLen, keyLen;
uint8_t *decKeyPtr;
uint8_t *ssidPtr;
// read the key from EEPROM - fileID 12
returnValue = aes_read_key(key);
if (returnValue != 0)
return returnValue;
// read the received data from fileID #13 and parse it according to the followings:
// 1) SSID LEN - not encrypted
// 2) SSID - not encrypted
// 3) KEY LEN - not encrypted. always 32 bytes long
// 4) Security type - not encrypted
// 5) KEY - encrypted together with true key length as the first byte in KEY
// to elaborate, there are two corner cases:
// 1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length
// 2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31
returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray);
if (returnValue != 0)
return returnValue;
ssidPtr = &profileArray[1];
ssidLen = profileArray[0];
decKeyPtr = &profileArray[profileArray[0] + 3];
aes_decrypt(decKeyPtr, key);
if (profileArray[profileArray[0] + 1] > 16)
aes_decrypt((uint8_t *)(decKeyPtr + 16), key);
if (*(uint8_t *)(decKeyPtr +31) != 0) {
if (*decKeyPtr == 31) {
keyLen = 31;
decKeyPtr++;
} else {
keyLen = 32;
}
} else {
keyLen = *decKeyPtr;
decKeyPtr++;
}
// add a profile
switch (profileArray[profileArray[0] + 2])
{
case WLAN_SEC_UNSEC://None
{
returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type
ssidPtr, // SSID
ssidLen, // SSID length
NULL, // BSSID
1, // Priority
0, 0, 0, 0, 0);
break;
}
case WLAN_SEC_WEP://WEP
{
returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type
ssidPtr, // SSID
ssidLen, // SSID length
NULL, // BSSID
1, // Priority
keyLen, // KEY length
0, // KEY index
0,
decKeyPtr, // KEY
0);
break;
}
case WLAN_SEC_WPA: //WPA
case WLAN_SEC_WPA2: //WPA2
{
returnValue = wlan_add_profile(WLAN_SEC_WPA2, // security type
ssidPtr,
ssidLen,
NULL, // BSSID
1, // Priority
0x18, // PairwiseCipher
0x1e, // GroupCipher
2, // KEY management
decKeyPtr, // KEY
keyLen); // KEY length
break;
}
}
return returnValue;
}
#endif
}
#include "mbed.h"
#include "rtos.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led1(PA_0);
DigitalOut led2(PA_1);
void led2_thread(void const *args) {
while (true) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment