217 lines · 4.6 KB · C
RawDownload
/* TODO/BUGS in no order:   should send acknowledgement when an sms is read from /phone/sms, not just on every read   consider notifying RIL of screen state using RIL_REQUEST_SCREEN_STATE to conserve power   too many assumptions made in loop_for_data() about read() giving exactly the right amount of data   parcel code will go crazy if ints overflow   need to support DTMF*/ #include "dat.h"#include "fns.h"#include "error.h"#include "version.h"#include "mp.h"#include "libsec.h"#include "keyboard.h"#include <stdio.h>#include <cutils/sockets.h>#include <stdlib.h>#include <cutils/jstring.h>#include <arpa/inet.h>#include <libgen.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <dlfcn.h> // Inferno-related globals enum{	Qdir,	Qctl}; Dirtab wifitab[] ={	".",	  {Qdir, 0, QTDIR}, 0, DMDIR|0555,	"wifictl",	  {Qctl},	    0, 0666,}; static struct {	QLock l;	Rendez r;	int ready;	int used;	char *msg;} status_msg; #define DPRINT if(1) print voidwifiinit(void){	int pid; 	pid = fork(); 	if (pid == 0) {		chdir("/data/misc/wifi");		execl("/system/bin/wpa_supplicant", "wpa_supplicant", "-D", "wext", "-i", "eth0", "-c", "/data/misc/wifi/wpa_supplicant.conf", NULL);	}//	kproc("phone", loop_for_data, 0, 0);} static Chan*wifiattach(char *spec){	// setup kprocs if necessary	return devattach('w', spec);} static Walkqid*wifiwalk(Chan *c, Chan *nc, char **name, int nname){	return devwalk(c, nc, name, nname, wifitab, nelem(wifitab), devgen);} static intwifistat(Chan *c, uchar *db, int n){	return devstat(c, db, n, wifitab, nelem(wifitab), devgen);} static Chan*wifiopen(Chan *c, int omode){	c = devopen(c, omode, wifitab, nelem(wifitab), devgen); 	return c;} static voidwificlose(Chan *c){	if((c->flag & COPEN) == 0)		return;} static longwifiread(Chan *c, void *va, long n, vlong offset){	char buf[255];	int i, str_offset;	if(c->qid.type & QTDIR) {		return devdirread(c, va, n, wifitab, nelem(wifitab), devgen);	} 	switch((ulong) c->qid.path) {	case Qctl://		return readstr(offset, va, n, power_state ? "on\n" : "off\n");		return 0;	}	return 0;} static longwifiwrite(Chan *c, void *va, long n, vlong offset){	char *pdu;	Rune *runestr;	int i, j;	Cmdbuf *cmd; 	if(c->qid.type & QTDIR)		error(Eperm); 	cmd = parsecmd(va, n);	if(waserror()) {		free(cmd);		nexterror();		return 0;	} 	switch((ulong) c->qid.path) {	case Qctl:		// Here we just look for which commands were sent. The nesting		// can get pretty ugly for commands with a lot of parameters		// (sorry!)//		if(strcmp(cmd->f[0], "on") == 0) {//			radio_power(1);//		} else if(strcmp(cmd->f[0], "off") == 0) {//			radio_power(0);//		} else if(strcmp(cmd->f[0], "net") == 0) {//			if(cmd->nf >= 2) {//				if(strcmp(cmd->f[1], "on") == 0) {//					// Ugly to do a different thing for each//					// # of parameters, but cmd->f is//					// dynamically allocated so we can't//					// just set cmd->f[cmd-nf:end] to NULL//					switch(cmd->nf) {//					case 2: activate_net(NULL, NULL, NULL, NULL);//						break;//					case 3: activate_net(cmd->f[2], NULL, NULL, NULL);//						break;//					case 4: activate_net(cmd->f[2], cmd->f[3], NULL, NULL);//						break;//					case 5: activate_net(cmd->f[2], cmd->f[3], cmd->f[4], NULL);//						break;//					default: activate_net(cmd->f[2], cmd->f[3], cmd->f[4], cmd->f[5]);//						break;//					}//				} else if(strcmp(cmd->f[1], "off") == 0) {//					deactivate_net();//				}//			}//		} else if(strcmp(cmd->f[0], "mute") == 0) {//			set_mute(1);//		} else if(strcmp(cmd->f[0], "unmute") == 0) {//			set_mute(0);//		} else if(strcmp(cmd->f[0], "route") == 0) {//			if(cmd->nf >= 2) {//				if(strcmp(cmd->f[1], "earpiece") == 0) {//					af_setParameters("routing=1");//				} else if(strcmp(cmd->f[1], "speaker") == 0) {//					af_setParameters("routing=2");//				} else if(strcmp(cmd->f[1], "headphone") == 0) {//					af_setParameters("routing=3");//				}//			}//		} else if(strcmp(cmd->f[0], "volume") == 0) {//			if(cmd->nf >= 2) {//				switch(strtol(cmd->f[1], NULL, 10)) {//				case 0: af_setVoiceVolume(0.0); break;//				case 1: af_setVoiceVolume(0.2); break;//				case 2: af_setVoiceVolume(0.4); break;//				case 3: af_setVoiceVolume(0.6); break;//				case 4: af_setVoiceVolume(0.8); break;//				case 5: af_setVoiceVolume(1.0); break;//				default: af_setVoiceVolume(1.0); break;//				}//			}//		}		break;	}	poperror();	free(cmd);	return n;} Dev wifidevtab = {	'w',	"wifi", 	wifiinit,	wifiattach,	wifiwalk,	wifistat,	wifiopen,	devcreate,	wificlose,	wifiread,	devbread,	wifiwrite,	devbwrite,	devremove,	devwstat};