Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
460b04a42b | |||
97857ce12c | |||
461b1b16b1 |
@ -766,6 +766,7 @@ char proc_ftpd(char * buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PWD_CMD:
|
case PWD_CMD:
|
||||||
|
case XPWD_CMD:
|
||||||
slen = sprintf(sendbuf, "257 \"%s\" is current directory.\r\n", ftp.workingdir);
|
slen = sprintf(sendbuf, "257 \"%s\" is current directory.\r\n", ftp.workingdir);
|
||||||
send(CTRL_SOCK, (uint8_t *)sendbuf, slen);
|
send(CTRL_SOCK, (uint8_t *)sendbuf, slen);
|
||||||
break;
|
break;
|
||||||
@ -840,6 +841,7 @@ char proc_ftpd(char * buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MKD_CMD:
|
case MKD_CMD:
|
||||||
|
case XMKD_CMD:
|
||||||
slen = strlen(arg);
|
slen = strlen(arg);
|
||||||
arg[slen - 1] = 0x00;
|
arg[slen - 1] = 0x00;
|
||||||
arg[slen - 2] = 0x00;
|
arg[slen - 2] = 0x00;
|
||||||
@ -879,9 +881,7 @@ char proc_ftpd(char * buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case XCWD_CMD:
|
case XCWD_CMD:
|
||||||
case XPWD_CMD:
|
|
||||||
case ACCT_CMD:
|
case ACCT_CMD:
|
||||||
case XMKD_CMD:
|
|
||||||
case XRMD_CMD:
|
case XRMD_CMD:
|
||||||
case RMD_CMD:
|
case RMD_CMD:
|
||||||
case STRU_CMD:
|
case STRU_CMD:
|
||||||
|
448
Internet/SNTP/sntp.c
Normal file
448
Internet/SNTP/sntp.c
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
/*
|
||||||
|
* sntp.c
|
||||||
|
*
|
||||||
|
* Created on: 2014. 12. 15.
|
||||||
|
* Author: Administrator
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "sntp.h"
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
|
ntpformat NTPformat;
|
||||||
|
datetime Nowdatetime;
|
||||||
|
uint8_t ntpmessage[48];
|
||||||
|
uint8_t *data_buf;
|
||||||
|
uint8_t NTP_SOCKET;
|
||||||
|
uint8_t time_zone;
|
||||||
|
uint16_t ntp_retry_cnt=0; //counting the ntp retry number
|
||||||
|
|
||||||
|
/*
|
||||||
|
00)UTC-12:00 Baker Island, Howland Island (both uninhabited)
|
||||||
|
01) UTC-11:00 American Samoa, Samoa
|
||||||
|
02) UTC-10:00 (Summer)French Polynesia (most), United States (Aleutian Islands, Hawaii)
|
||||||
|
03) UTC-09:30 Marquesas Islands
|
||||||
|
04) UTC-09:00 Gambier Islands;(Summer)United States (most of Alaska)
|
||||||
|
05) UTC-08:00 (Summer)Canada (most of British Columbia), Mexico (Baja California)
|
||||||
|
06) UTC-08:00 United States (California, most of Nevada, most of Oregon, Washington (state))
|
||||||
|
07) UTC-07:00 Mexico (Sonora), United States (Arizona); (Summer)Canada (Alberta)
|
||||||
|
08) UTC-07:00 Mexico (Chihuahua), United States (Colorado)
|
||||||
|
09) UTC-06:00 Costa Rica, El Salvador, Ecuador (Galapagos Islands), Guatemala, Honduras
|
||||||
|
10) UTC-06:00 Mexico (most), Nicaragua;(Summer)Canada (Manitoba, Saskatchewan), United States (Illinois, most of Texas)
|
||||||
|
11) UTC-05:00 Colombia, Cuba, Ecuador (continental), Haiti, Jamaica, Panama, Peru
|
||||||
|
12) UTC-05:00 (Summer)Canada (most of Ontario, most of Quebec)
|
||||||
|
13) UTC-05:00 United States (most of Florida, Georgia, Massachusetts, most of Michigan, New York, North Carolina, Ohio, Washington D.C.)
|
||||||
|
14) UTC-04:30 Venezuela
|
||||||
|
15) UTC-04:00 Bolivia, Brazil (Amazonas), Chile (continental), Dominican Republic, Canada (Nova Scotia), Paraguay,
|
||||||
|
16) UTC-04:00 Puerto Rico, Trinidad and Tobago
|
||||||
|
17) UTC-03:30 Canada (Newfoundland)
|
||||||
|
18) UTC-03:00 Argentina; (Summer) Brazil (Brasilia, Rio de Janeiro, Sao Paulo), most of Greenland, Uruguay
|
||||||
|
19) UTC-02:00 Brazil (Fernando de Noronha), South Georgia and the South Sandwich Islands
|
||||||
|
20) UTC-01:00 Portugal (Azores), Cape Verde
|
||||||
|
21) UTC±00:00 Cote d'Ivoire, Faroe Islands, Ghana, Iceland, Senegal; (Summer) Ireland, Portugal (continental and Madeira)
|
||||||
|
22) UTC±00:00 Spain (Canary Islands), Morocco, United Kingdom
|
||||||
|
23) UTC+01:00 Angola, Cameroon, Nigeria, Tunisia; (Summer)Albania, Algeria, Austria, Belgium, Bosnia and Herzegovina,
|
||||||
|
24) UTC+01:00 Spain (continental), Croatia, Czech Republic, Denmark, Germany, Hungary, Italy, Kinshasa, Kosovo,
|
||||||
|
25) UTC+01:00 Macedonia, France (metropolitan), the Netherlands, Norway, Poland, Serbia, Slovakia, Slovenia, Sweden, Switzerland
|
||||||
|
26) UTC+02:00 Libya, Egypt, Malawi, Mozambique, South Africa, Zambia, Zimbabwe, (Summer)Bulgaria, Cyprus, Estonia,
|
||||||
|
27) UTC+02:00 Finland, Greece, Israel, Jordan, Latvia, Lebanon, Lithuania, Moldova, Palestine, Romania, Syria, Turkey, Ukraine
|
||||||
|
28) UTC+03:00 Belarus, Djibouti, Eritrea, Ethiopia, Iraq, Kenya, Madagascar, Russia (Kaliningrad Oblast), Saudi Arabia,
|
||||||
|
29) UTC+03:00 South Sudan, Sudan, Somalia, South Sudan, Tanzania, Uganda, Yemen
|
||||||
|
30) UTC+03:30 (Summer)Iran
|
||||||
|
31) UTC+04:00 Armenia, Azerbaijan, Georgia, Mauritius, Oman, Russia (European), Seychelles, United Arab Emirates
|
||||||
|
32) UTC+04:30 Afghanistan
|
||||||
|
33) UTC+05:00 Kazakhstan (West), Maldives, Pakistan, Uzbekistan
|
||||||
|
34) UTC+05:30 India, Sri Lanka
|
||||||
|
35) UTC+05:45 Nepal
|
||||||
|
36) UTC+06:00 Kazakhstan (most), Bangladesh, Russia (Ural: Sverdlovsk Oblast, Chelyabinsk Oblast)
|
||||||
|
37) UTC+06:30 Cocos Islands, Myanmar
|
||||||
|
38) UTC+07:00 Jakarta, Russia (Novosibirsk Oblast), Thailand, Vietnam
|
||||||
|
39) UTC+08:00 China, Hong Kong, Russia (Krasnoyarsk Krai), Malaysia, Philippines, Singapore, Taiwan, most of Mongolia, Western Australia
|
||||||
|
40) UTC+09:00 Korea, East Timor, Russia (Irkutsk Oblast), Japan
|
||||||
|
41) UTC+09:30 Australia (Northern Territory);(Summer)Australia (South Australia))
|
||||||
|
42) UTC+10:00 Russia (Zabaykalsky Krai); (Summer)Australia (New South Wales, Queensland, Tasmania, Victoria)
|
||||||
|
43) UTC+10:30 Lord Howe Island
|
||||||
|
44) UTC+11:00 New Caledonia, Russia (Primorsky Krai), Solomon Islands
|
||||||
|
45) UTC+11:30 Norfolk Island
|
||||||
|
46) UTC+12:00 Fiji, Russia (Kamchatka Krai);(Summer)New Zealand
|
||||||
|
47) UTC+12:45 (Summer)New Zealand
|
||||||
|
48) UTC+13:00 Tonga
|
||||||
|
49) UTC+14:00 Kiribati (Line Islands)
|
||||||
|
*/
|
||||||
|
void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx)
|
||||||
|
{
|
||||||
|
tstamp seconds = 0;
|
||||||
|
uint8_t i=0;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
seconds = (seconds << 8) | buf[idx + i];
|
||||||
|
}
|
||||||
|
switch (time_zone)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
seconds -= 12*3600;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
seconds -= 11*3600;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
seconds -= 10*3600;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
seconds -= (9*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
seconds -= 9*3600;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
seconds -= 8*3600;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
seconds -= 7*3600;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
seconds -= 6*3600;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
case 13:
|
||||||
|
seconds -= 5*3600;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
seconds -= (4*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
case 16:
|
||||||
|
seconds -= 4*3600;
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
seconds -= (3*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
seconds -= 3*3600;
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
seconds -= 2*3600;
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
seconds -= 1*3600;
|
||||||
|
break;
|
||||||
|
case 21: //?
|
||||||
|
case 22:
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
case 24:
|
||||||
|
case 25:
|
||||||
|
seconds += 1*3600;
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
case 27:
|
||||||
|
seconds += 2*3600;
|
||||||
|
break;
|
||||||
|
case 28:
|
||||||
|
case 29:
|
||||||
|
seconds += 3*3600;
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
seconds += (3*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 31:
|
||||||
|
seconds += 4*3600;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
seconds += (4*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
seconds += 5*3600;
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
seconds += (5*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
seconds += (5*3600+45*60);
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
seconds += 6*3600;
|
||||||
|
break;
|
||||||
|
case 37:
|
||||||
|
seconds += (6*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 38:
|
||||||
|
seconds += 7*3600;
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
|
seconds += 8*3600;
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
seconds += 9*3600;
|
||||||
|
break;
|
||||||
|
case 41:
|
||||||
|
seconds += (9*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 42:
|
||||||
|
seconds += 10*3600;
|
||||||
|
break;
|
||||||
|
case 43:
|
||||||
|
seconds += (10*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 44:
|
||||||
|
seconds += 11*3600;
|
||||||
|
break;
|
||||||
|
case 45:
|
||||||
|
seconds += (11*3600+30*60);
|
||||||
|
break;
|
||||||
|
case 46:
|
||||||
|
seconds += 12*3600;
|
||||||
|
break;
|
||||||
|
case 47:
|
||||||
|
seconds += (12*3600+45*60);
|
||||||
|
break;
|
||||||
|
case 48:
|
||||||
|
seconds += 13*3600;
|
||||||
|
break;
|
||||||
|
case 49:
|
||||||
|
seconds += 14*3600;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//calculation for date
|
||||||
|
calcdatetime(seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf)
|
||||||
|
{
|
||||||
|
NTPformat.dstaddr[0] = ntp_server[0];
|
||||||
|
NTPformat.dstaddr[1] = ntp_server[1];
|
||||||
|
NTPformat.dstaddr[2] = ntp_server[2];
|
||||||
|
NTPformat.dstaddr[3] = ntp_server[3];
|
||||||
|
|
||||||
|
time_zone = tz;
|
||||||
|
|
||||||
|
data_buf = buf;
|
||||||
|
|
||||||
|
uint8_t Flag;
|
||||||
|
NTPformat.leap = 0; /* leap indicator */
|
||||||
|
NTPformat.version = 4; /* version number */
|
||||||
|
NTPformat.mode = 3; /* mode */
|
||||||
|
NTPformat.stratum = 0; /* stratum */
|
||||||
|
NTPformat.poll = 0; /* poll interval */
|
||||||
|
NTPformat.precision = 0; /* precision */
|
||||||
|
NTPformat.rootdelay = 0; /* root delay */
|
||||||
|
NTPformat.rootdisp = 0; /* root dispersion */
|
||||||
|
NTPformat.refid = 0; /* reference ID */
|
||||||
|
NTPformat.reftime = 0; /* reference time */
|
||||||
|
NTPformat.org = 0; /* origin timestamp */
|
||||||
|
NTPformat.rec = 0; /* receive timestamp */
|
||||||
|
NTPformat.xmt = 1; /* transmit timestamp */
|
||||||
|
|
||||||
|
Flag = (NTPformat.leap<<6)+(NTPformat.version<<3)+NTPformat.mode; //one byte Flag
|
||||||
|
memcpy(ntpmessage,(void const*)(&Flag),1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t SNTP_run(datetime *time)
|
||||||
|
{
|
||||||
|
uint16_t RSR_len;
|
||||||
|
uint32_t destip = 0;
|
||||||
|
uint16_t destport;
|
||||||
|
uint16_t startindex = 40; //last 8-byte of data_buf[size is 48 byte] is xmt, so the startindex should be 40
|
||||||
|
|
||||||
|
switch(getSn_SR(NTP_SOCKET))
|
||||||
|
{
|
||||||
|
case SOCK_UDP:
|
||||||
|
if ((RSR_len = getSn_RX_RSR(NTP_SOCKET)) > 0)
|
||||||
|
{
|
||||||
|
if (RSR_len > MAX_SNTP_BUF_SIZE) RSR_len = MAX_SNTP_BUF_SIZE; // if Rx data size is lager than TX_RX_MAX_BUF_SIZE
|
||||||
|
recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport);
|
||||||
|
|
||||||
|
get_seconds_from_ntp_server(data_buf,startindex);
|
||||||
|
time->yy = Nowdatetime.yy;
|
||||||
|
time->mo = Nowdatetime.mo;
|
||||||
|
time->dd = Nowdatetime.dd;
|
||||||
|
time->hh = Nowdatetime.hh;
|
||||||
|
time->mm = Nowdatetime.mm;
|
||||||
|
time->ss = Nowdatetime.ss;
|
||||||
|
|
||||||
|
ntp_retry_cnt=0;
|
||||||
|
close(NTP_SOCKET);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ntp_retry_cnt<0xFFFF)
|
||||||
|
{
|
||||||
|
if(ntp_retry_cnt==0)//first send request, no need to wait
|
||||||
|
{
|
||||||
|
sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
|
||||||
|
ntp_retry_cnt++;
|
||||||
|
}
|
||||||
|
else // send request again? it should wait for a while
|
||||||
|
{
|
||||||
|
if((ntp_retry_cnt % 0xFFF) == 0) //wait time
|
||||||
|
{
|
||||||
|
sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
|
||||||
|
#ifdef _SNTP_DEBUG_
|
||||||
|
printf("ntp retry: %d\r\n", ntp_retry_cnt);
|
||||||
|
#endif
|
||||||
|
ntp_retry_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //ntp retry fail
|
||||||
|
{
|
||||||
|
ntp_retry_cnt=0;
|
||||||
|
#ifdef _SNTP_DEBUG_
|
||||||
|
printf("ntp retry failed!\r\n");
|
||||||
|
#endif
|
||||||
|
close(NTP_SOCKET);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SOCK_CLOSED:
|
||||||
|
socket(NTP_SOCKET,Sn_MR_UDP,ntp_port,0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Return value
|
||||||
|
// 0 - failed / 1 - success
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calcdatetime(tstamp seconds)
|
||||||
|
{
|
||||||
|
uint8_t yf=0;
|
||||||
|
tstamp n=0,d=0,total_d=0,rz=0;
|
||||||
|
uint16_t y=0,r=0,yr=0;
|
||||||
|
signed long long yd=0;
|
||||||
|
|
||||||
|
n = seconds;
|
||||||
|
total_d = seconds/(SECS_PERDAY);
|
||||||
|
d=0;
|
||||||
|
uint32_t p_year_total_sec=SECS_PERDAY*365;
|
||||||
|
uint32_t r_year_total_sec=SECS_PERDAY*366;
|
||||||
|
while(n>=p_year_total_sec)
|
||||||
|
{
|
||||||
|
if((EPOCH+r)%400==0 || ((EPOCH+r)%100!=0 && (EPOCH+r)%4==0))
|
||||||
|
{
|
||||||
|
n = n -(r_year_total_sec);
|
||||||
|
d = d + 366;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n = n - (p_year_total_sec);
|
||||||
|
d = d + 365;
|
||||||
|
}
|
||||||
|
r+=1;
|
||||||
|
y+=1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
y += EPOCH;
|
||||||
|
|
||||||
|
Nowdatetime.yy = y;
|
||||||
|
|
||||||
|
yd=0;
|
||||||
|
yd = total_d - d;
|
||||||
|
|
||||||
|
yf=1;
|
||||||
|
while(yd>=28)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(yf==1 || yf==3 || yf==5 || yf==7 || yf==8 || yf==10 || yf==12)
|
||||||
|
{
|
||||||
|
yd -= 31;
|
||||||
|
if(yd<0)break;
|
||||||
|
rz += 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yf==2)
|
||||||
|
{
|
||||||
|
if (y%400==0 || (y%100!=0 && y%4==0))
|
||||||
|
{
|
||||||
|
yd -= 29;
|
||||||
|
if(yd<0)break;
|
||||||
|
rz += 29;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yd -= 28;
|
||||||
|
if(yd<0)break;
|
||||||
|
rz += 28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(yf==4 || yf==6 || yf==9 || yf==11 )
|
||||||
|
{
|
||||||
|
yd -= 30;
|
||||||
|
if(yd<0)break;
|
||||||
|
rz += 30;
|
||||||
|
}
|
||||||
|
yf += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
Nowdatetime.mo=yf;
|
||||||
|
yr = total_d-d-rz;
|
||||||
|
|
||||||
|
yr += 1;
|
||||||
|
|
||||||
|
Nowdatetime.dd=yr;
|
||||||
|
|
||||||
|
//calculation for time
|
||||||
|
seconds = seconds%SECS_PERDAY;
|
||||||
|
Nowdatetime.hh = seconds/3600;
|
||||||
|
Nowdatetime.mm = (seconds%3600)/60;
|
||||||
|
Nowdatetime.ss = (seconds%3600)%60;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tstamp changedatetime_to_seconds(void)
|
||||||
|
{
|
||||||
|
tstamp seconds=0;
|
||||||
|
uint32_t total_day=0;
|
||||||
|
uint16_t i=0,run_year_cnt=0,l=0;
|
||||||
|
|
||||||
|
l = Nowdatetime.yy;//low
|
||||||
|
|
||||||
|
|
||||||
|
for(i=EPOCH;i<l;i++)
|
||||||
|
{
|
||||||
|
if((i%400==0) || ((i%100!=0) && (i%4==0)))
|
||||||
|
{
|
||||||
|
run_year_cnt += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
total_day=(l-EPOCH-run_year_cnt)*365+run_year_cnt*366;
|
||||||
|
|
||||||
|
for(i=1;i<=Nowdatetime.mo;i++)
|
||||||
|
{
|
||||||
|
if(i==5 || i==7 || i==10 || i==12)
|
||||||
|
{
|
||||||
|
total_day += 30;
|
||||||
|
}
|
||||||
|
if (i==3)
|
||||||
|
{
|
||||||
|
if (l%400==0 && l%100!=0 && l%4==0)
|
||||||
|
{
|
||||||
|
total_day += 29;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
total_day += 28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i==2 || i==4 || i==6 || i==8 || i==9 || i==11)
|
||||||
|
{
|
||||||
|
total_day += 31;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
seconds = (total_day+Nowdatetime.dd-1)*24*3600;
|
||||||
|
seconds += Nowdatetime.ss;//seconds
|
||||||
|
seconds += Nowdatetime.mm*60;//minute
|
||||||
|
seconds += Nowdatetime.hh*3600;//hour
|
||||||
|
|
||||||
|
return seconds;
|
||||||
|
}
|
68
Internet/SNTP/sntp.h
Normal file
68
Internet/SNTP/sntp.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* sntp.h
|
||||||
|
*
|
||||||
|
* Created on: 2014. 12. 15.
|
||||||
|
* Author: Administrator
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SNTP_H_
|
||||||
|
#define SNTP_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Define it for Debug & Monitor DNS processing.
|
||||||
|
* @note If defined, it dependens on <stdio.h>
|
||||||
|
*/
|
||||||
|
//#define _SNTP_DEBUG_
|
||||||
|
|
||||||
|
#define MAX_SNTP_BUF_SIZE sizeof(ntpformat) ///< maximum size of DNS buffer. */
|
||||||
|
|
||||||
|
/* for ntpclient */
|
||||||
|
typedef signed char s_char;
|
||||||
|
typedef unsigned long long tstamp;
|
||||||
|
typedef unsigned int tdist;
|
||||||
|
|
||||||
|
typedef struct _ntpformat
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t dstaddr[4]; /* destination (local) address */
|
||||||
|
char version; /* version number */
|
||||||
|
char leap; /* leap indicator */
|
||||||
|
char mode; /* mode */
|
||||||
|
char stratum; /* stratum */
|
||||||
|
char poll; /* poll interval */
|
||||||
|
s_char precision; /* precision */
|
||||||
|
tdist rootdelay; /* root delay */
|
||||||
|
tdist rootdisp; /* root dispersion */
|
||||||
|
char refid; /* reference ID */
|
||||||
|
tstamp reftime; /* reference time */
|
||||||
|
tstamp org; /* origin timestamp */
|
||||||
|
tstamp rec; /* receive timestamp */
|
||||||
|
tstamp xmt; /* transmit timestamp */
|
||||||
|
|
||||||
|
|
||||||
|
} ntpformat;
|
||||||
|
|
||||||
|
typedef struct _datetime
|
||||||
|
{
|
||||||
|
uint16_t yy;
|
||||||
|
uint8_t mo;
|
||||||
|
uint8_t dd;
|
||||||
|
uint8_t hh;
|
||||||
|
uint8_t mm;
|
||||||
|
uint8_t ss;
|
||||||
|
} datetime;
|
||||||
|
|
||||||
|
#define ntp_port 123 //ntp server port number
|
||||||
|
#define SECS_PERDAY 86400UL // seconds in a day = 60*60*24
|
||||||
|
#define UTC_ADJ_HRS 9 // SEOUL : GMT+9
|
||||||
|
#define EPOCH 1900 // NTP start year
|
||||||
|
|
||||||
|
void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx);
|
||||||
|
void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf);
|
||||||
|
int8_t SNTP_run(datetime *time);
|
||||||
|
tstamp changedatetime_to_seconds(void);
|
||||||
|
void calcdatetime(tstamp seconds);
|
||||||
|
|
||||||
|
#endif /* SNTP_H_ */
|
158
Internet/TFTP/netutil.c
Normal file
158
Internet/TFTP/netutil.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "netutil.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a 32bit Address into a Dotted Decimal Format string.
|
||||||
|
*
|
||||||
|
* @param addr 32bit address.
|
||||||
|
* @return Dotted Decimal Format string.
|
||||||
|
*/
|
||||||
|
int8_t* inet_ntoa(uint32_t addr)
|
||||||
|
{
|
||||||
|
static int8_t addr_str[16];
|
||||||
|
memset(addr_str,0,16);
|
||||||
|
sprintf((char*)addr_str,"%d.%d.%d.%d",(int32_t)(addr>>24 & 0xFF),(int32_t)(addr>>16 & 0xFF),(int32_t)(addr>>8 & 0xFF),(int32_t)(addr & 0xFF));
|
||||||
|
return addr_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a 32bit Address into a Dotted Decimal Format string.
|
||||||
|
* This is differ from inet_ntoa in fixed length.
|
||||||
|
*
|
||||||
|
* @param addr 32bit address.
|
||||||
|
* @return Dotted Decimal Format string.
|
||||||
|
*/
|
||||||
|
int8_t* inet_ntoa_pad(uint32_t addr)
|
||||||
|
{
|
||||||
|
static int8_t addr_str[16];
|
||||||
|
memset(addr_str,0,16);
|
||||||
|
sprintf((char*)addr_str,"%03d.%03d.%03d.%03d",(int32_t)(addr>>24 & 0xFF),(int32_t)(addr>>16 & 0xFF),(int32_t)(addr>>8 & 0xFF),(int32_t)(addr & 0xFF));
|
||||||
|
return addr_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string containing an (Ipv4) Internet Protocol decimal dotted address into a 32bit address.
|
||||||
|
*
|
||||||
|
* @param addr Dotted Decimal Format string.
|
||||||
|
* @return 32bit address.
|
||||||
|
*/
|
||||||
|
uint32_t inet_addr(uint8_t* addr)
|
||||||
|
{
|
||||||
|
int8_t i;
|
||||||
|
uint32_t inetaddr = 0;
|
||||||
|
int8_t taddr[30];
|
||||||
|
int8_t * nexttok;
|
||||||
|
int32_t num;
|
||||||
|
strcpy((char*)taddr,(char*)addr);
|
||||||
|
|
||||||
|
nexttok = taddr;
|
||||||
|
for(i = 0; i < 4 ; i++)
|
||||||
|
{
|
||||||
|
nexttok = (int8_t*)strtok((char*)nexttok,".");
|
||||||
|
if(nexttok[0] == '0' && nexttok[1] == 'x') num = strtol((char*)nexttok+2, NULL, 16);
|
||||||
|
else num = strtol((char*)nexttok, NULL, 10);
|
||||||
|
inetaddr = inetaddr << 8;
|
||||||
|
inetaddr |= (num & 0xFF);
|
||||||
|
nexttok = NULL;
|
||||||
|
}
|
||||||
|
return inetaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swap the byte order of 16bit(short) wide variable.
|
||||||
|
*
|
||||||
|
* @param i 16bit value to swap
|
||||||
|
* @return Swapped value
|
||||||
|
*/
|
||||||
|
uint16_t swaps(uint16_t i)
|
||||||
|
{
|
||||||
|
uint16_t ret=0;
|
||||||
|
ret = (i & 0xFF) << 8;
|
||||||
|
ret |= ((i >> 8)& 0xFF);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swap the byte order of 32bit(long) wide variable.
|
||||||
|
*
|
||||||
|
* @param l 32bit value to convert
|
||||||
|
* @return Swapped value
|
||||||
|
*/
|
||||||
|
uint32_t swapl(uint32_t l)
|
||||||
|
{
|
||||||
|
uint32_t ret=0;
|
||||||
|
ret = (l & 0xFF) << 24;
|
||||||
|
ret |= ((l >> 8) & 0xFF) << 16;
|
||||||
|
ret |= ((l >> 16) & 0xFF) << 8;
|
||||||
|
ret |= ((l >> 24) & 0xFF);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* htons function converts a unsigned short from host to TCP/IP network byte order (which is big-endian).
|
||||||
|
*
|
||||||
|
* @param hostshort The value to convert.
|
||||||
|
* @return The value in TCP/IP network byte order.
|
||||||
|
*/
|
||||||
|
uint16_t htons(uint16_t hostshort)
|
||||||
|
{
|
||||||
|
#ifdef SYSTEM_LITTLE_ENDIAN
|
||||||
|
return swaps(hostshort);
|
||||||
|
#else
|
||||||
|
return hostshort;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* htonl function converts a unsigned long from host to TCP/IP network byte order (which is big-endian).
|
||||||
|
*
|
||||||
|
* @param hostlong The value to convert.
|
||||||
|
* @return The value in TCP/IP network byte order.
|
||||||
|
*/
|
||||||
|
uint32_t htonl(uint32_t hostlong)
|
||||||
|
{
|
||||||
|
#ifdef SYSTEM_LITTLE_ENDIAN
|
||||||
|
return swapl(hostlong);
|
||||||
|
#else
|
||||||
|
return hostlong;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ntohs function converts a unsigned short from TCP/IP network byte order
|
||||||
|
* to host byte order (which is little-endian on Intel processors).
|
||||||
|
*
|
||||||
|
* @param netshort The value to convert.
|
||||||
|
* @return A 16-bit number in host byte order
|
||||||
|
*/
|
||||||
|
uint32_t ntohs(uint16_t netshort)
|
||||||
|
{
|
||||||
|
#ifdef SYSTEM_LITTLE_ENDIAN
|
||||||
|
return htons(netshort);
|
||||||
|
#else
|
||||||
|
return netshort;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* converts a unsigned long from TCP/IP network byte order to host byte order
|
||||||
|
* (which is little-endian on Intel processors).
|
||||||
|
*
|
||||||
|
* @param netlong The value to convert.
|
||||||
|
* @return A 16-bit number in host byte order
|
||||||
|
*/
|
||||||
|
uint32_t ntohl(uint32_t netlong)
|
||||||
|
{
|
||||||
|
#ifdef SYSTEM_LITTLE_ENDIAN
|
||||||
|
return swapl(netlong);
|
||||||
|
#else
|
||||||
|
return netlong;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
19
Internet/TFTP/netutil.h
Normal file
19
Internet/TFTP/netutil.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#ifndef __NETUTIL_H__
|
||||||
|
#define __NETUTIL_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SYSTEM_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
int8_t* inet_ntoa(uint32_t addr);
|
||||||
|
int8_t* inet_ntoa_pad(uint32_t addr);
|
||||||
|
uint32_t inet_addr(uint8_t* addr);
|
||||||
|
uint16_t swaps(uint16_t i);
|
||||||
|
uint32_t swapl(uint32_t l);
|
||||||
|
uint16_t htons(uint16_t hostshort);
|
||||||
|
uint32_t htonl(uint32_t hostlong);
|
||||||
|
uint32_t ntohs(uint16_t netshort);
|
||||||
|
uint32_t ntohl(uint32_t netlong);
|
||||||
|
|
||||||
|
#endif
|
660
Internet/TFTP/tftp.c
Normal file
660
Internet/TFTP/tftp.c
Normal file
@ -0,0 +1,660 @@
|
|||||||
|
/**
|
||||||
|
* @file tftp.c
|
||||||
|
* @brief TFTP Source File.
|
||||||
|
* @version 0.1.0
|
||||||
|
* @author Sang-sik Kim
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes -----------------------------------------------------*/
|
||||||
|
#include <string.h>
|
||||||
|
#include "tftp.h"
|
||||||
|
#include "socket.h"
|
||||||
|
#include "netutil.h"
|
||||||
|
|
||||||
|
/* define -------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* typedef ------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Extern Variable ----------------------------------------------*/
|
||||||
|
|
||||||
|
/* Extern Functions ---------------------------------------------*/
|
||||||
|
#ifdef F_STORAGE
|
||||||
|
extern void save_data(uint8_t *data, uint32_t data_len, uint16_t block_number);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Global Variable ----------------------------------------------*/
|
||||||
|
static int g_tftp_socket = -1;
|
||||||
|
|
||||||
|
static uint8_t g_filename[FILE_NAME_SIZE];
|
||||||
|
|
||||||
|
static uint32_t g_server_ip = 0;
|
||||||
|
static uint16_t g_server_port = 0;
|
||||||
|
static uint16_t g_local_port = 0;
|
||||||
|
|
||||||
|
static uint32_t g_tftp_state = STATE_NONE;
|
||||||
|
static uint16_t g_block_num = 0;
|
||||||
|
|
||||||
|
static uint32_t g_timeout = 5;
|
||||||
|
static uint32_t g_resend_flag = 0;
|
||||||
|
static uint32_t tftp_time_cnt = 0;
|
||||||
|
static uint32_t tftp_retry_cnt = 0;
|
||||||
|
|
||||||
|
static uint8_t *g_tftp_rcv_buf = NULL;
|
||||||
|
|
||||||
|
static TFTP_OPTION default_tftp_opt = {
|
||||||
|
.code = (uint8_t *)"timeout",
|
||||||
|
.value = (uint8_t *)"5"
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t g_progress_state = TFTP_PROGRESS;
|
||||||
|
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
int dbg_level = (INFO_DBG | ERROR_DBG | IPC_DBG);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* static function define ---------------------------------------*/
|
||||||
|
static void set_filename(uint8_t *file, uint32_t file_size)
|
||||||
|
{
|
||||||
|
memcpy(g_filename, file, file_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_server_ip(uint32_t ipaddr)
|
||||||
|
{
|
||||||
|
g_server_ip = ipaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t get_server_ip()
|
||||||
|
{
|
||||||
|
return g_server_ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_server_port(uint16_t port)
|
||||||
|
{
|
||||||
|
g_server_port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t get_server_port()
|
||||||
|
{
|
||||||
|
return g_server_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_local_port(uint16_t port)
|
||||||
|
{
|
||||||
|
g_local_port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t get_local_port()
|
||||||
|
{
|
||||||
|
return g_local_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t genernate_port()
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_tftp_state(uint32_t state)
|
||||||
|
{
|
||||||
|
g_tftp_state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t get_tftp_state()
|
||||||
|
{
|
||||||
|
return g_tftp_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_tftp_timeout(uint32_t timeout)
|
||||||
|
{
|
||||||
|
g_timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t get_tftp_timeout()
|
||||||
|
{
|
||||||
|
return g_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_block_number(uint16_t block_number)
|
||||||
|
{
|
||||||
|
g_block_num = block_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t get_block_number()
|
||||||
|
{
|
||||||
|
return g_block_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_tftp_socket(uint8_t sock)
|
||||||
|
{
|
||||||
|
uint8_t sd, sck_state;
|
||||||
|
|
||||||
|
sd = socket(sock, Sn_MR_UDP, 51000, SF_IO_NONBLOCK);
|
||||||
|
if(sd != sock) {
|
||||||
|
//DBG_PRINT(ERROR_DBG, "[%s] socket error\r\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
getsockopt(sd , SO_STATUS, &sck_state);
|
||||||
|
} while(sck_state != SOCK_UDP);
|
||||||
|
|
||||||
|
return sd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_udp_packet(int socket, uint8_t *packet, uint32_t len, uint32_t ip, uint16_t port)
|
||||||
|
{
|
||||||
|
int snd_len;
|
||||||
|
|
||||||
|
ip = htonl(ip);
|
||||||
|
|
||||||
|
snd_len = sendto(socket, packet, len, (uint8_t *)&ip, port);
|
||||||
|
if(snd_len != len) {
|
||||||
|
//DBG_PRINT(ERROR_DBG, "[%s] sendto error\r\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return snd_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int recv_udp_packet(int socket, uint8_t *packet, uint32_t len, uint32_t *ip, uint16_t *port)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t sck_state;
|
||||||
|
uint16_t recv_len;
|
||||||
|
|
||||||
|
/* Receive Packet Process */
|
||||||
|
ret = getsockopt(socket, SO_STATUS, &sck_state);
|
||||||
|
if(ret != SOCK_OK) {
|
||||||
|
//DBG_PRINT(ERROR_DBG, "[%s] getsockopt SO_STATUS error\r\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sck_state == SOCK_UDP) {
|
||||||
|
ret = getsockopt(socket, SO_RECVBUF, &recv_len);
|
||||||
|
if(ret != SOCK_OK) {
|
||||||
|
//DBG_PRINT(ERROR_DBG, "[%s] getsockopt SO_RECVBUF error\r\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(recv_len) {
|
||||||
|
recv_len = recvfrom(socket, packet, len, (uint8_t *)ip, port);
|
||||||
|
if(recv_len < 0) {
|
||||||
|
//DBG_PRINT(ERROR_DBG, "[%s] recvfrom error\r\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ip = ntohl(*ip);
|
||||||
|
|
||||||
|
return recv_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_tftp_socket(int socket)
|
||||||
|
{
|
||||||
|
close(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void init_tftp(void)
|
||||||
|
{
|
||||||
|
g_filename[0] = 0;
|
||||||
|
|
||||||
|
set_server_ip(0);
|
||||||
|
set_server_port(0);
|
||||||
|
set_local_port(0);
|
||||||
|
|
||||||
|
set_tftp_state(STATE_NONE);
|
||||||
|
set_block_number(0);
|
||||||
|
|
||||||
|
/* timeout flag */
|
||||||
|
g_resend_flag = 0;
|
||||||
|
tftp_retry_cnt = tftp_time_cnt = 0;
|
||||||
|
|
||||||
|
g_progress_state = TFTP_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tftp_cancel_timeout(void)
|
||||||
|
{
|
||||||
|
if(g_resend_flag) {
|
||||||
|
g_resend_flag = 0;
|
||||||
|
tftp_retry_cnt = tftp_time_cnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tftp_reg_timeout()
|
||||||
|
{
|
||||||
|
if(g_resend_flag == 0) {
|
||||||
|
g_resend_flag = 1;
|
||||||
|
tftp_retry_cnt = tftp_time_cnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void process_tftp_option(uint8_t *msg, uint32_t msg_len)
|
||||||
|
{
|
||||||
|
/* TODO Option Process */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_tftp_rrq(uint8_t *filename, uint8_t *mode, TFTP_OPTION *opt, uint8_t opt_len)
|
||||||
|
{
|
||||||
|
uint8_t snd_buf[MAX_MTU_SIZE];
|
||||||
|
uint8_t *pkt = snd_buf;
|
||||||
|
uint32_t i, len;
|
||||||
|
|
||||||
|
*((uint16_t *)pkt) = htons(TFTP_RRQ);
|
||||||
|
pkt += 2;
|
||||||
|
strcpy((char *)pkt, (const char *)filename);
|
||||||
|
pkt += strlen((char *)filename) + 1;
|
||||||
|
strcpy((char *)pkt, (const char *)mode);
|
||||||
|
pkt += strlen((char *)mode) + 1;
|
||||||
|
|
||||||
|
for(i = 0 ; i < opt_len ; i++) {
|
||||||
|
strcpy((char *)pkt, (const char *)opt[i].code);
|
||||||
|
pkt += strlen((char *)opt[i].code) + 1;
|
||||||
|
strcpy((char *)pkt, (const char *)opt[i].value);
|
||||||
|
pkt += strlen((char *)opt[i].value) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = pkt - snd_buf;
|
||||||
|
|
||||||
|
send_udp_packet(g_tftp_socket, snd_buf, len, get_server_ip(), TFTP_SERVER_PORT);
|
||||||
|
set_tftp_state(STATE_RRQ);
|
||||||
|
set_filename(filename, strlen((char *)filename) + 1);
|
||||||
|
tftp_reg_timeout();
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, ">> TFTP RRQ : FileName(%s), Mode(%s)\r\n", filename, mode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // 2014.07.01 sskim
|
||||||
|
static void send_tftp_wrq(uint8_t *filename, uint8_t *mode, TFTP_OPTION *opt, uint8_t opt_len)
|
||||||
|
{
|
||||||
|
uint8_t snd_buf[MAX_MTU_SIZE];
|
||||||
|
uint8_t *pkt = snd_buf;
|
||||||
|
uint32_t i, len;
|
||||||
|
|
||||||
|
*((uint16_t *)pkt) = htons((uint16_t)TFTP_WRQ);
|
||||||
|
pkt += 2;
|
||||||
|
strcpy((char *)pkt, (const char *)filename);
|
||||||
|
pkt += strlen((char *)filename) + 1;
|
||||||
|
strcpy((char *)pkt, (const char *)mode);
|
||||||
|
pkt += strlen((char *)mode) + 1;
|
||||||
|
|
||||||
|
for(i = 0 ; i < opt_len ; i++) {
|
||||||
|
strcpy((char *)pkt, (const char *)opt[i].code);
|
||||||
|
pkt += strlen((char *)opt[i].code) + 1;
|
||||||
|
strcpy((char *)pkt, (const char *)opt[i].value);
|
||||||
|
pkt += strlen((char *)opt[i].value) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = pkt - snd_buf;
|
||||||
|
|
||||||
|
send_udp_packet(g_tftp_socket , snd_buf, len, get_server_ip(), TFTP_SERVER_PORT);
|
||||||
|
set_tftp_state(STATE_WRQ);
|
||||||
|
set_filename(filename, strlen((char *)filename) + 1);
|
||||||
|
tftp_reg_timeout();
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, ">> TFTP WRQ : FileName(%s), Mode(%s)\r\n", filename, mode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 // 2014.07.01 sskim
|
||||||
|
static void send_tftp_data(uint16_t block_number, uint8_t *data, uint16_t data_len)
|
||||||
|
{
|
||||||
|
uint8_t snd_buf[MAX_MTU_SIZE];
|
||||||
|
uint8_t *pkt = snd_buf;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
|
*((uint16_t *)pkt) = htons((uint16_t)TFTP_DATA);
|
||||||
|
pkt += 2;
|
||||||
|
*((uint16_t *)pkt) = htons(block_number);
|
||||||
|
pkt += 2;
|
||||||
|
memcpy(pkt, data, data_len);
|
||||||
|
pkt += data_len;
|
||||||
|
|
||||||
|
len = pkt - snd_buf;
|
||||||
|
|
||||||
|
send_udp_packet(g_tftp_socket , snd_buf, len, get_server_ip(), get_server_port());
|
||||||
|
tftp_reg_timeout();
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, ">> TFTP DATA : Block Number(%d), Data Length(%d)\r\n", block_number, data_len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void send_tftp_ack(uint16_t block_number)
|
||||||
|
{
|
||||||
|
uint8_t snd_buf[4];
|
||||||
|
uint8_t *pkt = snd_buf;
|
||||||
|
|
||||||
|
*((uint16_t *)pkt) = htons((uint16_t)TFTP_ACK);
|
||||||
|
pkt += 2;
|
||||||
|
*((uint16_t *)pkt) = htons(block_number);
|
||||||
|
pkt += 2;
|
||||||
|
|
||||||
|
send_udp_packet(g_tftp_socket , snd_buf, 4, get_server_ip(), get_server_port());
|
||||||
|
tftp_reg_timeout();
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, ">> TFTP ACK : Block Number(%d)\r\n", block_number);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // 2014.07.01 sskim
|
||||||
|
static void send_tftp_oack(TFTP_OPTION *opt, uint8_t opt_len)
|
||||||
|
{
|
||||||
|
uint8_t snd_buf[MAX_MTU_SIZE];
|
||||||
|
uint8_t *pkt = snd_buf;
|
||||||
|
uint32_t i, len;
|
||||||
|
|
||||||
|
*((uint16_t *)pkt) = htons((uint16_t)TFTP_OACK);
|
||||||
|
pkt += 2;
|
||||||
|
|
||||||
|
for(i = 0 ; i < opt_len ; i++) {
|
||||||
|
strcpy((char *)pkt, (const char *)opt[i].code);
|
||||||
|
pkt += strlen((char *)opt[i].code) + 1;
|
||||||
|
strcpy((char *)pkt, (const char *)opt[i].value);
|
||||||
|
pkt += strlen((char *)opt[i].value) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = pkt - snd_buf;
|
||||||
|
|
||||||
|
send_udp_packet(g_tftp_socket , snd_buf, len, get_server_ip(), get_server_port());
|
||||||
|
tftp_reg_timeout();
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, ">> TFTP OACK \r\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 // 2014.07.01 sskim
|
||||||
|
static void send_tftp_error(uint16_t error_number, uint8_t *error_message)
|
||||||
|
{
|
||||||
|
uint8_t snd_buf[MAX_MTU_SIZE];
|
||||||
|
uint8_t *pkt = snd_buf;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
|
*((uint16_t *)pkt) = htons((uint16_t)TFTP_ERROR);
|
||||||
|
pkt += 2;
|
||||||
|
*((uint16_t *)pkt) = htons(error_number);
|
||||||
|
pkt += 2;
|
||||||
|
strcpy((char *)pkt, (const char *)error_message);
|
||||||
|
pkt += strlen((char *)error_message) + 1;
|
||||||
|
|
||||||
|
len = pkt - snd_buf;
|
||||||
|
|
||||||
|
send_udp_packet(g_tftp_socket , snd_buf, len, get_server_ip(), get_server_port());
|
||||||
|
tftp_reg_timeout();
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, ">> TFTP ERROR : Error Number(%d)\r\n", error_number);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void recv_tftp_rrq(uint8_t *msg, uint32_t msg_len)
|
||||||
|
{
|
||||||
|
/* When TFTP Server Mode */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recv_tftp_wrq(uint8_t *msg, uint32_t msg_len)
|
||||||
|
{
|
||||||
|
/* When TFTP Server Mode */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recv_tftp_data(uint8_t *msg, uint32_t msg_len)
|
||||||
|
{
|
||||||
|
TFTP_DATA_T *data = (TFTP_DATA_T *)msg;
|
||||||
|
|
||||||
|
data->opcode = ntohs(data->opcode);
|
||||||
|
data->block_num = ntohs(data->block_num);
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, "<< TFTP_DATA : opcode(%d), block_num(%d)\r\n", data->opcode, data->block_num);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(get_tftp_state())
|
||||||
|
{
|
||||||
|
case STATE_RRQ :
|
||||||
|
case STATE_OACK :
|
||||||
|
if(data->block_num == 1) {
|
||||||
|
set_tftp_state(STATE_DATA);
|
||||||
|
set_block_number(data->block_num);
|
||||||
|
#ifdef F_STORAGE
|
||||||
|
save_data(data->data, msg_len - 4, data->block_num);
|
||||||
|
#endif
|
||||||
|
tftp_cancel_timeout();
|
||||||
|
}
|
||||||
|
send_tftp_ack(data->block_num);
|
||||||
|
|
||||||
|
if((msg_len - 4) < TFTP_BLK_SIZE) {
|
||||||
|
init_tftp();
|
||||||
|
g_progress_state = TFTP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_DATA :
|
||||||
|
if(data->block_num == (get_block_number() + 1)) {
|
||||||
|
set_block_number(data->block_num);
|
||||||
|
#ifdef F_STORAGE
|
||||||
|
save_data(data->data, msg_len - 4, data->block_num);
|
||||||
|
#endif
|
||||||
|
tftp_cancel_timeout();
|
||||||
|
}
|
||||||
|
send_tftp_ack(data->block_num);
|
||||||
|
|
||||||
|
if((msg_len - 4) < TFTP_BLK_SIZE) {
|
||||||
|
init_tftp();
|
||||||
|
g_progress_state = TFTP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
/* invalid message */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recv_tftp_ack(uint8_t *msg, uint32_t msg_len)
|
||||||
|
{
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, "<< TFTP_ACK : \r\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(get_tftp_state())
|
||||||
|
{
|
||||||
|
case STATE_WRQ :
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_ACK :
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
/* invalid message */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recv_tftp_oack(uint8_t *msg, uint32_t msg_len)
|
||||||
|
{
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, "<< TFTP_OACK : \r\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(get_tftp_state())
|
||||||
|
{
|
||||||
|
case STATE_RRQ :
|
||||||
|
process_tftp_option(msg, msg_len);
|
||||||
|
set_tftp_state(STATE_OACK);
|
||||||
|
tftp_cancel_timeout();
|
||||||
|
send_tftp_ack(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_WRQ :
|
||||||
|
process_tftp_option(msg, msg_len);
|
||||||
|
set_tftp_state(STATE_ACK);
|
||||||
|
tftp_cancel_timeout();
|
||||||
|
|
||||||
|
/* TODO DATA Transfer */
|
||||||
|
//send_tftp_data(...);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
/* invalid message */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recv_tftp_error(uint8_t *msg, uint32_t msg_len)
|
||||||
|
{
|
||||||
|
TFTP_ERROR_T *data= (TFTP_ERROR_T *)msg;
|
||||||
|
|
||||||
|
data->opcode = ntohs(data->opcode);
|
||||||
|
data->error_code = ntohs(data->error_code);
|
||||||
|
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(IPC_DBG, "<< TFTP_ERROR : %d (%s)\r\n", data->error_code, data->error_msg);
|
||||||
|
DBG_PRINT(ERROR_DBG, "[%s] Error Code : %d (%s)\r\n", __func__, data->error_code, data->error_msg);
|
||||||
|
#endif
|
||||||
|
init_tftp();
|
||||||
|
g_progress_state = TFTP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recv_tftp_packet(uint8_t *packet, uint32_t packet_len, uint32_t from_ip, uint16_t from_port)
|
||||||
|
{
|
||||||
|
uint16_t opcode;
|
||||||
|
|
||||||
|
/* Verify Server IP */
|
||||||
|
if(from_ip != get_server_ip()) {
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(ERROR_DBG, "[%s] Server IP faults\r\n", __func__);
|
||||||
|
DBG_PRINT(ERROR_DBG, "from IP : %08x, Server IP : %08x\r\n", from_ip, get_server_ip());
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
opcode = ntohs(*((uint16_t *)packet));
|
||||||
|
|
||||||
|
/* Set Server Port */
|
||||||
|
if((get_tftp_state() == STATE_WRQ) || (get_tftp_state() == STATE_RRQ)) {
|
||||||
|
set_server_port(from_port);
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(INFO_DBG, "[%s] Set Server Port : %d\r\n", __func__, from_port);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(opcode)
|
||||||
|
{
|
||||||
|
case TFTP_RRQ : /* When Server */
|
||||||
|
recv_tftp_rrq(packet, packet_len);
|
||||||
|
break;
|
||||||
|
case TFTP_WRQ : /* When Server */
|
||||||
|
recv_tftp_wrq(packet, packet_len);
|
||||||
|
break;
|
||||||
|
case TFTP_DATA :
|
||||||
|
recv_tftp_data(packet, packet_len);
|
||||||
|
break;
|
||||||
|
case TFTP_ACK :
|
||||||
|
recv_tftp_ack(packet, packet_len);
|
||||||
|
break;
|
||||||
|
case TFTP_OACK :
|
||||||
|
recv_tftp_oack(packet, packet_len);
|
||||||
|
break;
|
||||||
|
case TFTP_ERROR :
|
||||||
|
recv_tftp_error(packet, packet_len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
// Unknown Mesage
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Functions ----------------------------------------------------*/
|
||||||
|
void TFTP_init(uint8_t socket, uint8_t *buf)
|
||||||
|
{
|
||||||
|
init_tftp();
|
||||||
|
|
||||||
|
g_tftp_socket = open_tftp_socket(socket);
|
||||||
|
g_tftp_rcv_buf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TFTP_exit(void)
|
||||||
|
{
|
||||||
|
init_tftp();
|
||||||
|
|
||||||
|
close_tftp_socket(g_tftp_socket);
|
||||||
|
g_tftp_socket = -1;
|
||||||
|
|
||||||
|
g_tftp_rcv_buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TFTP_run(void)
|
||||||
|
{
|
||||||
|
uint16_t len, from_port;
|
||||||
|
uint32_t from_ip;
|
||||||
|
|
||||||
|
/* Timeout Process */
|
||||||
|
if(g_resend_flag) {
|
||||||
|
if(tftp_time_cnt >= g_timeout) {
|
||||||
|
switch(get_tftp_state()) {
|
||||||
|
case STATE_WRQ: // 미구현
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_RRQ:
|
||||||
|
send_tftp_rrq(g_filename, (uint8_t *)TRANS_BINARY, &default_tftp_opt, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_OACK:
|
||||||
|
case STATE_DATA:
|
||||||
|
send_tftp_ack(get_block_number());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_ACK: // 미구현
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tftp_time_cnt = 0;
|
||||||
|
tftp_retry_cnt++;
|
||||||
|
|
||||||
|
if(tftp_retry_cnt >= 5) {
|
||||||
|
init_tftp();
|
||||||
|
g_progress_state = TFTP_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Receive Packet Process */
|
||||||
|
len = recv_udp_packet(g_tftp_socket, g_tftp_rcv_buf, MAX_MTU_SIZE, &from_ip, &from_port);
|
||||||
|
if(len < 0) {
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(ERROR_DBG, "[%s] recv_udp_packet error\r\n", __func__);
|
||||||
|
#endif
|
||||||
|
return g_progress_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
recv_tftp_packet(g_tftp_rcv_buf, len, from_ip, from_port);
|
||||||
|
|
||||||
|
return g_progress_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TFTP_read_request(uint32_t server_ip, uint8_t *filename)
|
||||||
|
{
|
||||||
|
set_server_ip(server_ip);
|
||||||
|
#ifdef __TFTP_DEBUG__
|
||||||
|
DBG_PRINT(INFO_DBG, "[%s] Set Tftp Server : %x\r\n", __func__, server_ip);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_progress_state = TFTP_PROGRESS;
|
||||||
|
send_tftp_rrq(filename, (uint8_t *)TRANS_BINARY, &default_tftp_opt, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tftp_timeout_handler(void)
|
||||||
|
{
|
||||||
|
if(g_resend_flag)
|
||||||
|
tftp_time_cnt++;
|
||||||
|
}
|
93
Internet/TFTP/tftp.h
Normal file
93
Internet/TFTP/tftp.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* @file tftp.h
|
||||||
|
* @brief TFTP Header File.
|
||||||
|
* @version 0.1.0
|
||||||
|
* @author Sang-sik Kim
|
||||||
|
*/
|
||||||
|
#ifndef __TFTP_H__
|
||||||
|
#define __TFTP_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define F_APP_TFTP
|
||||||
|
#define __TFTP_DEBUG__
|
||||||
|
|
||||||
|
#define F_STORAGE // If your target support a storage, you have to activate this feature and implement.
|
||||||
|
|
||||||
|
#define SOCK_TFTP 1
|
||||||
|
|
||||||
|
#define INFO_DBG 0x01
|
||||||
|
#define ERROR_DBG 0x02
|
||||||
|
#define DEBUG_DBG 0x04
|
||||||
|
#define IPC_DBG 0x08
|
||||||
|
|
||||||
|
#define DBG_PRINT(level, format, args...) { \
|
||||||
|
if(dbg_level & level) \
|
||||||
|
printf(format, ##args); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NORMAL_MODE 0
|
||||||
|
#define TFTP_MODE 1
|
||||||
|
|
||||||
|
extern int dbg_level;
|
||||||
|
|
||||||
|
/* tftp message */
|
||||||
|
#define TFTP_RRQ 1
|
||||||
|
#define TFTP_WRQ 2
|
||||||
|
#define TFTP_DATA 3
|
||||||
|
#define TFTP_ACK 4
|
||||||
|
#define TFTP_ERROR 5
|
||||||
|
#define TFTP_OACK 6
|
||||||
|
|
||||||
|
/* tftp state */
|
||||||
|
#define STATE_NONE 0
|
||||||
|
#define STATE_RRQ 1
|
||||||
|
#define STATE_WRQ 2
|
||||||
|
#define STATE_DATA 3
|
||||||
|
#define STATE_ACK 4
|
||||||
|
#define STATE_OACK 5
|
||||||
|
|
||||||
|
/* tftp transfer mode */
|
||||||
|
#define TRANS_ASCII "netascii"
|
||||||
|
#define TRANS_BINARY "octet"
|
||||||
|
|
||||||
|
/* tftp progress state */
|
||||||
|
#define TFTP_PROGRESS 0
|
||||||
|
#define TFTP_FAIL 1
|
||||||
|
#define TFTP_SUCCESS 2
|
||||||
|
|
||||||
|
/* define */
|
||||||
|
#define TFTP_SERVER_PORT 69
|
||||||
|
#define TFTP_TEMP_PORT 51000
|
||||||
|
#define TFTP_BLK_SIZE 512
|
||||||
|
#define MAX_MTU_SIZE 1514
|
||||||
|
#define FILE_NAME_SIZE 20
|
||||||
|
|
||||||
|
//#define __TFTP_DEBUG__
|
||||||
|
|
||||||
|
/* typedef */
|
||||||
|
typedef struct tftp_data {
|
||||||
|
uint16_t opcode;
|
||||||
|
uint16_t block_num;
|
||||||
|
uint8_t data[0];
|
||||||
|
} TFTP_DATA_T;
|
||||||
|
|
||||||
|
typedef struct tftp_error {
|
||||||
|
uint16_t opcode;
|
||||||
|
uint16_t error_code;
|
||||||
|
uint8_t error_msg[0];
|
||||||
|
} TFTP_ERROR_T;
|
||||||
|
|
||||||
|
typedef struct tftp_option {
|
||||||
|
uint8_t *code;
|
||||||
|
uint8_t *value;
|
||||||
|
} TFTP_OPTION;
|
||||||
|
|
||||||
|
/* Functions */
|
||||||
|
void TFTP_init(uint8_t socket, uint8_t *buf);
|
||||||
|
void TFTP_exit(void);
|
||||||
|
int TFTP_run(void);
|
||||||
|
void TFTP_read_request(uint32_t server_ip, uint8_t *filename);
|
||||||
|
void tftp_timeout_handler(void);
|
||||||
|
|
||||||
|
#endif /*__TFTP_H__ */
|
Reference in New Issue
Block a user