網頁

2017年8月30日 星期三

SSL 網路程式設計

請參考 Raspberry OPENSSL 根證書 伺服端 客戶端 產生所有需要的檔案

sudo apt-get install libssl-dev

伺服器端程式
gcc server.c -o server -lcrypto -lssl
vi server.c
#include "openssl/bio.h"  
#include "openssl/ssl.h"  
#include "openssl/err.h" 

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define SERVER_PORT 8080
#define CA_CERT_FILE "../openssl/ca/ca.crt"
#define SERVER_CERT_FILE "../openssl/server/server.crt"
#define SERVER_KEY_FILE "../openssl/server/server.key"

typedef struct sockaddr SA;

int TcpInit()
{
    int listener;
    do{
        listener = socket(AF_INET, SOCK_STREAM, 0);
        if( listener == -1 )
            return 0;

        struct sockaddr_in sin;
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = 0;
        sin.sin_port = htons(SERVER_PORT);

        if( bind(listener, (SA*)&sin, sizeof(sin)) < 0 )
            break;

        if( listen(listener, 5) < 0)
            break;

        return listener;
    }while(0);

    return -1;
}

void print_peer_certificate(SSL *ssl)
{  
    X509* cert= NULL;  
    X509_NAME *name=NULL;  
    char buf[8192]={0};  
    BIO *bio_cert = NULL;  
    cert = SSL_get_peer_certificate(ssl);
    if (cert == NULL) {
        printf("SSL_get_peer_certificate() == NULL\n");  
        return;
    }
    if (SSL_get_verify_result(ssl) == X509_V_OK) {
        printf("SSL_get_verify_result(ssl) == X509_V_OK\n");  
    }
    name = X509_get_subject_name(cert);  
    X509_NAME_oneline(name,buf,8191);  
    printf("ServerSubjectName:%s\n",buf);  
    memset(buf,0,sizeof(buf));  
    bio_cert = BIO_new(BIO_s_mem());  
    PEM_write_bio_X509(bio_cert, cert);  
    BIO_read( bio_cert, buf, 8191);  
    printf("SERVER CERT:\n%s\n",buf);  
    if(bio_cert)BIO_free(bio_cert);  
    if(cert)X509_free(cert);  
}


static int verify_cb(int res, X509_STORE_CTX *xs)  
{  
    printf("SSL VERIFY RESULT :%d\n",res);  
    switch (xs->error)  
    {  
        case X509_V_ERR_UNABLE_TO_GET_CRL:  
            printf(" NOT GET CRL!\n");  
            return 1;  
        default :  
            break;  
    }  
    return res;  
}

int main(int argc, char **argv)  
{  
    SSL_CTX     *ctx;  
    SSL         *ssl;  
    X509        *client_cert;  
    char szBuffer[1024];  
    int nLen;  
    struct sockaddr_in addr;   
    int nListenFd, nAcceptFd;  

    nListenFd = TcpInit();
    SSLeay_add_ssl_algorithms();  
    OpenSSL_add_all_algorithms();  
    SSL_load_error_strings();  
    ERR_load_BIO_strings();  

    memset(&addr, 0, sizeof(addr));
    int len = sizeof(addr);
    nAcceptFd = accept(nListenFd, (struct sockaddr *)&addr, &len);   
    //int iMode = 1;
    //int iret = ioctlsocket(nAcceptFd, FIONBIO, (u_long FAR*)&iMode); 
    ctx = SSL_CTX_new (SSLv23_method());
    if( ctx == NULL)
    {
        printf("SSL_CTX_new error!\n");
        return -1;
    }

#define USE_CA_CERT
#ifdef USE_CA_CERT
// 使用 CA_CERT_FILE 檢查 Client 端的證書
    printf("SSL_CTX_set_verify(SSL_VERIFY_PEER)\n");
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);  

    if(!SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, NULL))
    {
        printf("SSL_CTX_load_verify_locations error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }
#else
    printf("SSL_CTX_set_verify(SSL_VERIFY_NONE)\n");
    SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);  
#endif

    if(SSL_CTX_use_certificate_file(ctx, SERVER_CERT_FILE, SSL_FILETYPE_PEM) <= 0)
    {
        printf("SSL_CTX_use_certificate_file error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }

    if(SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_FILE, SSL_FILETYPE_PEM) <= 0)
    {
        printf("SSL_CTX_use_PrivateKey_file error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }

    if(!SSL_CTX_check_private_key(ctx))
    {
        printf("SSL_CTX_check_private_key error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }
    ssl = SSL_new (ctx);
    if(!ssl)
    {
        printf("SSL_new error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }
    SSL_set_fd (ssl, nAcceptFd); 
    while(1){
        if(SSL_accept (ssl) != 1)
        {
            int icode = -1;
            ERR_print_errors_fp(stderr);
            int iret = SSL_get_error(ssl, icode);
            printf("SSL_accept error! code = %d, iret = %d\n", icode, iret);
            break;
        } else
            break;
    }
    print_peer_certificate(ssl);

    memset(szBuffer, 0, sizeof(szBuffer));  
    nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));  
    fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);  
    strcat(szBuffer, "\n this is from server========server resend to client");  
    SSL_write(ssl, szBuffer, strlen(szBuffer));  

    SSL_free (ssl);  
    SSL_CTX_free (ctx);  
    close(nAcceptFd);  
}

客戶端程式
gcc client.c -o client -lcrypto -lssl
vi client.c
#include "openssl/bio.h"  
#include "openssl/ssl.h"  
#include "openssl/err.h" 


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define SERVER_PORT 8080
#define SERVER_IP "127.0.0.1"


#define CA_CERT_FILE "../openssl/ca/ca.crt"
#define CLIENT_CERT_FILE "../openssl/client/client.crt"
#define CLIENT_KEY_FILE "../openssl/client/client.key"

void print_client_cert(char* path)  
{  
    X509 *cert =NULL;  
    FILE *fp = NULL;  
    fp = fopen(path,"rb");  
    cert = PEM_read_X509(fp, NULL, NULL, NULL);  
    X509_NAME *name=NULL;  
    char buf[8192]={0};  
    BIO *bio_cert = NULL;  
    name = X509_get_subject_name(cert);  
    X509_NAME_oneline(name,buf,8191);  
    printf("ClientSubjectName:%s\n",buf);  
    memset(buf,0,sizeof(buf));  
    bio_cert = BIO_new(BIO_s_mem());  
    PEM_write_bio_X509(bio_cert, cert);  
    BIO_read( bio_cert, buf, 8191);  
    printf("CLIENT CERT:\n%s\n",buf);  
    if(bio_cert)BIO_free(bio_cert);  
    fclose(fp);  
    if(cert) X509_free(cert);  
}

void print_peer_certificate(SSL *ssl)  
{  
    X509* cert= NULL;  
    X509_NAME *name=NULL;  
    char buf[8192]={0};  
    BIO *bio_cert = NULL;  
    cert = SSL_get_peer_certificate(ssl);
    if (cert == NULL) {
        printf("SSL_get_peer_certificate() == NULL\n");
        return;
    }
    if (SSL_get_verify_result(ssl) == X509_V_OK) {
        printf("SSL_get_verify_result(ssl) == X509_V_OK\n");  
    }
    name = X509_get_subject_name(cert);  
    X509_NAME_oneline(name,buf,8191);  
    printf("ServerSubjectName:%s\n",buf);  
    memset(buf,0,sizeof(buf));  
    bio_cert = BIO_new(BIO_s_mem());  
    PEM_write_bio_X509(bio_cert, cert);  
    BIO_read( bio_cert, buf, 8191);  
    printf("SERVER CERT:\n%s\n",buf);  
    if(bio_cert)BIO_free(bio_cert);  
    if(cert)X509_free(cert);  
}

static int verify_cb(int res, X509_STORE_CTX *xs)  
{  
    printf("SSL VERIFY RESULT :%d\n",res);  
    switch (xs->error)  
    {  
        case X509_V_ERR_UNABLE_TO_GET_CRL:  
            printf(" NOT GET CRL!\n");  
            return 1;  
        default :  
            break;  
    }  
    return res;  
}

int main(int argc, char **argv)  
{  
    char *address = SERVER_IP;

    if(argc > 1)
    {
        address = argv[1];
    }

    SSL_METHOD  *meth;  
    SSL_CTX     *ctx;  
    SSL         *ssl;  

    int nFd;  
    int nLen;  
    char szBuffer[1024];  

    SSLeay_add_ssl_algorithms();  
    OpenSSL_add_all_algorithms();  
    SSL_load_error_strings();  
    ERR_load_BIO_strings();  

    print_client_cert(CLIENT_CERT_FILE);

    // 使用SSL V3,V2  
    ctx = SSL_CTX_new (SSLv23_method());
    if( ctx == NULL)
    {
        printf("SSL_CTX_new error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }

#define USE_CA_CERT
#ifdef USE_CA_CERT
// 使用 CA_CERT_FILE 檢查 Server 端的證書
    printf("SSL_CTX_set_verify(SSL_VERIFY_PEER)\n");
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb);  

    if(!SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, NULL))
    {
        printf("SSL_CTX_load_verify_locations error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }
#else
    printf("SSL_CTX_set_verify(SSL_VERIFY_NONE)\n");
    SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);  
#endif

#define USE_CERT
#ifdef USE_CERT
    printf("SSL_CTX_use_certificate_file start!\n");
    if(SSL_CTX_use_certificate_file(ctx, CLIENT_CERT_FILE, SSL_FILETYPE_PEM) <= 0)
    {
        printf("SSL_CTX_use_certificate_file error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }

    printf("SSL_CTX_use_PrivateKey_file start!\n");
    if(SSL_CTX_use_PrivateKey_file(ctx, CLIENT_KEY_FILE, SSL_FILETYPE_PEM) <= 0)
    {
     printf("SSL_CTX_use_PrivateKey_file error!\n");
     ERR_print_errors_fp(stderr);
     return -1;
    }

    if(!SSL_CTX_check_private_key(ctx))
    {
     printf("SSL_CTX_check_private_key error!\n");
     ERR_print_errors_fp(stderr);
     return -1;
    }
#endif

    nFd = socket(AF_INET, SOCK_STREAM, 0); 

    struct sockaddr_in addr; 
    addr.sin_addr.s_addr = inet_addr(address);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(SERVER_PORT);

    if(connect(nFd, (struct sockaddr *)&addr, sizeof(addr)) < 0)  
    {  
        printf("connect\n"); 
        ERR_print_errors_fp(stderr);
        return -1;  
    }  

    ssl = SSL_new (ctx);
    if( ssl == NULL)
    {
        printf("SSL_new error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }
    SSL_set_fd (ssl, nFd);  
    if( SSL_connect (ssl) != 1)
    {
        printf("SSL_new error!\n");
        ERR_print_errors_fp(stderr);
        return -1;
    }

    print_peer_certificate(ssl);

    sprintf(szBuffer, "\nthis is from client+++++++++++++++client send to server");  
    SSL_write(ssl, szBuffer, strlen(szBuffer));  

    memset(szBuffer, 0, sizeof(szBuffer));  
    nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));  
    fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);  

    SSL_free (ssl);  
    SSL_CTX_free (ctx);  
    close(nFd);     
}



2017年8月29日 星期二

Raspberry OPENSSL 根證書 伺服端 客戶端

準備設定檔
pi@raspberrypi:~/OpenSSL/openssl $ cp /etc/ssl/openssl.cnf .
pi@raspberrypi:~/OpenSSL/openssl $ mkdir ca server client
pi@raspberrypi:~/OpenSSL/openssl $
產生根私鑰
pi@raspberrypi:~/OpenSSL/openssl $ openssl genrsa -out ca/ca.key 2048
Generating RSA private key, 2048 bit long modulus
..............................................................................................+++
......+++
e is 65537 (0x10001)
產生根證書
pi@raspberrypi:~/OpenSSL/openssl $ openssl req -new -x509 -key ca/ca.key -out ca
/ca.crt -days 3650
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:TW
State or Province Name (full name) [Some-State]:Taiwan
Locality Name (eg, city) []:Taichung
Organization Name (eg, company) [Internet Widgits Pty Ltd]:SDL
Organizational Unit Name (eg, section) []:R&D
Common Name (e.g. server FQDN or YOUR name) []:PiCA
Email Address []:
pi@raspberrypi:~/OpenSSL/openssl $ ls ca
ca.crt  ca.key
pi@raspberrypi:~/OpenSSL/openssl $
產生伺服端私鑰
pi@raspberrypi:~/OpenSSL/openssl $ openssl genrsa -out server/server.key 2048
Generating RSA private key, 2048 bit long modulus
.............................+++
..............+++
e is 65537 (0x10001)
產生伺服端需求證書
pi@raspberrypi:~/OpenSSL/openssl $ openssl req -new -key server/server.key -out server/server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:TW
State or Province Name (full name) [Some-State]:Taiwan
Locality Name (eg, city) []:Taichung
Organization Name (eg, company) [Internet Widgits Pty Ltd]:SDL
Organizational Unit Name (eg, section) []:R&D
Common Name (e.g. server FQDN or YOUR name) []:PiServer
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
pi@raspberrypi:~/OpenSSL/openssl $ ls server/
server.csr  server.key
pi@raspberrypi:~/OpenSSL/openssl $
產生客戶端私鑰
pi@raspberrypi:~/OpenSSL/openssl $ openssl genrsa -out client/client.key 2048
Generating RSA private key, 2048 bit long modulus
..............................................+++
....................................+++
e is 65537 (0x10001)
產生客戶端需求證書
pi@raspberrypi:~/OpenSSL/openssl $ openssl req -new -key client/client.key -out
client/client.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:TW
State or Province Name (full name) [Some-State]:Taiwan
Locality Name (eg, city) []:Taichung
Organization Name (eg, company) [Internet Widgits Pty Ltd]:SDL
Organizational Unit Name (eg, section) []:R&D
Common Name (e.g. server FQDN or YOUR name) []:PiClient
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
pi@raspberrypi:~/OpenSSL/openssl $ ls client/
client.csr  client.key
pi@raspberrypi:~/OpenSSL/openssl $
修改 dir 目錄
pi@raspberrypi:~/OpenSSL/openssl $ vi openssl.cnf
[ CA_default ]

#dir            = ./demoCA              # Where everything is kept
dir             = .             # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
#unique_subject = no                    # Set to 'no' to allow creation of
pi@raspberrypi:~/OpenSSL/openssl $
簽署證書環境準備
pi@raspberrypi:~/OpenSSL/openssl $ touch index.txt
pi@raspberrypi:~/OpenSSL/openssl $ echo "01">serial
pi@raspberrypi:~/OpenSSL/openssl $ mkdir newcerts
簽署伺服端證書
pi@raspberrypi:~/OpenSSL/openssl $ openssl ca -in server/server.csr -out server/server.crt -days 3650 -cert ca/ca.crt -keyfile ca/ca.key -config openssl.cnf
Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Aug 29 02:08:38 2017 GMT
            Not After : Aug 27 02:08:38 2027 GMT
        Subject:
            countryName               = TW
            stateOrProvinceName       = Taiwan
            organizationName          = SDL
            organizationalUnitName    = R&D
            commonName                = PiServer
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                4D:26:A0:55:4D:37:58:EE:10:D3:A0:8E:B8:93:35:E9:E5:84:1F:BC
            X509v3 Authority Key Identifier:
                keyid:F4:6D:3E:3D:93:2A:4A:81:85:62:C3:D7:4B:70:F9:28:F6:E6:A4:F4

Certificate is to be certified until Aug 27 02:08:38 2027 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
pi@raspberrypi:~/OpenSSL/openssl $ ls server/
server.crt  server.csr  server.key
pi@raspberrypi:~/OpenSSL/openssl $
簽署客戶端證書
pi@raspberrypi:~/OpenSSL/openssl $ openssl ca -in client/client.csr -out client/
client.crt -days 3650 -cert ca/ca.crt -keyfile ca/ca.key -config openssl.cnf
Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Aug 29 02:12:26 2017 GMT
            Not After : Aug 27 02:12:26 2027 GMT
        Subject:
            countryName               = TW
            stateOrProvinceName       = Taiwan
            organizationName          = SDL
            organizationalUnitName    = R&D
            commonName                = PiClient
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                45:1F:CC:47:19:FF:37:04:7A:8D:40:B8:1E:CA:08:11:36:E0:E7:EF
            X509v3 Authority Key Identifier:
                keyid:F4:6D:3E:3D:93:2A:4A:81:85:62:C3:D7:4B:70:F9:28:F6:E6:A4:F4

Certificate is to be certified until Aug 27 02:12:26 2027 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
pi@raspberrypi:~/OpenSSL/openssl $ ls client/
client.crt  client.csr  client.key
pi@raspberrypi:~/OpenSSL/openssl $
pi@raspberrypi:~/OpenSSL/openssl $ ls
ca      index.txt       index.txt.attr.old  newcerts     serial      server
client  index.txt.attr  index.txt.old       openssl.cnf  serial.old
pi@raspberrypi:~/OpenSSL/openssl $


2017年8月23日 星期三

HDMI 開關

關閉
sudo /opt/vc/bin/tvservice -o

開啟
sudo /opt/vc/bin/tvservice -p

約可省下 20-30mA

2017年8月2日 星期三

Raspberry & DS3231 RTC

由安裝作業系統後開始
Localisation Options/I1 Chance Locale
zh_TW.UTF-8 UTF-8
Localisation Options/I2 Chance Timezone
Asia/Taipei
Interfacing Options/P5 I2C

測試 I2C 上的裝置
sudo i2cdetect -y 1

sudo vi /etc/modules
#rtc-ds3231

sudo vi /boot/config.txt
dtoverlay=i2c-rtc,ds3231

sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get purge fake-hwclock
sudo apt-get -y remove fake-hwclock
sudo update-rc.d -f fake-hwclock remove
sudo systemctl stop fake-hwclock.service
sudo update-rc.d fake-hwclock disable S 6

hwclock
-r 讀取時間
-w 系統時間 寫入 RTC
-s 以 RTC 更新 系統時間
sudo hwclock -r;date '+%a %d %b %Y %02l:%M:%S %p'
ntptime

同步網路時間
sudo ntpd -s -d


開機產生的錯誤訊息
pi@raspberrypi:~ $ systemctl status systemd-modules-load.service
● systemd-modules-load.service - Load Kernel Modules
   Loaded: loaded (/lib/systemd/system/systemd-modules-load.service; static)
   Active: failed (Result: exit-code) since Thu 1970-01-01 08:00:03 CST; 47 years 6 months ago
     Docs: man:systemd-modules-load.service(8)
           man:modules-load.d(5)
  Process: 113 ExecStart=/lib/systemd/systemd-modules-load (code=exited, status=1/FAILURE)
 Main PID: 113 (code=exited, status=1/FAILURE)


alias gshutdown='gpio mode 7 out'

解決與 witty 電源控制模組衝突
vi /etc/init.d/witty
#       sudo /home/pi/WittyPi/wittyPi/runScript.sh >> /home/pi/WittyPi/wittyPi/schedule.log &
#       sudo /home/pi/WittyPi/wittyPi/syncTime.sh 5 &

vi wittyPi/utilities.sh
is_rtc_connected()
{
return 1
...
}

2017年6月15日 星期四

Witty Pi 電源管理

Raspberry Pi 沒有電源管理,必須要 shutdown 完成後才能關機,以免傷害檔案系統
Witty Pi 可以提供相關的功能


Witty Pi 需要軟體配合
pi@raspberrypi:~ $ wget!http://www.uugear.com/repo/WittyPi/installWittyPi.sh
pi@raspberrypi:~ $ sudo!sh!installWittyPi.sh

GPIO-17: LED
GPIO-4: 開關按鈕,若拉此腳為 LOW, 開始關機程序
若要更改 GPIO, 也要修改 /home/pi/wittyPi/daemon.sh 的 halt_pin 和 led_pin
不是所有腳位可以當 helt_pin, 需要
1. 開機預設為輸入
2. 預設狀態為 HIGH
可執行下列命令,查詢可用腳位
pi@raspberrypi:~/wittyPi $ gpio readall
如 GPIO-8(wiringPi pin 10)

不要使用 sudo shutdown -h now, 使用 gpio mode 7 out

使用 pin 腳
(3)GPIO-2: SDA1
(5)GPIO-3: SCL1
(7)GPIO-4:
(11)GPIO-17:
(8)GPIO-14:TXD

GPIO-14 非常特別,不能更換,開機後預設為HIGH, 關機後為LOW
Witty Pi 使用它來偵測 Raspberry Pi 的狀態

Raspberry Pi 3 新增藍芽裝置,藍芽對應UART0, GPIO-14 和 GPIO-15 對應 UART1
預設 Raspberry Pi 2
pi@raspberrypi:~ $ ls -al /dev/serial*
lrwxrwxrwx 1 root root 7 Jun 15 11:40 /dev/serial1 -> ttyAMA0
修改 /boot/config.txt, 單純使用 console
enable_uart=1
pi@raspberrypi:~ $ ls -al /dev/serial*
lrwxrwxrwx 1 root root 5 Jun 15 12:06 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root 7 Jun 15 12:06 /dev/serial1 -> ttyAMA0
修改 /boot/config.txt, 讓藍芽使用 mini-uart(/dev/ttyS0)
dtoverlay=pi3-miniuart-bt
pi@raspberrypi:~ $ ls -al /dev/serial*
lrwxrwxrwx 1 root root 7 Jun 15 11:40 /dev/serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 Jun 15 11:40 /dev/serial1 -> ttyS0

Raspberry Pi 網路設定

/etc/network/interfaces
---------------------------------
iface eth0 inet manual
allow-hotplug wlan0
iface wlan0 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
---------------------------------

/etc/wpa_supplicant/wpa_supplicant.conf
---------------------------------
country=TW
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
  ssid="SSID2"
  psk="password"
  key_mgmt=WPA-PSK
  priority=2
  id_str="id_SSID2"
}

network={
  ssid="SSID1"
  key_mgmt=NONE
  priority=1
  id_str="id_SSID1"
}
---------------------------------

/etc/dhcpcd.conf
---------------------------------
nohook lookup-hostname

interface eth0
static ip_address=192.168.1.61
netmask 255.255.255.0
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

interface wlan0
SSID DigiChance
static ip_address=192.168.1.60
netmask 255.255.255.0
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
---------------------------------

iwconfig wlan0 #查看目前無線網路設定
iwlist wlan0 scan #掃描無線網路
ifdown wlan0 #停用無線網路
ifup wlan0 #啟動無線網路


ssh 預設帳號
pi/raspberry


2017年5月24日 星期三

Arduino Yun 網路

Arduino Yun 也可同時啟動 AP+STA 模式,但測試時花了很多時間
因為 Arduino Yun 真的比 Linkit 7688 慢很多

回復AP模式或出廠值
1. 使用 WLAN 按鈕
按5秒,wifi 回AP模式 SSID=Arduino-Yun-XXXXXXXXXXXX, IP=192.168.240.1
按30秒,linux 環境回復出廠值,清除板上的 Flash 記憶體
2. 登入作業系統,使用命令
wifi-reset-and-reboot
reset-to-factory-anyway

wifi-reset-and-reboot 中加入下一行,才能正確回復AP模式
$UCI "delete" "wireless.@wifi-iface[1]"

設定檔位於 /etc/config
dhcp, network, wireless, firewall

使用網頁 (Arduino Luci)設定,新增 Wi-Fi Station 網路
Network/Wifi/Scan
Join Network
取消勾選 An additional network will be created if you leave this unchecked.
沒有取消勾選,會導致 AP 網路被取消掉

uci set wireless.@wifi-iface[1].ssid='DigiChance'
uci set wireless.@wifi-iface[1].key='xxxxx'
uci set wireless.@wifi-iface[1].encryption='psk2'
uci set wireless.@wifi-iface[1].bssid='B8:55:10:56:05:20'
uci commit wireless

uci set network.wwan.proto='static'
uci set network.wwan.ipaddr='192.168.1.60'
uci set network.wwan.netmask='255.255.255.0'
uci set network.wwan.gateway='192.168.1.1'
uci set network.wwan.dns='192.168.1.1'
uci commit network

修改完執行
/etc/init.d/network restart

相關命令
wifi up
wifi down
wifi status
ifconfig
ifconfig eth1 up
ifconfig eth1 down
ifconfig eth1 192.168.1.61 netmask 255.255.255.0
ifup EWAN // 參考 /etc/config/network
ifdown EWAN // 參考 /etc/config/network

同時啟動 ap+sta 模式,網路不用密碼,使用 MAC filter,會出問題,一直找不到如何解決
1. 不用密碼命令
uci set wireless.@wifi-iface[1].encryption='none'
2. MAC filter 似乎會檢查 BSSID
uci set wireless.@wifi-iface[1].bssid='B8:55:10:56:05:20'
3. 切開不同的網段,似乎能解決問題,但不同網段
uci set network.wwan.ipaddr='192.168.3.60'

若開機時沒接上有線網路,會導致無線網路開不起來
停止網路
uci set network.EWAN.auto='0'
開機後(無線網路啟動後)再啟動有線網路
編輯 /etc/rc.local
加入
ifconfig eth1 192.168.1.61 netmask 255.255.255.0
ifup wan
ifup EWAN

uci delete wireless.@wifi-iface[1]
uci add wireless wifi-iface
uci set wireless.@wifi-iface[1].network='wwan'
uci set wireless.@wifi-iface[1].device='radio0'
uci set wireless.@wifi-iface[1].mode='sta'
uci set wireless.@wifi-iface[1].ssid='DigiChance'
uci set wireless.@wifi-iface[1].key='22463458'
uci set wireless.@wifi-iface[1].encryption='psk2'
uci set wireless.@wifi-iface[1].bssid='B8:55:10:56:05:20'
uci commit wireless

uci delete network.wwan
uci add network interface
uci rename network.@interface[-1]='wwan'
uci set network.wwan._orig_ifname='wlan0-1'
uci set network.wwan._orig_bridge='false'
uci set network.wwan.proto='static'
uci set network.wwan.ipaddr='192.168.1.60'
uci set network.wwan.netmask='255.255.255.0'
uci set network.wwan.gateway='192.168.1.1'
uci set network.wwan.dns='192.168.1.1'
uci commit network

uci delete network.ewan
uci add network interface
uci rename network.@interface[-1]='ewan'
uci set network.ewan.ifname='eth1'
uci set network.ewan._orig_ifname='eth1-1'
uci set network.ewan.proto='static'
uci set network.ewan.ipaddr='192.168.1.61'
uci set network.ewan.netmask='255.255.255.0'
uci set network.ewan.gateway='192.168.1.1'
uci set network.ewan.dns='192.168.1.1'
uci commit network

wifi-reset-and-reboot 中加入
$UCI "delete" "wireless.@wifi-iface[1]"