2.6 设置vncserver
首先
apt-get update
然后,
apt-get install tightvncserver
然后vncserver设置启动窗口,设置登录访问密码等
我的这次木有成功,主要是展示一下如何做,是有些packages 没有装好,而且有些包装重复了。这个以后再弄。
3.3 配置AWS SDK,这个是AWS CLI,就是键盘敲打模式,不让用图形方式。
首先安装Arrow Electronics AWS-demo,命令如下
$ cd ~
$ git clone https://github.com/ArrowElectronics/aws-iot-device-sdk.git
$ cd aws-iot-device-sdk/scripts
$ ./install.sh
不过到现在,还没有把git安装上,于是乎
换条路线,安装依赖包
$ sudo apt-get update $ sudo apt-get -y install python-pip libperl-dev libgtk2.0-dev $ pip install awscli
安装完了AWS CLI
4 配置云端访问
4.1 AWS的权限登录
说明,使用命令是AWSCLI的 aws configure,然后依次出现以下信息,
AWS Access Key ID [None]: <enter Access Key Id>(这个是登录的用户名,是个人信息里面的一组数字ID组成的)
AWS Secret Access Key [None]: <enter Secret Access Key> (正式是验证的安全码,在IAM服务页找,然后复制)
Default region name [None]: us-east-1 (这个是开放的美国东1区,不是每个区都支持所以服务的)
Default output format [None]: <leave blank and just press enter/return>(可以留空不写)
4.2 创建目录并下载程序
创建目录
$ mkdir -p /home/linaro/Documents/arrow
进入该目录
$ cd /home/linaro/Documents/arrow
然后git clone范例程序
$ git clone https://github.com/ArrowElectronics/aws-iot-dragonconnect-c.git
$ cd aws-iot-dragonconnect-c/
运行setup script
$ cd scripts
$ ./setup.sh
然后就可以开始运行该程序了
$ cd /home/linaro/Documents/arrow/aws-iot-dragonconnect-c/DragonBoard/bin
$ sudo ./aws_demo
在初始的版本中,还需要用apt-get install git来安装git。
在上面的setup.sh的script命令文件中,在登录成功的账号下,完成了AWS的配置全过程,包括创建和上传jason格式的lambda函数,确定endpoint等。
4.3 connnect-C程序解析
这个文件在Dragonboard上执行的是C语言的aws_demo.c,主要代码见后,(参见https://github.com/ArrowElectronics/aws-iot-dragonconnect-c/blob/master/DragonBoard/src/aws_demo.c#L1-L1)
其中RootCA是公共的秘钥,在对应的Cert目录下,通过MQTT的订阅功能,可以提供对应板载音量按键的的访问和控制功能。程序首先载入参数设置,如果没有则需要新录入,然后listen对应的event。
#include <stdlib.h> | ||
#include <ctype.h> |
||
#include <unistd.h> | ||
#include <signal.h> | ||
#include <memory.h> | ||
#include <sys/time.h> | ||
#include <limits.h> | ||
#include <linux/input.h> | ||
#include "glib.h" | ||
#include "cJSON.h" | ||
#include "gpio.h" | ||
#include "led.h" | ||
#include "mqtt.h" | ||
#include "util.h" | ||
#include "mtime.h" | ||
#define GPIO12 12 | ||
#define MAX_BUF 40 | ||
#define MAX_PAYLOAD 100 | ||
#define VOL_UP_EVENT "/dev/input/event1" | ||
#define VOL_DOWN_EVENT "/dev/input/event0" | ||
//Prototypes | ||
int RegisterEventHandler(char *event, GIOFunc event_fp, void* context); | ||
gboolean On_VolUp_ButtonPress(GIOChannel *source, GIOCondition condition, gpointer data); | ||
gboolean On_VolDown_ButtonPress(GIOChannel *source, GIOCondition condition, gpointer data); | ||
//TODO: Move these in a separate file | ||
int MSG_GetDesiredState( int payload_len, char * payload, bool *des_state); | ||
int MSG_SetReportedState( int payload_len, char * payload, bool rep_state); | ||
//Globals | ||
char certDirectory[PATH_MAX + 1] = "../certs"; | ||
char HostAddress[255] = "__aws_host__"; | ||
uint16_t port = 8883; | ||
char vol_button_topic[]="things/%s/audio/events"; | ||
char led_state_sub_topic[]="$aws/things/%s/shadow/update/delta"; | ||
char led_state_pub_topic[]="$aws/things/%s/shadow/update"; | ||
GMainLoop* loop = NULL; | ||
/******************************************************************************* | ||
* parseInputArgsForConnectParams | ||
* | ||
********************************************************************************/ | ||
void parseInputArgsForConnectParams(int argc, char** argv) { | ||
int opt; | ||
while (-1 != (opt = getopt(argc, argv, "h:p:c:"))) { | ||
switch (opt) { | ||
case 'h': | ||
strcpy(HostAddress, optarg); | ||
DEBUG("Host %s", optarg); | ||
break; | ||
case 'p': | ||
port = atoi(optarg); | ||
DEBUG("arg %s", optarg); | ||
break; | ||
case 'c': | ||
strcpy(certDirectory, optarg); | ||
DEBUG("cert root directory %s", optarg); | ||
break; | ||
case '?': | ||
if (optopt == 'c') { | ||
ERROR("Option -%c requires an argument.", optopt); | ||
} | ||
else if (isprint(optopt)) { | ||
WARN("Unknown option `-%c'.", optopt); | ||
} | ||
else { | ||
WARN("Unknown option character `\\x%x'.", optopt); | ||
} | ||
break; | ||
default: | ||
ERROR("Error in command line argument parsing"); | ||
break; | ||
} | ||
} | ||
} | ||
/******************************************************************************* | ||
* Signal Handler | ||
* | ||
* Called when CTRL-c is pressed to quit the application | ||
* | ||
********************************************************************************/ | ||
void CTRL_C_Handler(int sig) | ||
{ | ||
if(loop) | ||
g_main_loop_quit (loop); | ||
INFO("CTRL-c pressed!"); | ||
} | ||
gboolean timer_func(gpointer user_data) | ||
{ | ||
//INFO("."); | ||
// process mqtt traffic during the main loop | ||
iot_mqtt_yield(10); | ||
return 1; | ||
} | ||
/******************************************************************************* | ||
* Main | ||
* | ||
********************************************************************************/ | ||
int main(int argc, char** argv) | ||
{ | ||
IoT_Error_t rc = NONE_ERROR; | ||
int32_t i = 0; | ||
int ret =0; | ||
char rootCA[PATH_MAX + 1]; | ||
char clientCRT[PATH_MAX + 1]; | ||
char clientKey[PATH_MAX + 1]; | ||
char CurrentWD[PATH_MAX + 1]; | ||
char cafileName[] = "/rootCA.crt"; | ||
char clientCRTName[] = "/aws.crt"; | ||
char clientKeyName[] = "/aws.key"; | ||
char* thingID; | ||
// | ||
//Register ctrl-c handler | ||
// | ||
signal(SIGINT, CTRL_C_Handler); | ||
// | ||
//Parse Input-parameters | ||
// | ||
parseInputArgsForConnectParams(argc, argv); | ||
// | ||
// Get the ThingID/MachineID | ||
// | ||
thingID = GetMachineID(); | ||
// | ||
// Export GPIO12 for LED output | ||
// | ||
ret = Export_GPIO(GPIO12); //Export GPIO12 for LED output | ||
if (ret != 0) { | ||
ERROR("Could not export LED GPIO"); | ||
} | ||
// | ||
//Register Event-handler for Vol+/- button | ||
// | ||
ret = RegisterEventHandler(VOL_UP_EVENT, On_VolUp_ButtonPress, (void*) thingID); | ||
if (ret != 0) { | ||
ERROR("Could not register EventHandler"); | ||
} | ||
ret = RegisterEventHandler(VOL_DOWN_EVENT, On_VolDown_ButtonPress,(void*) thingID); | ||
if (ret != 0) { | ||
ERROR("Could not register EventHandler"); | ||
} | ||
// | ||
//Create the mainloop for polling the button events | ||
// | ||
loop = g_main_loop_new( NULL, false ); | ||
if(!loop) { | ||
ERROR("Could not Create Main loop"); | ||
return -1; | ||
} | ||
// | ||
//Setting path to private key and certificates | ||
// | ||
sprintf(rootCA, "%s%s", certDirectory, cafileName); | ||
sprintf(clientCRT, "%s%s", certDirectory, clientCRTName); | ||
sprintf(clientKey, "%s%s", certDirectory, clientKeyName); | ||
INFO("ThingID: %s", thingID); | ||
INFO("AWS IoT SDK: %d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG); | ||
INFO("rootCA: %s", rootCA); | ||
INFO("clientCRT: %s", clientCRT); | ||
INFO("clientKey: %s\n", clientKey); | ||
struct stat reqFileStat; | ||
if (stat(rootCA, &reqFileStat) < 0 || stat(clientCRT, &reqFileStat) < 0 || | ||
stat(clientKey, &reqFileStat) < 0) | ||
{ | ||
ERROR("Root certificate and client certificate and key MUST be present."); | ||
exit(1); | ||
} | ||
// | ||
// Connect MQTT client | ||
// | ||
INFO("Connecting to %s:%d", HostAddress, port); | ||
rc = MQTT_Connect(HostAddress,port, thingID, rootCA, clientCRT, clientKey); | ||
if (NONE_ERROR != rc) { | ||
ERROR("Error[%d] connecting to %s:%d", rc, HostAddress, port); | ||
} | ||
// | ||
// Subscribe to LED status-changes topic | ||
// | ||
char topic[512]; | ||
sprintf(topic, led_state_sub_topic, thingID); | ||
INFO("Subscribing to topic:%s", topic); | ||
rc = MQTT_Subscribe(topic, QOS_0, MQTTcallbackHandler); | ||
if (NONE_ERROR != rc) { | ||
ERROR("Error[%d] subscribing to topic: %s", rc, led_state_sub_topic); | ||
} | ||
//iot_mqtt_yield(1000); //TODO: clarify | ||
// | ||
//Hook in a function into main loop that calls iot_mqtt_yield in regular intervals | ||
// | ||
g_timeout_add(1000, timer_func, 0); | ||
// | ||
//start the main loop | ||
//This call is blocking until the main loop is exited with a call to g_main_loop_quit(loop) | ||
//from the CTRL-C handler; | ||
INFO("Entering main-loop, please press ctrl-c to quit the demo-app:"); | ||
g_main_loop_run( loop ); | ||
INFO("Cleaning up application ..."); | ||
//Unsubscribe from Topics | ||
//Disconnect MQTT connection | ||
//Unregister GPIO-EventHandlers | ||
//UnExport GPIO's | ||
//Destroy main loop | ||
if(loop) | ||
g_main_loop_unref(loop); | ||
return rc; | ||
} | ||
/******************************************************************************* | ||
* | ||
* | ||
********************************************************************************/ | ||
int RegisterEventHandler(char *event, GIOFunc event_fp, void* context) | ||
{ | ||
GIOChannel *c1=NULL; | ||
c1 = g_io_channel_new_file(event, "r", NULL); | ||
if(!c1) | ||
return -1; | ||
g_io_channel_set_encoding(c1, NULL, NULL); | ||
//g_io_add_watch(c1, G_IO_IN, event_fp, context); | ||
g_io_add_watch_full(c1, G_PRIORITY_HIGH, G_IO_IN, event_fp, context, NULL); | ||
return 0; | ||
} | ||
/******************************************************************************* | ||
* MQTT Callback Handler | ||
* | ||
* Is called when the LEd status changes () | ||
********************************************************************************/ | ||
int MQTTcallbackHandler(MQTTCallbackParams params) | ||
{ | ||
IoT_Error_t rc = NONE_ERROR; | ||
int ret; | ||
bool des_state, rep_state; | ||
int payload_len = (int)params.MessageParams.PayloadLen; | ||
char* payload = (char*)params.MessageParams.pPayload; | ||
//Receive desired LED state in payload | ||
INFO("Subscribe callback"); | ||
INFO("%.*s\t%.*s", | ||
(int)params.TopicNameLen, params.pTopicName, | ||
(int)params.MessageParams.PayloadLen, (char*)params.MessageParams.pPayload); | ||
//Read the desired state from message | ||
ret = MSG_GetDesiredState( payload_len, payload, &des_state); | ||
if(ret !=0) | ||
goto JSON_ERROR; | ||
//Update current LED- and GPIO- state to the desired state | ||
INFO("Updating state: %d\n",des_state); | ||
SetLEDState(UserLED_4, des_state); | ||
Write_GPIO(GPIO12, des_state); | ||
//Write response message | ||
char msg_payload[MAX_PAYLOAD]; | ||
payload = msg_payload; | ||
payload_len = MAX_PAYLOAD; | ||
LED_State led_state; | ||
GetLEDState(UserLED_4, &led_state); | ||
ret = MSG_SetReportedState( payload_len, payload, (int)led_state); | ||
if(ret !=0) | ||
goto JSON_ERROR; | ||
char topic[512]; | ||
sprintf(topic, led_state_pub_topic, GetMachineID()); | ||
printf("Sending payload: %s", payload); | ||
rc = MQTT_Send_Message(topic, payload, strlen(payload) ); | ||
if (NONE_ERROR != rc) | ||
ERROR("Could not publish new LED state to topic: %s", topic ); | ||
return 0; | ||
JSON_ERROR: | ||
ERROR("JSON format Error! %s", (char*)params.MessageParams.pPayload); | ||
return -1; | ||
} | ||
/******************************************************************************* | ||
* | ||
* | ||
********************************************************************************/ | ||
gboolean On_VolUp_ButtonPress(GIOChannel *source, GIOCondition condition, gpointer data) | ||
{ | ||
IoT_Error_t rc = NONE_ERROR; | ||
GError *error=0; | ||
char buf[10]; | ||
char payload[MAX_PAYLOAD]; | ||
struct input_event event; | ||
gsize bytes_read; | ||
//read and clear the event | ||
g_io_channel_seek_position(source, 0, G_SEEK_SET, 0); | ||
g_io_channel_read_chars(source, (gchar*) &event, sizeof(event), &bytes_read, NULL); | ||
// if(bytes_read >0) | ||
// printf("Event1: keypress value=%x, type=%x, code=%x\n", event.value, event.type, event.code); | ||
if(event.code == 0x73 && event.value == 0x1) | ||
{ | ||
INFO("Vol_Up Button pressed!"); | ||
char* thingID = (char*) data; | ||
sprintf(payload, "{\n\"timestamp\": %lu, \"volume\": \"%s\" \n}\n", GetTimeSinceEpoch(), "increase"); | ||
printf("%s", payload); | ||
/**/ | ||
char topic[512]; | ||
sprintf(topic, vol_button_topic, thingID); | ||
rc = MQTT_Send_Message(topic, payload, strlen(payload)); | ||
if (NONE_ERROR != rc) | ||
ERROR("Could not publish event: "); | ||
} | ||
return 1; //indicate event handled | ||
} | ||
/******************************************************************************* | ||
* | ||
* | ||
********************************************************************************/ | ||
gboolean On_VolDown_ButtonPress(GIOChannel *source, GIOCondition condition, gpointer data) | ||
{ | ||
IoT_Error_t rc = NONE_ERROR; | ||
GError *error=0; | ||
char buf[10]; | ||
char payload[MAX_PAYLOAD]; | ||
struct input_event event; | ||
gsize bytes_read; | ||
//read and clear the event | ||
g_io_channel_seek_position(source, 0, G_SEEK_SET, 0); | ||
g_io_channel_read_chars(source, (gchar*) &event, sizeof(event), &bytes_read, NULL); | ||
// if(bytes_read >0) | ||
// printf("Event0: keypress value=%x, type=%x, code=%x\n", event.value, event.type, event.code); | ||
if(event.code == 0x72 && event.value == 0x1) | ||
{ | ||
INFO("Vol_Down Button pressed!"); | ||
char* thingID = (char*) data; | ||
sprintf(payload, "{\n\"timestamp\": %lu, \"volume\": \"%s\" \n}\n", GetTimeSinceEpoch(), "decrease"); | ||
printf("%s", payload); | ||
/**/ | ||
char topic[512]; | ||
sprintf(topic, vol_button_topic, thingID); | ||
rc = MQTT_Send_Message(topic, payload, strlen(payload)); | ||
if (NONE_ERROR != rc) | ||
ERROR("Could not publish event: "); | ||
} | ||
return 1; //indicate event handled | ||
} | ||
int MSG_GetDesiredState( int payload_len, char * payload, bool *des_state) | ||
{ | ||
int ret = 0; | ||
cJSON *root =cJSON_Parse(payload); | ||
if(!root) { | ||
ret = -1; | ||
goto JSON_CLEAN; | ||
} | ||
//Get the desired state | ||
cJSON *state = cJSON_GetObjectItem(root, "state"); | ||
if(!state){ | ||
ret = -1; | ||
goto JSON_CLEAN; | ||
} | ||
*des_state = (bool) cJSON_GetObjectItem(state, "active")->valueint; | ||
ret = 0; //seems like we succeeded | ||
JSON_CLEAN: | ||
if(root) | ||
cJSON_Delete(root); | ||
return ret; | ||
} | ||
int MSG_SetReportedState( int payload_len, char * payload, bool rep_state) | ||
{ | ||
//Publish the new state | ||
cJSON *root, *state, *reported_state; | ||
root = cJSON_CreateObject(); | ||
cJSON_AddItemToObject(root, "state", state = cJSON_CreateObject() ); | ||
cJSON_AddItemToObject(state, "reported", reported_state = cJSON_CreateObject() ); | ||
if (rep_state) | ||
cJSON_AddTrueToObject(reported_state, "active"); | ||
else | ||
cJSON_AddFalseToObject(reported_state, "active"); | ||
snprintf( payload, payload_len, "%s", cJSON_Print(root) ); | ||
JSON_CLEAN: | ||
if(root) | ||
cJSON_Delete(root); | ||
return 0; | ||
} |
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |