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
$cdscripts
$ ./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" | ||
#defineGPIO1212 | ||
#defineMAX_BUF40 | ||
#defineMAX_PAYLOAD100 | ||
#defineVOL_UP_EVENT"/dev/input/event1" | ||
#defineVOL_DOWN_EVENT"/dev/input/event0" | ||
//Prototypes | ||
intRegisterEventHandler(char*event, GIOFunc event_fp,void* context); | ||
gbooleanOn_VolUp_ButtonPress(GIOChannel *source, GIOCondition condition, gpointer data); | ||
gbooleanOn_VolDown_ButtonPress(GIOChannel *source, GIOCondition condition, gpointer data); | ||
//TODO: Move these in a separate file | ||
intMSG_GetDesiredState(intpayload_len,char* payload,bool*des_state); | ||
intMSG_SetReportedState(intpayload_len,char* payload,boolrep_state); | ||
//Globals | ||
charcertDirectory[PATH_MAX +1] ="../certs"; | ||
charHostAddress[255] ="__aws_host__"; | ||
uint16_tport =8883; | ||
charvol_button_topic[]="things/%s/audio/events"; | ||
charled_state_sub_topic[]="$aws/things/%s/shadow/update/delta"; | ||
charled_state_pub_topic[]="$aws/things/%s/shadow/update"; | ||
GMainLoop* loop =NULL; | ||
/******************************************************************************* | ||
* parseInputArgsForConnectParams | ||
* | ||
********************************************************************************/ | ||
voidparseInputArgsForConnectParams(intargc,char** argv) { | ||
intopt; | ||
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 -%crequires an argument.",optopt); | ||
} | ||
elseif(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 | ||
* | ||
********************************************************************************/ | ||
voidCTRL_C_Handler(intsig) | ||
{ | ||
if(loop) | ||
g_main_loop_quit(loop); | ||
INFO("CTRL-c pressed!"); | ||
} | ||
gbooleantimer_func(gpointer user_data) | ||
{ | ||
//INFO("."); | ||
// process mqtt traffic during the main loop | ||
iot_mqtt_yield(10); | ||
return1; | ||
} | ||
/******************************************************************************* | ||
* Main | ||
* | ||
********************************************************************************/ | ||
intmain(intargc,char** argv) | ||
{ | ||
IoT_Error_t rc = NONE_ERROR; | ||
int32_ti =0; | ||
intret =0; | ||
charrootCA[PATH_MAX +1]; | ||
charclientCRT[PATH_MAX +1]; | ||
charclientKey[PATH_MAX +1]; | ||
charCurrentWD[PATH_MAX +1]; | ||
charcafileName[] ="/rootCA.crt"; | ||
charclientCRTName[] ="/aws.crt"; | ||
charclientKeyName[] ="/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); | ||
structstat 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 | ||
// | ||
chartopic[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); | ||
returnrc; | ||
} | ||
/******************************************************************************* | ||
* | ||
* | ||
********************************************************************************/ | ||
intRegisterEventHandler(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); | ||
return0; | ||
} | ||
/******************************************************************************* | ||
* MQTT Callback Handler | ||
* | ||
* Is called when the LEd status changes () | ||
********************************************************************************/ | ||
intMQTTcallbackHandler(MQTTCallbackParams params) | ||
{ | ||
IoT_Error_t rc = NONE_ERROR; | ||
intret; | ||
booldes_state, rep_state; | ||
intpayload_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) | ||
gotoJSON_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 | ||
charmsg_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) | ||
gotoJSON_ERROR; | ||
chartopic[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 ); | ||
return0; | ||
JSON_ERROR: | ||
ERROR("JSON format Error!%s", (char*)params.MessageParams.pPayload); | ||
return-1; | ||
} | ||
/******************************************************************************* | ||
* | ||
* | ||
********************************************************************************/ | ||
gbooleanOn_VolUp_ButtonPress(GIOChannel *source, GIOCondition condition, gpointer data) | ||
{ | ||
IoT_Error_t rc = NONE_ERROR; | ||
GError *error=0; | ||
charbuf[10]; | ||
charpayload[MAX_PAYLOAD]; | ||
structinput_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); | ||
/**/ | ||
chartopic[512]; | ||
sprintf(topic, vol_button_topic, thingID); | ||
rc =MQTT_Send_Message(topic, payload,strlen(payload)); | ||
if(NONE_ERROR != rc) | ||
ERROR("Could not publish event:"); | ||
} | ||
return1;//indicate event handled | ||
} | ||
/******************************************************************************* | ||
* | ||
* | ||
********************************************************************************/ | ||
gbooleanOn_VolDown_ButtonPress(GIOChannel *source, GIOCondition condition, gpointer data) | ||
{ | ||
IoT_Error_t rc = NONE_ERROR; | ||
GError *error=0; | ||
charbuf[10]; | ||
charpayload[MAX_PAYLOAD]; | ||
structinput_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); | ||
/**/ | ||
chartopic[512]; | ||
sprintf(topic, vol_button_topic, thingID); | ||
rc =MQTT_Send_Message(topic, payload,strlen(payload)); | ||
if(NONE_ERROR != rc) | ||
ERROR("Could not publish event:"); | ||
} | ||
return1;//indicate event handled | ||
} | ||
intMSG_GetDesiredState(intpayload_len,char* payload,bool*des_state) | ||
{ | ||
intret =0; | ||
cJSON *root =cJSON_Parse(payload); | ||
if(!root) { | ||
ret = -1; | ||
gotoJSON_CLEAN; | ||
} | ||
//Get the desired state | ||
cJSON *state =cJSON_GetObjectItem(root,"state"); | ||
if(!state){ | ||
ret = -1; | ||
gotoJSON_CLEAN; | ||
} | ||
*des_state = (bool)cJSON_GetObjectItem(state,"active")->valueint; | ||
ret =0;//seems like we succeeded | ||
JSON_CLEAN: | ||
if(root) | ||
cJSON_Delete(root); | ||
returnret; | ||
} | ||
intMSG_SetReportedState(intpayload_len,char* payload,boolrep_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); | ||
return0; | ||
} |